P8-Panels/app/components/p8p_gantt_hooks.js

149 lines
6.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 { 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 };