forked from CITKParus/P8-Panels
197 lines
8.6 KiB
JavaScript
197 lines
8.6 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга
|
||
Контекст: Приложение
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useReducer, createContext, useEffect, useContext, useCallback, useMemo } from "react"; //ReactJS
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { APP_AT, INITIAL_STATE, applicationReducer } from "./application_reducer"; //Редьюсер состояния
|
||
import { MessagingСtx } from "./messaging"; //Контекст отображения сообщений
|
||
import { BackEndСtx } from "./backend"; //Контекст взаимодействия с сервером
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Клиентский API "ПАРУС 8 Онлайн"
|
||
const P8O_API = window.top?.parus?.clientApi;
|
||
|
||
//Структура объекта с описанием ошибок
|
||
const APPLICATION_CONTEXT_ERRORS_SHAPE = PropTypes.shape({
|
||
P8O_API_UNAVAILABLE: PropTypes.string.isRequired,
|
||
P8O_API_UNSUPPORTED: PropTypes.string.isRequired
|
||
});
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
//Контекст приложения
|
||
export const ApplicationСtx = createContext();
|
||
|
||
//Провайдер контекста приложения
|
||
export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, config, children }) => {
|
||
//Подключим редьюсер состояния
|
||
const [state, dispatch] = useReducer(applicationReducer, INITIAL_STATE(displaySizeGetter));
|
||
|
||
//Подключение к контексту взаимодействия с сервером
|
||
const { getConfig, getRespPayload } = useContext(BackEndСtx);
|
||
|
||
//Подключение к контексту отображения сообщений
|
||
const { showMsgErr } = useContext(MessagingСtx);
|
||
|
||
//Установка флага инициализированности приложения
|
||
const setInitialized = () => dispatch({ type: APP_AT.SET_INITIALIZED });
|
||
|
||
//Установка текущего размера экрана
|
||
const setDisplaySize = displaySize => dispatch({ type: APP_AT.SET_DISPLAY_SIZE, payload: displaySize });
|
||
|
||
//Установка базового URL приложения
|
||
const setUrlBase = urlBase => dispatch({ type: APP_AT.SET_URL_BASE, payload: urlBase });
|
||
|
||
//Установка списка панелей
|
||
const setPanels = panels => dispatch({ type: APP_AT.LOAD_PANELS, payload: panels });
|
||
|
||
//Поиск раздела по имени
|
||
const findPanelByName = name => state.panels.find(panel => panel.name == name);
|
||
|
||
//Отображение закладки "ПАРУС 8 Онлайн" с указанным URL
|
||
const pOnlineShowTab = useCallback(
|
||
({ id, url, caption, onClose }) => {
|
||
if (P8O_API) {
|
||
const _id = id || guidGenerator();
|
||
P8O_API.ui.openTab({ id: _id, url, caption, onClose: () => (onClose ? onClose(_id) : null) });
|
||
return _id;
|
||
} else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, guidGenerator, errors.P8O_API_UNAVAILABLE]
|
||
);
|
||
|
||
//Отображение раздела "ПАРУС 8 Онлайн"
|
||
const pOnlineShowUnit = useCallback(
|
||
({ unitCode, showMethod = "main", inputParameters, modal = true }) => {
|
||
if (P8O_API)
|
||
modal
|
||
? P8O_API.fn.openDocumentModal({ unitcode: unitCode, method: showMethod, inputParameters })
|
||
: P8O_API.fn.openDocument
|
||
? P8O_API.fn.openDocument({ unitcode: unitCode, method: showMethod, inputParameters })
|
||
: showMsgErr(errors.P8O_API_UNSUPPORTED);
|
||
else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, errors.P8O_API_UNAVAILABLE, errors.P8O_API_UNSUPPORTED]
|
||
);
|
||
|
||
//Отображение документа "ПАРУС 8 Онлайн"
|
||
const pOnlineShowDocument = useCallback(
|
||
({ unitCode, document, showMethod = "main", inRnParameter = "in_RN", modal = true }) => {
|
||
if (P8O_API)
|
||
modal
|
||
? P8O_API.fn.openDocumentModal({
|
||
unitcode: unitCode,
|
||
method: showMethod,
|
||
inputParameters: [{ name: inRnParameter, value: document }]
|
||
})
|
||
: P8O_API.fn.openDocument
|
||
? P8O_API.fn.openDocument({
|
||
unitcode: unitCode,
|
||
method: showMethod,
|
||
inputParameters: [{ name: inRnParameter, value: document }]
|
||
})
|
||
: showMsgErr(errors.P8O_API_UNSUPPORTED);
|
||
else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, errors.P8O_API_UNAVAILABLE, errors.P8O_API_UNSUPPORTED]
|
||
);
|
||
|
||
//Отображение словаря "ПАРУС 8 Онлайн"
|
||
const pOnlineShowDictionary = useCallback(
|
||
({ unitCode, showMethod = "main", inputParameters, callBack }) => {
|
||
if (P8O_API)
|
||
P8O_API.fn.openDictionary({ unitcode: unitCode, method: showMethod, inputParameters }, res => (callBack ? callBack(res) : null));
|
||
else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, errors.P8O_API_UNAVAILABLE]
|
||
);
|
||
|
||
//Исполнение пользовательской процедуры "ПАРУС 8 Онлайн"
|
||
const pOnlineUserProcedure = useCallback(
|
||
({ code, inputParameters, callBack }) => {
|
||
if (P8O_API) P8O_API.fn.performUserProcedureSync({ code, inputParameters }, res => (callBack ? callBack(res) : null));
|
||
else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, errors.P8O_API_UNAVAILABLE]
|
||
);
|
||
|
||
//Исполнение пользовательского отчёта "ПАРУС 8 Онлайн"
|
||
const pOnlineUserReport = useCallback(
|
||
({ code, inputParameters }) => {
|
||
if (P8O_API) P8O_API.fn.performUserReport({ code, inputParameters });
|
||
else showMsgErr(errors.P8O_API_UNAVAILABLE);
|
||
},
|
||
[showMsgErr, errors.P8O_API_UNAVAILABLE]
|
||
);
|
||
|
||
//Получение количества записей на странице
|
||
const configSystemPageSize = useMemo(() => config.SYSTEM.PAGE_SIZE, [config.SYSTEM.PAGE_SIZE]);
|
||
|
||
//Получение базового URL приложения
|
||
const configUrlBase = useMemo(() => state.urlBase, [state.urlBase]);
|
||
|
||
//Инициализация приложения
|
||
const initApp = useCallback(async () => {
|
||
//Читаем конфигурацию с сервера
|
||
let res = await getConfig();
|
||
//Сохраняем базовый URL приложения
|
||
setUrlBase(getRespPayload(res)?.Panels?.urlBase);
|
||
//Сохраняем список панелей
|
||
setPanels(getRespPayload(res)?.Panels?.Panel);
|
||
//Установим флаг завершения инициализации
|
||
setInitialized();
|
||
}, [getConfig, getRespPayload]);
|
||
|
||
//Обработка подключения контекста к странице
|
||
useEffect(() => {
|
||
if (!state.initialized) {
|
||
//Слушаем изменение размеров окна
|
||
window.addEventListener("resize", () => {
|
||
if (displaySizeGetter) setDisplaySize(displaySizeGetter());
|
||
});
|
||
//Инициализируем приложение
|
||
initApp();
|
||
}
|
||
}, [state.initialized, initApp, displaySizeGetter]);
|
||
|
||
//Вернём компонент провайдера
|
||
return (
|
||
<ApplicationСtx.Provider
|
||
value={{
|
||
findPanelByName,
|
||
pOnlineShowTab,
|
||
pOnlineShowUnit,
|
||
pOnlineShowDocument,
|
||
pOnlineShowDictionary,
|
||
pOnlineUserProcedure,
|
||
pOnlineUserReport,
|
||
configSystemPageSize,
|
||
configUrlBase,
|
||
appState: state
|
||
}}
|
||
>
|
||
{children}
|
||
</ApplicationСtx.Provider>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Провайдер контекста приложения
|
||
ApplicationContext.propTypes = {
|
||
errors: APPLICATION_CONTEXT_ERRORS_SHAPE.isRequired,
|
||
displaySizeGetter: PropTypes.func,
|
||
guidGenerator: PropTypes.func.isRequired,
|
||
config: PropTypes.object.isRequired,
|
||
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])
|
||
};
|