forked from CITKParus/P8-Panels
159 lines
6.4 KiB
JavaScript
159 lines
6.4 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - УДП - Доски задач
|
||
Компонент панели: Форма события
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useState, useEffect, useCallback } from "react"; //Классы React
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { Box, Typography, Tabs, Tab, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты
|
||
import { TaskFormTabInfo } from "./task_form_tab_info"; //Вкладка основной информации
|
||
import { TaskFormTabExecutor } from "./task_form_tab_executor"; //Вкладка информации об исполнителе
|
||
import { TaskFormTabProps } from "./task_form_tab_props"; //Вкладка информации со свойствами
|
||
import { useDocsProps } from "../hooks/task_dialog_hooks"; //Хук для получения свойств раздела "События"
|
||
import { hasValue } from "../../../core/utils";
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Стили
|
||
const STYLES = {
|
||
CONTAINER: { margin: "5px 0px", textAlign: "center" }
|
||
};
|
||
|
||
//------------------------------------
|
||
//Вспомогательные функции и компоненты
|
||
//------------------------------------
|
||
|
||
//Свойства вкладки
|
||
function a11yProps(index) {
|
||
return {
|
||
id: `simple-tab-${index}`,
|
||
"aria-controls": `simple-tabpanel-${index}`
|
||
};
|
||
}
|
||
|
||
//Вкладка информации
|
||
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
|
||
};
|
||
|
||
//Формирование кнопки для открытия раздела
|
||
export 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>
|
||
)
|
||
};
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Форма события
|
||
const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet, onDPReady }) => {
|
||
//Состояние вкладки
|
||
const [tab, setTab] = useState(0);
|
||
|
||
//Состояние допустимых дополнительных свойств
|
||
const [docProps] = useDocsProps(taskType);
|
||
|
||
//При изменении вкладки
|
||
const handleTabChange = (e, newValue) => {
|
||
setTab(newValue);
|
||
};
|
||
|
||
//При изменении поля
|
||
const handleFieldEdit = useCallback(
|
||
e => {
|
||
onTaskChange({
|
||
[e.target.id]: e.target.value,
|
||
//Связанные значения, если меняется одно, то необходимо обнулить другое
|
||
...(e.target.id === "sClntClnperson" ? { sClntClients: "" } : {}),
|
||
...(e.target.id === "sClntClients" ? { sClntClnperson: "" } : {})
|
||
});
|
||
},
|
||
[onTaskChange]
|
||
);
|
||
|
||
//При изменении доп. свойства
|
||
const handlePropEdit = useCallback(
|
||
(docProp, value) => {
|
||
onTaskChange({ docProps: { ...task.docProps, [docProp]: value } });
|
||
},
|
||
[onTaskChange, task.docProps]
|
||
);
|
||
|
||
//Проверка заполненности всех обязательных доп. свойств
|
||
useEffect(() => {
|
||
//Считываем количество незаполненных обязательных свойств
|
||
let notFilled = docProps.props.filter(docProp => docProp.BREQUIRE === true && !hasValue(task.docProps[docProp.SFORMATTED_ID])).length;
|
||
//Если доп. свойства загрузились и количество незаполненных = 0 - доп. свойства готовы, иначе не готовы
|
||
docProps.loaded && notFilled === 0 ? onDPReady(true) : onDPReady(false);
|
||
}, [docProps, onDPReady, task.docProps]);
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Box sx={STYLES.CONTAINER}>
|
||
<Typography pb={1} variant="h6">
|
||
{task.nRn ? "Исправление события" : "Добавление события"}
|
||
</Typography>
|
||
<Tabs value={tab} onChange={handleTabChange} 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={tab} index={0}>
|
||
<TaskFormTabInfo task={task} editable={editable} onFieldEdit={handleFieldEdit} onEventNextNumbGet={onEventNextNumbGet} />
|
||
</CustomTabPanel>
|
||
<CustomTabPanel value={tab} index={1}>
|
||
<TaskFormTabExecutor task={task} onFieldEdit={handleFieldEdit} />
|
||
</CustomTabPanel>
|
||
{docProps.props.length > 0 ? (
|
||
<CustomTabPanel value={tab} index={2}>
|
||
<TaskFormTabProps task={task} taskType={taskType} docProps={docProps} onPropEdit={handlePropEdit} />
|
||
</CustomTabPanel>
|
||
) : null}
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Форма события
|
||
TaskForm.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
taskType: PropTypes.string.isRequired,
|
||
onTaskChange: PropTypes.func.isRequired,
|
||
editable: PropTypes.bool.isRequired,
|
||
onEventNextNumbGet: PropTypes.func.isRequired,
|
||
onDPReady: PropTypes.func.isRequired
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { TaskForm };
|