mirror of
https://github.com/Balshgit/public.git
synced 2025-09-12 16:40:43 +03:00
168 lines
6.9 KiB
JavaScript
168 lines
6.9 KiB
JavaScript
class CeleryProgressBar {
|
|
|
|
constructor(progressUrl, options) {
|
|
this.progressUrl = progressUrl;
|
|
options = options || {};
|
|
let progressBarId = options.progressBarId || 'progress-bar';
|
|
let progressBarMessage = options.progressBarMessageId || 'progress-bar-message';
|
|
this.progressBarElement = options.progressBarElement || document.getElementById(progressBarId);
|
|
this.progressBarMessageElement = options.progressBarMessageElement || document.getElementById(progressBarMessage);
|
|
this.onProgress = options.onProgress || this.onProgressDefault;
|
|
this.onSuccess = options.onSuccess || this.onSuccessDefault;
|
|
this.onError = options.onError || this.onErrorDefault;
|
|
this.onTaskError = options.onTaskError || this.onTaskErrorDefault;
|
|
this.onDataError = options.onDataError || this.onError;
|
|
this.onRetry = options.onRetry || this.onRetryDefault;
|
|
this.onIgnored = options.onIgnored || this.onIgnoredDefault;
|
|
let resultElementId = options.resultElementId || 'celery-result';
|
|
this.resultElement = options.resultElement || document.getElementById(resultElementId);
|
|
this.onResult = options.onResult || this.onResultDefault;
|
|
// HTTP options
|
|
this.onNetworkError = options.onNetworkError || this.onError;
|
|
this.onHttpError = options.onHttpError || this.onError;
|
|
this.pollInterval = options.pollInterval || 500;
|
|
// Other options
|
|
let barColorsDefault = {
|
|
success: '#76ce60',
|
|
error: '#dc4f63',
|
|
progress: '#68a9ef',
|
|
ignored: '#7a7a7a'
|
|
}
|
|
this.barColors = Object.assign({}, barColorsDefault, options.barColors);
|
|
}
|
|
|
|
onSuccessDefault(progressBarElement, progressBarMessageElement, result) {
|
|
result = this.getMessageDetails(result);
|
|
progressBarElement.style.backgroundColor = this.barColors.success;
|
|
progressBarMessageElement.textContent = "Success! Please refresh page.";
|
|
}
|
|
|
|
onResultDefault(resultElement, result) {
|
|
if (resultElement) {
|
|
resultElement.textContent = result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default handler for all errors.
|
|
* @param data - A Response object for HTTP errors, undefined for other errors
|
|
*/
|
|
onErrorDefault(progressBarElement, progressBarMessageElement, excMessage, data) {
|
|
progressBarElement.style.backgroundColor = this.barColors.error;
|
|
excMessage = excMessage || '';
|
|
progressBarMessageElement.textContent = "Uh-Oh, something went wrong! " + excMessage;
|
|
}
|
|
|
|
onTaskErrorDefault(progressBarElement, progressBarMessageElement, excMessage) {
|
|
let message = this.getMessageDetails(excMessage);
|
|
this.onError(progressBarElement, progressBarMessageElement, message);
|
|
}
|
|
|
|
onRetryDefault(progressBarElement, progressBarMessageElement, excMessage, retryWhen) {
|
|
retryWhen = new Date(retryWhen);
|
|
let message = 'Retrying in ' + Math.round((retryWhen.getTime() - Date.now())/1000) + 's: ' + excMessage;
|
|
this.onError(progressBarElement, progressBarMessageElement, message);
|
|
}
|
|
|
|
onIgnoredDefault(progressBarElement, progressBarMessageElement, result) {
|
|
progressBarElement.style.backgroundColor = this.barColors.ignored;
|
|
progressBarMessageElement.textContent = result || 'Task result ignored!'
|
|
}
|
|
|
|
onProgressDefault(progressBarElement, progressBarMessageElement, progress) {
|
|
progressBarElement.style.backgroundColor = this.barColors.progress;
|
|
progressBarElement.style.width = progress.percent + "%";
|
|
var description = progress.description || "";
|
|
if (progress.current == 0) {
|
|
if (progress.pending === true) {
|
|
progressBarMessageElement.textContent = 'Waiting for task to start...';
|
|
} else {
|
|
progressBarMessageElement.textContent = 'Task started...';
|
|
}
|
|
} else {
|
|
progressBarMessageElement.textContent = progress.current + ' of ' + progress.total + ' processed. ' + description;
|
|
}
|
|
}
|
|
|
|
getMessageDetails(result) {
|
|
if (this.resultElement) {
|
|
return ''
|
|
} else {
|
|
return result || '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process update message data.
|
|
* @return true if the task is complete, false if it's not, undefined if `data` is invalid
|
|
*/
|
|
onData(data) {
|
|
let done = false;
|
|
if (data.progress) {
|
|
this.onProgress(this.progressBarElement, this.progressBarMessageElement, data.progress);
|
|
}
|
|
if (data.complete === true) {
|
|
done = true;
|
|
if (data.success === true) {
|
|
this.onSuccess(this.progressBarElement, this.progressBarMessageElement, data.result);
|
|
} else if (data.success === false) {
|
|
if (data.state === 'RETRY') {
|
|
this.onRetry(this.progressBarElement, this.progressBarMessageElement, data.result.message, data.result.when);
|
|
done = false;
|
|
delete data.result;
|
|
} else {
|
|
this.onTaskError(this.progressBarElement, this.progressBarMessageElement, data.result);
|
|
}
|
|
} else {
|
|
if (data.state === 'IGNORED') {
|
|
this.onIgnored(this.progressBarElement, this.progressBarMessageElement, data.result);
|
|
delete data.result;
|
|
} else {
|
|
done = undefined;
|
|
this.onDataError(this.progressBarElement, this.progressBarMessageElement, "Data Error");
|
|
}
|
|
}
|
|
if (data.hasOwnProperty('result')) {
|
|
this.onResult(this.resultElement, data.result);
|
|
}
|
|
} else if (data.complete === undefined) {
|
|
done = undefined;
|
|
this.onDataError(this.progressBarElement, this.progressBarMessageElement, "Data Error");
|
|
}
|
|
return done;
|
|
}
|
|
|
|
async connect() {
|
|
let response;
|
|
try {
|
|
response = await fetch(this.progressUrl);
|
|
} catch (networkError) {
|
|
this.onNetworkError(this.progressBarElement, this.progressBarMessageElement, "Network Error");
|
|
throw networkError;
|
|
}
|
|
|
|
if (response.status === 200) {
|
|
let data;
|
|
try {
|
|
data = await response.json();
|
|
} catch (parsingError) {
|
|
this.onDataError(this.progressBarElement, this.progressBarMessageElement, "Parsing Error")
|
|
throw parsingError;
|
|
}
|
|
|
|
const complete = this.onData(data);
|
|
|
|
if (complete === false) {
|
|
setTimeout(this.connect.bind(this), this.pollInterval);
|
|
}
|
|
} else {
|
|
this.onHttpError(this.progressBarElement, this.progressBarMessageElement, "HTTP Code " + response.status, response);
|
|
}
|
|
}
|
|
|
|
static initProgressBar(progressUrl, options) {
|
|
const bar = new this(progressUrl, options);
|
|
bar.connect();
|
|
}
|
|
}
|