Avoid concurrent AJAX requests and show loading indication

This commit is contained in:
Martchus 2022-03-12 18:53:46 +01:00
parent ac0d64fe3e
commit 6437c7eb42
5 changed files with 68 additions and 8 deletions

View File

@ -48,6 +48,7 @@ header nav li {
}
header nav ul li a, header nav ul li a:link, header nav ul li a:visited {
display: inline-block;
position: relative;
box-sizing: border-box;
text-decoration: none;
padding-left: 20px;
@ -62,6 +63,39 @@ header nav ul li a:hover, header nav ul li.active a {
color: #fff;
text-decoration: none;
}
header nav ul li.progress a:after {
content: '';
box-sizing: border-box;
position: absolute;
left: 0px;
bottom: 0px;
height: 5px;
width: 100%;
background: #08c;
animation: loading 2s infinite;
}
@keyframes loading {
0% {
margin-left: 0%;
width: 30%;
}
15% {
margin-left: 35%;
width: 50%;
}
50% {
margin-left: 70%;
width: 30%;
}
65% {
margin-left: 15%;
width: 50%;
}
100% {
margin-left: 0%;
width: 30%;
}
}
header nav li.active {
background-color: #000;
}
@ -99,4 +133,4 @@ main {
section {
background-color: white;
padding: 10px;
}
}

View File

@ -1,12 +1,34 @@
export const apiPrefix = 'api/v0';
let authError = false;
let ongoingRequests = {};
/// \brief Makes an AJAX query with basic error handling.
export function queryRoute(method, path, callback)
export function queryRoute(method, path, callback, type)
{
if (type) {
const ongoingRequest = ongoingRequests[type];
if (ongoingRequest) {
ongoingRequest.abort();
}
const navElement = document.getElementById(type + '-nav-link');
if (navElement) {
navElement.classList.add('progress');
}
}
const ajaxRequest = new XMLHttpRequest();
ajaxRequest.onreadystatechange = function() {
if (this.readyState === 4) {
if (type) {
if (ongoingRequests[type] !== ajaxRequest) {
return;
}
delete ongoingRequests[type];
const navElement = document.getElementById(type + '-nav-link');
if (navElement) {
navElement.classList.remove('progress');
}
}
const status = this.status;
authError = status === 403;
switch (status) {
@ -30,6 +52,9 @@ export function queryRoute(method, path, callback)
}
ajaxRequest.open(...args);
ajaxRequest.send();
if (type) {
ongoingRequests[type] = ajaxRequest;
}
return ajaxRequest;
}
@ -44,8 +69,9 @@ export function startFormQueryEx(formId, handler)
{
const form = document.getElementById(formId);
const params = makeFormQueryParameter(form);
const queryType = formId.endsWith('-form') ? formId.substr(0, formId.length - 5) : formId;
return {
ajaxRequest: queryRoute(form.method, form.getAttribute('action') + params, handler),
ajaxRequest: queryRoute(form.method, form.getAttribute('action') + params, handler, queryType),
form: form,
params, params,
};

View File

@ -34,13 +34,13 @@ export function initBuildActionsForm()
function queryBuildActions()
{
AjaxHelper.queryRoute('GET', '/build-action', showBuildActions);
AjaxHelper.queryRoute('GET', '/build-action', showBuildActions, 'build-action');
return true;
}
function queryBuildActionDetails(ids)
{
AjaxHelper.queryRoute('GET', '/build-action/details?' + AjaxHelper.makeIdParams(ids), showBuildActionDetails);
AjaxHelper.queryRoute('GET', '/build-action/details?' + AjaxHelper.makeIdParams(ids), showBuildActionDetails, 'build-action-details');
return true;
}

View File

@ -8,7 +8,7 @@ const status = {repoNames: undefined};
export function queryGlobalStatus()
{
AjaxHelper.queryRoute('GET', '/status', handleGlobalStatusUpdate);
AjaxHelper.queryRoute('GET', '/status', handleGlobalStatusUpdate, 'global');
return true;
}

View File

@ -25,7 +25,7 @@ export function initPackageDetails(sectionElement, sectionData, newPackages)
};
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(packageStr), function(ajaxRequest) {
showPackageDetails(ajaxRequest, packageObj);
});
}, 'package-details');
return true;
}
@ -38,7 +38,7 @@ export function queryPackageDetails(value, row)
{
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(makePackageID(row)), function(ajaxRequest) {
showPackageDetails(ajaxRequest, row);
});
}, 'package-details');
}
function switchToPackageDetails(packageID)