/* Парус 8 - Панели мониторинга - УДП - Доски задач Пользовательские хуки: Хуки основных данных */ //--------------------- //Подключение библиотек //--------------------- import { useState, useContext, useEffect, useCallback } from "react"; //Классы React import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером import { getRandomColor, getLocalStorageValue } from "../layouts"; //Вспомогательные функции //----------- //Тело модуля //----------- //Хук дополнительных данных const useExtraData = filtersType => { //Состояние дополнительных данных const [extraData, setExtraData] = useState({ dataLoaded: false, reload: false, typeLoaded: "", evRoutes: [], evPoints: [], noteTypes: [], docLinks: [] }); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); //Считывание учётных документов const handleDocLinksLoad = useCallback( async (type = filtersType) => { //Считываем данные const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DOCLINKS_GET", args: { SEVNTYPE_CODE: type }, isArray: name => name === "XDOCLINKS", respArg: "COUT" }); //Возвращаем учётные документы return [...(data?.XDOCLINKS || [])]; }, [executeStored, filtersType] ); useEffect(() => { //Загрузка дополнительных данных const loadExtraData = async () => { //Считываем данные const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_GET_INFO_BY_CODE", args: { SEVNTYPE_CODE: filtersType }, isArray: name => ["XEVROUTES", "XEVPOINTS", "XNOTETYPES"].includes(name), respArg: "COUT" }); //Форматируем типы примечаний под нужный формат let noteTypes = [...(data?.XNOTETYPES || [])].reduce((prev, cur) => [...prev, cur.SNAME], []); //Считываем учётные документы let docLinks = await handleDocLinksLoad(filtersType); //Обновляем дополнительные данные setExtraData({ dataLoaded: true, reload: false, typeLoaded: filtersType, evRoutes: [...(data?.XEVROUTES || [])], evPoints: [...(data?.XEVPOINTS || [])], noteTypes: [...noteTypes], docLinks: [...docLinks] }); }; //Если указан тип событий и необходимо обновить if (extraData.reload && filtersType) { //Загружаем дополнительные данные if (!extraData.typeLoaded || filtersType !== extraData.typeLoaded) { loadExtraData(); } } }, [executeStored, extraData.reload, extraData.typeLoaded, filtersType, handleDocLinksLoad]); return [extraData, setExtraData, handleDocLinksLoad]; }; //Хук заливок пользовательских настроек const useColorRules = () => { //Собственное состояние const [colorRules, setColorRules] = useState({ loaded: false, rules: [], selectedColorRule: JSON.parse(getLocalStorageValue("settingsColorRule") || {}) }); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); //При необходимости загрузки заливок useEffect(() => { //Считывание пользовательских настроек let getColorRules = async () => { //Считываем данные const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DP_RULES_GET", isArray: name => name === "XRULES", respArg: "COUT" }); //Формируем массив правил заливки пользовательских настроек let newColorRules = [...(data.XRULES || [])].reduce( (prev, cur) => [ ...prev, { id: prev.length, SFIELD: cur.SFIELD, SDP_NAME: cur.SDP_NAME, SCOLOR: cur.SCOLOR, STYPE: cur.STYPE, fromValue: cur.NFROM ?? cur.SFROM ?? cur.DFROM, toValue: cur.NTO ?? cur.STO ?? cur.DTO } ], [] ); //Устанавливаем заливки пользовательских настроек setColorRules(pv => ({ ...pv, loaded: true, rules: [...newColorRules] })); }; if (!colorRules.loaded) getColorRules(); }, [colorRules.loaded, executeStored]); //Сохранение при закрытии панели useEffect(() => { //Обработка события закрытия const onBeforeUnload = () => { localStorage.setItem("settingsColorRule", JSON.stringify(colorRules.selectedColorRule)); }; //Вешаем обработчик события закрытия window.addEventListener("beforeunload", onBeforeUnload); //Очищаем при размонтировании return () => { window.removeEventListener("beforeunload", onBeforeUnload); }; }, [colorRules.selectedColorRule]); return [colorRules, setColorRules]; }; //Хук статусов событий const useStatuses = filterType => { //Собственное состояние статусов const [statuses, setStatuses] = useState([]); //Состояние статусов const [statusesState, setStatusesState] = useState({ sorted: false, reload: true, attr: getLocalStorageValue("statusesSortAttr", "SEVNSTAT_NAME"), direction: getLocalStorageValue("statusesSortDirection", "asc") }); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); //При необходимости сортировки статусов useEffect(() => { //Сортируем статусы const sortStatuses = unsortedStatuses => { //Инициализируем поле сортировки и порядок сортировки const attr = statusesState.attr; const direction = statusesState.direction; //Сортируем let sortedStatuses = unsortedStatuses.sort((a, b) => direction === "asc" ? a[attr].localeCompare(b[attr]) : b[attr].localeCompare(a[attr]) ); //Возвращаем return sortedStatuses; }; //Загружаем и сортируем статусы const loadAndSortStatuses = async filterType => { //Инициализируем статусы let newStatuses = []; //Если требуется перезагрузка if (statusesState.reload) { const loadedStatuses = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVNSTATS_LOAD", args: { SCLNEVNTYPES: filterType }, isArray: name => name === "XSTATUS", respArg: "COUT" }); //Загружаем статусы и инициализируем цвета newStatuses = [...(loadedStatuses?.XSTATUS || [])].reduce( (prev, cur) => [...prev, { ...cur, color: getRandomColor(prev.length + 1) }], [] ); } else { //Загружаем из состояния newStatuses = [...statuses]; } //Сортируем, если требуется newStatuses = !statusesState.sorted ? sortStatuses(newStatuses) : newStatuses; //Обновляем состояние статусов setStatuses([...newStatuses]); //Обновляем информацию о состоянии статусов setStatusesState(pv => ({ ...pv, sorted: true, reload: false })); }; //При необходимости изменения сортировки if (filterType && (statusesState.reload || !statusesState.sorted)) { //Считываем старые статусы или загружаем новые loadAndSortStatuses(filterType); } }, [executeStored, filterType, statuses, statusesState.attr, statusesState.direction, statusesState.reload, statusesState.sorted]); //Сохранение при закрытии панели useEffect(() => { //Обработка события закрытия const onBeforeUnload = () => { localStorage.setItem("statusesSortAttr", statusesState.attr); localStorage.setItem("statusesSortDirection", statusesState.direction); }; //Вешаем обработчик события закрытия window.addEventListener("beforeunload", onBeforeUnload); //Очищаем при размонтировании return () => { window.removeEventListener("beforeunload", onBeforeUnload); }; }, [statusesState.attr, statusesState.direction]); return [statuses, statusesState, setStatuses, setStatusesState]; }; //---------------- //Интерфейс модуля //---------------- export { useExtraData, useColorRules, useStatuses };