summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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>