Закладка "Обучение" - списки выборок и классов, карточка класса (начало)
This commit is contained in:
parent
ef520e0932
commit
2da1772489
@ -1,5 +1,32 @@
|
||||
create or replace package UDO_PKG_EQUIPDS as
|
||||
|
||||
/* Список выборок данных */
|
||||
procedure LIST
|
||||
(
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
);
|
||||
|
||||
/* Список классов оборудования выборки данных */
|
||||
procedure CM_LIST
|
||||
(
|
||||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
);
|
||||
|
||||
/* Список файлов данных класса оборудования */
|
||||
procedure CMFL_LIST
|
||||
(
|
||||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
);
|
||||
|
||||
/* Список моделей класса оборудования */
|
||||
procedure CMML_LIST
|
||||
(
|
||||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
);
|
||||
|
||||
/* Код доступного действия с моделью по единице оборудования */
|
||||
function CMML_ACT_BY_EQCONFIG
|
||||
(
|
||||
@ -16,6 +43,222 @@ end UDO_PKG_EQUIPDS;
|
||||
/
|
||||
create or replace package body UDO_PKG_EQUIPDS as
|
||||
|
||||
/* Список выборок данных */
|
||||
procedure LIST
|
||||
(
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
)
|
||||
is
|
||||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
|
||||
NCUR integer; -- Курсор документа для результата
|
||||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||||
XDS PKG_XMAKE.TNODE; -- Элемент для выборки данных
|
||||
begin
|
||||
/* Открываем документ */
|
||||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||||
/* Обходим выборки данных */
|
||||
for C in (select T.RN NRN,
|
||||
T.NAME SNAME
|
||||
from UDO_T_EQUIPDS T
|
||||
where T.COMPANY = NCOMPANY
|
||||
order by T.NAME)
|
||||
loop
|
||||
XDS := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||
RNODE00 => XDS,
|
||||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||
SNAME => 'XDS',
|
||||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'NRN',
|
||||
SVALUE => C.NRN),
|
||||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'SNAME',
|
||||
SVALUE => C.SNAME))));
|
||||
end loop;
|
||||
/* Формируем XML-представление ответа */
|
||||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XDS);
|
||||
/* Конвертируем в CLOB */
|
||||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||||
ITYPE => PKG_XMAKE.CONTENT_,
|
||||
RNODE => XDOC,
|
||||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||||
/* Закрываем документ */
|
||||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||||
end LIST;
|
||||
|
||||
/* Список классов оборудования выборки данных */
|
||||
procedure CM_LIST
|
||||
(
|
||||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
)
|
||||
is
|
||||
NCUR integer; -- Курсор документа для результата
|
||||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||||
XDSCM PKG_XMAKE.TNODE; -- Элемент для выборки данных
|
||||
begin
|
||||
/* Открываем документ */
|
||||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||||
/* Обходим классы оборудования заданной выборки данных */
|
||||
for C in (select T.RN NRN,
|
||||
OK.CODE SCODE,
|
||||
OK.NAME SNAME
|
||||
from UDO_T_EQUIPDSCM T,
|
||||
EQOBJKIND OK
|
||||
where T.PRN = NEQUIPDS
|
||||
and T.EQOBJKIND = OK.RN
|
||||
order by OK.CODE)
|
||||
loop
|
||||
XDSCM := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||
RNODE00 => XDSCM,
|
||||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||
SNAME => 'XDSCM',
|
||||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'NRN',
|
||||
SVALUE => C.NRN),
|
||||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'SCODE',
|
||||
SVALUE => C.SCODE),
|
||||
RATTRIBUTE02 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'SNAME',
|
||||
SVALUE => C.SNAME))));
|
||||
end loop;
|
||||
/* Формируем XML-представление ответа */
|
||||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XDSCM);
|
||||
/* Конвертируем в CLOB */
|
||||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||||
ITYPE => PKG_XMAKE.CONTENT_,
|
||||
RNODE => XDOC,
|
||||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||||
/* Закрываем документ */
|
||||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||||
end CM_LIST;
|
||||
|
||||
/* Список файлов данных класса оборудования */
|
||||
procedure CMFL_LIST
|
||||
(
|
||||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
)
|
||||
is
|
||||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||||
begin
|
||||
/* Инициализируем таблицу данных */
|
||||
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 => 'SFILE_NAME',
|
||||
SCAPTION => 'Имя',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SDESCR',
|
||||
SCAPTION => 'Описание',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NSTATUS',
|
||||
SCAPTION => 'Состояние',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SERR',
|
||||
SCAPTION => 'Сообщение об ошибке',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
/* Обходим данные */
|
||||
for C in (select T.RN NRN,
|
||||
T.FILE_NAME SFILE_NAME,
|
||||
T.DESCR SDESCR,
|
||||
T.STATUS NSTATUS,
|
||||
T.ERR SERR
|
||||
from UDO_T_EQUIPDSCMFL T
|
||||
where T.PRN = NEQUIPDSCM
|
||||
order by T.RN)
|
||||
loop
|
||||
/* Добавляем колонки с данными */
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SFILE_NAME', SVALUE => C.SFILE_NAME);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SDESCR', SVALUE => C.SDESCR);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSTATUS', NVALUE => C.NSTATUS);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SERR', SVALUE => C.SERR);
|
||||
/* Добавляем строку в таблицу */
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||||
end loop;
|
||||
/* Сериализуем описание */
|
||||
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
||||
end CMFL_LIST;
|
||||
|
||||
/* Список моделей класса оборудования */
|
||||
procedure CMML_LIST
|
||||
(
|
||||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
)
|
||||
is
|
||||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||||
begin
|
||||
/* Инициализируем таблицу данных */
|
||||
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 => 'STASK',
|
||||
SCAPTION => 'Задача',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NPRECISION_P',
|
||||
SCAPTION => 'Точность (план)',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NPRECISION_F',
|
||||
SCAPTION => 'Точность (факт)',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NSTATUS',
|
||||
SCAPTION => 'Состояние',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SERR',
|
||||
SCAPTION => 'Сообщение об ошибке',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
/* Обходим данные */
|
||||
for C in (select T.RN NRN,
|
||||
T.TASK STASK,
|
||||
T.PRECISION_P NPRECISION_P,
|
||||
T.PRECISION_F NPRECISION_F,
|
||||
T.STATUS NSTATUS,
|
||||
T.ERR SERR
|
||||
from UDO_T_EQUIPDSCMML T
|
||||
where T.PRN = NEQUIPDSCM
|
||||
order by T.RN)
|
||||
loop
|
||||
/* Добавляем колонки с данными */
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'STASK', SVALUE => C.STASK);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPRECISION_P', NVALUE => C.NPRECISION_P);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPRECISION_F', NVALUE => C.NPRECISION_F);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSTATUS', NVALUE => C.NSTATUS);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SERR', SVALUE => C.SERR);
|
||||
/* Добавляем строку в таблицу */
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||||
end loop;
|
||||
/* Сериализуем описание */
|
||||
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
||||
end CMML_LIST;
|
||||
|
||||
/* Код доступного действия с моделью по единице оборудования */
|
||||
function CMML_ACT_BY_EQCONFIG
|
||||
(
|
||||
|
@ -7,8 +7,26 @@
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import { Grid } from "@mui/material"; //Интерфейсные компоненты
|
||||
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 {
|
||||
DS_RN_DEFAULT,
|
||||
useEquipDataSelectionList,
|
||||
useEquipDataSelectionClassMachineList,
|
||||
useEquipDataSelectionClassMachineFilesList,
|
||||
useEquipDataSelectionClassMachineModelsList
|
||||
} from "./admin_tab_hooks"; //Вспомогательные хуки
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
DATA_SELECTION_STACK: { alignItems: "center" },
|
||||
CLASS_MACHINE_ADD_BUTTON: { margin: "5px" }
|
||||
};
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
@ -16,15 +34,70 @@ import { Grid } from "@mui/material"; //Интерфейсные компоне
|
||||
|
||||
//Закладка администрирования
|
||||
const AdminTab = () => {
|
||||
//Собственное состояние - выбранная выборка данных
|
||||
const [equipDataSelection, setDataSelection] = useState(DS_RN_DEFAULT);
|
||||
|
||||
//Собственное состояние - выбранный класс оборудования
|
||||
const [equipDataSelectionClassMachine, setDataSelectionClassMachine] = useState(null);
|
||||
|
||||
//Загрузка списка выборок данных
|
||||
const { equipDataSelectionList } = useEquipDataSelectionList();
|
||||
|
||||
//Загрузка классов оборудования выбранной выборки данных
|
||||
const { equipDataSelectionClassMachineList } = useEquipDataSelectionClassMachineList(equipDataSelection);
|
||||
|
||||
//Загрузка файлов класса оборудования
|
||||
const { equipDataSelectionClassMachineFilesList } = useEquipDataSelectionClassMachineFilesList(equipDataSelectionClassMachine);
|
||||
|
||||
//Загрузка файлов класса оборудования
|
||||
const { equipDataSelectionClassMachineModelsList } = useEquipDataSelectionClassMachineModelsList(equipDataSelectionClassMachine);
|
||||
|
||||
//При подключении компонента к странице
|
||||
useEffect(() => {}, []);
|
||||
|
||||
//При смене выборки данных
|
||||
const handleDataSelectionChange = value => {
|
||||
setDataSelectionClassMachine(null);
|
||||
setDataSelection(value);
|
||||
};
|
||||
|
||||
//При нажатии на класс оборудования
|
||||
const handleDataSelectionClassMachineClick = value => setDataSelectionClassMachine(value);
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<div>
|
||||
<Box>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={{ backgroundColor: "magenta" }}>
|
||||
Здесь только администраторы могут работать
|
||||
<Grid item xs={12}>
|
||||
<Stack direction="row" spacing={2} p={2} sx={STYLES.DATA_SELECTION_STACK}>
|
||||
<EquipDataSelectionList list={equipDataSelectionList} value={equipDataSelection} onChange={handleDataSelectionChange} />
|
||||
<Button variant="contained" startIcon={<Icon>add</Icon>}>
|
||||
Добавить выборку
|
||||
</Button>
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container>
|
||||
<Grid item xs={2} hidden={equipDataSelection == DS_RN_DEFAULT}>
|
||||
<Button fullWidth startIcon={<Icon>add</Icon>} sx={STYLES.CLASS_MACHINE_ADD_BUTTON}>
|
||||
Добавить класс
|
||||
</Button>
|
||||
<EquipDataSelectionClassMachineList
|
||||
list={equipDataSelectionClassMachineList}
|
||||
value={equipDataSelectionClassMachine}
|
||||
onClick={handleDataSelectionClassMachineClick}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={10} hidden={equipDataSelectionClassMachine == null}>
|
||||
<EquipDataSelectionClassMachineCard
|
||||
filesList={equipDataSelectionClassMachineFilesList}
|
||||
modelsList={equipDataSelectionClassMachineModelsList}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
196
panels/eqs_tech_cond_forecast/admin_tab_hooks.js
Normal file
196
panels/eqs_tech_cond_forecast/admin_tab_hooks.js
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
|
||||
Закладка администрирования: кастомные хуки
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import { useState, useEffect, useContext } from "react"; //Классы React
|
||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Рег. номер выборки данных по умолчанию
|
||||
const DS_RN_DEFAULT = -1;
|
||||
|
||||
//Наименование выборки данных по умолчанию
|
||||
const DS_NAME_DEFAULT = "Не указана";
|
||||
|
||||
//Выборка данных по умолчанию
|
||||
const DS_DEFAULT = { NRN: DS_RN_DEFAULT, SNAME: DS_NAME_DEFAULT };
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Загрузка списка выборок данных
|
||||
const useEquipDataSelectionList = () => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
//Собственное состояние - данные
|
||||
const [data, setData] = useState([DS_DEFAULT]);
|
||||
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
const { executeStored } = useContext(BackEndСtx);
|
||||
|
||||
//Загрузка данных при изменении зависимостей
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.LIST",
|
||||
respArg: "COUT",
|
||||
isArray: name => ["XDS"].includes(name),
|
||||
loader: false
|
||||
});
|
||||
setData([DS_DEFAULT, ...(data?.XDS ? data.XDS : [])]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
loadData();
|
||||
}, [executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { equipDataSelectionList: data, equipDataSelectionListIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//Загрузка классов оборудования выбороки данных
|
||||
const useEquipDataSelectionClassMachineList = dataSelection => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
//Собственное состояние - данные
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
const { executeStored } = useContext(BackEndСtx);
|
||||
|
||||
//Загрузка данных при изменении зависимостейuse
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CM_LIST",
|
||||
args: { NEQUIPDS: dataSelection },
|
||||
respArg: "COUT",
|
||||
isArray: name => ["XDSCM"].includes(name),
|
||||
attributeValueProcessor: (name, val) => (["SCODE"].includes(name) ? undefined : val),
|
||||
loader: false
|
||||
});
|
||||
setData(data?.XDSCM || []);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
if (dataSelection && dataSelection != DS_RN_DEFAULT) loadData();
|
||||
}, [dataSelection, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { equipDataSelectionClassMachineList: data, equipDataSelectionClassMachineListIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//Загрузка списка файлов класса оборудования
|
||||
const useEquipDataSelectionClassMachineFilesList = classMachine => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
//Собственное состояние - таблица данных
|
||||
const [data, setData] = useState({
|
||||
init: false,
|
||||
columnsDef: [],
|
||||
rows: []
|
||||
});
|
||||
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
const { executeStored } = useContext(BackEndСtx);
|
||||
|
||||
//Загрузка данных при изменении зависимостей
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CMFL_LIST",
|
||||
args: { NEQUIPDSCM: classMachine },
|
||||
respArg: "COUT",
|
||||
loader: false
|
||||
});
|
||||
setData(pv => ({
|
||||
...pv,
|
||||
columnsDef: [...data.XCOLUMNS_DEF],
|
||||
rows: [...(data.XROWS || [])],
|
||||
init: true
|
||||
}));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
if (classMachine) loadData();
|
||||
}, [classMachine, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { equipDataSelectionClassMachineFilesList: data, equipDataSelectionClassMachineFilesListIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//Загрузка списка моделей класса оборудования
|
||||
const useEquipDataSelectionClassMachineModelsList = classMachine => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
//Собственное состояние - таблица данных
|
||||
const [data, setData] = useState({
|
||||
init: false,
|
||||
columnsDef: [],
|
||||
rows: []
|
||||
});
|
||||
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
const { executeStored } = useContext(BackEndСtx);
|
||||
|
||||
//Загрузка данных при изменении зависимостей
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CMML_LIST",
|
||||
args: { NEQUIPDSCM: classMachine },
|
||||
respArg: "COUT",
|
||||
loader: false
|
||||
});
|
||||
setData(pv => ({
|
||||
...pv,
|
||||
columnsDef: [...data.XCOLUMNS_DEF],
|
||||
rows: [...(data.XROWS || [])],
|
||||
init: true
|
||||
}));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
if (classMachine) loadData();
|
||||
}, [classMachine, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { equipDataSelectionClassMachineModelsList: data, equipDataSelectionClassMachineModelsListIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export {
|
||||
DS_RN_DEFAULT,
|
||||
useEquipDataSelectionList,
|
||||
useEquipDataSelectionClassMachineList,
|
||||
useEquipDataSelectionClassMachineFilesList,
|
||||
useEquipDataSelectionClassMachineModelsList
|
||||
};
|
206
panels/eqs_tech_cond_forecast/admin_tab_layout.js
Normal file
206
panels/eqs_tech_cond_forecast/admin_tab_layout.js
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
|
||||
Закладка администрирования: дополнительная разметка и вёрстка клиентских элементов
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import {
|
||||
Box,
|
||||
Stack,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
Select,
|
||||
MenuItem,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Card,
|
||||
CardContent,
|
||||
CardActions,
|
||||
Typography,
|
||||
Button
|
||||
} from "@mui/material"; //Интерфейсные компоненты
|
||||
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"; //Подключение компонентов к настройкам приложения
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Высота списка выборок данных
|
||||
const DS_SELECTOR_HEIGHT = "80px";
|
||||
|
||||
//Высота кнопки добавления технического объекта
|
||||
const CM_ADD_BTN_HEIGHT = "46.5px";
|
||||
|
||||
//Структура элемента списка выборок данных оборудования
|
||||
const EQUIP_DATA_SELECTION_LIST = PropTypes.shape({
|
||||
NRN: PropTypes.number.isRequired,
|
||||
SNAME: PropTypes.string.isRequired
|
||||
});
|
||||
|
||||
//Структура элемента списка классов оборудования выборки данных
|
||||
const EQUIP_DATA_SELECTION_CLASS_MACHINE_LIST = PropTypes.shape({
|
||||
NRN: PropTypes.number.isRequired,
|
||||
SCODE: PropTypes.string.isRequired,
|
||||
SNAME: PropTypes.string.isRequired
|
||||
});
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
EQUIP_DS_LIST_FORM_CONTROL: { minWidth: "300px" },
|
||||
EQUIP_DSCM_LIST: {
|
||||
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",
|
||||
...SCROLL_STYLES
|
||||
},
|
||||
EQUIP_DSCM_CARD: {
|
||||
minHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${DS_SELECTOR_HEIGHT})`,
|
||||
maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${DS_SELECTOR_HEIGHT})`,
|
||||
overflowY: "auto",
|
||||
...SCROLL_STYLES
|
||||
},
|
||||
FL_ML_TABLE: {
|
||||
height: `200px`,
|
||||
...SCROLL_STYLES
|
||||
}
|
||||
};
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Список выборок данных оборудования
|
||||
const EquipDataSelectionList = ({ list, value, onChange }) => {
|
||||
//При выборе элемента
|
||||
const handleChange = e => (onChange ? onChange(e.target.value) : null);
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<FormControl variant="standard" sx={STYLES.EQUIP_DS_LIST_FORM_CONTROL}>
|
||||
<InputLabel id="equipDSlabel">Выборка данных оборудования</InputLabel>
|
||||
<Select labelId="equipDSlabel" id="equipDS" label="Выборка данных оборудования" value={value} onChange={handleChange}>
|
||||
{list.map((item, i) => (
|
||||
<MenuItem key={i} value={item.NRN}>
|
||||
{item.SNAME}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств - Список выборок данных оборудования
|
||||
EquipDataSelectionList.propTypes = {
|
||||
list: PropTypes.arrayOf(EQUIP_DATA_SELECTION_LIST).isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
onChange: PropTypes.func
|
||||
};
|
||||
|
||||
//Список классов оборудования выборки данных
|
||||
const EquipDataSelectionClassMachineList = ({ list, value, onClick }) => {
|
||||
//При щелчке на элементе
|
||||
const handleClick = id => (onClick ? onClick(id) : null);
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<List sx={STYLES.EQUIP_DSCM_LIST}>
|
||||
{list.map((item, i) => (
|
||||
<ListItem disablePadding key={i}>
|
||||
<ListItemButton selected={value == item.NRN} onClick={() => handleClick(item.NRN)}>
|
||||
<ListItemText primary={item.SCODE} secondary={item.SNAME} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств - Список классов оборудования выборки данных
|
||||
EquipDataSelectionClassMachineList.propTypes = {
|
||||
list: PropTypes.arrayOf(EQUIP_DATA_SELECTION_CLASS_MACHINE_LIST).isRequired,
|
||||
value: PropTypes.number,
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
//Карточка класса оборудования выборки данных
|
||||
const EquipDataSelectionClassMachineCard = ({ filesList, modelsList }) => {
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Box p={2} sx={STYLES.EQUIP_DSCM_CARD}>
|
||||
<Stack spacing={2}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h5" component="div">
|
||||
Наименование технического объекта
|
||||
</Typography>
|
||||
<Typography sx={{ mb: 1.5 }} color="text.secondary">
|
||||
Состояние: готов к ...
|
||||
</Typography>
|
||||
<Typography variant="body2">фывафывафва</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button size="large">Сформировать</Button>
|
||||
<Button size="large">Передать данные</Button>
|
||||
<Button size="large">Обучить модель</Button>
|
||||
</CardActions>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h6" component="div">
|
||||
Файлы данных
|
||||
</Typography>
|
||||
<P8PDataGrid
|
||||
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
|
||||
containerComponentProps={{
|
||||
sx: STYLES.FL_ML_TABLE,
|
||||
elevation: 0
|
||||
}}
|
||||
columnsDef={filesList.columnsDef}
|
||||
rows={filesList.rows}
|
||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
||||
morePages={false}
|
||||
fixedHeader={true}
|
||||
reloading={false}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h6" component="div">
|
||||
Модели
|
||||
</Typography>
|
||||
<P8PDataGrid
|
||||
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
|
||||
containerComponentProps={{
|
||||
sx: STYLES.FL_ML_TABLE,
|
||||
elevation: 0
|
||||
}}
|
||||
columnsDef={modelsList.columnsDef}
|
||||
rows={modelsList.rows}
|
||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
||||
morePages={false}
|
||||
fixedHeader={true}
|
||||
reloading={false}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { EquipDataSelectionList, EquipDataSelectionClassMachineList, EquipDataSelectionClassMachineCard };
|
@ -7,8 +7,9 @@
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React, { useState, useEffect } from "react"; //Классы React
|
||||
import React, { useState } from "react"; //Классы React
|
||||
import { Box, Tabs, Tab } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { MODES, TabPanel } from "./eqs_tech_cond_forecast_lyaout"; //Вспомогательные компоненты и вёрстка
|
||||
import { AdminTab } from "./admin_tab"; //Интерфейс администрирования
|
||||
import { ForecastTab } from "./forecast_tab"; //Интерфейс прогнозирования
|
||||
|
||||
@ -16,23 +17,19 @@ import { ForecastTab } from "./forecast_tab"; //Интерфейс прогно
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Режимы работы панели
|
||||
const MODES = {
|
||||
FORECAST: 1,
|
||||
ADMIN: 2
|
||||
//Стили
|
||||
const STYLES = {
|
||||
TABS_CONTAINER_BOX: { borderBottom: 1, borderColor: "divider" }
|
||||
};
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Закладка
|
||||
const TapPanel = ({ children }) => <Box>{children}</Box>;
|
||||
|
||||
//Корневая панель прогнозирования технического состояния
|
||||
const EqsTechCondForecast = () => {
|
||||
//Собственное состояние
|
||||
const [mode, setMode] = useState(MODES.FORECAST);
|
||||
const [mode, setMode] = useState(MODES.ADMIN);
|
||||
|
||||
//При переключении закладки
|
||||
const handleTabChange = (e, newValue) => setMode(newValue);
|
||||
@ -40,22 +37,18 @@ const EqsTechCondForecast = () => {
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<>
|
||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
||||
<Box sx={STYLES.TABS_CONTAINER_BOX}>
|
||||
<Tabs value={mode} onChange={handleTabChange}>
|
||||
<Tab label="Прогноз" value={MODES.FORECAST} />
|
||||
<Tab label="Обучение" value={MODES.ADMIN} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
{mode == MODES.ADMIN ? (
|
||||
<TapPanel>
|
||||
<AdminTab />{" "}
|
||||
</TapPanel>
|
||||
) : null}
|
||||
{mode == MODES.FORECAST ? (
|
||||
<TapPanel>
|
||||
<TabPanel mode={mode} value={MODES.FORECAST}>
|
||||
<ForecastTab />
|
||||
</TapPanel>
|
||||
) : null}
|
||||
</TabPanel>
|
||||
<TabPanel mode={mode} value={MODES.ADMIN}>
|
||||
<AdminTab />
|
||||
</TabPanel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
|
||||
Корневая панель прогнозирования технического состояния: дополнительная разметка и вёрстка клиентских элементов
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Box } from "@mui/material"; //Интерфейсные компоненты
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Режимы работы панели
|
||||
const MODES = {
|
||||
FORECAST: 1,
|
||||
ADMIN: 2
|
||||
};
|
||||
|
||||
//Высота главного меню
|
||||
const APP_BAR_HEIGHT = "64px";
|
||||
|
||||
//Высота закладок
|
||||
const TABS_HEIGHT = "49px";
|
||||
|
||||
//Высота кнопки "Ещё"
|
||||
const TABLE_MORE_HEIGHT = "49px";
|
||||
|
||||
//Высота фильтров таблицы
|
||||
const TABLE_FILTERS_HEIGHT = "48px";
|
||||
|
||||
//Стиль скролов
|
||||
const SCROLL_STYLES = {
|
||||
"&::-webkit-scrollbar": {
|
||||
height: "8px",
|
||||
width: "8px"
|
||||
},
|
||||
"&::-webkit-scrollbar-track": {
|
||||
borderRadius: "8px",
|
||||
backgroundColor: "#EBEBEB"
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
borderRadius: "8px",
|
||||
backgroundColor: "#b4b4b4"
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb:hover": {
|
||||
backgroundColor: "#808080"
|
||||
}
|
||||
};
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Закладка
|
||||
const TabPanel = ({ mode, value, children }) => <Box hidden={mode != value}>{children}</Box>;
|
||||
|
||||
//Контроль свойств - Закладка
|
||||
TabPanel.propTypes = {
|
||||
mode: PropTypes.number.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
children: PropTypes.element
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { MODES, APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_MORE_HEIGHT, TABLE_FILTERS_HEIGHT, SCROLL_STYLES, TabPanel };
|
@ -13,25 +13,14 @@ import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; //Дерево
|
||||
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
|
||||
import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
|
||||
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
||||
import { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки
|
||||
import { APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_FILTERS_HEIGHT, TABLE_MORE_HEIGHT, SCROLL_STYLES } from "./eqs_tech_cond_forecast_lyaout"; //Общие Вспомогательные компоненты и вёрстка
|
||||
import { TechObjCard, eqConfigTechObjTableValueFormatter } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка
|
||||
import { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Высота главного меню
|
||||
const APP_BAR_HEIGHT = "64px";
|
||||
|
||||
//Высота закладок
|
||||
const TABS_HEIGHT = "49px";
|
||||
|
||||
//Высота кнопки "Ещё"
|
||||
const TABLE_MORE_HEIGHT = "49px";
|
||||
|
||||
//Высота фильтров таблицы
|
||||
const TABLE_FILTERS_HEIGHT = "48px";
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
LEFT_SIDE_GRID: {},
|
||||
@ -40,15 +29,15 @@ const STYLES = {
|
||||
minHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT})`,
|
||||
maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT})`,
|
||||
overflowX: "hidden",
|
||||
overflowY: "scroll",
|
||||
scrollbarWidth: "thin",
|
||||
padding: "3px"
|
||||
overflowY: "auto",
|
||||
padding: "3px",
|
||||
...SCROLL_STYLES
|
||||
},
|
||||
TECH_OBJ_TABLE: (morePages, filters) => ({
|
||||
height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${morePages ? TABLE_MORE_HEIGHT : "0px"} - ${
|
||||
filters ? TABLE_FILTERS_HEIGHT : "0px"
|
||||
})`,
|
||||
scrollbarWidth: "thin"
|
||||
...SCROLL_STYLES
|
||||
})
|
||||
};
|
||||
|
||||
@ -74,7 +63,7 @@ const ForecastTab = () => {
|
||||
const [techObjCardId, setTechObjCardId] = useState(null);
|
||||
|
||||
//Загрузчик веток дерева
|
||||
const { tree } = useEqConfigTree(loadingTreeItem);
|
||||
const { eQconfigTree } = useEqConfigTree(loadingTreeItem);
|
||||
|
||||
//Загрузчик технических объектов для выбранной ветки
|
||||
const { techObjsDataGrid, techObjsDataGridIsLoading } = useEqConfigTechObjTable(
|
||||
@ -89,11 +78,11 @@ const ForecastTab = () => {
|
||||
|
||||
//Обработка развёртывания/свёртывания уровня дерева
|
||||
const handleTreeItemExpansionToggle = (event, itemId, isExpanded) =>
|
||||
isExpanded && needLoadLevel(tree, itemId) ? setLoadingTreeItem(parseInt(itemId)) : null;
|
||||
isExpanded && needLoadLevel(eQconfigTree, itemId) ? setLoadingTreeItem(parseInt(itemId)) : null;
|
||||
|
||||
//Обработка фокусировки на элементе дерева
|
||||
const handleTreeItemFocus = (event, itemId) => {
|
||||
const item = findTreeItem(tree, itemId);
|
||||
const item = findTreeItem(eQconfigTree, itemId);
|
||||
if (item && item?.showCard) setTechObjCardId(parseInt(itemId));
|
||||
else {
|
||||
setTechObjCardId(null);
|
||||
@ -124,7 +113,7 @@ const ForecastTab = () => {
|
||||
<Grid container>
|
||||
<Grid item xs={3} sx={STYLES.LEFT_SIDE_GRID}>
|
||||
<Box sx={STYLES.TREE_BOX}>
|
||||
<RichTreeView items={tree} onItemExpansionToggle={handleTreeItemExpansionToggle} onItemFocus={handleTreeItemFocus} />
|
||||
<RichTreeView items={eQconfigTree} onItemExpansionToggle={handleTreeItemExpansionToggle} onItemFocus={handleTreeItemFocus} />
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={9} sx={STYLES.RIGHT_SIDE_GRID}>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
|
||||
Кастомные хуки закладки Прогнозирования
|
||||
Закладка прогнозирования: кастомные хуки
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
@ -91,7 +91,7 @@ const useEqConfigTree = parent => {
|
||||
}, [parent, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { tree, isLoading };
|
||||
return { eQconfigTree: tree, eQconfigTreeIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//Загрузка списка технических объектов
|
||||
@ -151,7 +151,7 @@ const useEqConfigTechObjCard = id => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
//Собственное состояние - данные дерева
|
||||
//Собственное состояние - данные карточки
|
||||
const [card, setCard] = useState({});
|
||||
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
|
||||
Дополнительная разметка и вёрстка клиентских элементов
|
||||
Закладка прогнозирования: дополнительная разметка и вёрстка клиентских элементов
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
@ -12,6 +12,16 @@ import PropTypes from "prop-types"; //Контроль свойств компо
|
||||
import { Box, Card, CardContent, Typography, CardActions, Button } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { formatDateRF } from "../../core/utils"; //Вспомогательные функции
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
TECH_OBJ_CARD_TITLE: { fontSize: 14 },
|
||||
TECH_OBJ_CARD_SUB_TITLE: { mb: 1.5 }
|
||||
};
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
@ -20,16 +30,16 @@ import { formatDateRF } from "../../core/utils"; //Вспомогательны
|
||||
const TechObjCard = ({ cardData }) => {
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Box p={3}>
|
||||
<Box p={2}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography sx={{ fontSize: 14 }} color="text.secondary" gutterBottom>
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_TITLE} color="text.secondary" gutterBottom>
|
||||
Технический объект
|
||||
</Typography>
|
||||
<Typography variant="h5" component="div">
|
||||
{cardData.SCODE}
|
||||
</Typography>
|
||||
<Typography sx={{ mb: 1.5 }} color="text.secondary">
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_SUB_TITLE} color="text.secondary">
|
||||
{cardData.DOPER_DATE}
|
||||
</Typography>
|
||||
<Typography variant="body2">{cardData.SNAME}</Typography>
|
||||
|
Loading…
x
Reference in New Issue
Block a user