summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliot Smith <elliot.smith@intel.com>2016-07-15 15:20:36 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-08-11 00:09:27 +0100
commit01c8496d47eb37a44442e79a7b071321599d7c6e (patch)
treed99258b6e3bba016815a1b0a0e1e70d5872babe3
parent6172fb1923a34b9ba286debcb89653a347c0f5e0 (diff)
downloadpoky-01c8496d47eb37a44442e79a7b071321599d7c6e.tar.gz
bitbake: toaster: show loading spinner after creating custom image
Creating a custom image through the "New custom image" dialog can sometimes result in a long pause between pressing the button to create the image, and being transferred to the page showing details of its content. This can make it appear as though pressing the button had no effect. To prevent this from happening, disable the button and text box in the new custom image dialog after the "Create image" button is pressed. Also show a loading spinner and "loading..." text on the button to make it clear that the application is still responding. [YOCTO #9475] (Bitbake rev: dd8bede91e08c0b64b949ca98c74e6144da88fd1) Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/toastergui/static/css/default.css12
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/libtoaster.js20
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js33
-rw-r--r--bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html7
4 files changed, 66 insertions, 6 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/css/default.css b/bitbake/lib/toaster/toastergui/static/css/default.css
index 3a0fbb82c8..0961c97747 100644
--- a/bitbake/lib/toaster/toastergui/static/css/default.css
+++ b/bitbake/lib/toaster/toastergui/static/css/default.css
@@ -250,6 +250,18 @@ code { color: #333; background-color: transparent; }
250/* Style the special no results message in the custom image details page */ 250/* Style the special no results message in the custom image details page */
251[id^="no-results-special-"] > .alert-warning > ol { margin-top: 10px; } 251[id^="no-results-special-"] > .alert-warning > ol { margin-top: 10px; }
252 252
253/* style the loading spinner in the new custom image dialog */
254#create-new-custom-image-btn [data-role="loading-state"] {
255 padding-left: 16px;
256}
257
258/* icon has to be absolutely positioned, otherwise the spin animation doesn't work */
259#create-new-custom-image-btn [data-role="loading-state"] .icon-spinner {
260 position: absolute;
261 left: 26px;
262 bottom: 26px;
263}
264
253/* Style the content of modal dialogs */ 265/* Style the content of modal dialogs */
254.modal-footer { text-align: left; } 266.modal-footer { text-align: left; }
255.date-filter-controls { margin-top: 10px; } 267.date-filter-controls { margin-top: 10px; }
diff --git a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
index a61b10e972..f56affd8ea 100644
--- a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -436,8 +436,23 @@ var libtoaster = (function () {
436 }); 436 });
437 } 437 }
438 438
439 // if true, the loading spinner for Ajax requests will be displayed
440 // if requests take more than 1200ms
441 var ajaxLoadingTimerEnabled = true;
442
443 // turn on the page-level loading spinner for Ajax requests
444 function _enableAjaxLoadingTimer() {
445 ajaxLoadingTimerEnabled = true;
446 }
447
448 // turn off the page-level loading spinner for Ajax requests
449 function _disableAjaxLoadingTimer() {
450 ajaxLoadingTimerEnabled = false;
451 }
439 452
440 return { 453 return {
454 enableAjaxLoadingTimer: _enableAjaxLoadingTimer,
455 disableAjaxLoadingTimer: _disableAjaxLoadingTimer,
441 reload_params : reload_params, 456 reload_params : reload_params,
442 startABuild : _startABuild, 457 startABuild : _startABuild,
443 cancelABuild : _cancelABuild, 458 cancelABuild : _cancelABuild,
@@ -485,7 +500,6 @@ function reload_params(params) {
485 window.location.href = url+"?"+callparams.join('&'); 500 window.location.href = url+"?"+callparams.join('&');
486} 501}
487 502
488
489/* Things that happen for all pages */ 503/* Things that happen for all pages */
490$(document).ready(function() { 504$(document).ready(function() {
491 505
@@ -644,7 +658,9 @@ $(document).ready(function() {
644 window.clearTimeout(ajaxLoadingTimer); 658 window.clearTimeout(ajaxLoadingTimer);
645 659
646 ajaxLoadingTimer = window.setTimeout(function() { 660 ajaxLoadingTimer = window.setTimeout(function() {
647 $("#loading-notification").fadeIn(); 661 if (libtoaster.ajaxLoadingTimerEnabled) {
662 $("#loading-notification").fadeIn();
663 }
648 }, 1200); 664 }, 1200);
649 }); 665 });
650 666
diff --git a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
index 8356c02b5a..dace8e3258 100644
--- a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
+++ b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
@@ -25,7 +25,11 @@ function newCustomImageModalInit(){
25 var duplicateNameMsg = "An image with this name already exists. Image names must be unique."; 25 var duplicateNameMsg = "An image with this name already exists. Image names must be unique.";
26 var duplicateImageInProjectMsg = "An image with this name already exists in this project." 26 var duplicateImageInProjectMsg = "An image with this name already exists in this project."
27 var invalidBaseRecipeIdMsg = "Please select an image to customise."; 27 var invalidBaseRecipeIdMsg = "Please select an image to customise.";
28 28
29 // set button to "submit" state and enable text entry so user can
30 // enter the custom recipe name
31 showSubmitState();
32
29 /* capture clicks on radio buttons inside the modal; when one is selected, 33 /* capture clicks on radio buttons inside the modal; when one is selected,
30 * set the recipe on the modal 34 * set the recipe on the modal
31 */ 35 */
@@ -40,6 +44,9 @@ function newCustomImageModalInit(){
40 }); 44 });
41 45
42 newCustomImgBtn.click(function(e){ 46 newCustomImgBtn.click(function(e){
47 // disable the button and text entry
48 showLoadingState();
49
43 e.preventDefault(); 50 e.preventDefault();
44 51
45 var baseRecipeId = imgCustomModal.data('recipe'); 52 var baseRecipeId = imgCustomModal.data('recipe');
@@ -69,12 +76,33 @@ function newCustomImageModalInit(){
69 } 76 }
70 } else { 77 } else {
71 imgCustomModal.modal('hide'); 78 imgCustomModal.modal('hide');
79 imgCustomModal.one('hidden.bs.modal', showSubmitState);
72 window.location.replace(ret.url + '?notify=new'); 80 window.location.replace(ret.url + '?notify=new');
73 } 81 }
74 }); 82 });
75 } 83 }
76 }); 84 });
77 85
86 // enable text entry, show "Create image" button text
87 function showSubmitState() {
88 libtoaster.enableAjaxLoadingTimer();
89 newCustomImgBtn.find('[data-role="loading-state"]').hide();
90 newCustomImgBtn.find('[data-role="submit-state"]').show();
91 newCustomImgBtn.removeAttr('disabled');
92 nameInput.removeAttr('disabled');
93 }
94
95 // disable text entry, show "Creating image..." button text;
96 // we also disabled the page-level ajax loading spinner while this spinner
97 // is active
98 function showLoadingState() {
99 libtoaster.disableAjaxLoadingTimer();
100 newCustomImgBtn.find('[data-role="submit-state"]').hide();
101 newCustomImgBtn.find('[data-role="loading-state"]').show();
102 newCustomImgBtn.attr('disabled', 'disabled');
103 nameInput.attr('disabled', 'disabled');
104 }
105
78 function showNameError(text){ 106 function showNameError(text){
79 invalidNameHelp.text(text); 107 invalidNameHelp.text(text);
80 invalidNameHelp.show(); 108 invalidNameHelp.show();
@@ -167,6 +195,5 @@ function newCustomImageModalSetRecipes(baseRecipes) {
167 195
168 // show the radio button container 196 // show the radio button container
169 imageSelector.show(); 197 imageSelector.show();
170 198 }
171 }
172} 199}
diff --git a/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html b/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
index 5caa68392c..d448d3afc1 100644
--- a/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
+++ b/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
@@ -48,7 +48,12 @@
48 </div> 48 </div>
49 49
50 <div class="modal-footer"> 50 <div class="modal-footer">
51 <button id="create-new-custom-image-btn" class="btn btn-primary btn-lg" data-original-title="" title="" disabled>Create custom image</button> 51 <button id="create-new-custom-image-btn" class="btn btn-primary btn-large" disabled>
52 <span data-role="submit-state">Create custom image</span>
53 <span data-role="loading-state" style="display:none">
54 <i class="fa-pulse icon-spinner"></i>&nbsp;Creating custom image...
55 </span>
56 </button>
52 </div> 57 </div>
53 </div> 58 </div>
54 </div> 59 </div>