203 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Парус 8 - Панели мониторинга - УДП - Доски задач
Компонент панели: Диалог формы события
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useState, useCallback, useContext, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Dialog, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты
import { useClientEvent } from "./hooks/task_dialog_hooks"; //Хук для события
import { useDocsProps } from "./hooks/task_dialog_hooks"; //Хук для получения доп. свойств раздела "События"
import { TaskForm } from "./components/task_form"; //Форма события
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
import { COMMON_STYLES } from "./styles"; //Общие стили
import { hasValue } from "../../core/utils"; //Вспомогательные процедуры и функции
//---------
//Константы
//---------
//Стили
const STYLES = {
DIALOG_CONTENT: {
paddingBottom: "0px",
maxHeight: "740px",
minHeight: "740px",
...COMMON_STYLES.SCROLL
}
};
//-----------
//Тело модуля
//-----------
//Диалог формы события
const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
//Собственное состояние
const [task, setTask] = useClientEvent(taskRn, taskType);
//Состояние допустимых дополнительных свойств
const [docProps] = useDocsProps(taskType);
//Состояние заполненности всех обязательных доп. свойств
const [docPropsReady, setDocPropsReady] = useState(false);
//Подключение к контексту взаимодействия с сервером
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
//При изменении информации о задаче
const handleTaskChange = useCallback(
newTaskValues => {
setTask(pv => ({ ...pv, ...newTaskValues }));
},
[setTask]
);
//При добавлении события
const handleInsertTask = async callBack => {
await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_INSERT",
args: {
SCRN: task.sCrn,
SPREF: task.sPrefix,
SNUMB: task.sNumber,
STYPE: task.sType,
SSTATUS: task.sStatus,
SPLAN_DATE: task.dPlanDate,
SINIT_PERSON: task.sInitClnperson,
SCLIENT_CLIENT: task.sClntClients,
SCLIENT_PERSON: task.sClntClnperson,
SDESCRIPTION: task.sDescription,
SREASON: task.sInitReason,
CPROPS: {
VALUE: object2Base64XML(
[
Object.fromEntries(
Object.entries(task.docProps)
// eslint-disable-next-line no-unused-vars
.filter(([_, v]) => v != (null || ""))
)
],
{
arrayNodeName: "props"
}
),
SDATA_TYPE: SERV_DATA_TYPE_CLOB
}
}
});
callBack();
};
//При исправлении события
const handleUpdateEvent = async callBack => {
await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_UPDATE",
args: {
NCLNEVENTS: task.nRn,
SCLIENT_CLIENT: task.sClntClients,
SCLIENT_PERSON: task.sClntClnperson,
SDESCRIPTION: task.sDescription,
CPROPS: {
// eslint-disable-next-line no-unused-vars
VALUE: object2Base64XML([Object.fromEntries(Object.entries(task.docProps).filter(([_, v]) => v != (null || "")))], {
arrayNodeName: "props"
}),
SDATA_TYPE: SERV_DATA_TYPE_CLOB
}
}
});
callBack();
};
//При считывании следующего номера события
const handleEventNextNumbGet = useCallback(async () => {
//Считываем данные
const data = await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_NEXTNUMB_GET",
args: {
SPREFIX: task.sPrefix
}
});
//Если данные есть
if (data) {
//Устанавливаем номер
setTask(pv => ({ ...pv, sNumber: data.SEVENT_NUMB }));
}
}, [executeStored, setTask, task.sPrefix]);
//Проверка заполненности всех обязательных доп. свойств
useEffect(() => {
//Если доп. свойства загрузились
if (docProps.loaded) {
//Проверяем остались ли обязательные незаполненные свойства
let notFilled = docProps.props.some(docProp => docProp.BREQUIRE === true && !hasValue(task.docProps[docProp.SFORMATTED_ID]));
//Если незаполненных обязательных доп. свойств не осталось - доп. свойства готовы, иначе не готовы
setDocPropsReady(!notFilled);
} else {
//Доп. свойства не готовы
setDocPropsReady(false);
}
}, [docProps.loaded, docProps.props, task.docProps]);
//Генерация содержимого
return (
<>
{!task.init && docProps.loaded && (
<Dialog open onClose={onClose ? onClose : null} fullWidth>
<DialogContent sx={STYLES.DIALOG_CONTENT}>
<TaskForm
task={task}
taskType={taskType}
editable={!taskRn || editable ? true : false}
docProps={docProps.props}
onTaskChange={handleTaskChange}
onEventNextNumbGet={handleEventNextNumbGet}
/>
</DialogContent>
{onClose ? (
<DialogActions sx={COMMON_STYLES.DIALOG_ACTIONS}>
{taskRn ? (
<Button
onClick={() => handleUpdateEvent(onClose).then(onTasksReload)}
disabled={task.updateDisabled || !editable || !docPropsReady}
>
Исправить
</Button>
) : (
<Button
onClick={() => handleInsertTask(onClose).then(onTasksReload)}
disabled={task.insertDisabled || !docPropsReady}
>
Добавить
</Button>
)}
<Button onClick={onClose}>Закрыть</Button>
</DialogActions>
) : null}
</Dialog>
)}{" "}
</>
);
};
//Контроль свойств - Диалог формы события
TaskDialog.propTypes = {
taskRn: PropTypes.number,
taskType: PropTypes.string.isRequired,
editable: PropTypes.bool,
onTasksReload: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired
};
//----------------
//Интерфейс модуля
//----------------
export { TaskDialog };