/* Парус 8 - Панели мониторинга Хуки для циклограмм */ //--------------------- //Подключение библиотек //--------------------- import { useState, useCallback, useEffect, useContext, useRef, useMemo } from "react"; //Классы React import { BackEndСtx } from "../context/backend"; //Контекст взаимодействия с сервером import { formatDateJSONDateOnly } from "../core/utils"; //Вспомогательные функции //--------- //Константы //--------- //Константы - значения по умолчанию const RESP_ARG_DEF = "COUT"; //Имя параметра, содержащего информацию о циклограмме const CG_NODE_NAME_DEF = "XCYCLOGRAM"; //Наименование узла, содержащего информацию о циклограмме //----------- //Тело модуля //----------- //Хук для P8PCyclogram const useP8PCyclogram = ({ stored, respArg = RESP_ARG_DEF, contentNodeName = CG_NODE_NAME_DEF, storedArgs = {}, executeStoredArgs = {}, allowDataLoad = () => true }) => { //Собственное состояние - циклограмма const [cyclogram, setCyclogram] = useState({ columns: [], groups: [], tasks: [], taskAttributes: [], title: null, lineHeight: 0, zoom: 1, zoomBar: true }); //Собственное состояние - признак загрузки данных const [isDataLoaded, setIsDataLoaded] = useState(false); //Собственное состояние - флаг загрузки const [isLoading, setLoading] = useState(false); //Собственное состояние - необходимость обновления данных const [reload, setReload] = useState(true); //Собственное состояние - дополнительные агрументы const refStoredArgs = useRef(storedArgs); //Собственное состояние - дополнительные параметры вызова процедуры const refExecuteStoredArgs = useRef(executeStoredArgs); //Признак допустимости обновления данных const isAllowDataLoad = useMemo(() => { return allowDataLoad(); }, [allowDataLoad]); //Подключение к контексту взаимодействия с сервером const { executeStored, isRespErr } = useContext(BackEndСtx); //Загрузка данных циклограммы с сервера const loadData = useCallback(async () => { try { setLoading(true); const data = await executeStored({ stored, args: { ...refStoredArgs.current }, attributeValueProcessor: (name, val) => (["ddate_start", "ddate_end"].includes(name) ? formatDateJSONDateOnly(val) : val), respArg, ...refExecuteStoredArgs.current }); setCyclogram(pv => ({ ...pv, ...data[contentNodeName] })); //Устанавливаем признак загрузки данных с учетом возможных ошибок setIsDataLoaded(!isRespErr(data)); } catch (e) { //Если произошла ошибка - данные не загружены setIsDataLoaded(false); } finally { //Сбрасываем признаки загрузки и перезагрузки данных setLoading(false); setReload(false); } }, [contentNodeName, executeStored, isRespErr, respArg, stored]); //При необходимости обновления циклограммы const doReload = useCallback(() => { setReload(true); }, []); //Проверка изменений параметров const isArgsChanged = useCallback( (currentArgs, args) => { //Если дополнительные параметры изменились (и сейчас не происходит загрузка данных с сервера) return !isLoading && JSON.stringify(currentArgs) != JSON.stringify(args); }, [isLoading] ); //При изменение дополнительных параметров процедуры useEffect(() => { //Если параметры изменились if (isArgsChanged(refStoredArgs.current, storedArgs)) { //Устанавливаем новые дополнительные параметры refStoredArgs.current = storedArgs; //При изменении дополнительных параметров необходимо перезагрузить данные setReload(true); } }, [storedArgs, isArgsChanged]); //При изменение дополнительных параметров вызова процедуры useEffect(() => { //Если параметры изменились if (isArgsChanged(refExecuteStoredArgs.current, executeStoredArgs)) { //Устанавливаем новые дополнительные параметры refExecuteStoredArgs.current = executeStoredArgs; //При изменении дополнительных параметров необходимо перезагрузить данные setReload(true); } }, [executeStoredArgs, isArgsChanged]); //При необходимости обновить данные циклограммы useEffect(() => { if (isAllowDataLoad && reload) { loadData(); } }, [isAllowDataLoad, reload, loadData]); //Возвращаем данные циклограммы return { cyclogram, isDataLoaded, isLoading, doReload }; }; //---------------- //Интерфейс модуля //---------------- export { useP8PCyclogram };