/* Парус 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 }, CYCLOGRAM_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 };