File: //home/arjun/projects/env/lib/python3.10/site-packages/flower/static/js/flower.js
/*jslint browser: true */
/*global $, WebSocket, jQuery */
var flower = (function () {
"use strict";
var alertContainer = document.getElementById('alert-container');
function show_alert(message, type) {
var wrapper = document.createElement('div');
wrapper.innerHTML = `
<div class="alert alert-${type} alert-dismissible" role="alert">
<div>${message}</div>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>`;
alertContainer.appendChild(wrapper);
}
function url_prefix() {
var prefix = $('#url_prefix').val();
if (prefix) {
prefix = prefix.replace(/\/+$/, '');
if (prefix.startsWith('/')) {
return prefix;
} else {
return '/' + prefix;
}
}
return '';
}
//https://github.com/DataTables/DataTables/blob/1.10.11/media/js/jquery.dataTables.js#L14882
function htmlEscapeEntities(d) {
return typeof d === 'string' ?
d.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') :
d;
}
function active_page(name) {
var pathname = $(location).attr('pathname');
if (name === '/') {
return pathname === (url_prefix() + name);
}
else {
return pathname.startsWith(url_prefix() + name);
}
}
$('#worker-refresh').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'GET',
url: url_prefix() + '/api/workers',
dataType: 'json',
data: {
workername: unescape(workername),
refresh: 1
},
success: function (data) {
show_alert(data.message || 'Successfully refreshed', 'success');
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-refresh-all').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
$.ajax({
type: 'GET',
url: url_prefix() + '/api/workers',
dataType: 'json',
data: {
refresh: 1
},
success: function (data) {
show_alert(data.message || 'Refreshed All Workers', 'success');
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-restart').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/restart/' + workername,
dataType: 'json',
data: {
workername: workername
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-shutdown').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
$('.dropdown-toggle').dropdown('hide');
var workername = $('#workername').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/shutdown/' + workername,
dataType: 'json',
data: {
workername: workername
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-grow').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
grow_size = $('#pool-size option:selected').html();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/grow/' + workername,
dataType: 'json',
data: {
'workername': workername,
'n': grow_size,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-shrink').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
shrink_size = $('#pool-size option:selected').html();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/shrink/' + workername,
dataType: 'json',
data: {
'workername': workername,
'n': shrink_size,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-pool-autoscale').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
min = $('#min-autoscale').val(),
max = $('#max-autoscale').val();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/pool/autoscale/' + workername,
dataType: 'json',
data: {
'workername': workername,
'min': min,
'max': max,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-add-consumer').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var workername = $('#workername').text(),
queue = $('#add-consumer-name').val();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/queue/add-consumer/' + workername,
dataType: 'json',
data: {
'workername': workername,
'queue': queue,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#worker-queues').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
if (!event.target.id.startsWith("worker-cancel-consumer")) {
return;
}
var workername = $('#workername').text(),
queue = $(event.target).closest("tr").children("td:eq(0)").text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/worker/queue/cancel-consumer/' + workername,
dataType: 'json',
data: {
'workername': workername,
'queue': queue,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#limits-table').on('click', function (event) {
if (event.target.id.startsWith("task-timeout-")) {
var timeout = parseInt($(event.target).siblings().closest("input").val()),
type = $(event.target).text().toLowerCase(),
taskname = $(event.target).closest("tr").children("td:eq(0)").text(),
post_data = {'workername': $('#workername').text()};
taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx]
post_data[type] = timeout;
if (!Number.isInteger(timeout)) {
show_alert("Invalid timeout value", "danger");
return;
}
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/timeout/' + taskname,
dataType: 'json',
data: post_data,
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert($(data.responseText).text(), "danger");
}
});
} else if (event.target.id.startsWith("task-rate-limit-")) {
var taskname = $(event.target).closest("tr").children("td:eq(0)").text(),
workername = $('#workername').text(),
ratelimit = parseInt($(event.target).prev().val());
taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx]
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/rate-limit/' + taskname,
dataType: 'json',
data: {
'workername': workername,
'ratelimit': ratelimit,
},
success: function (data) {
show_alert(data.message, "success");
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
}
});
$('#task-revoke').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var taskid = $('#taskid').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/revoke/' + taskid,
dataType: 'json',
data: {
'terminate': false,
},
success: function (data) {
show_alert(data.message, "success");
document.getElementById("task-revoke").disabled = true;
setTimeout(function() {location.reload();}, 5000);
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
$('#task-terminate').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var taskid = $('#taskid').text();
$.ajax({
type: 'POST',
url: url_prefix() + '/api/task/revoke/' + taskid,
dataType: 'json',
data: {
'terminate': true,
},
success: function (data) {
show_alert(data.message, "success");
document.getElementById("task-terminate").disabled = true;
setTimeout(function() {location.reload();}, 5000);
},
error: function (data) {
show_alert(data.responseText, "danger");
}
});
});
function sum(a, b) {
return parseInt(a, 10) + parseInt(b, 10);
}
function format_time(timestamp) {
var time = $('#time').val(),
prefix = time.startsWith('natural-time') ? 'natural-time' : 'time',
tz = time.substr(prefix.length + 1) || 'UTC';
if (prefix === 'natural-time') {
return moment.unix(timestamp).tz(tz).fromNow();
}
return moment.unix(timestamp).tz(tz).format('YYYY-MM-DD HH:mm:ss.SSS');
}
function isColumnVisible(name) {
var columns = $('#columns').val();
if (columns === "all")
return true;
if (columns) {
columns = columns.split(',').map(function (e) {
return e.trim();
});
return columns.indexOf(name) !== -1;
}
return true;
}
$.urlParam = function (name) {
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
return (results && results[1]) || 0;
};
$(document).ready(function () {
//https://github.com/twitter/bootstrap/issues/1768
var shiftWindow = function () {
scrollBy(0, -50);
};
if (location.hash) {
shiftWindow();
}
window.addEventListener("hashchange", shiftWindow);
// Make bootstrap tabs persistent
$(document).ready(function () {
if (location.hash !== '') {
$('a[href="' + location.hash + '"]').tab('show');
}
// Listen for tab shown events and update the URL hash fragment accordingly
$('.nav-tabs a[data-bs-toggle="tab"]').on('shown.bs.tab', function (event) {
const tabPaneId = $(event.target).attr('href').substr(1);
if (tabPaneId) {
window.location.hash = tabPaneId;
}
});
});
});
$(document).ready(function () {
if (!active_page('/') && !active_page('/workers')) {
return;
}
$('#workers-table').DataTable({
rowId: 'name',
searching: true,
select: false,
paging: true,
scrollCollapse: true,
lengthMenu: [15, 30, 50, 100],
pageLength: 15,
language: {
lengthMenu: 'Show _MENU_ workers',
info: 'Showing _START_ to _END_ of _TOTAL_ workers',
infoFiltered: '(filtered from _MAX_ total workers)'
},
ajax: url_prefix() + '/workers?json=1',
order: [
[1, "des"]
],
footerCallback: function( tfoot, data, start, end, display ) {
var api = this.api();
var columns = {2:"STARTED", 3:"", 4:"FAILURE", 5:"SUCCESS", 6:"RETRY"};
for (const [column, state] of Object.entries(columns)) {
var total = api.column(column).data().reduce(sum, 0);
var footer = total;
if (total !== 0) {
let queryParams = (state !== '' ? `?state=${state}` : '');
footer = '<a href="' + url_prefix() + '/tasks' + queryParams + '">' + total + '</a>';
}
$(api.column(column).footer()).html(footer);
}
},
columnDefs: [{
targets: 0,
data: 'hostname',
type: 'natural',
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/worker/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 1,
data: 'status',
className: "text-center",
width: "10%",
render: function (data, type, full, meta) {
if (data) {
return '<span class="badge bg-success">Online</span>';
} else {
return '<span class="badge bg-secondary">Offline</span>';
}
}
}, {
targets: 2,
data: 'active',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 3,
data: 'task-received',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 4,
data: 'task-failed',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 5,
data: 'task-succeeded',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 6,
data: 'task-retried',
className: "text-center",
width: "10%",
defaultContent: 0
}, {
targets: 7,
data: 'loadavg',
width: "10%",
className: "text-center text-nowrap",
render: function (data, type, full, meta) {
if (!full.status) {
return 'N/A';
}
if (Array.isArray(data)) {
return data.join(', ');
}
return data;
}
}, ],
});
var autorefresh_interval = $.urlParam('autorefresh') || 1;
if (autorefresh !== 0) {
setInterval( function () {
$('#workers-table').DataTable().ajax.reload(null, false);
}, autorefresh_interval * 1000);
}
});
$(document).ready(function () {
if (!active_page('/tasks')) {
return;
}
$('#tasks-table').DataTable({
rowId: 'uuid',
searching: true,
scrollX: true,
scrollCollapse: true,
processing: true,
serverSide: true,
colReorder: true,
lengthMenu: [15, 30, 50, 100],
pageLength: 15,
language: {
lengthMenu: 'Show _MENU_ tasks',
info: 'Showing _START_ to _END_ of _TOTAL_ tasks',
infoFiltered: '(filtered from _MAX_ total tasks)'
},
ajax: {
type: 'POST',
url: url_prefix() + '/tasks/datatable'
},
order: [
[7, "desc"]
],
oSearch: {
"sSearch": $.urlParam('state') ? 'state:' + $.urlParam('state') : ''
},
columnDefs: [{
targets: 0,
data: 'name',
visible: isColumnVisible('name'),
render: function (data, type, full, meta) {
return data;
}
}, {
targets: 1,
data: 'uuid',
visible: isColumnVisible('uuid'),
orderable: false,
className: "text-nowrap",
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/task/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 2,
data: 'state',
visible: isColumnVisible('state'),
className: "text-center",
render: function (data, type, full, meta) {
switch (data) {
case 'SUCCESS':
return '<span class="badge bg-success">' + data + '</span>';
case 'FAILURE':
return '<span class="badge bg-danger">' + data + '</span>';
default:
return '<span class="badge bg-secondary">' + data + '</span>';
}
}
}, {
targets: 3,
data: 'args',
className: "text-nowrap overflow-auto",
visible: isColumnVisible('args'),
render: htmlEscapeEntities
}, {
targets: 4,
data: 'kwargs',
className: "text-nowrap overflow-auto",
visible: isColumnVisible('kwargs'),
render: htmlEscapeEntities
}, {
targets: 5,
data: 'result',
visible: isColumnVisible('result'),
className: "text-nowrap overflow-auto",
render: htmlEscapeEntities
}, {
targets: 6,
data: 'received',
className: "text-nowrap",
visible: isColumnVisible('received'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 7,
data: 'started',
className: "text-nowrap",
visible: isColumnVisible('started'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 8,
data: 'runtime',
className: "text-center",
visible: isColumnVisible('runtime'),
render: function (data, type, full, meta) {
return data ? data.toFixed(2) : data;
}
}, {
targets: 9,
data: 'worker',
visible: isColumnVisible('worker'),
render: function (data, type, full, meta) {
return '<a href="' + url_prefix() + '/worker/' + encodeURIComponent(data) + '">' + data + '</a>';
}
}, {
targets: 10,
data: 'exchange',
visible: isColumnVisible('exchange')
}, {
targets: 11,
data: 'routing_key',
visible: isColumnVisible('routing_key')
}, {
targets: 12,
data: 'retries',
className: "text-center",
visible: isColumnVisible('retries')
}, {
targets: 13,
data: 'revoked',
className: "text-nowrap",
visible: isColumnVisible('revoked'),
render: function (data, type, full, meta) {
if (data) {
return format_time(data);
}
return data;
}
}, {
targets: 14,
data: 'exception',
className: "text-nowrap",
visible: isColumnVisible('exception')
}, {
targets: 15,
data: 'expires',
visible: isColumnVisible('expires')
}, {
targets: 16,
data: 'eta',
visible: isColumnVisible('eta')
}, ],
});
});
}(jQuery));