diff --git a/db/UDO_PKG_EQUIPDS.pck b/db/UDO_PKG_EQUIPDS.pck index 216a832..27cc026 100644 --- a/db/UDO_PKG_EQUIPDS.pck +++ b/db/UDO_PKG_EQUIPDS.pck @@ -6,6 +6,20 @@ create or replace package UDO_PKG_EQUIPDS as COUT out clob -- Сериализованная таблица данных ); + /* Клиентское добавление "Выборки данных оборудования" */ + procedure INS + ( + SCODE in varchar2, -- Мнемокод + SNAME in varchar2, -- Наименование + NRN out number -- Регистрационный номер + ); + + /* Клиентское удаление "Выборки данных оборудования" */ + procedure DEL + ( + NRN in number -- Регистрационный номер + ); + /* Список классов оборудования выборки данных */ procedure CM_LIST ( @@ -13,6 +27,27 @@ create or replace package UDO_PKG_EQUIPDS as COUT out clob -- Сериализованная таблица данных ); + /* Клиентское добавление "Выборки данных оборудования (классы оборудования)" */ + procedure CM_INS + ( + NPRN in number, -- Родитель + SEQOBJKIND in varchar2, -- Класс оборудования + SUSERPROCS_DATA in varchar2, -- Процедура формирования + SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных + SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных + SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе + SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе + SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой + SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой + NRN out number -- Регистрационный номер + ); + + /* Клиентское удаление "Выборки данных оборудования (классы оборудования)" */ + procedure CM_DEL + ( + NRN in number -- Регистрационный номер + ); + /* Список файлов данных класса оборудования */ procedure CMFL_LIST ( @@ -43,6 +78,11 @@ end UDO_PKG_EQUIPDS; / create or replace package body UDO_PKG_EQUIPDS as +/* +TODO: owner="root" created="06.08.2024" +text="Проверка прав доступа на работу с ""Выборками данных""" +*/ + /* Список выборок данных */ procedure LIST ( @@ -88,6 +128,32 @@ create or replace package body UDO_PKG_EQUIPDS as PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR); end LIST; + /* Клиентское добавление "Выборки данных оборудования" */ + procedure INS + ( + SCODE in varchar2, -- Мнемокод + SNAME in varchar2, -- Наименование + NRN out number -- Регистрационный номер + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация + begin + /* Добавляем запись */ + UDO_PKG_EQUIPDS_BASE.INS(NCOMPANY => NCOMPANY, SCODE => SCODE, SNAME => SNAME, NRN => NRN); + end INS; + + /* Клиентское удаление "Выборки данных оборудования" */ + procedure DEL + ( + NRN in number -- Регистрационный номер + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация + begin + /* Добавляем запись */ + UDO_PKG_EQUIPDS_BASE.DEL(NRN => NRN, NCOMPANY => NCOMPANY); + end DEL; + /* Список классов оборудования выборки данных */ procedure CM_LIST ( @@ -139,6 +205,64 @@ create or replace package body UDO_PKG_EQUIPDS as PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR); end CM_LIST; + /* Клиентское добавление "Выборки данных оборудования (классы оборудования)" */ + procedure CM_INS + ( + NPRN in number, -- Родитель + SEQOBJKIND in varchar2, -- Класс оборудования + SUSERPROCS_DATA in varchar2, -- Процедура формирования + SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных + SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных + SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе + SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе + SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой + SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой + NRN out number -- Регистрационный номер + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация + NEQOBJKIND PKG_STD.TREF; -- Рег. номер класса оборудования + NUSERPROCS_DATA PKG_STD.TREF; -- Рег. номер процедуры формирования + NEXSSERVICEFN_UPLOAD PKG_STD.TREF; -- Рег. номер функции обмена для выгрузки данных + NEXSSERVICEFN_SEND_MD PKG_STD.TREF; -- Рег. номер Функции обмена для передачи внешней системе + NEXSSERVICEFN_SEND_RQ PKG_STD.TREF; -- Рег. номер функции обмена для обработки внешней системой + begin + /* Разыменуем ссылки */ + UDO_PKG_EQUIPDS_BASE.CM_JOINS(NCOMPANY => NCOMPANY, + SEQOBJKIND => SEQOBJKIND, + SUSERPROCS_DATA => SUSERPROCS_DATA, + SEXSSERVICE_UPLOAD => SEXSSERVICE_UPLOAD, + SEXSSERVICEFN_UPLOAD => SEXSSERVICEFN_UPLOAD, + SEXSSERVICE_SEND_MD => SEXSSERVICE_SEND_MD, + SEXSSERVICEFN_SEND_MD => SEXSSERVICEFN_SEND_MD, + SEXSSERVICE_SEND_RQ => SEXSSERVICE_SEND_RQ, + SEXSSERVICEFN_SEND_RQ => SEXSSERVICEFN_SEND_RQ, + NEQOBJKIND => NEQOBJKIND, + NUSERPROCS_DATA => NUSERPROCS_DATA, + NEXSSERVICEFN_UPLOAD => NEXSSERVICEFN_UPLOAD, + NEXSSERVICEFN_SEND_MD => NEXSSERVICEFN_SEND_MD, + NEXSSERVICEFN_SEND_RQ => NEXSSERVICEFN_SEND_RQ); + /* Добавляем запись */ + UDO_PKG_EQUIPDS_BASE.CM_INS(NPRN => NPRN, + NEQOBJKIND => NEQOBJKIND, + NUSERPROCS_DATA => NUSERPROCS_DATA, + NEXSSERVICEFN_UPLOAD => NEXSSERVICEFN_UPLOAD, + NEXSSERVICEFN_SEND_MD => NEXSSERVICEFN_SEND_MD, + NEXSSERVICEFN_SEND_RQ => NEXSSERVICEFN_SEND_RQ, + NRN => NRN); + end CM_INS; + + /* Клиентское удаление "Выборки данных оборудования (классы оборудования)" */ + procedure CM_DEL + ( + NRN in number -- Регистрационный номер + ) + is + begin + /* Добавляем запись */ + UDO_PKG_EQUIPDS_BASE.CM_DEL(NRN => NRN); + end CM_DEL; + /* Список файлов данных класса оборудования */ procedure CMFL_LIST ( @@ -172,7 +296,8 @@ create or replace package body UDO_PKG_EQUIPDS as PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SERR', SCAPTION => 'Сообщение об ошибке', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); /* Обходим данные */ for C in (select T.RN NRN, T.FILE_NAME SFILE_NAME, @@ -233,7 +358,8 @@ create or replace package body UDO_PKG_EQUIPDS as PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SERR', SCAPTION => 'Сообщение об ошибке', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); /* Обходим данные */ for C in (select T.RN NRN, T.TASK STASK, diff --git a/db/UDO_PKG_EQUIPDS_BASE.pck b/db/UDO_PKG_EQUIPDS_BASE.pck index c6dbb26..4b2f34c 100644 --- a/db/UDO_PKG_EQUIPDS_BASE.pck +++ b/db/UDO_PKG_EQUIPDS_BASE.pck @@ -31,15 +31,15 @@ create or replace package UDO_PKG_EQUIPDS_BASE as NCOMPANY in number, -- Организация SEQOBJKIND in varchar2, -- Класс оборудования SUSERPROCS_DATA in varchar2, -- Процедура формирования - SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки на FTP - SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки на FTP + SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных + SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой NEQOBJKIND out number, -- Рег. номер класса оборудования NUSERPROCS_DATA out number, -- Рег. номер процедуры формирования - NEXSSERVICEFN_UPLOAD out number, -- Рег. номер функции обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD out number, -- Рег. номер функции обмена для выгрузки данных NEXSSERVICEFN_SEND_MD out number, -- Рег. номер Функции обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ out number -- Рег. номер функции обмена для обработки внешней системой ); @@ -50,7 +50,7 @@ create or replace package UDO_PKG_EQUIPDS_BASE as NPRN in number, -- Родитель NEQOBJKIND in number, -- Класс оборудования NUSERPROCS_DATA in number, -- Процедура формирования - NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки данных NEXSSERVICEFN_SEND_MD in number, -- Функция обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ in number, -- Функция обмена для обработки внешней системой NRN out number -- Регистрационный номер @@ -62,7 +62,7 @@ create or replace package UDO_PKG_EQUIPDS_BASE as NRN in number, -- Регистрационный номер NEQOBJKIND in number, -- Класс оборудования NUSERPROCS_DATA in number, -- Процедура формирования - NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки данных NEXSSERVICEFN_SEND_MD in number, -- Функция обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ in number -- Функция обмена для обработки внешней системой ); @@ -99,7 +99,7 @@ create or replace package UDO_PKG_EQUIPDS_BASE as procedure CMFL_SET_STATUS ( NRN in number, -- Регистрационный номер - NSTATUS in number, -- Состояние (0 - зарегистрирован, 1 - загружается на FTP, 2 - успешно загружен на FTP, 3 - ошибка загрузки на FTP, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) + NSTATUS in number, -- Состояние (0 - зарегистрирован, 1 - загружается на сервер, 2 - успешно загружен на сервер, 3 - ошибка загрузки на сервер, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) SQUEUE_ID in varchar2, -- Идентификатор очереди обработки SERR in varchar2 -- Сообщение об ошибке ); @@ -201,15 +201,15 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as NCOMPANY in number, -- Организация SEQOBJKIND in varchar2, -- Класс оборудования SUSERPROCS_DATA in varchar2, -- Процедура формирования - SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки на FTP - SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки на FTP + SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных + SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой NEQOBJKIND out number, -- Рег. номер класса оборудования NUSERPROCS_DATA out number, -- Рег. номер процедуры формирования - NEXSSERVICEFN_UPLOAD out number, -- Рег. номер функции обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD out number, -- Рег. номер функции обмена для выгрузки данных NEXSSERVICEFN_SEND_MD out number, -- Рег. номер Функции обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ out number -- Рег. номер функции обмена для обработки внешней системой ) @@ -228,7 +228,7 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as else P_EXCEPTION(0, 'Не указана процедура формирования данных выборки.'); end if; - /* Функция обмена для выгрузки на FTP */ + /* Функция обмена для выгрузки данных */ FIND_EXSSERVICE_CODE(NFLAG_SMART => 0, NFLAG_OPTION => 0, SCODE => SEXSSERVICE_UPLOAD, NRN => NEXSSERVICE); FIND_EXSSERVICEFN_CODE(NFLAG_SMART => 0, NFLAG_OPTION => 0, @@ -257,7 +257,7 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as NPRN in number, -- Родитель NEQOBJKIND in number, -- Класс оборудования NUSERPROCS_DATA in number, -- Процедура формирования - NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки данных NEXSSERVICEFN_SEND_MD in number, -- Функция обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ in number, -- Функция обмена для обработки внешней системой NRN out number -- Регистрационный номер @@ -293,7 +293,7 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as NRN in number, -- Регистрационный номер NEQOBJKIND in number, -- Класс оборудования NUSERPROCS_DATA in number, -- Процедура формирования - NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки на FTP + NEXSSERVICEFN_UPLOAD in number, -- Функция обмена для выгрузки данных NEXSSERVICEFN_SEND_MD in number, -- Функция обмена для передачи внешней системе NEXSSERVICEFN_SEND_RQ in number -- Функция обмена для обработки внешней системой ) @@ -366,7 +366,7 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as procedure CMFL_SET_STATUS ( NRN in number, -- Регистрационный номер - NSTATUS in number, -- Состояние (0 - зарегистрирован, 1 - загружается на FTP, 2 - успешно загружен на FTP, 3 - ошибка загрузки на FTP, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) + NSTATUS in number, -- Состояние (0 - зарегистрирован, 1 - загружается на сервер, 2 - успешно загружен на сервер, 3 - ошибка загрузки на сервер, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) SQUEUE_ID in varchar2, -- Идентификатор очереди обработки SERR in varchar2 -- Сообщение об ошибке ) diff --git a/db/UDO_P_EQUIPDSCMFL_CREATE.prc b/db/UDO_P_EQUIPDSCMFL_CREATE.prc new file mode 100644 index 0000000..566b8ca --- /dev/null +++ b/db/UDO_P_EQUIPDSCMFL_CREATE.prc @@ -0,0 +1,24 @@ +create or replace procedure UDO_P_EQUIPDSCMFL_CREATE +/* Тестовая процедура формирования данных выборки */ +( + NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных + NCNT in number -- Количество формируемых файлов +) +is + NTMP PKG_STD.TREF; -- Рег. номер добавленного файла данных +begin + /* Зачистим старые файлы */ + for C in (select T.RN from UDO_T_EQUIPDSCMFL T where T.PRN = NEQUIPDSCM) + loop + UDO_PKG_EQUIPDS_BASE.CMFL_DEL(NRN => C.RN); + end loop; + /* Добавим новые файлы */ + for I in 1 .. NCNT + loop + UDO_PKG_EQUIPDS_BASE.CMFL_INS(NPRN => NEQUIPDSCM, + SFILE_NAME => 'data_' || NEQUIPDSCM || '_' || I || '.xml', + SDESCR => 'Описание для файла №' || I, + NRN => NTMP); + end loop; +end; +/ diff --git a/db/UDO_T_EQUIPDSCMFL.sql b/db/UDO_T_EQUIPDSCMFL.sql index 2b26caf..fad9cd4 100644 --- a/db/UDO_T_EQUIPDSCMFL.sql +++ b/db/UDO_T_EQUIPDSCMFL.sql @@ -11,7 +11,7 @@ create table UDO_T_EQUIPDSCMFL DESCR varchar2(4000) default null, /* Идентификатор очереди обработки */ QUEUE_ID varchar2(200) default null, - /* Состояние (0 - зарегистрирован, 1 - загружается на FTP, 2 - успешно загружен на FTP, 3 - ошибка загрузки на FTP, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) */ + /* Состояние (0 - зарегистрирован, 1 - загружается на сервер, 2 - успешно загружен на сервер, 3 - ошибка загрузки на сервер, 4 - загружается во внешнюю систему, 5 - успешно загружен во внешнюю систему, 6 - при загрузке во внешнюю систему произошла ошибка) */ STATUS number(1) default 0 not null, /* Сообщение об ошибке */ ERR varchar2(4000) default null, diff --git a/panels/eqs_tech_cond_forecast/admin_tab.js b/panels/eqs_tech_cond_forecast/admin_tab.js index e85929d..599dcbc 100644 --- a/panels/eqs_tech_cond_forecast/admin_tab.js +++ b/panels/eqs_tech_cond_forecast/admin_tab.js @@ -7,9 +7,17 @@ //Подключение библиотек //--------------------- -import React, { useState, useEffect } from "react"; //Классы React -import { Box, Grid, Stack, Icon, Button } from "@mui/material"; //Интерфейсные компоненты -import { EquipDataSelectionList, EquipDataSelectionClassMachineList, EquipDataSelectionClassMachineCard } from "./admin_tab_layout"; //Вспомогательные компоненты и вёрстка +import React, { useState, useEffect, useContext } from "react"; //Классы React +import { Box, Grid, Stack, Icon, Button, IconButton } from "@mui/material"; //Интерфейсные компоненты +import { ApplicationСtx } from "../../context/application"; //Контекст приложения +import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с серверомs +import { + EquipDataSelectionIU, + EquipDataSelectionList, + EquipDataSelectionClassMachineIU, + EquipDataSelectionClassMachineList, + EquipDataSelectionClassMachineCard +} from "./admin_tab_layout"; //Вспомогательные компоненты и вёрстка import { DS_RN_DEFAULT, useEquipDataSelectionList, @@ -22,6 +30,9 @@ import { //Константы //--------- +//Начальное состояние флагов обновления +const REFRESH_INITIAL = { action: null, dataSelection: null, dataSelectionClassMachine: null, dataSelectionClassMachineFilesList: 0 }; + //Стили const STYLES = { DATA_SELECTION_STACK: { alignItems: "center" }, @@ -34,6 +45,18 @@ const STYLES = { //Закладка администрирования const AdminTab = () => { + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Подключение к контексту приложения + const { pOnlineUserProcedure } = useContext(ApplicationСtx); + + //Собственное состояние - отображаемые диалоги + const [dialogs, setDialogs] = useState({ dataSelectionIU: false, dataSelectionClassMachineIU: false }); + + //Собственное состояние - флаги обновления данных + const [refresh, setRefresh] = useState(REFRESH_INITIAL); + //Собственное состояние - выбранная выборка данных const [equipDataSelection, setDataSelection] = useState(DS_RN_DEFAULT); @@ -41,46 +64,142 @@ const AdminTab = () => { const [equipDataSelectionClassMachine, setDataSelectionClassMachine] = useState(null); //Загрузка списка выборок данных - const { equipDataSelectionList } = useEquipDataSelectionList(); + const { equipDataSelectionList } = useEquipDataSelectionList(refresh.dataSelection); //Загрузка классов оборудования выбранной выборки данных - const { equipDataSelectionClassMachineList } = useEquipDataSelectionClassMachineList(equipDataSelection); + const { equipDataSelectionClassMachineList } = useEquipDataSelectionClassMachineList(equipDataSelection, refresh.dataSelectionClassMachine); //Загрузка файлов класса оборудования - const { equipDataSelectionClassMachineFilesList } = useEquipDataSelectionClassMachineFilesList(equipDataSelectionClassMachine); + const { equipDataSelectionClassMachineFilesList } = useEquipDataSelectionClassMachineFilesList( + equipDataSelectionClassMachine, + refresh.dataSelectionClassMachineFilesList + ); //Загрузка файлов класса оборудования const { equipDataSelectionClassMachineModelsList } = useEquipDataSelectionClassMachineModelsList(equipDataSelectionClassMachine); - //При подключении компонента к странице - useEffect(() => {}, []); - //При смене выборки данных const handleDataSelectionChange = value => { - setDataSelectionClassMachine(null); setDataSelection(value); + setDataSelectionClassMachine(null); + setRefresh(REFRESH_INITIAL); + }; + + //При нажатии на "Добавить выборку" + const handleAddEquipDataSelection = () => setDialogs(pv => ({ ...pv, dataSelectionIU: true })); + + //При нажатии на "Удалить выборку" + const handleDeleteEquipDataSelection = async () => { + await executeStored({ stored: "UDO_PKG_EQUIPDS.DEL", args: { NRN: equipDataSelection } }); + setRefresh(pv => ({ ...pv, dataSelection: equipDataSelection * 2, action: "DEL" })); + setDataSelection(DS_RN_DEFAULT); + }; + + //При отмене диалога IU выборки + const handleEquipDataSelectionIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionIU: false })); + + //При сохранении диалога IU выборки + const handleEquipDataSelectionIUOk = async values => { + const data = await executeStored({ stored: "UDO_PKG_EQUIPDS.INS", args: { SCODE: values.code, SNAME: values.name } }); + setDialogs(pv => ({ ...pv, dataSelectionIU: false })); + setRefresh(pv => ({ ...pv, dataSelection: data.NRN, action: "INS" })); }; //При нажатии на класс оборудования const handleDataSelectionClassMachineClick = value => setDataSelectionClassMachine(value); + //При нажатии на "Добавить класс оборудования" + const handleAddEquipDataSelectionClassMachine = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: true })); + + //При нажатии на "Удалить класс оборудования" + const handleDeleteEquipDataSelectionClassMachine = async rn => { + await executeStored({ stored: "UDO_PKG_EQUIPDS.CM_DEL", args: { NRN: rn } }); + setRefresh(pv => ({ ...pv, dataSelectionClassMachine: rn * 2, action: "DEL" })); + setDataSelectionClassMachine(null); + }; + + //При отмене диалога IU класса оборудования + const handleEquipDataSelectionClassMachineIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: false })); + + //При сохранении диалога IU класса оборудования + const handleEquipDataSelectionClassMachineIUOk = async values => { + const data = await executeStored({ + stored: "UDO_PKG_EQUIPDS.CM_INS", + args: { + NPRN: equipDataSelection, + SEQOBJKIND: values.eqobjKind, + SUSERPROCS_DATA: values.userprocsData, + SEXSSERVICE_UPLOAD: values.exsServiceUpload, + SEXSSERVICEFN_UPLOAD: values.exsServiceFnUpload, + SEXSSERVICE_SEND_MD: values.exsServiceSendMd, + SEXSSERVICEFN_SEND_MD: values.exsServiceFnSendMd, + SEXSSERVICE_SEND_RQ: values.exsServiceSendRq, + SEXSSERVICEFN_SEND_RQ: values.exsServiceFnSendRq + } + }); + setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: false })); + setRefresh(pv => ({ ...pv, dataSelectionClassMachine: data.NRN, action: "INS" })); + }; + + //При нажатии "Сформировать" в списке файлов карточки класса оборудования + const handleMakeEquipDataSelectionClassMachineFiles = (rn, procedure) => { + pOnlineUserProcedure({ + code: procedure, + inputParameters: [{ name: "NEQUIPDSCM", value: rn }], + callBack: res => + res.success ? setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 })) : null + }); + }; + + //При изменении списка выборок данных + useEffect(() => { + if (refresh.action == "INS" && refresh.dataSelection) { + setDataSelection(refresh.dataSelection); + setDataSelectionClassMachine(null); + } + }, [equipDataSelectionList]); + + //При изменении списка классов оборудования выборки данных + useEffect(() => { + if (refresh.action == "INS" && refresh.dataSelectionClassMachine) setDataSelectionClassMachine(refresh.dataSelectionClassMachine); + }, [equipDataSelectionClassMachineList]); + //Генерация содержимого return ( + {dialogs.dataSelectionIU ? ( + + ) : null} + {dialogs.dataSelectionClassMachineIU ? ( + + ) : null} - + + add + + {equipDataSelection != DS_RN_DEFAULT ? ( + + delete + + ) : null} diff --git a/panels/eqs_tech_cond_forecast/admin_tab_hooks.js b/panels/eqs_tech_cond_forecast/admin_tab_hooks.js index 2ec3e41..7bb2693 100644 --- a/panels/eqs_tech_cond_forecast/admin_tab_hooks.js +++ b/panels/eqs_tech_cond_forecast/admin_tab_hooks.js @@ -28,7 +28,7 @@ const DS_DEFAULT = { NRN: DS_RN_DEFAULT, SNAME: DS_NAME_DEFAULT }; //----------- //Загрузка списка выборок данных -const useEquipDataSelectionList = () => { +const useEquipDataSelectionList = refresh => { //Собственное состояние - флаг загрузки const [isLoading, setLoading] = useState(false); @@ -47,6 +47,7 @@ const useEquipDataSelectionList = () => { stored: "UDO_PKG_EQUIPDS.LIST", respArg: "COUT", isArray: name => ["XDS"].includes(name), + attributeValueProcessor: (name, val) => (["SNAME"].includes(name) ? undefined : val), loader: false }); setData([DS_DEFAULT, ...(data?.XDS ? data.XDS : [])]); @@ -55,14 +56,14 @@ const useEquipDataSelectionList = () => { } }; loadData(); - }, [executeStored]); + }, [refresh, executeStored]); //Вернём данные return { equipDataSelectionList: data, equipDataSelectionListIsLoading: isLoading }; }; //Загрузка классов оборудования выбороки данных -const useEquipDataSelectionClassMachineList = dataSelection => { +const useEquipDataSelectionClassMachineList = (dataSelection, refresh) => { //Собственное состояние - флаг загрузки const [isLoading, setLoading] = useState(false); @@ -91,14 +92,14 @@ const useEquipDataSelectionClassMachineList = dataSelection => { } }; if (dataSelection && dataSelection != DS_RN_DEFAULT) loadData(); - }, [dataSelection, executeStored]); + }, [dataSelection, refresh, executeStored]); //Вернём данные return { equipDataSelectionClassMachineList: data, equipDataSelectionClassMachineListIsLoading: isLoading }; }; //Загрузка списка файлов класса оборудования -const useEquipDataSelectionClassMachineFilesList = classMachine => { +const useEquipDataSelectionClassMachineFilesList = (classMachine, refresh) => { //Собственное состояние - флаг загрузки const [isLoading, setLoading] = useState(false); @@ -134,7 +135,7 @@ const useEquipDataSelectionClassMachineFilesList = classMachine => { } }; if (classMachine) loadData(); - }, [classMachine, executeStored]); + }, [classMachine, refresh, executeStored]); //Вернём данные return { equipDataSelectionClassMachineFilesList: data, equipDataSelectionClassMachineFilesListIsLoading: isLoading }; diff --git a/panels/eqs_tech_cond_forecast/admin_tab_layout.js b/panels/eqs_tech_cond_forecast/admin_tab_layout.js index 7224caf..67015c3 100644 --- a/panels/eqs_tech_cond_forecast/admin_tab_layout.js +++ b/panels/eqs_tech_cond_forecast/admin_tab_layout.js @@ -7,7 +7,7 @@ //Подключение библиотек //--------------------- -import React from "react"; //Классы React +import React, { useState, useContext, useEffect } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Box, @@ -22,10 +22,20 @@ import { ListItemText, Card, CardContent, - CardActions, Typography, - Button + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Input, + InputAdornment, + IconButton, + Icon } from "@mui/material"; //Интерфейсные компоненты +import { useTheme } from "@mui/material/styles"; //Темы оформления +import { ApplicationСtx } from "../../context/application"; //Контекст приложения +import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы import { APP_BAR_HEIGHT, TABS_HEIGHT, SCROLL_STYLES } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения @@ -60,7 +70,9 @@ const STYLES = { minHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${DS_SELECTOR_HEIGHT} - ${CM_ADD_BTN_HEIGHT})`, maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${DS_SELECTOR_HEIGHT} - ${CM_ADD_BTN_HEIGHT})`, overflowX: "hidden", - overflowY: "auto", + overflowY: "scroll", + paddingLeft: "15px", + paddingRight: "15px", ...SCROLL_STYLES }, EQUIP_DSCM_CARD: { @@ -75,10 +87,236 @@ const STYLES = { } }; +//------------------------------------ +//Вспомогательные функции и компоненты +//------------------------------------ + +//Поле ввода из словаря +const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, ...other }) => { + //Значение элемента + const [value, setValue] = useState(elementValue); + + //При получении нового значения из вне + useEffect(() => { + setValue(elementValue); + }, [elementValue]); + + //Выбор значения из словаря + const handleDictionaryClick = () => + dictionary ? dictionary(res => (res ? res.map(i => handleChange({ target: { name: i.name, value: i.value } })) : null)) : null; + + //Изменение значения элемента + const handleChange = e => { + setValue(e.target.value); + if (onChange) onChange(e.target.name, e.target.value); + }; + + //Генерация содержимого + return ( + + + {labelText} + + + list + + + ) : null + } + onChange={handleChange} + /> + + + ); +}; + +//Контроль свойств - Поле ввода из словаря +IUDFormTextField.propTypes = { + elementCode: PropTypes.string.isRequired, + elementValue: PropTypes.string, + labelText: PropTypes.string.isRequired, + onChange: PropTypes.func, + dictionary: PropTypes.func +}; + //----------- //Тело модуля //----------- +//Диалог IU выборки данных +const EquipDataSelectionIU = ({ onOk, onCancel }) => { + //Собственное состояние - значения формы + const [values, setValues] = useState({ code: "", name: "" }); + + //Отработка воода значения в форму + const handleValueChanged = (name, value) => { + setValues(pv => ({ ...pv, [name]: value })); + }; + + //Генерация содержимого + return ( + (onOk ? onCancel() : null)}> + Выборка данных + + + + + + + + + + ); +}; + +//Контроль свойств - Диалог IU выборки данных +EquipDataSelectionIU.propTypes = { + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + +//Диалог IU класса оборудования выборки данных +const EquipDataSelectionClassMachineIU = ({ onOk, onCancel }) => { + //Подключение к контексту приложения + const { pOnlineShowDictionary } = useContext(ApplicationСtx); + + //Собственное состояние - значения формы + const [values, setValues] = useState({ + eqobjKind: "", + userprocsData: "", + exsServiceUpload: "", + exsServiceFnUpload: "", + exsServiceSendMd: "", + exsServiceFnSendMd: "", + exsServiceSendRq: "", + exsServiceFnSendRq: "" + }); + + //Отработка воода значения в форму + const handleValueChanged = (name, value) => setValues(pv => ({ ...pv, [name]: value })); + + //Выбор класса оборудования из словаря + const selectEqobjKind = (name, callBack) => { + pOnlineShowDictionary({ + unitCode: "EquipObjectKinds", + callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_FULLCODE }] : null) + }); + }; + + //Выбор процедуры формирования из словаря + const selectUserProcsData = (name, callBack) => { + pOnlineShowDictionary({ + unitCode: "UserProcedures", + callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_CODE }] : null) + }); + }; + + //Выбор функции обмена для выгрузки данных + const selectServiceFn = (name, callBack) => { + pOnlineShowDictionary({ + unitCode: "EXSService", + callBack: res => + callBack( + res.success + ? [ + { name, value: res.outParameters.out_FN_CODE }, + { + name: + name == "exsServiceFnUpload" + ? "exsServiceUpload" + : name == "exsServiceFnSendMd" + ? "exsServiceSendMd" + : "exsServiceSendRq", + value: res.outParameters.out_CODE + } + ] + : null + ) + }); + }; + + //Генерация содержимого + return ( + (onOk ? onCancel() : null)}> + Класс оборудования выборки данных + + selectEqobjKind("eqobjKind", callBack)} + /> + selectUserProcsData("userprocsData", callBack)} + /> + + selectServiceFn("exsServiceFnUpload", callBack)} + /> + + selectServiceFn("exsServiceFnSendMd", callBack)} + /> + + selectServiceFn("exsServiceFnSendRq", callBack)} + /> + + + + + + + ); +}; + +//Контроль свойств - Диалог IU класса оборудования выборки данных +EquipDataSelectionClassMachineIU.propTypes = { + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + //Список выборок данных оборудования const EquipDataSelectionList = ({ list, value, onChange }) => { //При выборе элемента @@ -133,32 +371,44 @@ EquipDataSelectionClassMachineList.propTypes = { }; //Карточка класса оборудования выборки данных -const EquipDataSelectionClassMachineCard = ({ filesList, modelsList }) => { +const EquipDataSelectionClassMachineCard = ({ card, filesList, modelsList, onCardDelete, onClassMachineFilesMake }) => { + //Подключаемся к теме + const theme = useTheme(); + + //При нажатии на "Удалить" для карточки + const handleCardDeleteClick = () => (onCardDelete ? onCardDelete(card.NRN) : null); + + //При нажатии на "Сформировать" для файлов данных + const handleClassMachineFilesMakeClick = () => (onClassMachineFilesMake ? onClassMachineFilesMake(card.NRN, card.SUSERPROCS_DATA) : null); + //Генерация содержимого return ( - - Наименование технического объекта - + + + Наименование технического объекта + + + delete + + Состояние: готов к ... фывафывафва - - - - - - - Файлы данных - + + + Файлы данных + + + { morePages={false} fixedHeader={true} reloading={false} + headCellRender={filesListHeadCellRender} + dataCellRender={prms => filesListDataCellRender({ ...prms, theme })} /> @@ -199,8 +451,69 @@ const EquipDataSelectionClassMachineCard = ({ filesList, modelsList }) => { ); }; +//Контроль свойств - Карточка класса оборудования выборки данных +EquipDataSelectionClassMachineCard.propTypes = { + card: PropTypes.object.isRequired, + filesList: PropTypes.object.isRequired, + modelsList: PropTypes.object.isRequired, + onCardDelete: PropTypes.func, + onClassMachineFilesMake: PropTypes.func +}; + +//Формирование значения для колонки "Состояние" проекта +const formatFileStateValue = (theme, value, err) => { + const [text, icon, color] = + value == 0 + ? ["Зарегистрирован", "app_registration", null] + : value == 1 + ? ["Загружается на сервер", "file_upload", theme.palette.warning.main] + : value == 2 + ? ["Успешно загружен на сервер", "dns", theme.palette.primary.main] + : value == 3 + ? [`Ошибка загрузки на сервер: ${err}`, "error", theme.palette.error.main] + : value == 4 + ? ["Загружается во внешнюю систему", "cloud_upload", theme.palette.warning.main] + : value == 5 + ? ["Успешно загружен во внешнюю систему", "cloud_done", theme.palette.success.main] + : [`Ошибка загрузки во внешнюю систему: ${err}`, "error", theme.palette.error.main]; + return ( + + {icon} + {text} + + ); +}; + +//Форматирование колонок таблицы файлов класса оборудования выборки данных +const filesListDataCellRender = ({ row, columnDef, theme }) => { + switch (columnDef.name) { + case "NSTATUS": + return { + cellProps: { align: "left" }, + data: formatFileStateValue(theme, row.NSTATUS, row.SERR) + }; + } +}; + +//Генерация представления ячейки заголовка +const filesListHeadCellRender = ({ columnDef }) => { + switch (columnDef.name) { + case "NSTATUS": + return { + stackProps: { justifyContent: "left" }, + cellProps: { align: "left" } + }; + } +}; + //---------------- //Интерфейс модуля //---------------- -export { EquipDataSelectionList, EquipDataSelectionClassMachineList, EquipDataSelectionClassMachineCard }; +export { + EquipDataSelectionIU, + EquipDataSelectionClassMachineIU, + EquipDataSelectionList, + EquipDataSelectionClassMachineList, + EquipDataSelectionClassMachineCard +};