forked from CITKParus/P8-Panels
684 lines
28 KiB
JavaScript
684 lines
28 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - УДП - Доски задач
|
||
Компонент панели: Диалог формы события
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useState, useContext, useEffect } from "react"; //Классы React
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { Box, Typography, TextField, Dialog, DialogContent, DialogActions, Button, Tabs, Tab, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты
|
||
import { useClientEvent, useDocsProps } from "../hooks"; //Вспомогательные хуки
|
||
import { APP_STYLES } from "../../../../app.styles"; //Типовые стили
|
||
import { ApplicationСtx } from "../../../context/application"; //Контекст приложения
|
||
import dayjs from "dayjs"; //Работа с датами
|
||
import customParseFormat from "dayjs/plugin/customParseFormat"; //Настройка пользовательского формата даты
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Перечисление "Значение по умолчанию"
|
||
const DP_DEFAULT_VALUE = Object.freeze({ 0: "defaultStr", 1: "defaultNum", 2: "defaultDate", 3: "defaultNum" });
|
||
//Перечисление "Префикс формата данных"
|
||
const DP_TYPE_PREFIX = Object.freeze({ 0: "S", 1: "N", 2: "D", 3: "N" });
|
||
//Перечисление "Входящее значение дополнительного словаря"
|
||
const DP_IN_VALUE = Object.freeze({ 0: "pos_str_value", 1: "pos_num_value", 2: "pos_date_value", 3: "pos_num_value" });
|
||
//Перечисление "Исходящее значение дополнительного словаря"
|
||
const DP_RETURN_VALUE = Object.freeze({ 0: "str_value", 1: "num_value", 2: "date_value", 3: "num_value" });
|
||
|
||
//Стили
|
||
const STYLES = {
|
||
CONTAINER: { margin: "5px 0px", textAlign: "center" },
|
||
DIALOG_CONTENT: {
|
||
paddingBottom: "0px",
|
||
maxHeight: "740px",
|
||
minHeight: "740px",
|
||
...APP_STYLES.SCROLL
|
||
},
|
||
DIALOG_ACTIONS: { justifyContent: "end", paddingRight: "24px", paddingLeft: "24px" },
|
||
BOX_WITH_LEGEND: { border: "1px solid #939393" },
|
||
BOX_SINGLE_COLUMN: { display: "flex", flexDirection: "column", gap: "10px" },
|
||
BOX_FEW_COLUMNS: { display: "flex", flexWrap: "wrap", justifyContent: "space-between" },
|
||
BOX_LEFT_ALIGN: { display: "flex", justifyContent: "flex-start" },
|
||
LEGEND: { textAlign: "left" },
|
||
TEXT_FIELD: (widthVal, greyDisabled = false) => ({
|
||
margin: "4px",
|
||
...(widthVal ? { width: widthVal } : {}),
|
||
...(greyDisabled
|
||
? {
|
||
"& .MuiInputBase-input.Mui-disabled": {
|
||
WebkitTextFillColor: "rgba(0, 0, 0, 0.87)"
|
||
},
|
||
"& .MuiInputLabel-root.Mui-disabled": {
|
||
WebkitTextFillColor: "rgba(0, 0, 0, 0.6)"
|
||
}
|
||
}
|
||
: {})
|
||
})
|
||
};
|
||
|
||
//------------------------------------
|
||
//Вспомогательные функции и компоненты
|
||
//------------------------------------
|
||
|
||
//Подключение настройки пользовательского формата даты
|
||
dayjs.extend(customParseFormat);
|
||
|
||
//Свойства вкладки
|
||
function a11yProps(index) {
|
||
return {
|
||
id: `simple-tab-${index}`,
|
||
"aria-controls": `simple-tabpanel-${index}`
|
||
};
|
||
}
|
||
|
||
//Формирование кнопки для открытия раздела
|
||
const getInputProps = (onClick, disabled = false, icon = "list") => {
|
||
return {
|
||
endAdornment: (
|
||
<InputAdornment position="end">
|
||
<IconButton disabled={disabled} aria-label={`select`} onClick={onClick} edge="end">
|
||
<Icon>{icon}</Icon>
|
||
</IconButton>
|
||
</InputAdornment>
|
||
)
|
||
};
|
||
};
|
||
|
||
//Вкладка информации
|
||
function CustomTabPanel(props) {
|
||
const { children, value, index, ...other } = props;
|
||
|
||
return (
|
||
<Box role="tabpanel" hidden={value !== index} id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other}>
|
||
{value === index && <Box pt={1}>{children}</Box>}
|
||
</Box>
|
||
);
|
||
}
|
||
|
||
//Контроль свойств - Вкладка информации
|
||
CustomTabPanel.propTypes = {
|
||
children: PropTypes.node,
|
||
index: PropTypes.number.isRequired,
|
||
value: PropTypes.number.isRequired
|
||
};
|
||
|
||
//Вкладка основной информации
|
||
const MainEventInfoTab = ({
|
||
task,
|
||
editable,
|
||
handleFieldEdit,
|
||
handleClientClientsOpen,
|
||
handleClientPersonOpen,
|
||
handleCrnOpen,
|
||
handleEventNextNumbGet
|
||
}) => {
|
||
return (
|
||
<Box>
|
||
<Box sx={STYLES.BOX_WITH_LEGEND} component="fieldset">
|
||
<legend style={STYLES.LEGEND}>Событие</legend>
|
||
<Box sx={STYLES.BOX_FEW_COLUMNS}>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD()}
|
||
id="scrn"
|
||
label="Каталог"
|
||
fullWidth
|
||
value={task.scrn}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
InputProps={getInputProps(handleCrnOpen)}
|
||
required
|
||
disabled={task.isUpdate}
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD("225px")}
|
||
id="sprefix"
|
||
label="Префикс"
|
||
value={task.sprefix}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
required
|
||
disabled={task.isUpdate}
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD("225px")}
|
||
id="snumber"
|
||
label="Номер"
|
||
value={task.snumber}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
required
|
||
disabled={task.isUpdate}
|
||
InputProps={getInputProps(handleEventNextNumbGet, !task.sprefix || task.isUpdate, "refresh")}
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD("225px", !task.isUpdate)}
|
||
id="stype"
|
||
label="Тип"
|
||
value={task.stype}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
required
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD("225px", !task.isUpdate)}
|
||
id="sstatus"
|
||
label="Статус"
|
||
value={task.sstatus}
|
||
variant="standard"
|
||
disabled
|
||
required
|
||
onChange={handleFieldEdit}
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD()}
|
||
fullWidth
|
||
id="sdescription"
|
||
label="Описание"
|
||
value={task.sdescription}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled={!task.stype || !editable}
|
||
required
|
||
multiline
|
||
minRows={7}
|
||
maxRows={7}
|
||
></TextField>
|
||
</Box>
|
||
</Box>
|
||
<Box sx={{ ...STYLES.BOX_WITH_LEGEND, ...STYLES.BOX_SINGLE_COLUMN }} component="fieldset">
|
||
<legend style={STYLES.LEGEND}>Клиент</legend>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD()}
|
||
id="sclnt_clnclients"
|
||
label="Организация"
|
||
value={task.sclnt_clnclients}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled={!task.stype}
|
||
InputProps={getInputProps(handleClientClientsOpen, !task.stype)}
|
||
></TextField>
|
||
<TextField
|
||
sx={STYLES.TEXT_FIELD()}
|
||
id="sclnt_clnperson"
|
||
label="Сотрудник"
|
||
value={task.sclnt_clnperson}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled={!task.stype}
|
||
InputProps={getInputProps(() => handleClientPersonOpen(0), !task.stype)}
|
||
></TextField>
|
||
</Box>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Вкладка основной информации
|
||
MainEventInfoTab.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
editable: PropTypes.bool.isRequired,
|
||
handleFieldEdit: PropTypes.func.isRequired,
|
||
handleClientClientsOpen: PropTypes.func.isRequired,
|
||
handleClientPersonOpen: PropTypes.func.isRequired,
|
||
handleCrnOpen: PropTypes.func.isRequired,
|
||
handleEventNextNumbGet: PropTypes.func.isRequired
|
||
};
|
||
|
||
//Вкладка информации об исполнителе
|
||
const ExecutorEventInfoTab = ({ task, handleFieldEdit, handleClientPersonOpen }) => {
|
||
return (
|
||
<Box>
|
||
<Box sx={{ ...STYLES.BOX_WITH_LEGEND, ...STYLES.BOX_LEFT_ALIGN }} component="fieldset">
|
||
<legend style={STYLES.LEGEND}>Планирование</legend>
|
||
<TextField
|
||
id="dplan_date"
|
||
label="Начало работ"
|
||
InputLabelProps={{ shrink: true }}
|
||
type="datetime-local"
|
||
variant="standard"
|
||
value={task.dplan_date ? dayjs(task.dplan_date, "DD.MM.YYYY HH:mm").format("YYYY-MM-DD HH:mm") : ""}
|
||
onChange={handleFieldEdit}
|
||
disabled={task.isUpdate}
|
||
></TextField>
|
||
</Box>
|
||
<Box sx={{ ...STYLES.BOX_WITH_LEGEND, ...STYLES.BOX_SINGLE_COLUMN }} component="fieldset">
|
||
<legend style={STYLES.LEGEND}>Инициатор</legend>
|
||
<TextField
|
||
id="sinit_clnperson"
|
||
label="Сотрудник"
|
||
value={task.sinit_clnperson}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled={task.isUpdate}
|
||
InputProps={getInputProps(() => handleClientPersonOpen(1), task.isUpdate)}
|
||
></TextField>
|
||
<TextField
|
||
id="sinit_user"
|
||
label="Пользователь"
|
||
value={task.sinit_user}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sinit_reason"
|
||
label="Основание"
|
||
value={task.sinit_reason}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled={task.isUpdate}
|
||
></TextField>
|
||
</Box>
|
||
<Box sx={{ ...STYLES.BOX_WITH_LEGEND, ...STYLES.BOX_SINGLE_COLUMN }} component="fieldset">
|
||
<legend style={STYLES.LEGEND}>Направить</legend>
|
||
<TextField
|
||
id="sto_company"
|
||
label="Организация"
|
||
value={task.sto_company}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_department"
|
||
label="Подразделение"
|
||
value={task.sto_department}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_clnpost"
|
||
label="Должность"
|
||
value={task.sto_clnpost}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_clnpsdep"
|
||
label="Штатная должность"
|
||
value={task.sto_clnpsdep}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_clnperson"
|
||
label="Сотрудник"
|
||
value={task.sto_clnperson}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_fcstaffgrp"
|
||
label="Нештатная должность"
|
||
value={task.sto_fcstaffgrp}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_user"
|
||
label="Пользователь"
|
||
value={task.sto_user}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
<TextField
|
||
id="sto_usergrp"
|
||
label="Группа пользователей"
|
||
value={task.sto_usergrp}
|
||
variant="standard"
|
||
onChange={handleFieldEdit}
|
||
disabled
|
||
></TextField>
|
||
</Box>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Вкладка информации об исполнителе
|
||
ExecutorEventInfoTab.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
handleFieldEdit: PropTypes.func.isRequired,
|
||
handleClientPersonOpen: PropTypes.func.isRequired
|
||
};
|
||
|
||
//Вкладка информации со свойствами
|
||
const PropsEventInfoTab = ({ task, docProps, handlePropEdit }) => {
|
||
//Подключение к контексту приложения
|
||
const { pOnlineShowDictionary } = useContext(ApplicationСtx);
|
||
|
||
//Формат дополнительного свойства типа число (длина, точность)
|
||
const DPNumFormat = (l, p) => new RegExp("^(\\d{1," + (l - p) + "}" + (p > 0 ? "((\\.|,)\\d{1," + p + "})?" : "") + ")?$");
|
||
|
||
//Формат дополнительного свойства типа строка (длина)
|
||
const DPStrFormat = l => new RegExp("^.{0," + l + "}$");
|
||
|
||
//Проверка валидности числа
|
||
const isValidDPNum = (length, prec, value) => {
|
||
return DPNumFormat(length, prec).test(value);
|
||
};
|
||
|
||
//Проверка валидности строки
|
||
const isValidDPStr = (length, value) => {
|
||
return DPStrFormat(length).test(value);
|
||
};
|
||
|
||
//Признак ошибки валидации
|
||
const validationError = (value = "", format, numW, numPrec, strW) => {
|
||
if (format === 0) return isValidDPStr(strW, value);
|
||
else if (format === 1) {
|
||
return isValidDPNum(numW, numPrec, value);
|
||
} else return true;
|
||
};
|
||
|
||
//Конвертация времени в привычный формат
|
||
const timeFromSqlFormat = ts => {
|
||
if (ts.indexOf(".") !== -1) {
|
||
let s = 24 * 60 * 60 * ts;
|
||
const h = Math.trunc(s / (60 * 60));
|
||
s = s % (60 * 60);
|
||
const m = Math.trunc(s / 60);
|
||
s = Math.round(s % 60);
|
||
const formattedTime = ("0" + h).slice(-2) + ":" + ("0" + m).slice(-2) + ":" + ("0" + s).slice(-2);
|
||
return formattedTime;
|
||
}
|
||
return ts;
|
||
};
|
||
|
||
//Выбор из словаря или дополнительного словаря
|
||
const handleDict = async (dp, curValue = null) => {
|
||
dp.entryType === 1
|
||
? pOnlineShowDictionary({
|
||
unitCode: dp.unitcode,
|
||
showMethod: dp.showMethodCode,
|
||
inputParameters: dp.paramRn ? [{ name: dp.paramIn, value: curValue }] : null,
|
||
callBack: res => {
|
||
res.success
|
||
? handlePropEdit({
|
||
target: {
|
||
id: `${DP_TYPE_PREFIX[dp.format]}DP_${dp.rn}`,
|
||
value: res.outParameters[dp.paramOut]
|
||
}
|
||
})
|
||
: null;
|
||
}
|
||
})
|
||
: pOnlineShowDictionary({
|
||
unitCode: "ExtraDictionaries",
|
||
showMethod: "values",
|
||
inputParameters: [
|
||
{ name: "pos_rn", value: dp.extraDictRn },
|
||
{ name: DP_IN_VALUE[dp.format], value: curValue }
|
||
],
|
||
callBack: res => {
|
||
res.success
|
||
? handlePropEdit({
|
||
target: {
|
||
id: `${DP_TYPE_PREFIX[dp.format]}DP_${dp.rn}`,
|
||
value: res.outParameters[DP_RETURN_VALUE[dp.format]]
|
||
}
|
||
})
|
||
: null;
|
||
}
|
||
});
|
||
};
|
||
|
||
//Инициализация дополнительного свойства
|
||
const initProp = prop => {
|
||
//Значение свойства
|
||
const value = task.docProps[`${DP_TYPE_PREFIX[prop.format]}DP_${prop.rn}`];
|
||
if (
|
||
(task.nrn || task.docProps[`${DP_TYPE_PREFIX[prop.format]}DP_${prop.rn}`]) &&
|
||
task.docProps[`${DP_TYPE_PREFIX[prop.format]}DP_${prop.rn}`] !== undefined
|
||
) {
|
||
//Строка или число
|
||
if (prop.format < 2) return prop.numPrecision ? String(value).replace(".", ",") : value;
|
||
//Дата
|
||
else if (prop.format === 2) {
|
||
//Дата без времени
|
||
if (prop.dataSubtype === 0) return dayjs(value).format("YYYY-MM-DD");
|
||
//Дата + время без секунд
|
||
else if (prop.dataSubtype === 1) return dayjs(value).format("YYYY-MM-DD HH:mm");
|
||
//Дата + время с секундами
|
||
else return dayjs(value).format("YYYY-MM-DD HH:mm:ss");
|
||
}
|
||
//Время
|
||
else {
|
||
return timeFromSqlFormat(value);
|
||
}
|
||
} else if (task.nrn) {
|
||
return "";
|
||
} else return prop[DP_DEFAULT_VALUE[prop.format]];
|
||
};
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Box>
|
||
<Box sx={STYLES.BOX_WITH_LEGEND} component="fieldset">
|
||
{docProps.props.map(dp => {
|
||
return dp.showInGrid ? (
|
||
<TextField
|
||
error={
|
||
!validationError(
|
||
task.docProps[`${DP_TYPE_PREFIX[dp.format]}DP_${dp.rn}`],
|
||
dp.format,
|
||
dp.numWidth,
|
||
dp.numPrecision,
|
||
dp.strWidth
|
||
)
|
||
}
|
||
key={dp.id}
|
||
sx={STYLES.TEXT_FIELD()}
|
||
id={`${DP_TYPE_PREFIX[dp.format]}DP_${dp.rn}`}
|
||
type={dp.format < 2 ? "string" : dp.format === 2 ? (dp.dataSubtype === 0 ? "date" : "datetime-local") : "time"}
|
||
label={dp.name}
|
||
fullWidth
|
||
value={initProp(dp)}
|
||
variant="standard"
|
||
onChange={handlePropEdit}
|
||
inputProps={(dp.format === 2 && dp.dataSubtype === 2) || (dp.format === 3 && dp.dataSubtype === 1) ? { step: 1 } : {}}
|
||
InputProps={
|
||
dp.entryType > 0
|
||
? getInputProps(() => handleDict(dp, task.docProps[`${DP_TYPE_PREFIX[dp.format]}DP_${dp.rn}`]))
|
||
: null
|
||
}
|
||
InputLabelProps={
|
||
dp.format < 2
|
||
? {}
|
||
: {
|
||
shrink: true
|
||
}
|
||
}
|
||
required={dp.require}
|
||
disabled={dp.readonly}
|
||
/>
|
||
) : null;
|
||
})}
|
||
</Box>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Вкладка информации со свойствами
|
||
PropsEventInfoTab.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
docProps: PropTypes.object.isRequired,
|
||
handlePropEdit: PropTypes.func.isRequired
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Форма события
|
||
const TaskForm = ({
|
||
task,
|
||
taskType,
|
||
setTask,
|
||
editable,
|
||
handleClientClientsOpen,
|
||
handleClientPersonOpen,
|
||
handleCrnOpen,
|
||
handleEventNextNumbGet,
|
||
handleDPReady
|
||
}) => {
|
||
//Состояние вкладки
|
||
const [value, setValue] = useState(0);
|
||
|
||
//Состояние допустимых дополнительных свойств
|
||
const [docProps] = useDocsProps(taskType);
|
||
|
||
//При изменении вкладки
|
||
const handleChange = (event, newValue) => {
|
||
setValue(newValue);
|
||
};
|
||
|
||
//При изменении поля
|
||
const handleFieldEdit = e => {
|
||
setTask(pv => ({
|
||
...pv,
|
||
[e.target.id]: e.target.value,
|
||
//Связанные значения, если меняется одно, то необходимо обнулить другое
|
||
...(e.target.id === "sclnt_clnperson" ? { sclnt_clnclients: "" } : {}),
|
||
...(e.target.id === "sclnt_clnclients" ? { sclnt_clnperson: "" } : {})
|
||
}));
|
||
};
|
||
|
||
//При изменении свойства
|
||
const handlePropEdit = e => {
|
||
setTask(pv => ({
|
||
...pv,
|
||
docProps: { ...pv.docProps, [e.target.id]: e.target.value }
|
||
}));
|
||
};
|
||
|
||
//При заполнении всех обязательных свойств
|
||
useEffect(() => {
|
||
let i = 0;
|
||
docProps.props.filter(dp => dp.require === true).map(prop => (!task.docProps[`${DP_TYPE_PREFIX[prop.format]}DP_${prop.rn}`] ? i++ : null));
|
||
docProps.loaded && i === 0 ? handleDPReady(true) : handleDPReady(false);
|
||
}, [docProps, handleDPReady, task.docProps]);
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Box sx={STYLES.CONTAINER}>
|
||
<Typography pb={1} variant="h6">
|
||
{task.nrn ? "Исправление события" : "Добавление события"}
|
||
</Typography>
|
||
<Tabs value={value} onChange={handleChange} aria-label="tabs of values">
|
||
<Tab label="Событие" {...a11yProps(0)} />
|
||
<Tab label="Исполнитель" {...a11yProps(1)} />
|
||
{docProps.props.length > 0 ? <Tab label="Свойства" {...a11yProps(2)} /> : null}
|
||
</Tabs>
|
||
<CustomTabPanel value={value} index={0}>
|
||
<MainEventInfoTab
|
||
task={task}
|
||
editable={editable}
|
||
handleFieldEdit={handleFieldEdit}
|
||
handleClientClientsOpen={handleClientClientsOpen}
|
||
handleClientPersonOpen={handleClientPersonOpen}
|
||
handleCrnOpen={handleCrnOpen}
|
||
handleEventNextNumbGet={handleEventNextNumbGet}
|
||
/>
|
||
</CustomTabPanel>
|
||
<CustomTabPanel value={value} index={1}>
|
||
<ExecutorEventInfoTab task={task} handleFieldEdit={handleFieldEdit} handleClientPersonOpen={handleClientPersonOpen} />
|
||
</CustomTabPanel>
|
||
{docProps.props.length > 0 ? (
|
||
<CustomTabPanel value={value} index={2}>
|
||
<PropsEventInfoTab task={task} taskType={taskType} docProps={docProps} handlePropEdit={handlePropEdit} />
|
||
</CustomTabPanel>
|
||
) : null}
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Форма события
|
||
TaskForm.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
taskType: PropTypes.string.isRequired,
|
||
setTask: PropTypes.func.isRequired,
|
||
editable: PropTypes.bool.isRequired,
|
||
handleClientClientsOpen: PropTypes.func.isRequired,
|
||
handleClientPersonOpen: PropTypes.func.isRequired,
|
||
handleCrnOpen: PropTypes.func.isRequired,
|
||
handleEventNextNumbGet: PropTypes.func.isRequired,
|
||
handleDPReady: PropTypes.func.isRequired
|
||
};
|
||
|
||
//Диалог с формой события
|
||
const TaskFormDialog = ({ taskRn, taskType, taskStatus, editable, handleReload, onClose }) => {
|
||
//Собственное состояние
|
||
const [task, setTask, insertEvent, updateEvent, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet] =
|
||
useClientEvent(taskRn, taskType, taskStatus);
|
||
|
||
//Состояние заполненности всех обязательных свойств
|
||
const [dpReady, setDPReady] = useState(false);
|
||
|
||
//Изменение состояния заполненности всех обязательных свойств
|
||
const handleDPReady = v => setDPReady(v);
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Dialog open onClose={onClose ? onClose : null} fullWidth>
|
||
<DialogContent sx={STYLES.DIALOG_CONTENT}>
|
||
<TaskForm
|
||
task={task}
|
||
taskType={taskType}
|
||
setTask={setTask}
|
||
editable={!taskRn || editable ? true : false}
|
||
handleClientClientsOpen={handleClientClientsOpen}
|
||
handleClientPersonOpen={handleClientPersonOpen}
|
||
handleCrnOpen={handleCrnOpen}
|
||
handleEventNextNumbGet={handleEventNextNumbGet}
|
||
handleDPReady={handleDPReady}
|
||
/>
|
||
</DialogContent>
|
||
{onClose ? (
|
||
<DialogActions sx={STYLES.DIALOG_ACTIONS}>
|
||
{taskRn ? (
|
||
<Button onClick={() => updateEvent(onClose).then(handleReload)} disabled={task.updateDisabled || !editable || !dpReady}>
|
||
Исправить
|
||
</Button>
|
||
) : (
|
||
<Button
|
||
onClick={() => {
|
||
insertEvent(onClose).then(handleReload);
|
||
}}
|
||
disabled={task.insertDisabled || !dpReady}
|
||
>
|
||
Добавить
|
||
</Button>
|
||
)}
|
||
<Button onClick={onClose}>Закрыть</Button>
|
||
</DialogActions>
|
||
) : null}
|
||
</Dialog>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Диалог с формой события
|
||
TaskFormDialog.propTypes = {
|
||
taskRn: PropTypes.number,
|
||
taskType: PropTypes.string.isRequired,
|
||
taskStatus: PropTypes.string,
|
||
editable: PropTypes.bool,
|
||
handleReload: PropTypes.func.isRequired,
|
||
onClose: PropTypes.func.isRequired
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { TaskFormDialog };
|