diff --git a/README.md b/README.md index 3238480..37f8aa8 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ # "Панели" расширение к "ПАРУС 8 Онлайн" +## Оглавление + +[Термины и сокращения](#термины-и-сокращения)\ +[I. Назначение](#i-назначение)\ +[II. Состав](#ii-состав)\ +[III. Требования к разработчику](#iii-требования-к-разработчику)\ +[IV. Установка](#iv-установка)\ +[V. Подключение панелей](#v-подключение-панелей)\ +[VI. Разработка панелей](#vi-разработка-панелей) + ## Термины и сокращения **Система** - "ПАРУС 8 Предприятие"\ @@ -15,7 +25,8 @@ **CSS** - Cascading Style Sheets - каскадные таблицы стилей\ **DOM** - Document Object Model - объектная модель документа (в контексте данного документа - HTML)\ **JS** - JavaScript — мультипарадигменный интерпретируемый язык программирования\ -**JSX** - JavaScript eXtension - расширение JavaScript, которое позволяет создавать деревья DOM с использованием синтаксиса, подобного XML +**JSX** - JavaScript eXtension - расширение JavaScript, которое позволяет создавать деревья DOM с использованием синтаксиса, подобного XML\ +**АРМ** - Автоматизированное Рабочее Место ## I. Назначение @@ -86,15 +97,15 @@ git clone https://github.com/CITKParus/P8-Panels.git 7. Перезапустите сервер приложений "ПАРУС 8 Онлайн" -## V. Подключение поставляемых панелей мониторинга +## V. Подключение панелей -В корневом каталоге репозитория ["P8-Panels"](https://github.com/CITKParus/P8-Panels) расположен файл "p8panels.config", содержащий конфигурацию поставляемых с расширением типовых панелей. - -Данный файл определяет какие панели подключены к WEB-приложению, порядок формирования пунктов главного меню "ПАРУС 8 Онлайн" для доступа к подключенным панелям, состав галереи панелей и бокового меню навигации WEB-приложения "Парус 8 - Панели мониторинга", работающего в контексте "ПАРУС 8 Онлайн". +Файл "p8panels.config", располагаемый в каталоге "Config" сервера приложений "ПАРУС 8 Онлайн", определяет какие панели подключены к WEB-приложению, порядок формирования пунктов главного меню "ПАРУС 8 Онлайн" для доступа к подключенным панелям, состав галереи панелей и бокового меню навигации WEB-приложения "Парус 8 - Панели мониторинга", работающего в контексте "ПАРУС 8 Онлайн". ![Главное меню, галерея панелей и боковое меню панелей](docs/img/51.png) -Данный файл конфигурации необходимо разместить локально, в папке "Config" сервера приложений "ПАРУС 8 Онлайн". +В корневом каталоге репозитория ["P8-Panels"](https://github.com/CITKParus/P8-Panels) расположен файл "p8panels.config", содержащий конфигурацию поставляемых с расширением типовых панелей. + +Данный файл конфигурации необходимо разместить локально, в каталоге "Config" сервера приложений "ПАРУС 8 Онлайн". Например, если сервер приложений установлен в "c:\p8web20\WebClient", то путь к "p8panels.config" должен быть "c:\p8web20\WebClient\Config\p8panels.config". Рассмотрим формат файла конфигурации панелей на примере. Ниже приведён фрагмет "p8panels.config" из поставки расширения. @@ -159,14 +170,241 @@ git clone https://github.com/CITKParus/P8-Panels.git Подключение разработанных пользователем панелей осуществляется путём добавления элементов `Panels` в файл конфигурации (при необходимости и элементов `App\MenuItems`, если предполагается открытие панели через главное меню WEB-приложения "ПАРУС 8 Онлайн"). -> Будьте внимательны при обновлении: если в локальном файле "p8panels.config" содержится конфигурация пользовательских панелей, то его нельзя заменять копированием дистрибутивной версии файла при обновлении - будут утеряны сделанные настройки. В этом случае файл следует модифицировать экспертным путём, добавив в локальный "p8panels.config" изменения из дистрибутивного вручную. +Изменения файла конфигурации в части элементов `MenuItems` требуют перезапуска сервера приложений "ПАРУС 8 Онлайн" и завершения/начала сеансов конечных пользователей. -## VI. Разработка пользовательских панелей +> **Будьте внимательны при обновлении:** если в локальном файле "p8panels.config" содержится конфигурация пользовательских панелей, то его нельзя заменять копированием дистрибутивной версии файла при обновлении - будут утеряны сделанные настройки. В этом случае файл следует модифицировать экспертным путём, добавив в локальный "p8panels.config" изменения из дистрибутивного вручную. + +## VI. Разработка панелей + +> **Внимание:** данное руководство не является обучающим курсом по WEB-разработке как таковой. Изложенные ниже сведения о порядке реализации пользовательских панелей, даны с учётом приведённых ранее требований к разработчику. ### Общие сведения +Расширение "Панели" позволяет подключать нестандартные интерфейсы разрабатываемые на местах, без привлечения вендора. Это могут быть не только панели мониторинга, но и формы ввода данных, различные АРМ, выполняющие бизнес-функции в Системе. + +С точки зрения клиенсткой части, Панели представляют собой функциональные компоненты React, автоматически (благодаря описанному выше файлу конфигурации) встраиваемые в систему маршрутизации WEB-приложения "Парус 8 - Панели мониторинга" (далее "приложения" или "WEB-приложения", если контекст явно не указывает на иное). Каждая панель состоит из: + +- Набора JS-объектов и функций, управляющих состоянием панели +- Функций для обмена данными с сервером БД Системы и выполнения бизнес-процедур в ней +- JSX разметки, отражающей смену состояния панели + +Такая структура исходного кода панели продиктована архитектурными требованиями к функциональным React-компонентам. Каждая панель (и все необходимые для её функционирования JS-модули и вспомогательный файлы) размещается в отдельном каталоге (см. выше - "app/panels", здесь и далее каталоги указаны относительно корневого каталога размещения приложения, если явно не указано иное) WEB-приложения "Парус 8 - Панели мониторинга". + +Каждая панель должна иметь в составе "index.js" - точку входа по умолчанию. "index.js" должен экспортировать фунциональный React-компонент панели с имененем `RootClass` (см. для примера "app/panels/prj_fin/index.js"). + +После добавления новых панелей в состав приложения необходима его "пересборка". Для этого предусмотрены преднастроенные скрипты `dev` и `build`. Скрипты размещены в секции `scripts` файла зависимостей `package.json` WEB-приложения. Исполнение скриптов сборки выполняется через пакетный менеджер `npm` из корневого каталога приложения: + +``` +REM Запуск скрипта для отладочной сборки +c:\inetpub\p8web20\WebClient\Modules\P8-Panels>npm run dev + +REM Запуск скрипта финальной сборки +c:\inetpub\p8web20\WebClient\Modules\P8-Panels>npm run build +``` + +Скрипт финальной сборки формирует обновлённое WEB-приложение в каталоге "dist" и завершает работу. Скрипт отладочной сборки обновляет WEB-приложение в каталоге "dist" и остаётся в активном режиме, "слушая" измнения файлов исходного кода приложения и автоматически обновляя "dist", если таковые изменения будут зафиксированы. Это позволяет отлаживать панели не выполняя пересборку вручную. + +После пересборки обновлённые/новые панели доступны конечному пользователю для эксплуатации через WEB-приложение "ПАРУС 8 Онлайн". + +Серверная часть любой из панелей - набор хранимых процедур/функций/пакетов БД Системы. Состав объектов, их алгоритмы, входные параметры и выходные данные зависят от специфики панели и специально не регламентируются. Необходимо понимать, что с помощью специального API из клиентской JS-функции панели можно обращаться к хранимым объектам БД - исполнять их, передавать значения входных параметров (например, считанные из форм ввода, размещённых на панели), получать и отображать на панели значения выходных параметров исполненного серверного объекта (в виде таблиц, карточек, графиков и прочими способами, отвечающими функциональным требованиям реализуемой панели). + ### API для взаимодействия с сервером "ПАРУС 8 Предприятие" +Для исполнения хранимых процедур/функций БД Системы в составе расширения предусмотрен специальный API. Его подключение к компоненте панели осуществляется через контекст `BackEndСtx` ("app/context/backend.js"). + +В состав API входят: + +- `SERV_DATA_TYPE_STR` - константа для типа данных "строка", при описании параметров исполняемых хранимых объектов +- `SERV_DATA_TYPE_NUMB` - константа для типа данных "число", при описании параметров исполняемых хранимых объектов +- `SERV_DATA_TYPE_DATE` - константа для типа данных "дата", при описании параметров исполняемых хранимых объектов +- `SERV_DATA_TYPE_CLOB` - константа для типа данных "текст", при описании параметров исполняемых хранимых объектов +- `isRespErr` - проверка результата исполнения серверного объекта на наличие ошибок +- `getRespErrMessage` - получение ошибки исполнения серверного объекта +- `getRespPayload` - получение выходных значений, полученных после успешного исполнения +- `executeStored` - асинхронное исполнение хранимой процедуры/функции БД Системы +- `getConfig` - асинхронное считывание параметров конфигурации, определённых в "p8panels.config" (возвращает их JSON-представление) + +При формировании ответов, функции, получающие данные с сервера, возвращают типовые значения: + +``` +//Типовой успех +{ + SSTATUS: "OK", + XPAYLOAD: Object +} + +//Типовая ошибка +{ + SSTATUS: "ERR", + SMESSAGE: String +} +``` + +Где: + +- `SSTATUS` - состояние исполнения (`"OK"` или `"ERR"`) +- `XPAYLOAD` - полезная нагрузка, данные полученные от серверного объекта +- `SMESSAGE` - текст сообщения об ошибке + +#### `boolean isRespErr(Object)` + +**Входные параметры:** результат вызова `executeStored` + +**Результат:** `true` - если полученный на вход результат исполнения `executeStored` содержит ошибку, `false` - в остальных случаях + +#### `String getRespErrMessage(Object)` + +**Входные параметры:** результат вызова `executeStored` + +**Результат:** текст сообщения об ошибке - если полученный на вход результат исполнения `executeStored` содержит ошибку, пустая строка (`""`) - в остальных случаях + +#### `Object getRespPayload(Object)` + +**Входные параметры:** результат вызова `executeStored` (вызов должен осуществляться с параметром `fullResponse = true`) + +**Результат:** объект с данными, размещёнными в `XPAYLOAD` ответа сервера - если полученный на вход результат исполнения `executeStored` содержит полезную нагрузку, `null` - в остальных случаях + +#### `async Object executeStored(Object)` + +**Входные параметры:** + +``` +{ + stored, + args, + respArg, + isArray, + tagValueProcessor, + attributeValueProcessor, + loader = true, + loaderMessage = "", + throwError = true, + showErrorMessage = true, + fullResponse = false, + spreadOutArguments = true +} +``` + +`stored` - обязательный, строка, имя исполняемого хранимого объекта (для пакетных - "ПАКЕТ.ОБЪЕКТ")\ +`args` - необязательный, объект, описание параметров исполняемого хранимого объета вида: `{"ПАРАМЕТР": "ЗНАЧЕНИЕ"|{VALUE: "ЗНАЧЕНИЕ", SDATA_TYPE: SERV_DATA_TYPE_*}}` (если тип данных параметров не указан явно - произойдёт попытка их автоматического определения, с CLOB-параметрами это не всегда может произойти корректно)\ +`respArg` - необязательный, строка, имя выходного параметра исполняемого объекта, значение которого необходимо вернуть как данные ответа (если не указан - возвращвется типовой ответ)\ +`isArray`, `tagValueProcessor`, `attributeValueProcessor` - необязательны, функции, позволяющие провести корректировку парсинга XML-ответа сервера в JSON (сигнатура и назначение функций описаны в документации к [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser/blob/HEAD/docs/v4/2.XMLparseOptions.md))\ +`loader` - отображать типовой индикатор процесса\ +`loaderMessage` - текст индикатора процесса (при отсутствии будет использован типовой)\ +`throwError` - признак генерации исключения, если false - возвращает ошибку в типовом формате\ +`showErrorMessage` - отображать типовое клиентское сообщение об ошибке, в случае её возникновения (только если `throwError = true`) + +**Результат:** объект с данными, размещёнными в `XPAYLOAD` ответа сервера (если `fullResponse = false`) или полный типовой ответ (описан выше). + +**Пример:** + +``` +import React, { useState, useContext } from "react"; //Классы React +import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером + +//Функциональный компонент панели (или её части) +const MyPanel = () => { + //Собственное состояние + const [state, setState] = useState({ + dataLoaded: false, + data: [], + filters: null, + orders: null + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx); + + //Загрузка данных проектов с сервера + const loadProjects = async (agentName) => { + //Исполняем процедуру + const data = await executeStored({ + stored: "UDO_P_GET_MY_DATA", + args: { + CFILTERS: { VALUE: state.filters, SDATA_TYPE: SERV_DATA_TYPE_CLOB }, + CORDERS: { VALUE: state.orders, SDATA_TYPE: SERV_DATA_TYPE_CLOB }, + SAGENT: agentName + }, + respArg: "COUT" + }); + //Отражаем данные в состоянии + setState(pv => ({ ...pv, data: [...data], dataLoaded: true })); + } +}; + +``` + +#### `async Object getConfig(Object)` + +**Входные параметры:** + +``` +{ + loader = true, + loaderMessage = "", + throwError = true, + showErrorMessage = true +} +``` + +`loader` - отображать типовой индикатор процесса\ +`loaderMessage` - текст индикатора процесса (при отсутствии будет использован типовой)\ +`throwError` - признак генерации исключения, если false - возвращает ошибку в типовом формате\ +`showErrorMessage` - отображать типовое клиентское сообщение об ошибке, в случае её возникновения (только если `throwError = true`) + +**Результат:** + +``` +{ + SSTATUS: "OK", + XPAYLOAD: JSON-представление файла конфигурации +} +``` + +где `XPAYLOAD` объект вида (см. описание атрибутов выше, в описании "p8panels.config"): + +``` +{ + "MenuItems": { + "App": [ + { + "MenuItem": [ + { + "parent": ..., + "name": ..., + "caption": ..., + "url": ..., + "separator": ... + }, + ... + ], + "name": "Realiz" + }, + ... + ] + }, + "Panels": { + "Panel": [ + { + "name": ..., + "group": ..., + "caption": ..., + "desc": ..., + "url": ..., + "path": ..., + "icon": ..., + "showInPanelsList": ..., + "preview": ... + }, + ... + ], + "urlBase": ... + } +} +``` + +### API для взаимодействия с WEB-приложением "ПАРУС 8 Онлайн" + ### Компоненты пользовательского интерфейса #### Типовые интерфейсные примитивы @@ -184,5 +422,3 @@ git clone https://github.com/CITKParus/P8-Panels.git ##### Графики "P8PChart" ##### Диаграмма ганта "P8PGantt" - -### API для взаимодействия с WEB-приложением "ПАРУС 8 Онлайн"