aboutsummaryrefslogtreecommitdiffstats
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 0d3570a21fd..96eedfcb7a9 100644
--- a/bitbake/lib/toaster/toastergui/static/css/default.css
+++ b/bitbake/lib/toaster/toastergui/static/css/default.css
@@ -249,6 +249,18 @@ code { color: #333; background-color: transparent; }
/* Style the special no results message in the custom image details page */
[id^="no-results-special-"] > .alert-warning > ol { margin-top: 10px; }
+/* style the loading spinner in the new custom image dialog */
+#create-new-custom-image-btn [data-role="loading-state"] {
+ padding-left: 16px;
+}
+
+/* icon has to be absolutely positioned, otherwise the spin animation doesn't work */
+#create-new-custom-image-btn [data-role="loading-state"] .icon-spinner {
+ position: absolute;
+ left: 26px;
+ bottom: 26px;
+}
+
/* Style the content of modal dialogs */
.modal-footer { text-align: left; }
.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 eafe70ddee4..b8bf1a2a3fc 100644
--- a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -421,8 +421,23 @@ var libtoaster = (function () {
});
}
+ // if true, the loading spinner for Ajax requests will be displayed
+ // if requests take more than 1200ms
+ var ajaxLoadingTimerEnabled = true;
+
+ // turn on the page-level loading spinner for Ajax requests
+ function _enableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = true;
+ }
+
+ // turn off the page-level loading spinner for Ajax requests
+ function _disableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = false;
+ }
return {
+ enableAjaxLoadingTimer: _enableAjaxLoadingTimer,
+ disableAjaxLoadingTimer: _disableAjaxLoadingTimer,
reload_params : reload_params,
startABuild : _startABuild,
cancelABuild : _cancelABuild,
@@ -469,7 +484,6 @@ function reload_params(params) {
window.location.href = url+"?"+callparams.join('&');
}
-
/* Things that happen for all pages */
$(document).ready(function() {
@@ -628,7 +642,9 @@ $(document).ready(function() {
window.clearTimeout(ajaxLoadingTimer);
ajaxLoadingTimer = window.setTimeout(function() {
- $("#loading-notification").fadeIn();
+ if (libtoaster.ajaxLoadingTimerEnabled) {
+ $("#loading-notification").fadeIn();
+ }
}, 1200);
});
diff --git a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
index 8356c02b5a8..dace8e3258d 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(){
var duplicateNameMsg = "An image with this name already exists. Image names must be unique.";
var duplicateImageInProjectMsg = "An image with this name already exists in this project."
var invalidBaseRecipeIdMsg = "Please select an image to customise.";
-
+
+ // set button to "submit" state and enable text entry so user can
+ // enter the custom recipe name
+ showSubmitState();
+
/* capture clicks on radio buttons inside the modal; when one is selected,
* set the recipe on the modal
*/
@@ -40,6 +44,9 @@ function newCustomImageModalInit(){
});
newCustomImgBtn.click(function(e){
+ // disable the button and text entry
+ showLoadingState();
+
e.preventDefault();
var baseRecipeId = imgCustomModal.data('recipe');
@@ -69,12 +76,33 @@ function newCustomImageModalInit(){
}
} else {
imgCustomModal.modal('hide');
+ imgCustomModal.one('hidden.bs.modal', showSubmitState);
window.location.replace(ret.url + '?notify=new');
}
});
}
});
+ // enable text entry, show "Create image" button text
+ function showSubmitState() {
+ libtoaster.enableAjaxLoadingTimer();
+ newCustomImgBtn.find('[data-role="loading-state"]').hide();
+ newCustomImgBtn.find('[data-role="submit-state"]').show();
+ newCustomImgBtn.removeAttr('disabled');
+ nameInput.removeAttr('disabled');
+ }
+
+ // disable text entry, show "Creating image..." button text;
+ // we also disabled the page-level ajax loading spinner while this spinner
+ // is active
+ function showLoadingState() {
+ libtoaster.disableAjaxLoadingTimer();
+ newCustomImgBtn.find('[data-role="submit-state"]').hide();
+ newCustomImgBtn.find('[data-role="loading-state"]').show();
+ newCustomImgBtn.attr('disabled', 'disabled');
+ nameInput.attr('disabled', 'disabled');
+ }
+
function showNameError(text){
invalidNameHelp.text(text);
invalidNameHelp.show();
@@ -167,6 +195,5 @@ function newCustomImageModalSetRecipes(baseRecipes) {
// show the radio button container
imageSelector.show();
-
- }
+ }
}
diff --git a/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html b/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
index 5caa68392c9..d448d3afc12 100644
--- a/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
+++ b/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
@@ -48,7 +48,12 @@
</div>
<div class="modal-footer">
- <button id="create-new-custom-image-btn" class="btn btn-primary btn-lg" data-original-title="" title="" disabled>Create custom image</button>
+ <button id="create-new-custom-image-btn" class="btn btn-primary btn-large" disabled>
+ <span data-role="submit-state">Create custom image</span>
+ <span data-role="loading-state" style="display:none">
+ <i class="fa-pulse icon-spinner"></i>&nbsp;Creating custom image...
+ </span>
+ </button>
</div>
</div>
</div>