Закладка "Прогнозирование" - структура и список технологических объектов (начало)

This commit is contained in:
Mikhail Chechnev 2024-08-02 15:32:38 +03:00
parent 5358680479
commit 57d7dd2e68
4 changed files with 373 additions and 39 deletions

View File

@ -1,6 +1,40 @@
create or replace package UDO_PKG_EQUIPDS as
/* Код доступного действия с моделью по единице оборудования */
function CMML_ACT_BY_EQCONFIG
(
NEQCONFIG in number -- Рег. номер позиции состава оборудования
) return number; -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
/* Список моделей по единице оборудования */
function CMML_LIST_BY_EQCONFIG
(
NEQCONFIG in number -- Рег. номер позиции состава оборудования
) return varchar2; -- Список моделей с системным разделителем по умолчанию
end UDO_PKG_EQUIPDS;
/
create or replace package body UDO_PKG_EQUIPDS as
/* Код доступного действия с моделью по единице оборудования */
function CMML_ACT_BY_EQCONFIG
(
NEQCONFIG in number -- Рег. номер позиции состава оборудования
) return number -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
is
begin
return 2;
end CMML_ACT_BY_EQCONFIG;
/* Список моделей по единице оборудования */
function CMML_LIST_BY_EQCONFIG
(
NEQCONFIG in number -- Рег. номер позиции состава оборудования
) return varchar2 -- Список моделей с системным разделителем по умолчанию
is
begin
return 'TCF;RUL;FP';
end CMML_LIST_BY_EQCONFIG;
end UDO_PKG_EQUIPDS;
/

View File

@ -3,14 +3,23 @@ create or replace package UDO_PKG_EQUIPTCF as
/* Формирование дерева состава оборудования */
procedure EQCONFIG_HIER
(
NPEQCONFIG in number, -- Рег. номер родительского узла состава оборудования
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
COUT out clob -- Сериализованное XML-представление дерева
);
/* Условия отбора технических объектов */
procedure EQCONFIG_THOBJ_LIST_COND;
/* Формирование списка технических объектов для выбранного узла состава оборудования */
procedure EQCONFIG_THOBJ_DG
procedure EQCONFIG_THOBJ_LIST
(
NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CFILTERS in clob, -- Фильтры
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
end UDO_PKG_EQUIPTCF;
@ -22,7 +31,7 @@ create or replace package body UDO_PKG_EQUIPTCF as
(
NCUR in integer, -- Курсор документа для результата
NCOMPANY in number, -- Рег. номер организации
NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования
NEQPARENT in number -- Рег. номер родительского узла состава оборудования
) return PKG_XMAKE.TNODE -- XML-описание веток дерева
is
XLEAF PKG_XMAKE.TNODE; -- Текущий лист
@ -48,8 +57,9 @@ create or replace package body UDO_PKG_EQUIPTCF as
where M.PR_OBJ_LEVEL = OL.RN(+)
and ((M.FICT_REC = 0) or ((M.FICT_REC = 1) and (CMP_VC2(M.NAME, F_EQCONFIG_EXTRANAME(0)) = 1)))
and exists (select null from V_USERPRIV_HIER_SINGL UP where UP.HIERARCHY = M.RN)
and COALESCE(M.EQPARENT, 0) = NPEQCONFIG
and M.COMPANY = NCOMPANY)
and COALESCE(M.EQPARENT, 0) = NEQPARENT
and M.COMPANY = NCOMPANY
order by 3)
loop
/* Если есть дочерние ветки */
if (C.NHASCHILDREN = 1) then
@ -88,7 +98,7 @@ create or replace package body UDO_PKG_EQUIPTCF as
/* Формирование дерева состава оборудования */
procedure EQCONFIG_HIER
(
NPEQCONFIG in number, -- Рег. номер родительского узла состава оборудования
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
COUT out clob -- Сериализованное XML-представление дерева
)
is
@ -101,7 +111,7 @@ create or replace package body UDO_PKG_EQUIPTCF as
/* Формируем XML-представление ветки для запрошенного родителя */
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'XDATA',
RNODE00 => EQCONFIG_HIER_NODE(NCUR => NCUR, NCOMPANY => NCOMPANY, NPEQCONFIG => NPEQCONFIG));
RNODE00 => EQCONFIG_HIER_NODE(NCUR => NCUR, NCOMPANY => NCOMPANY, NEQPARENT => NEQPARENT));
/* Конвертируем в CLOB */
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
ITYPE => PKG_XMAKE.CONTENT_,
@ -113,15 +123,199 @@ create or replace package body UDO_PKG_EQUIPTCF as
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
end EQCONFIG_HIER;
/* Формирование списка технических объектов для выбранного узла состава оборудования */
procedure EQCONFIG_THOBJ_DG
(
NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования
)
/* Условия отбора технических объектов */
procedure EQCONFIG_THOBJ_LIST_COND
is
begin
/* Установка главной таблицы */
PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'EQCONFIG');
/* Обозначение */
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', SCONDITION_NAME => 'SCODEFrom');
/* Наименование */
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME', SCONDITION_NAME => 'SNAMEFrom');
/* Дата ввода в эксплуатацию */
PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'OPER_DATE',
SCONDITION_NAME_FROM => 'DOPER_DATEFrom',
SCONDITION_NAME_TO => 'DOPER_DATETo');
end EQCONFIG_THOBJ_LIST_COND;
/* Формирование списка технических объектов для выбранного узла состава оборудования */
procedure EQCONFIG_THOBJ_LIST
(
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CFILTERS in clob, -- Фильтры
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора
RF PKG_P8PANELS_VISUAL.TFILTERS; -- Фильтры
RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
begin
/* Читаем фильтры */
RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS);
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCODE',
SCAPTION => 'Обозначение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME',
SCAPTION => 'Наименование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DOPER_DATE',
SCAPTION => 'Дата ввода в эксплуатацию',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SUSE_KIND',
SCAPTION => 'Состояние',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NOBJ_KIND',
SCAPTION => 'Рег. номер класса технического объекта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SOBJ_KIND',
SCAPTION => 'Класс',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEQUIPDSCMML',
SCAPTION => 'Модели прогнозирования',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NEQUIPDSCMML_ACTION',
SCAPTION => 'Действия с моделью',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select C.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.CODE SCODE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C."NAME" SNAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OPER_DATE DOPER_DATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.CODE SUSE_KIND,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OBJ_KIND NOBJ_KIND,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' OK.CODE SOBJ_KIND,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_LIST_BY_EQCONFIG') || '(C.RN) SEQUIPDSCMML,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_ACT_BY_EQCONFIG') || '(C.RN) NEQUIPDSCMML_ACTION');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from EQCONFIG C');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join EQOBJKIND OK on C.OBJ_KIND = OK.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join HLSTATETYPES ST on C.HLSTATETYPES = ST.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where C.EQPARENT = :NEQPARENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL);
/* Учтём фильтры */
PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT,
NCOMPANY => NCOMPANY,
SUNIT => 'EquipConfiguration',
SPROCEDURE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_LIST_COND'),
RDATA_GRID => RDG,
RFILTERS => RF);
/* Разбираем его */
ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT');
PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL);
/* Делаем подстановку параметров */
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NEQPARENT', NVALUE => NEQPARENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO);
/* Описываем структуру записи курсора */
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 4);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 7);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 8);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
/* Делаем выборку */
if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
null;
end EQCONFIG_THOBJ_DG;
end if;
/* Обходим выбранные записи */
while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
loop
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DOPER_DATE',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SUSE_KIND',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NOBJ_KIND',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SOBJ_KIND',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SEQUIPDSCMML',
ICURSOR => ICURSOR,
NPOSITION => 8);
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NEQUIPDSCMML_ACTION',
ICURSOR => ICURSOR,
NPOSITION => 9);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end EQCONFIG_THOBJ_LIST;
end UDO_PKG_EQUIPTCF;
/

View File

@ -10,7 +10,9 @@
import React, { useState } from "react"; //Классы React
import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты
import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; //Дерево
import { useEqConfigTree, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки
import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { useEqConfigTree, useEqConfigTechObjTable, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки
//---------
//Константы
@ -22,6 +24,9 @@ const APP_BAR_HEIGHT = "64px";
//Высота закладок
const TABS_HEIGHT = "49px";
//Высота кнопки "Ещё"
const TABLE_MORE_HEIGHT = "47px";
//Стили
const STYLES = {
LEFT_SIDE_GRID: { backgroundColor: "red" },
@ -34,9 +39,13 @@ const STYLES = {
overflowY: "auto",
scrollbarWidth: "thin",
scrollbarColor: "red blue"
}
},
TECH_OBJ_TABLE: { height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${TABLE_MORE_HEIGHT})` }
};
//Начальное состояние спецификации техничких объектов
const TECH_OBJ_SPEC_INIT = { parent: null, filters: null, orders: null, pageNumber: 1 };
//-----------
//Тело модуля
//-----------
@ -46,15 +55,35 @@ const ForecastTab = () => {
//Собственное состояние - текущая загружаемая ветка
const [loadingTreeItem, setLoadingTreeItem] = useState(0);
//Собственное состояние - спецификация технических объектов
const [techObjSpec, setTechObjSpec] = useState({ ...TECH_OBJ_SPEC_INIT });
//Загрузчик веток дерева
const { tree } = useEqConfigTree(loadingTreeItem);
//Загрузчик технических объектов для выбранной ветки
const { techObjsDataGrid, techObjsDataGridIsLoading } = useEqConfigTechObjTable(
techObjSpec.parent,
techObjSpec.filters,
techObjSpec.orders,
techObjSpec.pageNumber
);
//Обработка развёртывания/свёртывания уровня дерева
const handleTreeItemExpansionToggle = (event, itemId, isExpanded) =>
isExpanded && needLoadLevel(tree, itemId) ? setLoadingTreeItem(parseInt(itemId)) : null;
//Обработка фокусировки на элементе дерева
const handleTreeItemFocus = (event, itemId, isExpanded) => console.log(event, itemId, isExpanded);
const handleTreeItemFocus = (event, itemId) => setTechObjSpec({ ...TECH_OBJ_SPEC_INIT, parent: parseInt(itemId) });
//При изменении состояния фильтров спецификации технических объектов
const handleTechObjSpecFilterChanged = ({ filters }) => setTechObjSpec(pv => ({ ...pv, filters: [...filters], pageNumber: 1 }));
//При изменении состояния сортировки спецификации технических объектов
const handleTechObjSpecOrderChanged = ({ orders }) => setTechObjSpec(pv => ({ ...pv, orders: [...orders], pageNumber: 1 }));
//При изменении количества отображаемых страниц спецификации технических объектов
const handleTechObjSpecPagesCountChanged = () => setTechObjSpec(pv => ({ ...pv, pageNumber: pv.pageNumber + 1 }));
//Генерация содержимого
return (
@ -66,7 +95,27 @@ const ForecastTab = () => {
</Box>
</Grid>
<Grid item xs={8} sx={STYLES.RIGHT_SIDE_GRID}>
ОБОРУДОВАНИЕ
{techObjsDataGrid.init ? (
<P8PDataGrid
{...{
...P8P_DATA_GRID_CONFIG_PROPS,
noDataFoundText:
techObjsDataGridIsLoading || !techObjsDataGrid.init
? "Минуточку..."
: "Выбранный уровень структуры не содержит данных о технических объектах"
}}
containerComponentProps={{ sx: STYLES.TECH_OBJ_TABLE, elevation: 0 }}
columnsDef={techObjsDataGrid.columnsDef}
rows={techObjsDataGrid.rows}
size={P8P_DATA_GRID_SIZE.SMALL}
morePages={techObjsDataGrid.morePages}
fixedHeader={true}
reloading={false}
onFilterChanged={handleTechObjSpecFilterChanged}
onOrderChanged={handleTechObjSpecOrderChanged}
onPagesCountChanged={handleTechObjSpecPagesCountChanged}
/>
) : null}
</Grid>
</Grid>
</div>

View File

@ -9,35 +9,40 @@
import { useState, useEffect, useContext } from "react"; //Классы React
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { deepCopyObject } from "../../core/utils"; //Утилиты
import { deepCopyObject, object2Base64XML } from "../../core/utils"; //Вспомогательные функции
//---------
//Константы
//---------
//Размер страницы данных
const DATA_GRID_PAGE_SIZE = 5;
//-----------------------
//Вспомогательные функции
//-----------------------
//Поиск элемента в дереве
const findTreeItem = (tree, id) => {
for (let i = 0; i < tree.length; i++) {
if (tree[i].id == id) return tree[i];
if (Array.isArray(tree[i].children)) {
let childRes = findTreeItem(tree[i].children, id);
if (childRes) return childRes;
}
}
};
//Проверка необходимости загрузки уровня для указанного родителя
const needLoadLevel = (tree, parent) => {
let res = false;
tree.forEach(treeItem => {
if (treeItem.id == parent) {
if (treeItem.children && treeItem.children.length == 1 && treeItem.children[0].id.endsWith("loader")) res = true;
}
if (treeItem.children && treeItem.children.length > 0 && !treeItem.children[0].id.endsWith("loader"))
res = needLoadLevel(treeItem.children, parent);
});
return res;
let item = findTreeItem(tree, parent);
return !item ? false : item.children && item.children.length == 1 && item.children[0].id.endsWith("loader") ? true : false;
};
//Встраивание уровня в указанного родителя
const appendLevel = (tree, parent, children) => {
tree.forEach(treeItem => {
if (treeItem.id == parent) {
treeItem.children = children;
return;
}
if (treeItem.children && treeItem.children.length > 0 && !treeItem.children[0].id.endsWith("loader"))
appendLevel(treeItem.children, parent, children);
});
let item = findTreeItem(tree, parent);
if (item) item.children = children;
};
//-----------
@ -63,7 +68,7 @@ const useEqConfigTree = parent => {
const data = await executeStored({
stored: "UDO_PKG_EQUIPTCF.EQCONFIG_HIER",
args: {
NPEQCONFIG: parent
NEQPARENT: parent
},
respArg: "COUT",
isArray: name => ["children"].includes(name),
@ -89,8 +94,60 @@ const useEqConfigTree = parent => {
return { tree, isLoading };
};
//Загрузка списка технических объектов
const useEqConfigTechObjTable = (parent, filters, orders, pageNumber) => {
//Собственное состояние - флаг загрузки
const [isLoading, setLoading] = useState(false);
//Собственное состояние - таблица данных
const [data, setData] = useState({
init: false,
columnsDef: [],
rows: [],
morePages: true
});
//Подключение к контексту взаимодействия с сервером
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
//Загрузка данных при изменении зависимостей
useEffect(() => {
const loadData = async () => {
try {
setLoading(true);
const data = await executeStored({
stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_LIST",
args: {
NEQPARENT: parent,
CFILTERS: { VALUE: object2Base64XML(filters, { arrayNodeName: "filters" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
CORDERS: { VALUE: object2Base64XML(orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
NPAGE_NUMBER: pageNumber,
NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
NINCLUDE_DEF: pageNumber == 1 ? 1 : 0
},
respArg: "COUT",
loader: false
});
setData(pv => ({
...pv,
columnsDef: data.XCOLUMNS_DEF ? [...data.XCOLUMNS_DEF] : pv.columnsDef,
rows: pageNumber == 1 ? [...(data.XROWS || [])] : [...pv.rows, ...(data.XROWS || [])],
morePages: DATA_GRID_PAGE_SIZE == 0 ? false : (data.XROWS || []).length >= DATA_GRID_PAGE_SIZE,
init: true
}));
} finally {
setLoading(false);
}
};
if (parent) loadData();
}, [parent, filters, orders, pageNumber, executeStored, SERV_DATA_TYPE_CLOB]);
//Вернём данные
return { techObjsDataGrid: data, techObjsDataGridIsLoading: isLoading };
};
//----------------
//Интерфейс модуля
//----------------
export { useEqConfigTree, needLoadLevel };
export { useEqConfigTree, useEqConfigTechObjTable, needLoadLevel };