Действия с моделями в карточке класса выборки данных, карточка технического объекта
This commit is contained in:
parent
1cb78fc446
commit
f7c0dd0e10
@ -31,7 +31,7 @@ create or replace package UDO_PKG_EQUIPDS as
|
||||
procedure CM_LIST
|
||||
(
|
||||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
COUT out clob -- Сериализованный список
|
||||
);
|
||||
|
||||
/* Клиентское добавление "Выборки данных оборудования (классы оборудования)" */
|
||||
@ -102,17 +102,18 @@ create or replace package UDO_PKG_EQUIPDS as
|
||||
NEQUIPDSCMML in number -- Рег. номер модели класса оборудования выборки данных
|
||||
);
|
||||
|
||||
/* Код доступного действия с моделью по единице оборудования */
|
||||
function CMML_ACT_BY_EQCONFIG
|
||||
/* Состояние моделей по единице оборудования */
|
||||
function CMML_STATUS_BY_EQCONFIG
|
||||
(
|
||||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||||
) return number; -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
|
||||
) return number; -- Код действия с моделью (0 - нет моделей, 1 - есть модели в процессе обучения, 2 - есть обученные модели)
|
||||
|
||||
/* Список моделей по единице оборудования */
|
||||
function CMML_LIST_BY_EQCONFIG
|
||||
procedure CMML_LIST_BY_EQCONFIG
|
||||
(
|
||||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||||
) return varchar2; -- Список моделей с системным разделителем по умолчанию
|
||||
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
);
|
||||
|
||||
end UDO_PKG_EQUIPDS;
|
||||
/
|
||||
@ -273,7 +274,7 @@ text="Проверка прав доступа на работу с ""Выбор
|
||||
procedure CM_LIST
|
||||
(
|
||||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
COUT out clob -- Сериализованный список
|
||||
)
|
||||
is
|
||||
NCUR integer; -- Курсор документа для результата
|
||||
@ -493,7 +494,8 @@ text="Проверка прав доступа на работу с ""Выбор
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'STASK',
|
||||
SCAPTION => 'Задача',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||
SHINT => 'Алгоритм прогонозирования модели:<br>' || UDO_PKG_EQUIPDS_BASE.CMML_TASK_HINT());
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NPRECISION_P',
|
||||
SCAPTION => 'Точность (план)',
|
||||
@ -511,6 +513,10 @@ text="Проверка прав доступа на работу с ""Выбор
|
||||
SCAPTION => 'Сообщение об ошибке',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||
BVISIBLE => false);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SACTIONS',
|
||||
SCAPTION => 'Действия',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
/* Обходим данные */
|
||||
for C in (select T.RN NRN,
|
||||
T.TASK STASK,
|
||||
@ -529,6 +535,7 @@ text="Проверка прав доступа на работу с ""Выбор
|
||||
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.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SACTIONS');
|
||||
/* Добавляем строку в таблицу */
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||||
end loop;
|
||||
@ -585,24 +592,127 @@ text="Проверка прав доступа на работу с ""Выбор
|
||||
end loop;
|
||||
end CMML_SEND_RQ;
|
||||
|
||||
/* Код доступного действия с моделью по единице оборудования */
|
||||
function CMML_ACT_BY_EQCONFIG
|
||||
/* Состояние моделей по единице оборудования */
|
||||
function CMML_STATUS_BY_EQCONFIG
|
||||
(
|
||||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||||
) return number -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
|
||||
) return number -- Код действия с моделью (0 - нет моделей, 1 - есть модели в процессе обучения, 2 - есть обученные модели)
|
||||
is
|
||||
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
||||
begin
|
||||
return 2;
|
||||
end CMML_ACT_BY_EQCONFIG;
|
||||
/* По умолчанию - моделей нет */
|
||||
NRES := 0;
|
||||
/* Обходим модели */
|
||||
for C in (select ML.STATUS
|
||||
from UDO_T_EQUIPDSCM CM,
|
||||
UDO_T_EQUIPDSCMML ML
|
||||
where CM.EQOBJKIND = (select CF.OBJ_KIND from EQCONFIG CF where CF.RN = NEQCONFIG)
|
||||
and CM.RN = ML.PRN)
|
||||
loop
|
||||
/* Модель есть */
|
||||
NRES := 1;
|
||||
/* Если она уже обучена */
|
||||
if (C.STATUS = 2) then
|
||||
NRES := 2;
|
||||
end if;
|
||||
end loop;
|
||||
/* Возвращаем результат */
|
||||
return NRES;
|
||||
end CMML_STATUS_BY_EQCONFIG;
|
||||
|
||||
/* Список моделей по единице оборудования */
|
||||
function CMML_LIST_BY_EQCONFIG
|
||||
procedure CMML_LIST_BY_EQCONFIG
|
||||
(
|
||||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||||
) return varchar2 -- Список моделей с системным разделителем по умолчанию
|
||||
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
|
||||
COUT out clob -- Сериализованная таблица данных
|
||||
)
|
||||
is
|
||||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||||
begin
|
||||
return 'TCF;RUL;FP';
|
||||
/* Инициализируем таблицу данных */
|
||||
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 => 'NEQUIPDS',
|
||||
SCAPTION => 'Рег. номер выборки',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||||
BVISIBLE => false);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NEQUIPDSCM',
|
||||
SCAPTION => 'Рег. номер класса оборудования выборки',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||||
BVISIBLE => false);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SNEQUIPDS',
|
||||
SCAPTION => 'Выборка',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'STASK',
|
||||
SCAPTION => 'Задача',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||
SHINT => 'Алгоритм прогонозирования модели:<br>' ||
|
||||
UDO_PKG_EQUIPDS_BASE.CMML_TASK_HINT());
|
||||
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,
|
||||
BVISIBLE => false);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SACTIONS',
|
||||
SCAPTION => 'Действия',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||||
/* Обходим данные */
|
||||
for C in (select T.RN NRN,
|
||||
CM.PRN NEQUIPDS,
|
||||
T.PRN NEQUIPDSCM,
|
||||
DS.NAME SNEQUIPDS,
|
||||
T.TASK STASK,
|
||||
T.PRECISION_P NPRECISION_P,
|
||||
T.PRECISION_F NPRECISION_F,
|
||||
T.STATUS NSTATUS,
|
||||
T.ERR SERR
|
||||
from UDO_T_EQUIPDSCMML T,
|
||||
UDO_T_EQUIPDSCM CM,
|
||||
UDO_T_EQUIPDS DS
|
||||
where T.PRN = CM.RN
|
||||
and CM.PRN = DS.RN
|
||||
and CM.EQOBJKIND = (select CF.OBJ_KIND from EQCONFIG CF where CF.RN = NEQCONFIG)
|
||||
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 => 'NEQUIPDS', NVALUE => C.NEQUIPDS);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NEQUIPDSCM', NVALUE => C.NEQUIPDSCM);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNEQUIPDS', SVALUE => C.SNEQUIPDS);
|
||||
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.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SACTIONS');
|
||||
/* Добавляем строку в таблицу */
|
||||
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_BY_EQCONFIG;
|
||||
|
||||
end UDO_PKG_EQUIPDS;
|
||||
|
@ -143,6 +143,10 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
|
||||
SERR in varchar2 -- Сообщение об ошибке
|
||||
);
|
||||
|
||||
/* Формирование подсказки для задачи "Выборки данных оборудования (классы оборудования, модели)" */
|
||||
function CMML_TASK_HINT
|
||||
return varchar2; -- Подсказка для задачи
|
||||
|
||||
end UDO_PKG_EQUIPDS_BASE;
|
||||
/
|
||||
create or replace package body UDO_PKG_EQUIPDS_BASE as
|
||||
@ -456,5 +460,13 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
|
||||
where T.RN = NRN;
|
||||
end CMML_SET_STATUS;
|
||||
|
||||
/* Формирование подсказки для задачи "Выборки данных оборудования (классы оборудования, модели)" */
|
||||
function CMML_TASK_HINT
|
||||
return varchar2 -- Подсказка для задачи
|
||||
is
|
||||
begin
|
||||
return '<b>TCF</b> - Оценка технического состояния (<b>T</b>echnical <b>C</b>ondition <b>F</b>orecast)<br>' || '<b>RUL</b> - Прогнозирование остаточного ресурса (<b>R</b>emaining <b>U</b>seful <b>L</b>ife)<br>' || '<b>FP</b> - Прогнозирование отказа (<b>F</b>ailure <b>P</b>redict)';
|
||||
end CMML_TASK_HINT;
|
||||
|
||||
end UDO_PKG_EQUIPDS_BASE;
|
||||
/
|
||||
|
@ -166,13 +166,12 @@ text="Проверка прав доступа при формировании
|
||||
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME',
|
||||
SCONDITION_NAME => 'SOBJ_KINDFrom',
|
||||
SJOINS => 'OBJ_KIND <- RN;EQOBJKIND');
|
||||
/* Модели прогнозирования */
|
||||
if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'SEQUIPDSCMMLFrom') = 1) then
|
||||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'UPPER(' ||
|
||||
PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_LIST_BY_EQCONFIG') ||
|
||||
'(RN)) like REPLACE(REPLACE(UPPER(:SEQUIPDSCMML), ''?'', ''_''), ''*'', ''%'')');
|
||||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'SEQUIPDSCMML',
|
||||
SVALUE => PKG_COND_BROKER.GET_CONDITION_STR(SCONDITION_NAME => 'SEQUIPDSCMMLFrom'));
|
||||
/* Действия с моделями прогнозирования */
|
||||
if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NCMML_STATUSFrom') = 1) then
|
||||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_STATUS_BY_EQCONFIG') ||
|
||||
'(RN) = :NCMML_STATUS');
|
||||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NCMML_STATUS',
|
||||
SVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NCMML_STATUSFrom'));
|
||||
end if;
|
||||
end EQCONFIG_THOBJ_LIST_COND;
|
||||
|
||||
@ -194,6 +193,7 @@ text="Проверка прав доступа при формировании
|
||||
RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки
|
||||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||||
RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов
|
||||
NROW_FROM PKG_STD.TREF; -- Номер строки с
|
||||
NROW_TO PKG_STD.TREF; -- Номер строки по
|
||||
CSQL clob; -- Буфер для запроса
|
||||
@ -251,21 +251,16 @@ text="Проверка прав доступа при формировании
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||
BORDER => true,
|
||||
BFILTER => true);
|
||||
PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
|
||||
PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
|
||||
PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'SEQUIPDSCMML',
|
||||
SCAPTION => 'Модели прогнозирования',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||
SHINT => '<b>Модели прогнозирования</b> - доступные для использования модели прогнозирования и задачи, ими решаемые:<br>' ||
|
||||
'<b>TCF</b> - Оценка технического состояния (<b>T</b>echnical <b>C</b>ondition <b>F</b>orecast)<br>' ||
|
||||
'<b>RUL</b> - Прогнозирование остаточного ресурса (<b>R</b>emaining <b>U</b>seful <b>L</b>ife)<br>' ||
|
||||
'<b>FP</b> - Прогнозирование отказа (<b>F</b>ailure <b>P</b>redict)',
|
||||
BORDER => true,
|
||||
BFILTER => true);
|
||||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||
SNAME => 'NEQUIPDSCMML_ACTION',
|
||||
SCAPTION => 'Действия с моделью',
|
||||
SNAME => 'NCMML_STATUS',
|
||||
SCAPTION => 'Модель',
|
||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||||
BVISIBLE => false);
|
||||
BORDER => true,
|
||||
BFILTER => true,
|
||||
RCOL_VALS => RCOL_VALS);
|
||||
/* Обходим данные */
|
||||
begin
|
||||
/* Добавляем подсказку совместимости */
|
||||
@ -281,8 +276,7 @@ text="Проверка прав доступа при формировании
|
||||
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.NAME 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 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_STATUS_BY_EQCONFIG') || '(C.RN) NCMML_STATUS');
|
||||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from EQCONFIG C');
|
||||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join HLSTATETYPES ST on C.HLSTATETYPES = ST.RN,');
|
||||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' EQOBJKIND OK');
|
||||
@ -315,9 +309,8 @@ text="Проверка прав доступа при формировании
|
||||
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 => 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;
|
||||
@ -349,14 +342,10 @@ text="Проверка прав доступа при формировании
|
||||
SNAME => 'SOBJ_KIND',
|
||||
ICURSOR => ICURSOR,
|
||||
NPOSITION => 7);
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW,
|
||||
SNAME => 'SEQUIPDSCMML',
|
||||
PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW,
|
||||
SNAME => 'NCMML_STATUS',
|
||||
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;
|
||||
@ -388,9 +377,12 @@ text="Проверка прав доступа при формировании
|
||||
for C in (select T.RN NRN,
|
||||
T.CODE SCODE,
|
||||
T.NAME SNAME,
|
||||
T.OPER_DATE DOPER_DATE
|
||||
from EQCONFIG T
|
||||
where T.RN = NEQCONFIG)
|
||||
T.OPER_DATE DOPER_DATE,
|
||||
OK.NAME SEQOBJKIND
|
||||
from EQCONFIG T,
|
||||
EQOBJKIND OK
|
||||
where T.RN = NEQCONFIG
|
||||
and T.OBJ_KIND = OK.RN)
|
||||
loop
|
||||
/* Соберем карточку */
|
||||
XCARD := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||
@ -407,7 +399,10 @@ text="Проверка прав доступа при формировании
|
||||
SVALUE => C.SNAME),
|
||||
RATTRIBUTE03 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'DOPER_DATE',
|
||||
DVALUE => C.DOPER_DATE)));
|
||||
DVALUE => C.DOPER_DATE),
|
||||
RATTRIBUTE04 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||||
SNAME => 'SEQOBJKIND',
|
||||
SVALUE => C.SEQOBJKIND)));
|
||||
end loop;
|
||||
/* Формируем XML-представление документа ответа */
|
||||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XCARD);
|
||||
|
@ -8,6 +8,7 @@
|
||||
//---------------------
|
||||
|
||||
import React, { useState, useEffect, useContext } from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Box, Grid, Stack, Icon, Button, IconButton } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
|
||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с серверомs
|
||||
@ -16,7 +17,8 @@ import {
|
||||
EquipDataSelectionList,
|
||||
EquipDataSelectionClassMachineIU,
|
||||
EquipDataSelectionClassMachineList,
|
||||
EquipDataSelectionClassMachineCard
|
||||
EquipDataSelectionClassMachineCard,
|
||||
EquipDataSelectionClassMachineModelIU
|
||||
} from "./admin_tab_layout"; //Вспомогательные компоненты и вёрстка
|
||||
import {
|
||||
DS_RN_DEFAULT,
|
||||
@ -37,7 +39,8 @@ const REFRESH_INITIAL = {
|
||||
dataSelection: null,
|
||||
dataSelectionClassMachine: null,
|
||||
dataSelectionClassMachineCard: 0,
|
||||
dataSelectionClassMachineFilesList: 0
|
||||
dataSelectionClassMachineFilesList: 0,
|
||||
dataSelectionClassMachineModelsList: 0
|
||||
};
|
||||
|
||||
//Стили
|
||||
@ -51,7 +54,7 @@ const STYLES = {
|
||||
//-----------
|
||||
|
||||
//Закладка администрирования
|
||||
const AdminTab = () => {
|
||||
const AdminTab = ({ dataSelection = DS_RN_DEFAULT, dataSelectionClassMachine = null }) => {
|
||||
//Подключение к контексту взаимодействия с сервером
|
||||
const { executeStored } = useContext(BackEndСtx);
|
||||
|
||||
@ -59,16 +62,16 @@ const AdminTab = () => {
|
||||
const { pOnlineUserProcedure } = useContext(ApplicationСtx);
|
||||
|
||||
//Собственное состояние - отображаемые диалоги
|
||||
const [dialogs, setDialogs] = useState({ dataSelectionIU: false, dataSelectionClassMachineIU: false });
|
||||
const [dialogs, setDialogs] = useState({ dataSelectionIU: false, dataSelectionClassMachineIU: false, dataSelectionClassMachineModelIU: false });
|
||||
|
||||
//Собственное состояние - флаги обновления данных
|
||||
const [refresh, setRefresh] = useState(REFRESH_INITIAL);
|
||||
|
||||
//Собственное состояние - выбранная выборка данных
|
||||
const [equipDataSelection, setDataSelection] = useState(DS_RN_DEFAULT);
|
||||
const [equipDataSelection, setDataSelection] = useState(dataSelection);
|
||||
|
||||
//Собственное состояние - выбранный класс оборудования
|
||||
const [equipDataSelectionClassMachine, setDataSelectionClassMachine] = useState(null);
|
||||
const [equipDataSelectionClassMachine, setDataSelectionClassMachine] = useState(dataSelectionClassMachine);
|
||||
|
||||
//Загрузка списка выборок данных
|
||||
const { equipDataSelectionList } = useEquipDataSelectionList(refresh.dataSelection);
|
||||
@ -88,8 +91,11 @@ const AdminTab = () => {
|
||||
refresh.dataSelectionClassMachineFilesList
|
||||
);
|
||||
|
||||
//Загрузка файлов класса оборудования
|
||||
const { equipDataSelectionClassMachineModelsList } = useEquipDataSelectionClassMachineModelsList(equipDataSelectionClassMachine);
|
||||
//Загрузка моделей класса оборудования
|
||||
const { equipDataSelectionClassMachineModelsList } = useEquipDataSelectionClassMachineModelsList(
|
||||
equipDataSelectionClassMachine,
|
||||
refresh.dataSelectionClassMachineModelsList
|
||||
);
|
||||
|
||||
//При смене выборки данных
|
||||
const handleDataSelectionChange = value => {
|
||||
@ -166,37 +172,71 @@ const AdminTab = () => {
|
||||
|
||||
//При нажатии "Загрузить на сервер" в списке файлов карточки класса оборудования
|
||||
const handleUploadEquipDataSelectionClassMachineFiles = async equipDSCM => {
|
||||
await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CMFL_UPLOAD",
|
||||
args: {
|
||||
NEQUIPDSCM: equipDSCM
|
||||
}
|
||||
});
|
||||
await executeStored({ stored: "UDO_PKG_EQUIPDS.CMFL_UPLOAD", args: { NEQUIPDSCM: equipDSCM } });
|
||||
setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
|
||||
};
|
||||
|
||||
//При нажатии "Передать внешней системе" в списке файлов карточки класса оборудования
|
||||
const handleSendMdEquipDataSelectionClassMachineFiles = async equipDSCM => {
|
||||
await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CMFL_SEND_MD",
|
||||
args: {
|
||||
NEQUIPDSCM: equipDSCM
|
||||
}
|
||||
});
|
||||
await executeStored({ stored: "UDO_PKG_EQUIPDS.CMFL_SEND_MD", args: { NEQUIPDSCM: equipDSCM } });
|
||||
setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
|
||||
};
|
||||
|
||||
//При нажатии на "Добавить модель класса оборудования"
|
||||
const handleAddEquipDataSelectionClassMachineModel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: true }));
|
||||
|
||||
//При нажатии на "Удалить модель класса оборудования"
|
||||
const handleDeleteEquipDataSelectionClassMachineModel = async equipDSCMML => {
|
||||
await executeStored({ stored: "UDO_PKG_EQUIPDS.CMML_DEL", args: { NRN: equipDSCMML } });
|
||||
setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
|
||||
};
|
||||
|
||||
//При отмене диалога IU модели класса оборудования
|
||||
const handleEquipDataSelectionClassMachineModelIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: false }));
|
||||
|
||||
//При сохранении диалога IU модели класса оборудования
|
||||
const handleEquipDataSelectionClassMachineModelIUOk = async values => {
|
||||
await executeStored({
|
||||
stored: "UDO_PKG_EQUIPDS.CMML_INS",
|
||||
args: {
|
||||
NPRN: equipDataSelectionClassMachine,
|
||||
STASK: values.task,
|
||||
NPRECISION_P: parseInt(values.precisionP)
|
||||
}
|
||||
});
|
||||
setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: false }));
|
||||
setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
|
||||
};
|
||||
|
||||
//При нажатии "Обучить" в списке моделей карточки класса оборудования
|
||||
const handleSendRqEquipDataSelectionClassMachineModel = async equipDSCMML => {
|
||||
await executeStored({ stored: "UDO_PKG_EQUIPDS.CMML_SEND_RQ", args: { NEQUIPDSCMML: equipDSCMML } });
|
||||
setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
|
||||
};
|
||||
|
||||
//При измении выборки данных через свойства
|
||||
useEffect(() => {
|
||||
setDataSelection(dataSelection);
|
||||
}, [dataSelection]);
|
||||
|
||||
//При изменеии класса оборудования через свойства
|
||||
useEffect(() => {
|
||||
setDataSelectionClassMachine(dataSelectionClassMachine);
|
||||
}, [dataSelectionClassMachine]);
|
||||
|
||||
//При изменении списка выборок данных
|
||||
useEffect(() => {
|
||||
if (refresh.action == "INS" && refresh.dataSelection) {
|
||||
setDataSelection(refresh.dataSelection);
|
||||
setDataSelectionClassMachine(null);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [equipDataSelectionList]);
|
||||
|
||||
//При изменении списка классов оборудования выборки данных
|
||||
useEffect(() => {
|
||||
if (refresh.action == "INS" && refresh.dataSelectionClassMachine) setDataSelectionClassMachine(refresh.dataSelectionClassMachine);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [equipDataSelectionClassMachineList]);
|
||||
|
||||
//Генерация содержимого
|
||||
@ -211,6 +251,12 @@ const AdminTab = () => {
|
||||
onCancel={handleEquipDataSelectionClassMachineIUCancel}
|
||||
/>
|
||||
) : null}
|
||||
{dialogs.dataSelectionClassMachineModelIU ? (
|
||||
<EquipDataSelectionClassMachineModelIU
|
||||
onOk={handleEquipDataSelectionClassMachineModelIUOk}
|
||||
onCancel={handleEquipDataSelectionClassMachineModelIUCancel}
|
||||
/>
|
||||
) : null}
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Stack direction="row" spacing={2} p={2} sx={STYLES.DATA_SELECTION_STACK}>
|
||||
@ -251,6 +297,9 @@ const AdminTab = () => {
|
||||
onClassMachineFilesMake={handleMakeEquipDataSelectionClassMachineFiles}
|
||||
onClassMachineFilesUpload={handleUploadEquipDataSelectionClassMachineFiles}
|
||||
onClassMachineFilesSendMd={handleSendMdEquipDataSelectionClassMachineFiles}
|
||||
onClassMachineModelAdd={handleAddEquipDataSelectionClassMachineModel}
|
||||
onClassMachineModelDelete={handleDeleteEquipDataSelectionClassMachineModel}
|
||||
onClassMachineModelSendRq={handleSendRqEquipDataSelectionClassMachineModel}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@ -260,6 +309,12 @@ const AdminTab = () => {
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств - Закладка администрирования
|
||||
AdminTab.propTypes = {
|
||||
dataSelection: PropTypes.number,
|
||||
dataSelectionClassMachine: PropTypes.number
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
@ -176,7 +176,7 @@ const useEquipDataSelectionClassMachineFilesList = (classMachine, refresh) => {
|
||||
};
|
||||
|
||||
//Загрузка списка моделей класса оборудования
|
||||
const useEquipDataSelectionClassMachineModelsList = classMachine => {
|
||||
const useEquipDataSelectionClassMachineModelsList = (classMachine, refresh) => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
@ -212,7 +212,7 @@ const useEquipDataSelectionClassMachineModelsList = classMachine => {
|
||||
}
|
||||
};
|
||||
if (classMachine) loadData();
|
||||
}, [classMachine, executeStored]);
|
||||
}, [classMachine, refresh, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { equipDataSelectionClassMachineModelsList: data, equipDataSelectionClassMachineModelsListIsLoading: isLoading };
|
||||
|
@ -36,9 +36,10 @@ import {
|
||||
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 { APP_BAR_HEIGHT, TABS_HEIGHT, SCROLL_STYLES, formatModelStateValue } 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"; //Подключение компонентов к настройкам приложения
|
||||
import { DS_RN_DEFAULT } from "./admin_tab_hooks"; //Вспомогательные хуки
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
@ -104,7 +105,7 @@ const STYLES = {
|
||||
//------------------------------------
|
||||
|
||||
//Поле ввода из словаря
|
||||
const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, ...other }) => {
|
||||
const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, list, ...other }) => {
|
||||
//Значение элемента
|
||||
const [value, setValue] = useState(elementValue);
|
||||
|
||||
@ -119,6 +120,7 @@ const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dict
|
||||
|
||||
//Изменение значения элемента
|
||||
const handleChange = e => {
|
||||
console.log(e.target.name, e.target.value);
|
||||
setValue(e.target.value);
|
||||
if (onChange) onChange(e.target.name, e.target.value);
|
||||
};
|
||||
@ -127,6 +129,27 @@ const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dict
|
||||
return (
|
||||
<Box p={1}>
|
||||
<FormControl variant="standard" fullWidth {...other}>
|
||||
{list ? (
|
||||
<>
|
||||
<InputLabel id={`${elementCode}Lable`}>{labelText}</InputLabel>
|
||||
<Select
|
||||
labelId={`${elementCode}Lable`}
|
||||
id={elementCode}
|
||||
name={elementCode}
|
||||
label={labelText}
|
||||
value={value ? value : ""}
|
||||
onChange={handleChange}
|
||||
displayEmpty
|
||||
>
|
||||
{list.map((item, i) => (
|
||||
<MenuItem key={i} value={item.value ? item.value : ""}>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<InputLabel htmlFor={elementCode}>{labelText}</InputLabel>
|
||||
<Input
|
||||
id={elementCode}
|
||||
@ -143,6 +166,8 @@ const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dict
|
||||
}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</FormControl>
|
||||
</Box>
|
||||
);
|
||||
@ -154,7 +179,8 @@ IUDFormTextField.propTypes = {
|
||||
elementValue: PropTypes.string,
|
||||
labelText: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
dictionary: PropTypes.func
|
||||
dictionary: PropTypes.func,
|
||||
list: PropTypes.array
|
||||
};
|
||||
|
||||
//Кнопка с дополнительной подписью
|
||||
@ -165,7 +191,9 @@ const ExtraCaptionButton = ({ caption, title, subtitle, maxWidth, onClick, theme
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Stack sx={STYLES.EXTRA_CAPTION_BUTTON_CONTAINER(theme, maxWidth)}>
|
||||
<Button onClick={handleClick}>{caption}</Button>
|
||||
<Button onClick={handleClick} size={"small"}>
|
||||
{caption}
|
||||
</Button>
|
||||
<Typography variant="caption" color="text.secondary" sx={STYLES.EXTRA_CAPTION_BUTTON_TITLE} title={subtitle}>
|
||||
<b>{title}</b> {subtitle}
|
||||
</Typography>
|
||||
@ -218,6 +246,37 @@ const filesListDataCellRender = ({ row, columnDef, theme }) => {
|
||||
}
|
||||
};
|
||||
|
||||
//Форматирование колонок таблицы моделей класса оборудования выборки данных
|
||||
const modelsListDataCellRender = ({ row, columnDef, theme, card, onDelete, onSendRq }) => {
|
||||
switch (columnDef.name) {
|
||||
case "NSTATUS":
|
||||
return {
|
||||
cellProps: { align: "left" },
|
||||
data: formatModelStateValue(theme, row.NSTATUS, row.SERR)
|
||||
};
|
||||
case "SACTIONS":
|
||||
return {
|
||||
data: (
|
||||
<Stack spacing={1} direction={"row"} alignItems={"center"}>
|
||||
<IconButton onClick={() => (onDelete ? onDelete(row.NRN) : null)}>
|
||||
<Icon>delete</Icon>
|
||||
</IconButton>
|
||||
{row.NSTATUS == 0 ? (
|
||||
<ExtraCaptionButton
|
||||
caption="Запрос на обучение"
|
||||
title="СО:"
|
||||
subtitle={card.SEXSSERVICE_SEND_RQ}
|
||||
maxWidth="200px"
|
||||
onClick={() => (onSendRq ? onSendRq(row.NRN) : null)}
|
||||
theme={theme}
|
||||
/>
|
||||
) : null}
|
||||
</Stack>
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//Форматирование ячеек заголовка таблиц файлов и моделей класса оборудования выборки данных
|
||||
const classMachineCardTableHeadCellRender = ({ columnDef }) => {
|
||||
switch (columnDef.name) {
|
||||
@ -226,6 +285,8 @@ const classMachineCardTableHeadCellRender = ({ columnDef }) => {
|
||||
stackProps: { justifyContent: "left" },
|
||||
cellProps: { align: "left" }
|
||||
};
|
||||
case "SACTIONS":
|
||||
return { data: " " };
|
||||
}
|
||||
};
|
||||
|
||||
@ -401,6 +462,50 @@ EquipDataSelectionClassMachineIU.propTypes = {
|
||||
onCancel: PropTypes.func
|
||||
};
|
||||
|
||||
//Диалог IU модели класса оборудования выборки данных
|
||||
const EquipDataSelectionClassMachineModelIU = ({ onOk, onCancel }) => {
|
||||
//Собственное состояние - значения формы
|
||||
const [values, setValues] = useState({
|
||||
task: "RUL",
|
||||
precisionP: ""
|
||||
});
|
||||
|
||||
//Отработка воода значения в форму
|
||||
const handleValueChanged = (name, value) => setValues(pv => ({ ...pv, [name]: value }));
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Dialog open={true} onClose={() => (onOk ? onCancel() : null)}>
|
||||
<DialogTitle>Модель класса оборудования выборки данных</DialogTitle>
|
||||
<DialogContent>
|
||||
<IUDFormTextField
|
||||
elementCode={"task"}
|
||||
elementValue={values.task}
|
||||
labelText={"Задача"}
|
||||
onChange={handleValueChanged}
|
||||
list={[
|
||||
{ value: null, name: "Не указана" },
|
||||
{ value: "TCF", name: "TCF - оценка технического состояния (Technical Condition Forecast)" },
|
||||
{ value: "RUL", name: "RUL - прогнозирование остаточного ресурса (Remaining Useful Life)" },
|
||||
{ value: "FP", name: "FP - Прогнозирование отказа (Failure Predict)" }
|
||||
]}
|
||||
/>
|
||||
<IUDFormTextField elementCode={"precisionP"} elementValue={values.precisionP} labelText={"Точность"} onChange={handleValueChanged} />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => (onOk ? onOk(values) : null)}>{BUTTONS.OK}</Button>
|
||||
<Button onClick={() => (onOk ? onCancel() : null)}>{BUTTONS.CANCEL}</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств - Диалог IU модели класса оборудования выборки данных
|
||||
EquipDataSelectionClassMachineModelIU.propTypes = {
|
||||
onOk: PropTypes.func,
|
||||
onCancel: PropTypes.func
|
||||
};
|
||||
|
||||
//Список выборок данных оборудования
|
||||
const EquipDataSelectionList = ({ list, value, onChange }) => {
|
||||
//При выборе элемента
|
||||
@ -410,7 +515,14 @@ const EquipDataSelectionList = ({ list, value, onChange }) => {
|
||||
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}>
|
||||
<Select
|
||||
labelId="equipDSlabel"
|
||||
id="equipDS"
|
||||
label="Выборка данных оборудования"
|
||||
value={list.length == 1 ? DS_RN_DEFAULT : value}
|
||||
onChange={handleChange}
|
||||
displayEmpty
|
||||
>
|
||||
{list.map((item, i) => (
|
||||
<MenuItem key={i} value={item.NRN}>
|
||||
{item.SNAME}
|
||||
@ -462,7 +574,10 @@ const EquipDataSelectionClassMachineCard = ({
|
||||
onCardDelete,
|
||||
onClassMachineFilesMake,
|
||||
onClassMachineFilesUpload,
|
||||
onClassMachineFilesSendMd
|
||||
onClassMachineFilesSendMd,
|
||||
onClassMachineModelAdd,
|
||||
onClassMachineModelDelete,
|
||||
onClassMachineModelSendRq
|
||||
}) => {
|
||||
//Подключаемся к теме
|
||||
const theme = useTheme();
|
||||
@ -479,6 +594,15 @@ const EquipDataSelectionClassMachineCard = ({
|
||||
//При нажатии на "Загрузить на сервер" для файлов данных
|
||||
const handleClassMachineFilesSendMdClick = () => (onClassMachineFilesSendMd ? onClassMachineFilesSendMd(card.NRN) : null);
|
||||
|
||||
//При нажатии на "Добавить" для моделей
|
||||
const handleClassMachineModelAddClick = () => (onClassMachineModelAdd ? onClassMachineModelAdd() : null);
|
||||
|
||||
//При нажатии на "Удалить" для моделей
|
||||
const handleClassMachineModelDeleteClick = equipDSCMML => (onClassMachineModelDelete ? onClassMachineModelDelete(equipDSCMML) : null);
|
||||
|
||||
//При нажатии на "Обучить" для моделей
|
||||
const handleClassMachineModelSendRqClick = equipDSCMML => (onClassMachineModelSendRq ? onClassMachineModelSendRq(equipDSCMML) : null);
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Box p={2} sx={STYLES.EQUIP_DSCM_CARD}>
|
||||
@ -525,10 +649,7 @@ const EquipDataSelectionClassMachineCard = ({
|
||||
</Stack>
|
||||
<P8PDataGrid
|
||||
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
|
||||
containerComponentProps={{
|
||||
sx: STYLES.FL_ML_TABLE,
|
||||
elevation: 0
|
||||
}}
|
||||
containerComponentProps={{ sx: STYLES.FL_ML_TABLE, elevation: 0 }}
|
||||
columnsDef={filesList.columnsDef}
|
||||
rows={filesList.rows}
|
||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
||||
@ -546,13 +667,13 @@ const EquipDataSelectionClassMachineCard = ({
|
||||
<Typography variant="h6" component="div">
|
||||
Модели
|
||||
</Typography>
|
||||
<IconButton onClick={handleClassMachineModelAddClick}>
|
||||
<Icon>add</Icon>
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<P8PDataGrid
|
||||
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
|
||||
containerComponentProps={{
|
||||
sx: STYLES.FL_ML_TABLE,
|
||||
elevation: 0
|
||||
}}
|
||||
containerComponentProps={{ sx: STYLES.FL_ML_TABLE, elevation: 0 }}
|
||||
columnsDef={modelsList.columnsDef}
|
||||
rows={modelsList.rows}
|
||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
||||
@ -560,6 +681,15 @@ const EquipDataSelectionClassMachineCard = ({
|
||||
fixedHeader={true}
|
||||
reloading={false}
|
||||
headCellRender={classMachineCardTableHeadCellRender}
|
||||
dataCellRender={prms =>
|
||||
modelsListDataCellRender({
|
||||
...prms,
|
||||
theme,
|
||||
card,
|
||||
onDelete: handleClassMachineModelDeleteClick,
|
||||
onSendRq: handleClassMachineModelSendRqClick
|
||||
})
|
||||
}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@ -577,7 +707,10 @@ EquipDataSelectionClassMachineCard.propTypes = {
|
||||
onCardDelete: PropTypes.func,
|
||||
onClassMachineFilesMake: PropTypes.func,
|
||||
onClassMachineFilesUpload: PropTypes.func,
|
||||
onClassMachineFilesSendMd: PropTypes.func
|
||||
onClassMachineFilesSendMd: PropTypes.func,
|
||||
onClassMachineModelAdd: PropTypes.func,
|
||||
onClassMachineModelDelete: PropTypes.func,
|
||||
onClassMachineModelSendRq: PropTypes.func
|
||||
};
|
||||
|
||||
//----------------
|
||||
@ -587,6 +720,7 @@ EquipDataSelectionClassMachineCard.propTypes = {
|
||||
export {
|
||||
EquipDataSelectionIU,
|
||||
EquipDataSelectionClassMachineIU,
|
||||
EquipDataSelectionClassMachineModelIU,
|
||||
EquipDataSelectionList,
|
||||
EquipDataSelectionClassMachineList,
|
||||
EquipDataSelectionClassMachineCard
|
||||
|
@ -17,6 +17,13 @@ import { ForecastTab } from "./forecast_tab"; //Интерфейс прогно
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Состояние по умолчанию
|
||||
const STATE_INITIAL = {
|
||||
mode: MODES.FORECAST,
|
||||
dataSelection: -1,
|
||||
dataSelectionClassMachine: null
|
||||
};
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
TABS_CONTAINER_BOX: { borderBottom: 1, borderColor: "divider" }
|
||||
@ -29,25 +36,34 @@ const STYLES = {
|
||||
//Корневая панель прогнозирования технического состояния
|
||||
const EqsTechCondForecast = () => {
|
||||
//Собственное состояние
|
||||
const [mode, setMode] = useState(MODES.ADMIN);
|
||||
const [state, setState] = useState(STATE_INITIAL);
|
||||
|
||||
//При переключении закладки
|
||||
const handleTabChange = (e, newValue) => setMode(newValue);
|
||||
const handleTabChange = (e, newValue) => setState(pv => ({ ...pv, mode: newValue }));
|
||||
|
||||
//При запросе перехода на закладку администрирования
|
||||
const handleGoToAdmin = (dataSelection, dataSelectionClassMachine) =>
|
||||
setState(pv => ({
|
||||
...pv,
|
||||
mode: MODES.ADMIN,
|
||||
dataSelection: dataSelection ? dataSelection : STATE_INITIAL.dataSelection,
|
||||
dataSelectionClassMachine: dataSelectionClassMachine ? dataSelectionClassMachine : STATE_INITIAL.dataSelectionClassMachine
|
||||
}));
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<>
|
||||
<Box sx={STYLES.TABS_CONTAINER_BOX}>
|
||||
<Tabs value={mode} onChange={handleTabChange}>
|
||||
<Tabs value={state.mode} onChange={handleTabChange}>
|
||||
<Tab label="Прогноз" value={MODES.FORECAST} />
|
||||
<Tab label="Обучение" value={MODES.ADMIN} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
<TabPanel mode={mode} value={MODES.FORECAST}>
|
||||
<ForecastTab />
|
||||
<TabPanel mode={state.mode} value={MODES.FORECAST}>
|
||||
<ForecastTab onGoToAdmin={handleGoToAdmin} />
|
||||
</TabPanel>
|
||||
<TabPanel mode={mode} value={MODES.ADMIN}>
|
||||
<AdminTab />
|
||||
<TabPanel mode={state.mode} value={MODES.ADMIN}>
|
||||
<AdminTab dataSelection={state.dataSelection} dataSelectionClassMachine={state.dataSelectionClassMachine} />
|
||||
</TabPanel>
|
||||
</>
|
||||
);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Box } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { Box, Stack, Icon } from "@mui/material"; //Интерфейсные компоненты
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
@ -56,6 +56,24 @@ const SCROLL_STYLES = {
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Формирование значения для колонки "Состояние" модели класса оборудования выборки данных
|
||||
const formatModelStateValue = (theme, value, err) => {
|
||||
const [text, icon, color] =
|
||||
value == 0
|
||||
? ["Зарегистрирована", "app_registration", null]
|
||||
: value == 1
|
||||
? ["Обрабатывается внешней системой", "manage_history", theme.palette.warning.main]
|
||||
: value == 2
|
||||
? ["Успешно обработана внешней системой", "check_circle", theme.palette.primary.main]
|
||||
: [`Ошибка обработки внешней системой: ${err}`, "error", theme.palette.error.main];
|
||||
return (
|
||||
<Stack direction="row" gap={0.5} alignItems="center" justifyContent="left" color={color}>
|
||||
<Icon title={text}>{icon}</Icon>
|
||||
{text}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
//Закладка
|
||||
const TabPanel = ({ mode, value, children }) => <Box hidden={mode != value}>{children}</Box>;
|
||||
|
||||
@ -70,4 +88,4 @@ TabPanel.propTypes = {
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { MODES, APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_MORE_HEIGHT, TABLE_FILTERS_HEIGHT, SCROLL_STYLES, TabPanel };
|
||||
export { MODES, APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_MORE_HEIGHT, TABLE_FILTERS_HEIGHT, SCROLL_STYLES, formatModelStateValue, TabPanel };
|
||||
|
@ -8,14 +8,23 @@
|
||||
//---------------------
|
||||
|
||||
import React, { useState, useContext } from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; //Дерево
|
||||
import { useTreeViewApiRef } from "@mui/x-tree-view/hooks/useTreeViewApiRef"; //API дерева
|
||||
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 { 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"; //Вспомогательные хуки
|
||||
import { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка
|
||||
import {
|
||||
useEqConfigTree,
|
||||
useEqConfigTechObjTable,
|
||||
useEqConfigTechObjCard,
|
||||
useTechObjModelsList,
|
||||
findTreeItem,
|
||||
needLoadLevel
|
||||
} from "./forecast_tab_hooks"; //Вспомогательные хуки
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
@ -49,10 +58,13 @@ const TECH_OBJ_SPEC_INIT = { parent: null, filters: [], orders: [], pageNumber:
|
||||
//-----------
|
||||
|
||||
//Закладка прогнозирования
|
||||
const ForecastTab = () => {
|
||||
const ForecastTab = ({ onGoToAdmin }) => {
|
||||
//Подключение к контексту сообщений
|
||||
const { InlineMsgInfo } = useContext(MessagingСtx);
|
||||
|
||||
//Подключение к API дерева
|
||||
const apiRef = useTreeViewApiRef();
|
||||
|
||||
//Собственное состояние - текущая загружаемая ветка
|
||||
const [loadingTreeItem, setLoadingTreeItem] = useState(0);
|
||||
|
||||
@ -73,9 +85,12 @@ const ForecastTab = () => {
|
||||
techObjSpec.pageNumber
|
||||
);
|
||||
|
||||
//Загрузчик карточки выбоанного технического объекта
|
||||
//Загрузчик карточки выбранного технического объекта
|
||||
const { techObjCard, techObjCardIsLoading } = useEqConfigTechObjCard(techObjCardId);
|
||||
|
||||
//Загрузчик моделей выбранного технического объекта
|
||||
const { techObjModelsList, techObjModelsListIsLoading } = useTechObjModelsList(techObjCardId);
|
||||
|
||||
//Обработка развёртывания/свёртывания уровня дерева
|
||||
const handleTreeItemExpansionToggle = (event, itemId, isExpanded) =>
|
||||
isExpanded && needLoadLevel(eQconfigTree, itemId) ? setLoadingTreeItem(parseInt(itemId)) : null;
|
||||
@ -99,6 +114,23 @@ const ForecastTab = () => {
|
||||
//При изменении количества отображаемых страниц спецификации технических объектов
|
||||
const handleTechObjSpecPagesCountChanged = () => setTechObjSpec(pv => ({ ...pv, pageNumber: pv.pageNumber + 1 }));
|
||||
|
||||
//При выполнении действия в колоке "Модели" таблицы технических объектов
|
||||
const handleCMMLStatusClick = (event, row) => {
|
||||
if (row.NCMML_STATUS == 0) {
|
||||
if (onGoToAdmin) onGoToAdmin();
|
||||
} else {
|
||||
const item = findTreeItem(eQconfigTree, row.NRN);
|
||||
if (item && item?.showCard) apiRef.current?.focusItem(event, item.id);
|
||||
else setTechObjCardId(parseInt(row.NRN));
|
||||
}
|
||||
};
|
||||
|
||||
//При переходе к закладке администрирования из карточки технического объекта
|
||||
const handleTechObjeCardGoToModel = model => (onGoToAdmin ? onGoToAdmin(model.NEQUIPDS, model.NEQUIPDSCM) : null);
|
||||
|
||||
//При закрытии карточки технического объекта
|
||||
const handleTechObjeCardClose = () => setTechObjCardId(null);
|
||||
|
||||
//Текст при отсутствии данных в списке технических объектов
|
||||
const noDataFoundText =
|
||||
techObjsDataGridIsLoading || !techObjsDataGrid.init
|
||||
@ -113,13 +145,23 @@ const ForecastTab = () => {
|
||||
<Grid container>
|
||||
<Grid item xs={3} sx={STYLES.LEFT_SIDE_GRID}>
|
||||
<Box sx={STYLES.TREE_BOX}>
|
||||
<RichTreeView items={eQconfigTree} onItemExpansionToggle={handleTreeItemExpansionToggle} onItemFocus={handleTreeItemFocus} />
|
||||
<RichTreeView
|
||||
apiRef={apiRef}
|
||||
items={eQconfigTree}
|
||||
onItemExpansionToggle={handleTreeItemExpansionToggle}
|
||||
onItemFocus={handleTreeItemFocus}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={9} sx={STYLES.RIGHT_SIDE_GRID}>
|
||||
{techObjCardId ? (
|
||||
!techObjCardIsLoading ? (
|
||||
<TechObjCard cardData={techObjCard} />
|
||||
!techObjCardIsLoading && !techObjModelsListIsLoading ? (
|
||||
<TechObjCard
|
||||
cardData={techObjCard}
|
||||
modelsList={techObjModelsList}
|
||||
onClose={handleTechObjeCardClose}
|
||||
onGoToModel={handleTechObjeCardGoToModel}
|
||||
/>
|
||||
) : null
|
||||
) : techObjsDataGrid.init ? (
|
||||
<P8PDataGrid
|
||||
@ -136,6 +178,7 @@ const ForecastTab = () => {
|
||||
fixedHeader={true}
|
||||
reloading={false}
|
||||
valueFormatter={eqConfigTechObjTableValueFormatter}
|
||||
dataCellRender={prms => eqConfigTechObjTableDataCellRender({ ...prms, onCMMLStatus: handleCMMLStatusClick })}
|
||||
onFilterChanged={handleTechObjSpecFilterChanged}
|
||||
onOrderChanged={handleTechObjSpecOrderChanged}
|
||||
onPagesCountChanged={handleTechObjSpecPagesCountChanged}
|
||||
@ -149,6 +192,11 @@ const ForecastTab = () => {
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств - Закладка прогнозирования
|
||||
ForecastTab.propTypes = {
|
||||
onGoToAdmin: PropTypes.func
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
@ -126,7 +126,7 @@ const useEqConfigTechObjTable = (parent, filters, orders, pageNumber) => {
|
||||
NINCLUDE_DEF: pageNumber == 1 ? 1 : 0
|
||||
},
|
||||
respArg: "COUT",
|
||||
loader: false
|
||||
loader: true
|
||||
});
|
||||
setData(pv => ({
|
||||
...pv,
|
||||
@ -182,8 +182,51 @@ const useEqConfigTechObjCard = id => {
|
||||
return { techObjCard: card, techObjCardIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//Загрузка списка моделей единицы оборудования
|
||||
const useTechObjModelsList = (id, refresh) => {
|
||||
//Собственное состояние - флаг загрузки
|
||||
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_BY_EQCONFIG",
|
||||
args: { NEQCONFIG: id },
|
||||
respArg: "COUT",
|
||||
loader: false
|
||||
});
|
||||
setData(pv => ({
|
||||
...pv,
|
||||
columnsDef: [...data.XCOLUMNS_DEF],
|
||||
rows: [...(data.XROWS || [])],
|
||||
init: true
|
||||
}));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
if (id) loadData();
|
||||
}, [id, refresh, executeStored]);
|
||||
|
||||
//Вернём данные
|
||||
return { techObjModelsList: data, techObjModelsListIsLoading: isLoading };
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel };
|
||||
export { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel, useTechObjModelsList };
|
||||
|
@ -9,8 +9,13 @@
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Box, Card, CardContent, Typography, CardActions, Button } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { Stack, Icon, Box, Card, CardContent, Typography, CardActions, Button, IconButton, Divider } from "@mui/material"; //Интерфейсные компоненты
|
||||
import { useTheme } from "@mui/material/styles"; //Темы оформления
|
||||
import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
|
||||
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
||||
import { formatDateRF } from "../../core/utils"; //Вспомогательные функции
|
||||
import { SCROLL_STYLES, formatModelStateValue } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
@ -19,7 +24,59 @@ import { formatDateRF } from "../../core/utils"; //Вспомогательны
|
||||
//Стили
|
||||
const STYLES = {
|
||||
TECH_OBJ_CARD_TITLE: { fontSize: 14 },
|
||||
TECH_OBJ_CARD_SUB_TITLE: { mb: 1.5 }
|
||||
TECH_OBJ_CARD_SUB_TITLE: { mb: 1.5 },
|
||||
EQ_ML_TABLE: {
|
||||
maxHeight: "200px",
|
||||
...SCROLL_STYLES
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------
|
||||
//Вспомогательные функции и компоненты
|
||||
//------------------------------------
|
||||
|
||||
//Форматирование ячеек заголовка таблицы моделей единицы оборудования
|
||||
const techObjCardModelsTableHeadCellRender = ({ columnDef }) => {
|
||||
switch (columnDef.name) {
|
||||
case "NSTATUS":
|
||||
return {
|
||||
stackProps: { justifyContent: "left" },
|
||||
cellProps: { align: "left" }
|
||||
};
|
||||
case "SACTIONS":
|
||||
return { data: " " };
|
||||
}
|
||||
};
|
||||
|
||||
//Форматирование колонок таблицы моделей класса оборудования выборки данных
|
||||
const techObjCardModelsTableDataCellRender = ({ row, columnDef, theme, onGoToModel, onGetPrediction }) => {
|
||||
switch (columnDef.name) {
|
||||
case "SNEQUIPDS":
|
||||
case "STASK":
|
||||
case "NPRECISION_P":
|
||||
case "NPRECISION_F":
|
||||
return {
|
||||
data: (
|
||||
<Link component="button" variant="body2" align="left" underline="hover" onClick={() => onGoToModel(row)}>
|
||||
{row[columnDef.name]}
|
||||
</Link>
|
||||
)
|
||||
};
|
||||
case "NSTATUS":
|
||||
return {
|
||||
cellProps: { align: "left" },
|
||||
data: formatModelStateValue(theme, row.NSTATUS, row.SERR)
|
||||
};
|
||||
case "SACTIONS":
|
||||
return {
|
||||
data:
|
||||
row.NSTATUS == 2 ? (
|
||||
<Button variant="outlined" color="success" onClick={() => onGetPrediction(row)}>
|
||||
Прогноз
|
||||
</Button>
|
||||
) : null
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//-----------
|
||||
@ -27,27 +84,71 @@ const STYLES = {
|
||||
//-----------
|
||||
|
||||
//Карточка технического объекта
|
||||
const TechObjCard = ({ cardData }) => {
|
||||
const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => {
|
||||
//Подключаемся к теме
|
||||
const theme = useTheme();
|
||||
|
||||
//При нажатии на кнопку закрытия карточки
|
||||
const handleClose = () => (onClose ? onClose() : null);
|
||||
|
||||
//При нажатии на переход к модели
|
||||
const handleGoToModelClick = model => (onGoToModel ? onGoToModel(model) : null);
|
||||
|
||||
//При нажатии на запрос предсказания
|
||||
const handleGetPredictionClick = model => {
|
||||
console.log(model);
|
||||
};
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<Box p={2}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_TITLE} color="text.secondary" gutterBottom>
|
||||
<Stack spacing={2} direction={"row"} alignItems={"center"}>
|
||||
<IconButton onClick={handleClose}>
|
||||
<Icon>close</Icon>
|
||||
</IconButton>
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_TITLE} color="text.secondary" variant="caption" gutterBottom>
|
||||
Технический объект
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography variant="h5" component="div">
|
||||
{cardData.SCODE}
|
||||
</Typography>
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_SUB_TITLE} color="text.secondary">
|
||||
{cardData.DOPER_DATE}
|
||||
<Typography sx={STYLES.TECH_OBJ_CARD_SUB_TITLE} color="text.secondary" variant="caption" gutterBottom>
|
||||
{`Введён в эксплуатацию: ${formatDateRF(cardData.DOPER_DATE)}`}
|
||||
<br />
|
||||
{`Класс: ${cardData.SEQOBJKIND}`}
|
||||
</Typography>
|
||||
<Typography variant="body2">{cardData.SNAME}</Typography>
|
||||
<Typography variant="h6">{cardData.SNAME}</Typography>
|
||||
<br />
|
||||
<Divider />
|
||||
<Typography variant="h6" component="div">
|
||||
Модели
|
||||
</Typography>
|
||||
<P8PDataGrid
|
||||
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
|
||||
containerComponentProps={{ sx: STYLES.EQ_ML_TABLE, elevation: 0 }}
|
||||
columnsDef={modelsList.columnsDef}
|
||||
rows={modelsList.rows}
|
||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
||||
morePages={false}
|
||||
fixedHeader={true}
|
||||
reloading={false}
|
||||
headCellRender={techObjCardModelsTableHeadCellRender}
|
||||
dataCellRender={prms =>
|
||||
techObjCardModelsTableDataCellRender({
|
||||
...prms,
|
||||
theme,
|
||||
onGoToModel: handleGoToModelClick,
|
||||
onGetPrediction: handleGetPredictionClick
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button size="large">Прогнозировать</Button>
|
||||
<Button size="large">Ремонтировать</Button>
|
||||
<Button size="large">Обучать</Button>
|
||||
<Button>Ремонтировать</Button>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</Box>
|
||||
@ -56,20 +157,49 @@ const TechObjCard = ({ cardData }) => {
|
||||
|
||||
//Контроль свойств - Карточка технического объекта
|
||||
TechObjCard.propTypes = {
|
||||
cardData: PropTypes.object
|
||||
cardData: PropTypes.object.isRequired,
|
||||
modelsList: PropTypes.object.isRequired,
|
||||
onClose: PropTypes.func,
|
||||
onGoToModel: PropTypes.func
|
||||
};
|
||||
|
||||
//Формирование значения для колонки "Медель" таблицы технических объектов
|
||||
const formatTechObjCMMLStatusValue = value => (value == 0 ? "Обучить" : value == 1 ? "Обучается" : "Прогнозировать");
|
||||
|
||||
//Формирование цвета для колонки "Медель" таблицы технических объектов
|
||||
const formatTechObjCMMLStatusColor = value => (value == 0 ? "primary" : value == 1 ? "warning" : "success");
|
||||
|
||||
//Форматирование значений колонок таблицы технических объектов
|
||||
const eqConfigTechObjTableValueFormatter = ({ value, columnDef }) => {
|
||||
switch (columnDef.name) {
|
||||
case "DOPER_DATE":
|
||||
return formatDateRF(value);
|
||||
case "NCMML_STATUS":
|
||||
return formatTechObjCMMLStatusValue(value);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
//Форматирование колонок таблицы технических объектов
|
||||
const eqConfigTechObjTableDataCellRender = ({ row, columnDef, onCMMLStatus }) => {
|
||||
switch (columnDef.name) {
|
||||
case "NCMML_STATUS":
|
||||
return {
|
||||
data: (
|
||||
<Button
|
||||
variant="outlined"
|
||||
color={formatTechObjCMMLStatusColor(row[columnDef.name])}
|
||||
onClick={event => (onCMMLStatus ? onCMMLStatus(event, row) : null)}
|
||||
>
|
||||
{formatTechObjCMMLStatusValue(row[columnDef.name])}
|
||||
</Button>
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { TechObjCard, eqConfigTechObjTableValueFormatter };
|
||||
export { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender };
|
||||
|
Loading…
x
Reference in New Issue
Block a user