diff --git a/app/app.js b/app/app.js index 5d3f2f1..13a6acd 100644 --- a/app/app.js +++ b/app/app.js @@ -14,7 +14,7 @@ import { ApplicationСtx } from "./context/application"; //Контекст пр import { NavigationContext, NavigationCtx, getRootLocation } from "./context/navigation"; //Контекст навигации import { P8PAppErrorPage } from "./components/p8p_app_error_page"; //Страница с ошибкой import { P8PAppWorkspace } from "./components/p8p_app_workspace"; //Рабочее пространство панели -import { P8PPanelsMenuGrid, P8P_PANELS_MENU_PANEL_SHAPE } from "./components/p8p_panels_menu"; //Меню панелей +import { P8PPanelsMenuDesktop, P8PPanelsMenuGrid, P8P_PANELS_MENU_PANEL_SHAPE } from "./components/p8p_panels_menu"; //Меню панелей import { BUTTONS, ERRORS, ERRORS_HTTP } from "../app.text"; //Текстовые ресурсы и константы import { P8P_PANELS_MENU_GRID_CONFIG_PROPS, P8P_APP_WORKSPACE_CONFIG_PROPS } from "./config_wrapper"; //Подключение компонентов к настройкам приложения @@ -51,13 +51,29 @@ RouterError.propTypes = { //Главное меню приложения const MainMenu = ({ panels = [] } = {}) => { //Подключение к контексту навигации - const { navigatePanel } = useContext(NavigationCtx); + const { navigatePanel, isNavigationSearch, getNavigationSearch } = useContext(NavigationCtx); + + //Подключение к контексту приложения + const { configUrlBase, pOnlineShowTab } = useContext(ApplicationСtx); + + //Получим параметры запроса из адресной строки + const qS = isNavigationSearch() ? getNavigationSearch() : null; //Отработка действия навигации элемента меню - const handleItemNavigate = panel => navigatePanel(panel); + const handleItemNavigate = (panel, newTab) => + newTab ? pOnlineShowTab({ id: panel.name, url: `${configUrlBase}${panel.url}`, caption: panel.caption }) : navigatePanel(panel); //Генерация содержимого - return ; + return qS?.mode === "DESKTOP" ? ( + handleItemNavigate(panel, true)} + /> + ) : ( + handleItemNavigate(panel, false)} /> + ); }; //Контроль свойств - главное меню приложения diff --git a/app/components/p8p_panels_menu.js b/app/components/p8p_panels_menu.js index 828b12a..145258f 100644 --- a/app/components/p8p_panels_menu.js +++ b/app/components/p8p_panels_menu.js @@ -35,7 +35,8 @@ import { //Типы меню const P8P_PANELS_MENU_VARIANT = { DRAWER: "DRAWER", - GRID: "GRID" + GRID: "GRID", + DESKTOP: "DESKTOP" }; //Структура элемента описания панели @@ -53,36 +54,16 @@ const P8P_PANELS_MENU_PANEL_SHAPE = PropTypes.shape({ //Стили const STYLES = { - CONTAINER: { - display: "flex", - justifyContent: "center", - alignItems: "flex-start", - minHeight: "100vh" - }, - GRID: { - maxWidth: 1200, - direction: "row", - justifyContent: "left", - alignItems: "stretch" - }, - PANEL_CARD: { - maxWidth: 400, - height: "100%", - flexDirection: "column", - display: "flex" - }, - PANEL_CARD_MEDIA: { - height: 140 - }, - PANEL_CARD_CONTENT_TITLE: { - alignItems: "center" - }, - PANEL_CARD_ACTIONS: { - marginTop: "auto", - display: "flex", - justifyContent: "flex-end", - alignItems: "flex-start" - } + GRID_CONTAINER: { display: "flex", justifyContent: "center", alignItems: "flex-start", minHeight: "100vh" }, + GRID: { maxWidth: 1200, direction: "row", justifyContent: "left", alignItems: "stretch" }, + GRID_PANEL_CARD: { maxWidth: 400, height: "100%", flexDirection: "column", display: "flex" }, + GRID_PANEL_CARD_MEDIA: { height: 140 }, + GRID_PANEL_CARD_CONTENT_TITLE: { alignItems: "center" }, + GRID_PANEL_CARD_ACTIONS: { marginTop: "auto", display: "flex", justifyContent: "flex-end", alignItems: "flex-start" }, + DESKTOP_GROUP_HEADER: { fontWeight: "bold", fontFamily: "tahoma, arial, verdana, sans-serif!important", fontSize: "13px!important" }, + DESKTOP_ITEM_BUTTON: { fontSize: "12px", textTransform: "none", "&:hover": { backgroundColor: "#c3e1ff" } }, + DESKTOP_ITEM_STACK: { justifyContent: "center", alignItems: "center" }, + DESKTOP_ITEM_ICON: { width: "64px", height: "64px", fontSize: "64px" } }; //-------------------------------- @@ -90,7 +71,7 @@ const STYLES = { //-------------------------------- //Формирование групп -const getGroups = panels => { +const getGroups = (panels, group) => { let res = []; let addDefaultGroup = false; for (const panel of panels) @@ -99,13 +80,14 @@ const getGroups = panels => { if (!panel.group) addDefaultGroup = true; } if (addDefaultGroup || res.length == 0) res.push(null); + if (group) res = res.filter(g => g == group); return res; }; //Формирование ссылок на панели -const getPanelsLinks = ({ variant, panels, selectedPanel, defaultGroupTytle, navigateCaption, onItemNavigate }) => { +const getPanelsLinks = ({ variant, panels, selectedPanel, group, defaultGroupTytle, navigateCaption, onItemNavigate }) => { //Получим группы - let grps = getGroups(panels); + let grps = getGroups(panels, group); //Построим ссылки const panelsLinks = []; @@ -118,8 +100,14 @@ const getPanelsLinks = ({ variant, panels, selectedPanel, defaultGroupTytle, nav {grp ? grp : defaultGroupTytle} - ) : ( + ) : variant === P8P_PANELS_MENU_VARIANT.DRAWER ? ( + ) : ( + + + {grp ? grp : defaultGroupTytle} + + ) ); for (const panel of panels) { @@ -127,12 +115,12 @@ const getPanelsLinks = ({ variant, panels, selectedPanel, defaultGroupTytle, nav panelsLinks.push( variant === P8P_PANELS_MENU_VARIANT.GRID ? ( - + {panel.preview ? ( - + ) : null} - + {panel.icon ? {panel.icon} : null} {panel.caption} @@ -140,14 +128,14 @@ const getPanelsLinks = ({ variant, panels, selectedPanel, defaultGroupTytle, nav {panel.desc} - + - ) : ( + ) : variant === P8P_PANELS_MENU_VARIANT.DRAWER ? ( + ) : ( + ) ); } @@ -195,7 +195,7 @@ const P8PPanelsMenuGrid = ({ onItemNavigate, navigateCaption, panels = [], defau //Генерация содержимого return ( - + {panelsLinks} @@ -211,8 +211,25 @@ P8PPanelsMenuGrid.propTypes = { defaultGroupTytle: PropTypes.string.isRequired }; +//Меню панелей - рабочий стол +const P8PPanelsMenuDesktop = ({ group, onItemNavigate, panels = [], defaultGroupTytle } = {}) => { + //Формируем ссылки на панели + const panelsLinks = getPanelsLinks({ variant: P8P_PANELS_MENU_VARIANT.DESKTOP, panels, group, defaultGroupTytle, onItemNavigate }); + + //Генерация содержимого + return {panelsLinks}; +}; + +//Контроль свойств - Меню панелей - рабочий стол +P8PPanelsMenuDesktop.propTypes = { + group: PropTypes.string, + onItemNavigate: PropTypes.func, + panels: PropTypes.arrayOf(P8P_PANELS_MENU_PANEL_SHAPE).isRequired, + defaultGroupTytle: PropTypes.string.isRequired +}; + //---------------- //Интерфейс модуля //---------------- -export { P8P_PANELS_MENU_PANEL_SHAPE, P8PPanelsMenuDrawer, P8PPanelsMenuGrid }; +export { P8P_PANELS_MENU_PANEL_SHAPE, P8PPanelsMenuDrawer, P8PPanelsMenuGrid, P8PPanelsMenuDesktop }; diff --git a/app/context/application.js b/app/context/application.js index 9f2c8c2..d613fcc 100644 --- a/app/context/application.js +++ b/app/context/application.js @@ -18,7 +18,7 @@ import { BackEndСtx } from "./backend"; //Контекст взаимодейс //--------- //Клиентский API "ПАРУС 8 Онлайн" -const P8O_API = window.parent?.parus?.clientApi; +const P8O_API = window.top?.parus?.clientApi; //Структура объекта с описанием ошибок const APPLICATION_CONTEXT_ERRORS_SHAPE = PropTypes.shape({ @@ -49,6 +49,9 @@ export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, c //Установка текущего размера экрана 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 }); @@ -117,10 +120,15 @@ export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, c //Получение количества записей на странице 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); //Установим флаг завершения инициализации @@ -151,6 +159,7 @@ export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, c pOnlineUserProcedure, pOnlineUserReport, configSystemPageSize, + configUrlBase, appState: state }} > diff --git a/app/context/application_reducer.js b/app/context/application_reducer.js index 6fe80eb..60eec90 100644 --- a/app/context/application_reducer.js +++ b/app/context/application_reducer.js @@ -9,6 +9,7 @@ //Типы действий const APP_AT = { + SET_URL_BASE: "SET_URL_BASE", //Установка базового URL приложения LOAD_PANELS: "LOAD_PANELS", //Загрузка списка панелей SET_INITIALIZED: "SET_INITIALIZED", //Установка флага инициализированности приложения SET_DISPLAY_SIZE: "SET_DISPLAY_SIZE" //Установка текущего типового размера экрана @@ -17,6 +18,7 @@ const APP_AT = { //Состояние приложения по умолчанию const INITIAL_STATE = displaySizeGetter => ({ displaySize: displaySizeGetter(), + urlBase: "", panels: [], panelsLoaded: false, initialized: false @@ -28,6 +30,8 @@ const INITIAL_STATE = displaySizeGetter => ({ //Обработчики действий const handlers = { + //Установка базового URL приложения + [APP_AT.SET_URL_BASE]: (state, { payload }) => ({ ...state, urlBase: payload }), //Загрузка списка панелей [APP_AT.LOAD_PANELS]: (state, { payload }) => { let panels = []; diff --git a/app/panels/dummy/dummy.js b/app/panels/dummy/dummy.js index 39c4083..332e074 100644 --- a/app/panels/dummy/dummy.js +++ b/app/panels/dummy/dummy.js @@ -19,10 +19,10 @@ import { BUTTONS, ERRORS } from "../../../app.text"; //Текстовые рес //Заглушка const Dummy = () => { //Подключение к контексту навигации - const { navigateBack } = useContext(NavigationCtx); + const { navigateRoot } = useContext(NavigationCtx); //Генерация содержимого - return navigateBack()} navigateCaption={BUTTONS.NAVIGATE_BACK} />; + return navigateRoot()} navigateCaption={BUTTONS.NAVIGATE_HOME} />; }; //----------------