Files
tnsu-approval-route/frontend/lib-commonjs/webparts/approvalAdmin/components/screens/RouteStepsScreen.js
T
gorbenko.pavel 91361c439b правочки
2026-07-29 14:43:18 +05:00

214 lines
16 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RouteStepsScreen = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var models_1 = require("../../models");
var ui_1 = require("../ui");
function emptyForm(nextOrderNo) {
return {
orderNo: String(nextOrderNo),
status: models_1.RouteStepStatus.Approval,
kind: 'email',
executorEmail: '',
position: '',
projectRole: models_1.ProjectRole.ProjectManager,
headType: models_1.HeadType.Chief,
allowReassignToOtherApprovers: false
};
}
var STATUS_OPTIONS = [models_1.RouteStepStatus.Approval, models_1.RouteStepStatus.Execution]
.map(function (v) { return ({ value: v, label: models_1.routeStepStatusLabels[v] }); });
var PROJECT_ROLE_OPTIONS = Object.values(models_1.ProjectRole)
.filter(function (v) { return v !== models_1.ProjectRole.None; })
.map(function (v) { return ({ value: v, label: models_1.projectRoleLabels[v] }); });
var HEAD_TYPE_OPTIONS = Object.values(models_1.HeadType)
.filter(function (v) { return v !== models_1.HeadType.None; })
.map(function (v) { return ({ value: v, label: models_1.headTypeLabels[v] }); });
var RouteStepsScreen = function (_a) {
var api = _a.api, route = _a.route, requestTypeName = _a.requestTypeName, onBack = _a.onBack;
var _b = React.useState([]), items = _b[0], setItems = _b[1];
var _c = React.useState(true), loading = _c[0], setLoading = _c[1];
var _d = React.useState(), loadError = _d[0], setLoadError = _d[1];
var _e = React.useState(), warning = _e[0], setWarning = _e[1];
var _f = React.useState(), editing = _f[0], setEditing = _f[1];
var _g = React.useState(false), showForm = _g[0], setShowForm = _g[1];
var _h = React.useState(emptyForm(1)), form = _h[0], setForm = _h[1];
var _j = React.useState(), formError = _j[0], setFormError = _j[1];
var _k = React.useState(false), saving = _k[0], setSaving = _k[1];
var _l = React.useState(), deleting = _l[0], setDeleting = _l[1];
var _m = React.useState(), deleteError = _m[0], setDeleteError = _m[1];
var _o = React.useState(false), deleteBusy = _o[0], setDeleteBusy = _o[1];
var load = React.useCallback(function () {
setLoading(true);
setLoadError(undefined);
api.templateRouteSteps
.list(route.id)
.then(setItems)
.catch(function (e) { return setLoadError(e.message); })
.finally(function () { return setLoading(false); });
}, [api, route.id]);
React.useEffect(function () { load(); }, [load]);
var openCreate = function () {
setEditing(undefined);
var nextOrder = items.length > 0 ? Math.max.apply(Math, items.map(function (s) { return s.orderNo; })) + 1 : 1;
setForm(emptyForm(nextOrder));
setFormError(undefined);
setShowForm(true);
};
var openEdit = function (item) {
var _a, _b;
setEditing(item);
setForm({
orderNo: String(item.orderNo),
status: item.status,
kind: (0, models_1.detectExecutorKind)(item),
executorEmail: (_a = item.executorEmail) !== null && _a !== void 0 ? _a : '',
position: (_b = item.position) !== null && _b !== void 0 ? _b : '',
projectRole: item.projectRole && item.projectRole !== models_1.ProjectRole.None ? item.projectRole : models_1.ProjectRole.ProjectManager,
headType: item.headType && item.headType !== models_1.HeadType.None ? item.headType : models_1.HeadType.Chief,
allowReassignToOtherApprovers: item.allowReassignToOtherApprovers
});
setFormError(undefined);
setShowForm(true);
};
var submit = function () {
var orderNo = Number(form.orderNo);
if (!orderNo || orderNo < 1) {
setFormError('Порядковый номер шага обязателен.');
return;
}
if (form.kind === 'email' && !form.executorEmail.trim()) {
setFormError('Укажите email исполнителя.');
return;
}
if (form.kind === 'position' && !form.position.trim()) {
setFormError('Укажите должность.');
return;
}
var payload = {
orderNo: orderNo,
status: form.status,
allowReassignToOtherApprovers: form.allowReassignToOtherApprovers,
executorEmail: form.kind === 'email' ? form.executorEmail.trim() : null,
position: form.kind === 'position' ? form.position.trim() : null,
projectRole: form.kind === 'projectRole' ? form.projectRole : null,
headType: form.kind === 'headType' ? form.headType : null
};
setSaving(true);
setFormError(undefined);
var request = editing
? api.templateRouteSteps.update(route.id, editing.id, payload)
: api.templateRouteSteps.create(route.id, payload);
request
.then(function (step) {
var _a;
setShowForm(false);
setWarning((_a = step.warning) !== null && _a !== void 0 ? _a : undefined);
load();
})
.catch(function (e) { return setFormError(e.message); })
.finally(function () { return setSaving(false); });
};
var confirmDelete = function () {
if (!deleting)
return;
setDeleteBusy(true);
setDeleteError(undefined);
api.templateRouteSteps
.remove(route.id, deleting.id)
.then(function () {
setDeleting(undefined);
load();
})
.catch(function (e) { return setDeleteError(e.message); })
.finally(function () { return setDeleteBusy(false); });
};
var sorted = tslib_1.__spreadArray([], items, true).sort(function (a, b) { return a.orderNo - b.orderNo; });
return (React.createElement("div", null,
React.createElement(ui_1.Breadcrumbs, { items: [
{ label: 'Главная' },
{ label: 'Маршруты согласования', onClick: onBack },
{ label: "\u0428\u0430\u0433\u0438 \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0430 #".concat(route.id) }
] }),
React.createElement(ui_1.PageHeader, { icon: "flag-check", subtitle: "".concat(requestTypeName, " \u00B7 ").concat(models_1.routeTypeLabels[route.routeType]), title: "\u041C\u0430\u0440\u0448\u0440\u0443\u0442 #".concat(route.id), actions: React.createElement(React.Fragment, null,
React.createElement(ui_1.Button, { variant: "ghost", icon: "arrow-left", onClick: onBack }, "\u041A \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043C"),
React.createElement(ui_1.Button, { variant: "accent", icon: "plus", onClick: openCreate }, "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0448\u0430\u0433")) }),
warning && React.createElement(ui_1.Alert, { kind: "warn" }, warning),
loadError && React.createElement(ui_1.Alert, { kind: "err" }, loadError),
deleteError && React.createElement(ui_1.Alert, { kind: "err" }, deleteError),
React.createElement(ui_1.DataTable, { columns: [
{ key: 'order', header: '№', width: '50px', render: function (r) { return r.orderNo; } },
{
key: 'executor',
header: 'Исполнитель',
render: function (r) { return React.createElement(ui_1.PrimaryCell, null, describeExecutor(r)); }
},
{
key: 'status',
header: 'Статус',
render: function (r) { return (React.createElement(ui_1.Badge, { variant: r.status === models_1.RouteStepStatus.Approval ? 'gold' : 'blue' }, models_1.routeStepStatusLabels[r.status])); }
},
{
key: 'reassign',
header: 'Переназначение',
align: 'center',
render: function (r) { return (r.allowReassignToOtherApprovers ? React.createElement(ui_1.Badge, { variant: "ok" }, "\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u043E") : React.createElement(ui_1.Badge, { variant: "neutral" }, "\u041D\u0435\u0442")); }
},
{
key: 'actions',
header: '',
width: '100px',
align: 'right',
sticky: true,
render: function (r) { return (React.createElement(ui_1.ActionsCell, null,
React.createElement(ui_1.IconButton, { icon: "edit", label: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C", onClick: function () { return openEdit(r); } }),
React.createElement(ui_1.IconButton, { icon: "trash", label: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", danger: true, onClick: function () { setDeleteError(undefined); setDeleting(r); } }))); }
}
], rows: sorted, keyOf: function (r) { return r.id; }, emptyMessage: loading ? 'Загрузка...' : 'Шагов пока нет — добавьте первый.' }),
showForm && (React.createElement(ui_1.Modal, { title: editing ? "\u0428\u0430\u0433 #".concat(editing.orderNo) : 'Новый шаг маршрута', onClose: function () { return setShowForm(false); }, footer: React.createElement(React.Fragment, null,
React.createElement(ui_1.Button, { variant: "secondary", onClick: function () { return setShowForm(false); }, disabled: saving }, "\u041E\u0442\u043C\u0435\u043D\u0430"),
React.createElement(ui_1.Button, { variant: "accent", icon: "check", onClick: submit, disabled: saving }, saving ? 'Сохранение...' : 'Сохранить')) },
formError && React.createElement(ui_1.Alert, { kind: "err" }, formError),
React.createElement(ui_1.FormGrid, null,
React.createElement(ui_1.Field, { label: "\u041F\u043E\u0440\u044F\u0434\u043A\u043E\u0432\u044B\u0439 \u043D\u043E\u043C\u0435\u0440", required: true },
React.createElement(ui_1.TextInput, { type: "number", min: 1, value: form.orderNo, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { orderNo: e.target.value })); } })),
React.createElement(ui_1.Field, { label: "\u0421\u0442\u0430\u0442\u0443\u0441 \u0448\u0430\u0433\u0430", required: true },
React.createElement(ui_1.Select, { options: STATUS_OPTIONS, value: form.status, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { status: e.target.value })); } })),
React.createElement(ui_1.Field, { label: "\u041A\u0442\u043E \u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C", required: true, full: true, hint: "\u0414\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043E \u0440\u043E\u0432\u043D\u043E \u043E\u0434\u043D\u043E \u0438\u0437 \u043F\u043E\u043B\u0435\u0439." },
React.createElement(ui_1.RadioGroup, { name: "executorKind", value: form.kind, onChange: function (kind) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { kind: kind })); }, options: [
{ value: 'email', label: 'Конкретный сотрудник (email)' },
{ value: 'position', label: 'По должности в компании инициатора' },
{
value: 'projectRole',
label: 'По роли в проекте',
disabled: !route.byProject,
disabledHint: 'Недоступно: маршрут не учитывает проект (по проекту = нет).'
},
{ value: 'headType', label: 'По типу руководителя' }
] })),
form.kind === 'email' && (React.createElement(ui_1.Field, { label: "Email \u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044F", required: true, full: true },
React.createElement(ui_1.TextInput, { value: form.executorEmail, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { executorEmail: e.target.value })); }, placeholder: "user@tnsu.kz" }))),
form.kind === 'position' && (React.createElement(ui_1.Field, { label: "\u0414\u043E\u043B\u0436\u043D\u043E\u0441\u0442\u044C", required: true, full: true, hint: "\u0418\u0449\u0435\u0442\u0441\u044F \u0432 \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0435 api.tnsu.kz \u043F\u043E \u043A\u043E\u043C\u043F\u0430\u043D\u0438\u0438 \u0438\u043D\u0438\u0446\u0438\u0430\u0442\u043E\u0440\u0430." },
React.createElement(ui_1.TextInput, { value: form.position, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { position: e.target.value })); }, placeholder: "\u0413\u043B\u0430\u0432\u043D\u044B\u0439 \u0438\u043D\u0436\u0435\u043D\u0435\u0440" }))),
form.kind === 'projectRole' && (React.createElement(ui_1.Field, { label: "\u0420\u043E\u043B\u044C \u0432 \u043F\u0440\u043E\u0435\u043A\u0442\u0435", required: true, full: true },
React.createElement(ui_1.Select, { options: PROJECT_ROLE_OPTIONS, value: form.projectRole, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { projectRole: e.target.value })); } }))),
form.kind === 'headType' && (React.createElement(ui_1.Field, { label: "\u0422\u0438\u043F \u0440\u0443\u043A\u043E\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044F", required: true, full: true },
React.createElement(ui_1.Select, { options: HEAD_TYPE_OPTIONS, value: form.headType, onChange: function (e) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { headType: e.target.value })); } }))),
React.createElement(ui_1.Field, { label: "\u041F\u0435\u0440\u0435\u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435", full: true },
React.createElement(ui_1.Checkbox, { label: "\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u043F\u0435\u0440\u0435\u043D\u0430\u0437\u043D\u0430\u0447\u0430\u0442\u044C \u0434\u0440\u0443\u0433\u0438\u043C \u0441\u043E\u0433\u043B\u0430\u0441\u0443\u044E\u0449\u0438\u043C", checked: form.allowReassignToOtherApprovers, onChange: function (v) { return setForm(tslib_1.__assign(tslib_1.__assign({}, form), { allowReassignToOtherApprovers: v })); } }))))),
deleting && (React.createElement(ui_1.ConfirmDialog, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0448\u0430\u0433?", text: "\u0428\u0430\u0433 #".concat(deleting.orderNo, " \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043B\u0451\u043D \u0431\u0435\u0437\u0432\u043E\u0437\u0432\u0440\u0430\u0442\u043D\u043E."), confirmLabel: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", busy: deleteBusy, onCancel: function () { return setDeleting(undefined); }, onConfirm: confirmDelete }))));
};
exports.RouteStepsScreen = RouteStepsScreen;
function describeExecutor(step) {
if (step.executorEmail)
return step.executorEmail;
if (step.position)
return step.position;
if (step.projectRole && step.projectRole !== models_1.ProjectRole.None)
return "\u0420\u043E\u043B\u044C: ".concat(models_1.projectRoleLabels[step.projectRole]);
if (step.headType && step.headType !== models_1.HeadType.None)
return "\u0420\u0443\u043A\u043E\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C: ".concat(models_1.headTypeLabels[step.headType]);
return '—';
}
//# sourceMappingURL=RouteStepsScreen.js.map