On 25/07/2016 08:57, "[email protected] on behalf of Elliot
Smith" <[email protected] on behalf of
[email protected]> wrote:

>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]

This works for me.

Thanks!

Belén

>
>Signed-off-by: Elliot Smith <[email protected]>
>---
> .../lib/toaster/toastergui/static/css/default.css  | 12 ++++++++
> .../lib/toaster/toastergui/static/js/libtoaster.js | 20 +++++++++++--
> .../toastergui/static/js/newcustomimage_modal.js   | 33
>++++++++++++++++++++--
> .../toastergui/templates/newcustomimage_modal.html |  7 ++++-
> 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 0d3570a..96eedfc 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 eafe70d..b8bf1a2 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 8356c02..dace8e3 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 5caa683..d448d3a 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>
>-- 
>2.7.4
>
>-- 
>_______________________________________________
>toaster mailing list
>[email protected]
>https://lists.yoctoproject.org/listinfo/toaster

-- 
_______________________________________________
toaster mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/toaster

Reply via email to