/*
Парус 8 - Панели мониторинга - Примеры для разработчиков
Пример: Циклограмма "P8PCyclogram"
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useState, useContext, useCallback, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import {
Typography,
Grid,
Button,
Box,
DialogContent,
List,
ListItem,
ListItemText,
Divider,
TextField,
DialogActions,
Stack,
Icon
} from "@mui/material"; //Интерфейсные элементы
import { formatDateJSONDateOnly, formatDateRF } from "../../core/utils"; //Вспомогательные функции
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
import { P8PCyclogram } from "../../components/p8p_cyclogram"; //Циклограмма
import { P8P_CYCLOGRAM_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
//---------
//Константы
//---------
//Отступ контейнера страницы от заголовка
const CONTAINER_PADDING_TOP = "20px";
//Высота заголовка страницы
const TITLE_HEIGHT = "47px";
//Высота строк
const LINE_HEIGHT = 30;
//Стили
const STYLES = {
CONTAINER: { textAlign: "center", paddingTop: CONTAINER_PADDING_TOP },
TITLE: { paddingBottom: "15px", height: TITLE_HEIGHT },
GANTT_CONTAINER: {
height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TITLE_HEIGHT} - ${CONTAINER_PADDING_TOP})`,
width: "100vw",
paddingTop: "5px"
},
TASK_EDITOR_CONTENT: { minWidth: 400, overflowX: "auto" },
TASK_EDITOR_LIST: { width: "100%", minWidth: 300, maxWidth: 700, bgcolor: "background.paper" },
GROUP_HEADER: height => ({
border: "1px solid",
backgroundColor: "#ecf8fb",
height: height,
borderRadius: "10px",
display: "flex",
alignItems: "center",
justifyContent: "space-around"
})
};
//---------------------------------------------
//Вспомогательные функции форматирования данных
//---------------------------------------------
//Диалог открытия задачи
const CustomTaskDialog = ({ task, ident, handleReload, close }) => {
//Собственное состояние
const [taskDates, setTaskDates] = useState({ start: task.ddate_start, end: task.ddate_end });
//Тип проекта
const textType = task.type === 0 ? "Задачи проекта" : task.type === 1 ? "Этап проекта" : "Работа проекта";
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
//Изменение дат задачи
const changeDates = useCallback(async () => {
//Изменяем даты задачи
await executeStored({
stored: "PKG_P8PANELS_SAMPLES.CYCLOGRAM_TASK_MODIFY",
args: {
NIDENT: ident,
NRN: task.rn,
SDATE_FROM: formatDateRF(taskDates.start),
SDATE_TO: formatDateRF(taskDates.end)
}
});
handleReload();
close();
}, [close, executeStored, handleReload, ident, task.rn, taskDates.end, taskDates.start]);
//При нажатии OK
const handleOk = () => {
//Изменяем даты задачи
changeDates();
};
return (
<>
setTaskDates(pv => ({ ...pv, start: e.target.value }))}
variant="standard"
size="small"
margin="normal"
>
}
/>
setTaskDates(pv => ({ ...pv, end: e.target.value }))}
variant="standard"
size="small"
margin="normal"
>
}
/>
{task.type === 0 ? "description" : task.type === 1 ? "check" : "work_outline"}
{textType}
}
/>
>
);
};
//Контроль свойств - Диалог открытия задачи
CustomTaskDialog.propTypes = {
task: PropTypes.object.isRequired,
ident: PropTypes.number.isRequired,
handleReload: PropTypes.func.isRequired,
close: PropTypes.func.isRequired
};
//Заголовок группы
const CustomGroupHeader = ({ group }) => {
return (
{group.name}
);
};
//Контроль свойств - Заголовок группы
CustomGroupHeader.propTypes = {
group: PropTypes.object.isRequired
};
//Отображение задачи
const taskRenderer = ({ task }) => {
//Если это задачи проекта
if (task.type === 0) {
return {
taskStyle: { border: "3px solid #ebe058" }
};
}
};
//-----------
//Тело модуля
//-----------
//Пример: Циклограмма "P8PCyclogram"
const Cyclogram = ({ title }) => {
//Собственное состояние
const [state, setState] = useState({
init: false,
dataLoaded: false,
reload: true,
ident: null
});
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
//При необходимости перезагрузки
const handleReload = () => {
setState(pv => ({ ...pv, reload: true }));
};
//При необходимости обновить данные таблицы
useEffect(() => {
//Загрузка данных циклограммы с сервера
const loadData = async () => {
const data = await executeStored({
stored: "PKG_P8PANELS_SAMPLES.CYCLOGRAM",
args: { NIDENT: state.ident },
attributeValueProcessor: (name, val) =>
name === "name" ? undefined : ["ddate_start", "ddate_end"].includes(name) ? formatDateJSONDateOnly(val) : val,
respArg: "COUT"
});
setState(pv => ({ ...pv, dataLoaded: true, ...data.XCYCLOGRAM, reload: false }));
};
//Если указан идентификатор и требуется перезагрузить
if (state.ident && state.reload) loadData();
}, [state.ident, state.reload, executeStored]);
//При подключении компонента к странице
useEffect(() => {
//Инициализация данных циклограммы
const initData = async () => {
const data = await executeStored({ stored: "PKG_P8PANELS_SAMPLES.CYCLOGRAM_INIT", args: { NIDENT: state.ident } });
setState(pv => ({ ...pv, init: true, ident: data.NIDENT, reload: true }));
};
//Если требуется проинициализировать
if (!state.init) {
initData();
}
}, [executeStored, state.ident, state.init]);
return (
{title}
{state.dataLoaded ? (
(
)}
taskRenderer={prms => taskRenderer(prms)}
groupHeaderRenderer={prms => }
/>
) : null}
);
};
//Контроль свойств - Пример: Циклограмма "P8PCyclogram"
Cyclogram.propTypes = {
title: PropTypes.string.isRequired
};
//----------------
//Интерфейс модуля
//----------------
export { Cyclogram };