Avoid concurrent AJAX requests and show loading indication
This commit is contained in:
parent
ac0d64fe3e
commit
6437c7eb42
|
@ -48,6 +48,7 @@ header nav li {
|
||||||
}
|
}
|
||||||
header nav ul li a, header nav ul li a:link, header nav ul li a:visited {
|
header nav ul li a, header nav ul li a:link, header nav ul li a:visited {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
@ -62,6 +63,39 @@ header nav ul li a:hover, header nav ul li.active a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-decoration: none;
|
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 {
|
header nav li.active {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
@ -99,4 +133,4 @@ main {
|
||||||
section {
|
section {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,34 @@
|
||||||
export const apiPrefix = 'api/v0';
|
export const apiPrefix = 'api/v0';
|
||||||
let authError = false;
|
let authError = false;
|
||||||
|
let ongoingRequests = {};
|
||||||
|
|
||||||
/// \brief Makes an AJAX query with basic error handling.
|
/// \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();
|
const ajaxRequest = new XMLHttpRequest();
|
||||||
ajaxRequest.onreadystatechange = function() {
|
ajaxRequest.onreadystatechange = function() {
|
||||||
if (this.readyState === 4) {
|
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;
|
const status = this.status;
|
||||||
authError = status === 403;
|
authError = status === 403;
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -30,6 +52,9 @@ export function queryRoute(method, path, callback)
|
||||||
}
|
}
|
||||||
ajaxRequest.open(...args);
|
ajaxRequest.open(...args);
|
||||||
ajaxRequest.send();
|
ajaxRequest.send();
|
||||||
|
if (type) {
|
||||||
|
ongoingRequests[type] = ajaxRequest;
|
||||||
|
}
|
||||||
return ajaxRequest;
|
return ajaxRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +69,9 @@ export function startFormQueryEx(formId, handler)
|
||||||
{
|
{
|
||||||
const form = document.getElementById(formId);
|
const form = document.getElementById(formId);
|
||||||
const params = makeFormQueryParameter(form);
|
const params = makeFormQueryParameter(form);
|
||||||
|
const queryType = formId.endsWith('-form') ? formId.substr(0, formId.length - 5) : formId;
|
||||||
return {
|
return {
|
||||||
ajaxRequest: queryRoute(form.method, form.getAttribute('action') + params, handler),
|
ajaxRequest: queryRoute(form.method, form.getAttribute('action') + params, handler, queryType),
|
||||||
form: form,
|
form: form,
|
||||||
params, params,
|
params, params,
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,13 +34,13 @@ export function initBuildActionsForm()
|
||||||
|
|
||||||
function queryBuildActions()
|
function queryBuildActions()
|
||||||
{
|
{
|
||||||
AjaxHelper.queryRoute('GET', '/build-action', showBuildActions);
|
AjaxHelper.queryRoute('GET', '/build-action', showBuildActions, 'build-action');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryBuildActionDetails(ids)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ const status = {repoNames: undefined};
|
||||||
|
|
||||||
export function queryGlobalStatus()
|
export function queryGlobalStatus()
|
||||||
{
|
{
|
||||||
AjaxHelper.queryRoute('GET', '/status', handleGlobalStatusUpdate);
|
AjaxHelper.queryRoute('GET', '/status', handleGlobalStatusUpdate, 'global');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ export function initPackageDetails(sectionElement, sectionData, newPackages)
|
||||||
};
|
};
|
||||||
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(packageStr), function(ajaxRequest) {
|
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(packageStr), function(ajaxRequest) {
|
||||||
showPackageDetails(ajaxRequest, packageObj);
|
showPackageDetails(ajaxRequest, packageObj);
|
||||||
});
|
}, 'package-details');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export function queryPackageDetails(value, row)
|
||||||
{
|
{
|
||||||
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(makePackageID(row)), function(ajaxRequest) {
|
AjaxHelper.queryRoute('GET', '/packages?details=1&name=' + encodeURIComponent(makePackageID(row)), function(ajaxRequest) {
|
||||||
showPackageDetails(ajaxRequest, row);
|
showPackageDetails(ajaxRequest, row);
|
||||||
});
|
}, 'package-details');
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToPackageDetails(packageID)
|
function switchToPackageDetails(packageID)
|
||||||
|
|
Loading…
Reference in New Issue