Merge lp:~abentley/launchpad/sharing-spinners into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Merged at revision: 12854
Proposed branch: lp:~abentley/launchpad/sharing-spinners
Merge into: lp:launchpad
Diff against target: 308 lines (+94/-20)
4 files modified
lib/lp/translations/javascript/sourcepackage_sharing_details.js (+31/-15)
lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html (+14/-5)
lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.js (+33/-0)
lib/lp/translations/templates/sourcepackage-sharing-details.pt (+16/-0)
To merge this branch: bzr merge lp:~abentley/launchpad/sharing-spinners
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+57888@code.launchpad.net

Commit message

Add spinners to translation-sharing actions.

Description of the change

= Summary =
Fix bug #758922: Missing spinners on translations +sharing-details js actions

== Proposed fix ==
Add hidden spinners to web page, show them as needed.

== Pre-implementation notes ==
None

== Implementation details ==
Added a new "pending" boolean to checklist items. When this is true, the TranslationSharingController will show the spinner and hide the picker. When this is false, the TranslationSharingController will hide the spinner and may show the picker.

== Tests ==
firefox lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html

== Demo and Q/A ==
Go to the +sharing-details page for a SourcePackage. Ensure that when each setting is changed, a spinner is shown. This should happen both when the list item was formlerly uncheckd and when it was formerly checked.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/translations/templates/sourcepackage-sharing-details.pt
  lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.js
  lib/lp/translations/javascript/sourcepackage_sharing_details.js
  lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/translations/javascript/sourcepackage_sharing_details.js'
--- lib/lp/translations/javascript/sourcepackage_sharing_details.js 2011-04-18 13:27:33 +0000
+++ lib/lp/translations/javascript/sourcepackage_sharing_details.js 2011-04-18 13:41:39 +0000
@@ -26,7 +26,8 @@
26 }26 }
27 },27 },
28 // The HTML identifier of the item.28 // The HTML identifier of the item.
29 identifier: null29 identifier: null,
30 pending: {value: false}
30};31};
31Y.extend(CheckItem, Y.Base, {32Y.extend(CheckItem, Y.Base, {
32});33});
@@ -224,9 +225,8 @@
224}225}
225226
226227
227function IOHandler(flash_target, error_handler) {228function IOHandler(controller, check, error_handler) {
228 that = this;229 that = this;
229 this.flash_target = flash_target;
230 if (!Y.Lang.isValue(error_handler)){230 if (!Y.Lang.isValue(error_handler)){
231 this.error_handler = new Y.lp.client.ErrorHandler();231 this.error_handler = new Y.lp.client.ErrorHandler();
232 }232 }
@@ -234,7 +234,10 @@
234 this.error_handler = error_handler;234 this.error_handler = error_handler;
235 }235 }
236 this.error_handler.showError = function(error_msg) {236 this.error_handler.showError = function(error_msg) {
237 Y.lp.app.errors.display_error(Y.one(that.flash_target), error_msg);237 check.set('pending', false);
238 controller.update_check(check);
239 var flash_target = Y.one(controller.visible_check_selector(check));
240 Y.lp.app.errors.display_error(Y.one(flash_target), error_msg);
238 };241 };
239}242}
240243
@@ -373,6 +376,8 @@
373 var productseries_check = that.get('tsconfig').get('product_series');376 var productseries_check = that.get('tsconfig').get('product_series');
374 var lp_client = new Y.lp.client.Launchpad();377 var lp_client = new Y.lp.client.Launchpad();
375 function save_productseries(config) {378 function save_productseries(config) {
379 productseries_check.set('pending', true);
380 that.update_check(productseries_check);
376 var source_package = that.get('source_package');381 var source_package = that.get('source_package');
377 config.parameters = {382 config.parameters = {
378 productseries: productseries_summary.api_uri};383 productseries: productseries_summary.api_uri};
@@ -398,11 +403,11 @@
398 }403 }
399 function set_usage(product) {404 function set_usage(product) {
400 that.replace_product(product);405 that.replace_product(product);
406 productseries_check.set('pending', false);
401 that.update();407 that.update();
402 that.flash_check_green(productseries_check);408 that.flash_check_green(productseries_check);
403 }409 }
404 var css_selector = this.visible_check_selector(productseries_check);410 var io_handler = new IOHandler(this, productseries_check);
405 var io_handler = new IOHandler(css_selector);
406 save_productseries(io_handler.chain_config(411 save_productseries(io_handler.chain_config(
407 get_productseries, cache_productseries, cache_branch, set_usage));412 get_productseries, cache_productseries, cache_branch, set_usage));
408 },413 },
@@ -421,6 +426,8 @@
421 * closure, such as "that" and "branch_summary".426 * closure, such as "that" and "branch_summary".
422 */427 */
423 function save_branch(config) {428 function save_branch(config) {
429 branch_check.set('pending', true);
430 that.update_check(branch_check);
424 productseries.set('branch_link', branch_summary.api_uri);431 productseries.set('branch_link', branch_summary.api_uri);
425 productseries.lp_save(config);432 productseries.lp_save(config);
426 }433 }
@@ -433,11 +440,11 @@
433 }440 }
434 function finish(new_productseries){441 function finish(new_productseries){
435 that.replace_productseries(new_productseries);442 that.replace_productseries(new_productseries);
443 branch_check.set('pending', false);
436 that.update();444 that.update();
437 that.flash_check_green(branch_check);445 that.flash_check_green(branch_check);
438 }446 }
439 css_selector = that.visible_check_selector(branch_check);447 var io_handler = new IOHandler(this, branch_check);
440 var io_handler = new IOHandler(css_selector);
441 save_branch(io_handler.chain_config(get_branch, set_link, finish));448 save_branch(io_handler.chain_config(get_branch, set_link, finish));
442 },449 },
443 /**450 /**
@@ -475,6 +482,7 @@
475 */482 */
476 update_check: function(check){483 update_check: function(check){
477 var complete = Y.one(this.check_selector(check, true));484 var complete = Y.one(this.check_selector(check, true));
485 var hide_picker = !check.get('enabled') || check.get('pending');
478 var link = complete.one('.link a');486 var link = complete.one('.link a');
479 if (link !== null){487 if (link !== null){
480 link.set('href', check.get('url'));488 link.set('href', check.get('url'));
@@ -484,14 +492,19 @@
484 complete.toggleClass('lowlight', !check.get('enabled'));492 complete.toggleClass('lowlight', !check.get('enabled'));
485 var complete_picker = Y.one(this.picker_selector(check, true));493 var complete_picker = Y.one(this.picker_selector(check, true));
486 if (complete_picker !== null) {494 if (complete_picker !== null) {
487 complete_picker.toggleClass('unseen', !check.get('enabled'));495 complete_picker.toggleClass('unseen', hide_picker);
488 }496 }
489 var incomplete = Y.one(this.check_selector(check, false));497 var incomplete = Y.one(this.check_selector(check, false));
490 incomplete.toggleClass('unseen', check.get('complete'));498 incomplete.toggleClass('unseen', check.get('complete'));
491 incomplete.toggleClass('lowlight', !check.get('enabled'));499 incomplete.toggleClass('lowlight', !check.get('enabled'));
492 var incomplete_picker = Y.one(this.picker_selector(check, false));500 var incomplete_picker = Y.one(this.picker_selector(check, false));
493 if (incomplete_picker !== null) {501 if (incomplete_picker !== null) {
494 incomplete_picker.toggleClass('unseen', !check.get('enabled'));502 incomplete_picker.toggleClass('unseen', hide_picker);
503 }
504 var selector = this.visible_check_selector(check) + '-spinner';
505 var spinner = Y.one(selector);
506 if (Y.Lang.isValue(spinner)){
507 spinner.toggleClass('unseen', !check.get('pending'));
495 }508 }
496 },509 },
497 flash_check_green: function(check) {510 flash_check_green: function(check) {
@@ -542,14 +555,15 @@
542 product_series.set('translations_autoimport_mode', mode);555 product_series.set('translations_autoimport_mode', mode);
543 var autoimport_check = sharing_controller.get(556 var autoimport_check = sharing_controller.get(
544 'tsconfig').get('autoimport');557 'tsconfig').get('autoimport');
545 var css_selector = sharing_controller.visible_check_selector(558 handler = new IOHandler(sharing_controller, autoimport_check);
546 autoimport_check);
547 handler = new IOHandler(css_selector);
548 function update_controller() {559 function update_controller() {
549 sharing_controller.set_autoimport_mode(mode);560 sharing_controller.set_autoimport_mode(mode);
561 autoimport_check.set('pending', false);
550 sharing_controller.update();562 sharing_controller.update();
551 sharing_controller.flash_check_green(autoimport_check);563 sharing_controller.flash_check_green(autoimport_check);
552 }564 }
565 autoimport_check.set('pending', true);
566 sharing_controller.update_check(autoimport_check);
553 /* XXX: AaronBentley 2011-04-04 bug=369293: Avoid 412 on repeated567 /* XXX: AaronBentley 2011-04-04 bug=369293: Avoid 412 on repeated
554 * changes. This does not increase the risk of changing from a568 * changes. This does not increase the risk of changing from a
555 * stale value, because the staleness check is not reasonable.569 * stale value, because the staleness check is not reasonable.
@@ -581,12 +595,14 @@
581 }595 }
582 function replace_product(new_product) {596 function replace_product(new_product) {
583 sharing_controller.replace_product(new_product);597 sharing_controller.replace_product(new_product);
598 usage.set('pending', false);
584 sharing_controller.update();599 sharing_controller.update();
585 sharing_controller.flash_check_green(usage);600 sharing_controller.flash_check_green(usage);
586 }601 }
587 css_selector = sharing_controller.visible_check_selector(usage);
588 var io_handler = new IOHandler(602 var io_handler = new IOHandler(
589 css_selector, new Y.lp.client.FormErrorHandler());603 sharing_controller, usage, new Y.lp.client.FormErrorHandler());
604 usage.set('pending', true);
605 sharing_controller.update_check(usage);
590 var config = io_handler.chain_config(606 var config = io_handler.chain_config(
591 get_productseries, replace_productseries, get_product,607 get_productseries, replace_productseries, get_product,
592 replace_product);608 replace_product);
593609
=== modified file 'lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html'
--- lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html 2011-04-04 19:36:27 +0000
+++ lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.html 2011-04-18 13:41:39 +0000
@@ -46,8 +46,13 @@
46 <div id="branch-complete">Branch selected: <span class="link"><a46 <div id="branch-complete">Branch selected: <span class="link"><a
47 href="#" class="link"></a></span>47 href="#" class="link"></a></span>
48 <span id="branch-complete-picker"><a href="#"></a></span>48 <span id="branch-complete-picker"><a href="#"></a></span>
49 </div>49 <img src="../../../../canonical/launchpad/images/spinner.gif"
50 <div id="branch-incomplete">No branch selected.</div>50 id="branch-complete-spinner"/>
51 </div>
52 <div id="branch-incomplete">No branch selected.
53 <img src="../../../../canonical/launchpad/images/spinner.gif"
54 id="branch-incomplete-spinner"/>
55 </div>
51 <span id="branch-incomplete-picker"><a href="#"></a></span>56 <span id="branch-incomplete-picker"><a href="#"></a></span>
52 <div id="translation-incomplete">57 <div id="translation-incomplete">
53 Translations are not enabled on the upstream project.58 Translations are not enabled on the upstream project.
@@ -58,12 +63,16 @@
58 <a href="#enable-translations"></a>63 <a href="#enable-translations"></a>
59 </div>64 </div>
60 <div id="upstream-sync-incomplete">65 <div id="upstream-sync-incomplete">
61 Automatic synchronization of translations is not enabled.66 Automatic synchronization of translations is not enabled.
62 <a href="#enable-sync"></a>67 <img src="../../../../canonical/launchpad/images/spinner.gif"
68 id="upstream-sync-incomplete-spinner"/>
69 <span id="upstream-sync-incomplete-picker"><a href="#enable-sync"></a></span>
63 </div>70 </div>
64 <div id="upstream-sync-complete">71 <div id="upstream-sync-complete">
65 Automatic synchronization of translations is enabled.72 Automatic synchronization of translations is enabled.
66 <a href="#enable-sync"></a>73 <span id="upstream-sync-complete-picker"><a href="#enable-sync"></a></span>
74 <img src="../../../../canonical/launchpad/images/spinner.gif"
75 id="upstream-sync-complete-spinner"/>
67 </div>76 </div>
68 </div>77 </div>
69 <!-- The test output -->78 <!-- The test output -->
7079
=== modified file 'lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.js'
--- lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.js 2011-04-14 15:43:14 +0000
+++ lib/lp/translations/javascript/tests/test_sourcepackage_sharing_details.js 2011-04-18 13:41:39 +0000
@@ -210,6 +210,39 @@
210 ctrl.update_check(branch);210 ctrl.update_check(branch);
211 Y.Assert.isFalse(incomplete.hasClass('lowlight'));211 Y.Assert.isFalse(incomplete.hasClass('lowlight'));
212 },212 },
213 test_update_check_pending: function(){
214 var incomplete_spinner = Y.one(
215 '#upstream-sync-incomplete-spinner');
216 var ctrl = new TranslationSharingController();
217 var autoimport = ctrl.get('tsconfig').get('autoimport');
218 var branch = ctrl.get('tsconfig').get('branch');
219 branch.set_link('a', 'b');
220 var incomplete_picker = Y.one(
221 ctrl.picker_selector(autoimport, false));
222 ctrl.update_check(autoimport);
223 Y.Assert.isTrue(
224 incomplete_spinner.hasClass('unseen'), 'spinner unseen');
225 Y.Assert.isFalse(
226 incomplete_picker.hasClass('unseen'), 'picker seen');
227 autoimport.set('pending', true);
228 ctrl.update_check(autoimport);
229 Y.Assert.isFalse(
230 incomplete_spinner.hasClass('unseen'), 'spinner seen');
231 Y.Assert.isTrue(
232 incomplete_picker.hasClass('unseen'), 'picker unseen');
233 autoimport.set('complete', true);
234 var complete_spinner = Y.one(
235 '#upstream-sync-complete-spinner');
236 var complete_picker = Y.one(
237 ctrl.picker_selector(autoimport, true));
238 ctrl.update_check(autoimport);
239 Y.Assert.isFalse(complete_spinner.hasClass('unseen'));
240 Y.Assert.isTrue(complete_picker.hasClass('unseen'));
241 autoimport.set('pending', false);
242 ctrl.update_check(autoimport);
243 Y.Assert.isTrue(complete_spinner.hasClass('unseen'));
244 Y.Assert.isFalse(complete_picker.hasClass('unseen'));
245 },
213 test_set_autoimport_mode: function() {246 test_set_autoimport_mode: function() {
214 var ctrl = new TranslationSharingController();247 var ctrl = new TranslationSharingController();
215 var check = ctrl.get('tsconfig').get('autoimport');248 var check = ctrl.get('tsconfig').get('autoimport');
216249
=== modified file 'lib/lp/translations/templates/sourcepackage-sharing-details.pt'
--- lib/lp/translations/templates/sourcepackage-sharing-details.pt 2011-04-11 17:16:28 +0000
+++ lib/lp/translations/templates/sourcepackage-sharing-details.pt 2011-04-18 13:41:39 +0000
@@ -39,6 +39,8 @@
39 <span id="packaging-incomplete-picker">39 <span id="packaging-incomplete-picker">
40 <a tal:replace="structure view/set_packaging_link/escapedtext" />40 <a tal:replace="structure view/set_packaging_link/escapedtext" />
41 </span>41 </span>
42 <img src="/@@/spinner" class="unseen"
43 id="packaging-incomplete-spinner"/>
42 </li>44 </li>
43 <li tal:attributes="class view/packaging_complete_class"45 <li tal:attributes="class view/packaging_complete_class"
44 id="packaging-complete">46 id="packaging-complete">
@@ -51,6 +53,8 @@
51 <span id="packaging-complete-picker">53 <span id="packaging-complete-picker">
52 <a tal:replace="structure view/change_packaging_link/escapedtext" />54 <a tal:replace="structure view/change_packaging_link/escapedtext" />
53 </span>55 </span>
56 <img src="/@@/spinner" class="unseen"
57 id="packaging-complete-spinner"/>
54 <a tal:replace="structure view/remove_packaging_link/escapedtext" />58 <a tal:replace="structure view/remove_packaging_link/escapedtext" />
55 </li>59 </li>
56 <li tal:attributes="class view/branch_incomplete_class"60 <li tal:attributes="class view/branch_incomplete_class"
@@ -59,6 +63,8 @@
59 <span id="branch-incomplete-picker">63 <span id="branch-incomplete-picker">
60 <a tal:replace="structure view/new_branch_link/escapedtext" />64 <a tal:replace="structure view/new_branch_link/escapedtext" />
61 </span>65 </span>
66 <img src="/@@/spinner" class="unseen"
67 id="branch-incomplete-spinner"/>
62 </li>68 </li>
63 <li tal:attributes="class view/branch_complete_class"69 <li tal:attributes="class view/branch_complete_class"
64 id="branch-complete">70 id="branch-complete">
@@ -69,6 +75,8 @@
69 <span id="branch-complete-picker">75 <span id="branch-complete-picker">
70 <a tal:replace="structure view/change_branch_link/escapedtext" />76 <a tal:replace="structure view/change_branch_link/escapedtext" />
71 </span>77 </span>
78 <img src="/@@/spinner" class="unseen"
79 id="branch-complete-spinner"/>
72 </li>80 </li>
73 <li tal:attributes="class view/translations_disabled_class"81 <li tal:attributes="class view/translations_disabled_class"
74 id="translation-incomplete">82 id="translation-incomplete">
@@ -76,6 +84,8 @@
76 <span id="translation-incomplete-picker">84 <span id="translation-incomplete-picker">
77 <a tal:replace="structure view/configure_translations_link_unconfigured/escapedtext" />85 <a tal:replace="structure view/configure_translations_link_unconfigured/escapedtext" />
78 </span>86 </span>
87 <img src="/@@/spinner" class="unseen"
88 id="translation-incomplete-spinner"/>
79 </li>89 </li>
80 <li tal:attributes="class view/translations_enabled_class"90 <li tal:attributes="class view/translations_enabled_class"
81 id="translation-complete">91 id="translation-complete">
@@ -83,6 +93,8 @@
83 <span id="translation-complete-picker">93 <span id="translation-complete-picker">
84 <a tal:replace="structure view/configure_translations_link_configured/escapedtext" />94 <a tal:replace="structure view/configure_translations_link_configured/escapedtext" />
85 </span>95 </span>
96 <img src="/@@/spinner" class="unseen"
97 id="translation-complete-spinner"/>
86 </li>98 </li>
87 <li tal:attributes="class view/upstream_sync_disabled_class"99 <li tal:attributes="class view/upstream_sync_disabled_class"
88 id="upstream-sync-incomplete">100 id="upstream-sync-incomplete">
@@ -90,6 +102,8 @@
90 <span id="upstream-sync-incomplete-picker">102 <span id="upstream-sync-incomplete-picker">
91 <a tal:replace="structure view/translation_sync_link_unconfigured/escapedtext" />103 <a tal:replace="structure view/translation_sync_link_unconfigured/escapedtext" />
92 </span>104 </span>
105 <img src="/@@/spinner" class="unseen"
106 id="upstream-sync-incomplete-spinner"/>
93 </li>107 </li>
94 <li tal:attributes="class view/upstream_sync_enabled_class"108 <li tal:attributes="class view/upstream_sync_enabled_class"
95 id="upstream-sync-complete">109 id="upstream-sync-complete">
@@ -97,6 +111,8 @@
97 <span id="upstream-sync-complete-picker">111 <span id="upstream-sync-complete-picker">
98 <a tal:replace="structure view/translation_sync_link_configured/escapedtext" />112 <a tal:replace="structure view/translation_sync_link_configured/escapedtext" />
99 </span>113 </span>
114 <img src="/@@/spinner" class="unseen"
115 id="upstream-sync-complete-spinner"/>
100 </li>116 </li>
101 </ul>117 </ul>
102 </dd>118 </dd>