Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block UI for some long running tasks #543

Merged
merged 9 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* globals OME, $ */

/**
* Create an overlay that blocks the user from interacting with the UI,
* for example to prevent a long-running action from being interrupted
* or repeated before it is completed.
* @param promise When this promise resolves (successfully or otherwise) the overlay closes
* @param message The optional message to display (defaults to "Please wait")
* @param quiet Don't print timing to console
* @returns {*|jQuery} The jQuery element holding the dialog; no need to do anything with it
*/
OME.progress_overlay = function (promise, message, quiet) {
'use strict';
const startTime = new Date().getTime();
const dialog = $('<div><span class="spinner"></span>&nbsp;' + (message || 'Please wait') + '</div>')
.appendTo(document.body)
.dialog({
modal: true,
autoOpen: true,
closeOnEscape: false,
draggable: false,
resizable: false,
classes: {
'ui-dialog': 'ome-modal-progress',
}
});
promise.finally(() => {
dialog.dialog('destroy').remove();
if (!quiet) {
window.console.log('UI blocked for ' + (new Date().getTime() - startTime).toString() + 'ms');
}
});
return dialog;
};

// add styles
(function () {
'use strict';
const styleSheet = document.createElement("style");
styleSheet.innerText = `
.ome-modal-progress button {
display: none;
}

.ome-modal-progress .ui-dialog-content {
justify-content: center;
align-items: center;
font-size: larger;
display: flex;
}

.ome-modal-progress .spinner {
background-image: url("data:image/gif;base64,R0lGODlhEAAQAPIAAP///zxKW9HU2G95hjxKW4eQmqCnr6yyuSH5BAkKAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOw==");
width: 16px;
height: 16px;
display: inline-block;
}
`;
document.head.appendChild(styleSheet);
})();
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ OME.refreshThumbnails = function(options) {
spw_selector = "#image-" + options.imageId + ", #wellImages li[data-imageId='" + options.imageId + "']";
}

var promise = Promise.resolve();
// Try SPW data or Search data by directly updating thumb src...
var $thumbs = $(spw_selector + ", " + search_selector);
if ($thumbs.length > 0){
Expand All @@ -392,7 +393,7 @@ OME.refreshThumbnails = function(options) {
// filter out empty wells etc.
return img_id.length > 0;
}).get();
OME.load_thumbnails(
promise = OME.load_thumbnails(
options.thumbnail_url,
iids, options.thumbnailsBatch,
options.defaultThumbnail
Expand All @@ -407,59 +408,68 @@ OME.refreshThumbnails = function(options) {
data = {'imageId': options.imageId};
}
var e = {'type': type};
update_thumbnails_panel(e, data);
promise = update_thumbnails_panel(e, data);
}

// Update viewport via global variable
if (!options.ignorePreview && OME.preview_viewport && OME.preview_viewport.loadedImg.id) {
OME.preview_viewport.load(OME.preview_viewport.loadedImg.id);
}

return promise;
};

OME.load_thumbnails = function(thumbnails_url, input, batch, dthumb) {
OME.load_thumbnails = function (thumbnails_url, input, batch, dthumb) {
// load thumbnails in a batches
if (input.length > 0 && batch > 0) {
var iids = input.slice(0 , batch)
var iids = input.slice(0, batch)
if (iids.length > 0) {
$.ajax({
type: "GET",
url: thumbnails_url,
data: $.param( { id: iids }, true),
dataType: 'json',
success: function(data){
var invalid_thumbs = [];
$.each(data, function(key, value) {
if (value !== null) {
// SPW Plate and WellImages
$("img#image-"+key).attr("src", value);
$("#wellImages li[data-imageId='" + key + "'] img").attr("src", value);
$("#well_birds_eye img[data-imageid='" + key + "']").attr("src", value);
// Search results
$("#image_icon-" + key + " img").attr("src", value);
var promise = new Promise(function (resolve) {
$.ajax({
type: "GET",
url: thumbnails_url,
data: $.param({id: iids}, true),
dataType: 'json',
success: function (data) {
var invalid_thumbs = [];
$.each(data, function (key, value) {
if (value !== null) {
// SPW Plate and WellImages
$("img#image-" + key).attr("src", value);
$("#wellImages li[data-imageId='" + key + "'] img").attr("src", value);
$("#well_birds_eye img[data-imageid='" + key + "']").attr("src", value);
// Search results
$("#image_icon-" + key + " img").attr("src", value);
} else {
invalid_thumbs.push(key);
}
});
// If we got invalid thumbnails as a set and ALL failed, try re-loading 1 at a time
if (invalid_thumbs.length === iids.length && batch > 1) {
OME.load_thumbnails(thumbnails_url, invalid_thumbs, 1, dthumb).then(resolve);
} else {
invalid_thumbs.push(key);
// If only some thumbs failed (or single thumb failed), show placeholder
if ((invalid_thumbs.length < iids.length) || (batch === 1 && invalid_thumbs.length === 1)) {
// If batch > 1 then we try loading again, otherwise we failed...
invalid_thumbs.forEach(function (key) {
$("img#image-" + key).attr("src", dthumb);
$("#wellImages li[data-imageId='" + key + "'] img").attr("src", dthumb);
$("#image_icon-" + key + " img").attr("src", dthumb);
});
}
resolve();
}
});
// If we got invalid thumbnails as a set and ALL failed, try re-loading 1 at a time
if (invalid_thumbs.length === iids.length && batch > 1) {
OME.load_thumbnails(thumbnails_url, invalid_thumbs, 1, dthumb);
}
// If only some thumbs failed (or single thumb failed), show placeholder
if ((invalid_thumbs.length < iids.length) || (batch === 1 && invalid_thumbs.length === 1)) {
// If batch > 1 then we try loading again, otherwise we failed...
invalid_thumbs.forEach(function(key){
$("img#image-"+key).attr("src", dthumb);
$("#wellImages li[data-imageId='" + key + "'] img").attr("src", dthumb);
$("#image_icon-" + key + " img").attr("src", dthumb);
});
}
}
},
error: resolve,
});
});
input = input.slice(batch, input.length);
OME.load_thumbnails(thumbnails_url, input, batch, dthumb);
return Promise.all([promise, OME.load_thumbnails(thumbnails_url, input, batch, dthumb)]);
}
}
}
return Promise.resolve();
};

OME.load_thumbnail = function(iid, thumbnails_url, callback) {
// load thumbnails in a batches
$.ajax({
Expand Down Expand Up @@ -1142,17 +1152,23 @@ OME.applyRenderingSettings = function(rdef_url, selected) {
function() {
var clicked_button_text = rdef_confirm_dialog.data("clicked_button");
if (clicked_button_text === "OK") {
$.ajax({
type: "POST",
dataType: 'text',
traditional: true,
url: rdef_url,
data: data,
success: function(data){
// update thumbnails
OME.refreshThumbnails();
}
});
OME.progress_overlay(
new Promise((resolve) => {
$.ajax({
type: "POST",
dataType: 'text',
traditional: true,
url: rdef_url,
data: data,
success: function(data){
// update thumbnails
OME.refreshThumbnails().finally(() => resolve());
},
error: resolve,
});
}),
'Applying rendering settings...'
);
}
},
"Change Rendering Settings?",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,37 +321,42 @@
$("#rdef-save-all")
.attr('title', "Apply and Save settings to all images in " + pid)
.prop('disabled', false).removeClass("button-disabled")
.on('click', function(){
var $span = $('span', this),
spanTxt = $span.text();
$span.text("Saving...");
var typeId = pid.split("-");
var rdefQry = OME.preview_viewport.getQuery(true);
// need to paste current settings to all images...
var url = "{% url 'webgateway_copy_image_rdef_json' %}"+ "?" + rdefQry;
data = {
"toids": typeId[1],
"to_type": typeId[0],
"imageId": OME.preview_viewport.loadedImg.id // Need imageId for 'apply to all'
}
$.ajax({
type: "POST",
dataType: 'text',
traditional: true,
url: url,
data: data,
success: function(data){
.on('click', function () {
OME.progress_overlay(
new Promise((resolve) => {
var $span = $('span', this),
spanTxt = $span.text();
$span.text("Saving...");
var typeId = pid.split("-");
var rdefQry = OME.preview_viewport.getQuery(true);
// need to paste current settings to all images...
var url = "{% url 'webgateway_copy_image_rdef_json' %}" + "?" + rdefQry;
data = {
"toids": typeId[1],
"to_type": typeId[0],
"imageId": OME.preview_viewport.loadedImg.id // Need imageId for 'apply to all'
}
$.ajax({
type: "POST",
dataType: 'text',
traditional: true,
url: url,
data: data,
success: function (data) {
$span.text(spanTxt);
// update thumbnails
OME.refreshThumbnails({
'ignorePreview': true,
'thumbnail_url': "{% url 'get_thumbnails_json' %}",
'defaultThumbnail': "{% static 'webgateway/img/image128.png' %}",
'thumbnailsBatch': 1
});
}).finally(() => resolve());
updateMyRdef(OME.preview_viewport.getQuery());
}
});
},
error: resolve,
});
}),
'Saving to all...');
});
}
{% endif %}
Expand Down
1 change: 1 addition & 0 deletions omeroweb/webclient/templates/webclient/base/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<script type="text/javascript" src="{% static "webclient/javascript/jquery.editinplace-0.1.2.js" %}"></script>
<script type="text/javascript" src="{% static "3rdparty/jquery.form-4.3.0.js" %}"></script>
<script type="text/javascript" src="{% static "webclient/javascript/ome.tagging_form.js"|add:url_suffix %}"></script>
<script type="text/javascript" src="{% static "webclient/javascript/ome.progress_overlay.js"|add:url_suffix %}"></script>

<!-- preview viewer... -->
<script type="text/javascript" src="{% static "3rdparty/jquery.blockUI-2.66.0.js" %}"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<script type="text/javascript" src="{% static "webclient/javascript/ome.right_panel_customanns_pane.js"|add:url_suffix %}"></script>
<script type="text/javascript" src="{% static "webclient/javascript/ome.right_panel_ratings_pane.js"|add:url_suffix %}"></script>
<script type="text/javascript" src="{% static "webclient/javascript/ome.right_panel_mapanns_pane.js"|add:url_suffix %}"></script>

<script type="text/javascript" src="{% static "webclient/javascript/ome.progress_overlay.js"|add:url_suffix %}"></script>

<!-- preview viewer... -->
<script type="text/javascript" src="{% static "3rdparty/jquery.blockUI-2.66.0.js" %}"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,14 @@
$("#content_details").html("");
parentId = undefined;
clearThumbnailsPanel();
return;
return Promise.resolve();
}
var dtype = selected[0].type;
if (selected.length > 1 && dtype !== "image") {
$("#content_details").html("");
parentId = undefined;
clearThumbnailsPanel();
return;
return Promise.resolve();
}

// parent node could be dataset, orphaned, share or tag
Expand All @@ -182,12 +182,12 @@
} else if (dtype === "plate" || dtype === "acquisition") {
parentId = undefined;
load_spw(event, data);
return;
return Promise.resolve();
// All other types have blank centre panel
} else {
parentId = undefined;
clearThumbnailsPanel();
return;
return Promise.resolve();
}

if (!parentNode) {
Expand All @@ -206,7 +206,7 @@

highlightSelectedThumbs(selected);

return;
return Promise.resolve();
}
// update single thumbnail, see OME.refreshThumbnails
if (event.type === "refreshThumb") {
Expand All @@ -217,7 +217,7 @@
$("li#image_icon-"+data.imageId+ " img").attr("src", thumb);
}
);
return;
return Promise.resolve();
}

parentId = newParentId;
Expand Down Expand Up @@ -312,7 +312,7 @@
if (parentNode.type === "share") {
thumbnailsBatch = 1;
}
OME.load_thumbnails(
var promise = OME.load_thumbnails(
thumbUrl, iids, thumbnailsBatch,
"{% static 'webgateway/img/image128.png' %}"
);
Expand All @@ -331,7 +331,7 @@
// scroll to selected thumbnail (if any)
focusThumbnail();

return;
return promise;
}

// Update thumbnails when we switch between plugins
Expand Down
Loading
Loading