213 lines
16 KiB
JavaScript
213 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',
|
|
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
|