forked from CITKParus/P8-Panels
149 lines
6.3 KiB
JavaScript
149 lines
6.3 KiB
JavaScript
/*
|
||
Парус 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 GANTT_NODE_NAME_DEF = "XGANTT"; //Наименование узла, содержащего информацию о диаграмме ганта
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Хук для P8PGantt
|
||
const useP8PGantt = ({
|
||
stored,
|
||
respArg = RESP_ARG_DEF,
|
||
contentNodeName = GANTT_NODE_NAME_DEF,
|
||
storedArgs = {},
|
||
executeStoredArgs = {},
|
||
allowDataLoad = () => true
|
||
}) => {
|
||
//Собственное состояние - диаграмма ганта
|
||
const [gantt, setGantt] = useState({
|
||
title: null,
|
||
zoom: null,
|
||
zoomBar: null,
|
||
readOnly: false,
|
||
readOnlyDates: false,
|
||
readOnlyProgress: false,
|
||
taskAttributes: [],
|
||
tasks: [],
|
||
taskColors: []
|
||
});
|
||
|
||
//Собственное состояние - признак загрузки данных
|
||
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) =>
|
||
name == "numb" ? undefined : ["start", "end"].includes(name) ? formatDateJSONDateOnly(val) : val,
|
||
respArg,
|
||
...refExecuteStoredArgs.current
|
||
});
|
||
setGantt(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 { gantt, isDataLoaded, isLoading, doReload };
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { useP8PGantt };
|