@moxb/shards-meteor-process-manager-antd
Version:
Shards: Meteor process manager - antd UI
200 lines (199 loc) • 10.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProcessManagerUI = void 0;
var React = require("react");
var react_1 = require("react");
var antd_1 = require("antd");
var icons_1 = require("@ant-design/icons");
var react_html_1 = require("@moxb/react-html");
var meteor_react_1 = require("@moxb/meteor-react");
var shards_meteor_process_manager_core_1 = require("@moxb/shards-meteor-process-manager-core");
require("./process-manager.css");
// eslint-disable-next-line complexity
var getProgressBarState = function (status) {
if (!(status === null || status === void 0 ? void 0 : status.state)) {
return 'normal';
}
switch (status.state) {
case 'failed':
return 'exception';
case 'idle':
case 'stopped':
return 'normal';
case 'scheduled':
case 'running':
case 'stopRequested':
case 'stopping':
return 'active';
case 'done':
return 'success';
default:
console.log('Unknown state', status.state);
return 'normal';
}
};
function formatTime(time) {
return time ? time.toLocaleTimeString() : '(missing time)';
}
/**
* Pad numbers with a 0 if necessary.
*
* (ie. 8 -> "08")
*/
var padNumber = function (x) {
var int = Math.floor(x);
return int < 10 ? '0' + int : '' + int;
};
/**
* Format seconds as a clock.
*
* (ie. 80 -> 01:20)
*/
var formatDuration = function (secs) {
return secs === undefined
? 'missing time'
: secs > 3600
? padNumber(secs / 3600) + ':' + padNumber((secs % 3600) / 60) + ':' + padNumber(secs % 60)
: padNumber(secs / 60) + ':' + padNumber(secs % 60);
};
// eslint-disable-next-line complexity
var getProgressBarMessage = function (status, progress) {
if (!(status === null || status === void 0 ? void 0 : status.state)) {
return '';
}
switch (status.state) {
case 'failed':
return "".concat(status.error, " at ").concat(formatTime(status.failedAt));
case 'idle':
return '';
case 'stopped':
return "Stopped at ".concat(formatTime(status.stoppedAt));
case 'scheduled':
return 'Scheduled ...';
case 'running':
return (React.createElement("span", null,
status.runningSince && React.createElement(react_html_1.CountingClock, { measureSince: status.runningSince.getTime() }),
"\u00A0",
progress.message));
case 'stopRequested':
case 'stopping':
return (React.createElement("span", null,
status.runningSince && React.createElement(react_html_1.CountingClock, { measureSince: status.runningSince.getTime() }),
"\u00A0",
progress.message,
" ",
React.createElement("span", { className: 'stopping-flag' }, "(stopping)")));
case 'done':
return "Finished at ".concat(formatTime(status.doneAt), ", in ").concat(formatDuration(status.duration), ".");
}
};
var activeStates = ['scheduled', 'running', 'stopRequested', 'stopping', 'stopped', 'failed'];
var isStateActive = function (state) { return (state ? activeStates.includes(state) : false); };
function ProcessTableRawUI(props) {
var scopeId = props.scopeId, processes = props.processes, search = props.search, error = props.error;
if (error) {
return React.createElement(antd_1.Alert, { type: 'error', message: error });
}
return (React.createElement(antd_1.Table, { dataSource: processes, rowKey: '_id', columns: [
{
title: '',
dataIndex: 'status',
width: '20%',
render: function (status, process) {
if (status === void 0) { status = { state: 'idle' }; }
var state = status.state;
var processId = process.processId, warning = process.warning, special = process.special;
var run = function () {
return shards_meteor_process_manager_core_1.launchProcessMethod.call({ scopeId: scopeId, processId: processId }, function (launchError, _result) {
if (launchError) {
console.log('Error:', launchError.error || launchError.message);
}
});
};
var isStopping = ['stopRequested', 'stopping'].includes(state);
return (React.createElement(React.Fragment, null,
warning ? (React.createElement(antd_1.Popconfirm, { title: warning, onConfirm: run, okText: "Yes", cancelText: "No" },
React.createElement(antd_1.Button, { danger: true, disabled: ['scheduled', 'running', 'stopRequested', 'stopping'].includes(state) }, "Run"))) : (React.createElement(antd_1.Button, { type: special ? 'default' : 'primary', onClick: run, disabled: ['scheduled', 'running', 'stopRequested', 'stopping'].includes(state) }, "Run")),
['scheduled', 'running', 'stopRequested', 'stopping'].includes(state) && (React.createElement(antd_1.Button, { disabled: isStopping, onClick: function () { return shards_meteor_process_manager_core_1.stopProcessMethod.call({ scopeId: scopeId, processId: processId }); } },
"Stop",
isStopping && React.createElement(antd_1.Spin, null)))));
},
},
{
dataIndex: 'name',
title: 'Topic',
width: '40%',
render: function (name) { return (0, react_html_1.highlightedText)(name, search); },
},
{
dataIndex: 'special',
title: 'Special?',
width: '5%',
render: function (value) { return (value ? React.createElement(icons_1.CheckOutlined, null) : null); },
},
{
dataIndex: 'detailLevel',
title: 'Detail level',
width: '5%',
// render: (value) => (value ? <CheckOutlined /> : null),
},
{
title: 'Progress',
dataIndex: 'progress',
render: function (progress, process) {
var _a;
if (progress === void 0) { progress = { message: '', rate: 0 }; }
var processId = process.processId;
var myStatus = getProgressBarState(process.status);
var myMessage = getProgressBarMessage(process.status, progress);
var state = ((_a = process.status) === null || _a === void 0 ? void 0 : _a.state) || 'wtf';
return (React.createElement(React.Fragment, null,
['scheduled', 'running', 'stopRequested', 'stopping'].includes(state) && (React.createElement(icons_1.SyncOutlined, { spin: true, style: { marginRight: '1em' } })),
myMessage,
React.createElement(antd_1.Progress, { percent: Math.round(progress.rate * 100), status: myStatus }),
['failed', 'stopped'].includes(state) && (React.createElement(antd_1.Button, { onClick: function () { return shards_meteor_process_manager_core_1.dismissProcessMessagesMethod.call({ scopeId: scopeId, processId: processId }); } }, "Dismiss"))));
},
},
] }));
}
var ProcessTableUI = React.memo(ProcessTableRawUI, function (_, props) { return !props.ready; });
function ProcessManagerUI(props) {
var scopeId = props.scopeId;
var _a = (0, react_1.useState)(''), search = _a[0], setSearch = _a[1];
var _b = (0, react_1.useState)(true), focusOnActive = _b[0], setFocusOnActive = _b[1];
var _c = (0, react_1.useState)(true), hideDetails = _c[0], setHideDetails = _c[1];
var _d = (0, react_1.useState)(true), hideSpecial = _d[0], setHideSpecial = _d[1];
var _e = (0, react_1.useState)(), localError = _e[0], setLocalError = _e[1];
var _f = (0, meteor_react_1.useMeteorPublication)(shards_meteor_process_manager_core_1.publicationBackgroundProcesses, {
scopeId: scopeId,
search: search,
}, 'ProcessManagerUI'), areProcessesLoading = _f[0], processes = _f[1], processError = _f[2];
var hasActive = processes.some(function (p) { var _a; return isStateActive((_a = p.status) === null || _a === void 0 ? void 0 : _a.state); });
var shownProcesses = processes.filter(function (p) {
var _a;
return isStateActive((_a = p.status) === null || _a === void 0 ? void 0 : _a.state) || // always show active
((!hideDetails || p.detailLevel === 1) && // hide details if required
(!hideSpecial || !p.special) && // hide special if requested
(!hasActive || !focusOnActive));
} // hide inactive if required
);
return (React.createElement(React.Fragment, null,
React.createElement(antd_1.Row, null,
React.createElement(antd_1.Col, { span: 4 }, "Search for process:"),
React.createElement(antd_1.Col, null,
React.createElement(antd_1.Input.Search, { placeholder: "", value: search, onChange: function (event) { return setSearch(event.target.value); }, style: { width: 200 } }),
areProcessesLoading() && React.createElement(antd_1.Spin, null)),
React.createElement(antd_1.Col, null,
React.createElement(antd_1.Checkbox, { checked: focusOnActive, onChange: function (v) { return setFocusOnActive(v.target.checked); } }, "Focus on active")),
React.createElement(antd_1.Col, null,
React.createElement(antd_1.Checkbox, { checked: hideDetails, onChange: function (v) { return setHideDetails(v.target.checked); } }, "Hide details")),
React.createElement(antd_1.Col, null,
React.createElement(antd_1.Checkbox, { checked: hideSpecial, onChange: function (v) { return setHideSpecial(v.target.checked); } }, "Hide special"))),
React.createElement(ProcessTableUI, { scopeId: scopeId, processes: shownProcesses, search: search, ready: !areProcessesLoading(), error: localError || processError }),
React.createElement(antd_1.Button, { danger: true, onClick: function () {
return shards_meteor_process_manager_core_1.purgeProcesses
.callPromise(scopeId)
.catch(function (error) { return setLocalError("Can't reset processes: " + error.message); });
} }, "Reset processes")));
}
exports.ProcessManagerUI = ProcessManagerUI;