Закладка "Прогнозирование" - фильтры и сортировки в списке технических объектов, коррекция стилей и сообщений об отсуствии данных

This commit is contained in:
Mikhail Chechnev 2024-08-04 01:54:21 +03:00
parent fcdd04cd27
commit ef520e0932
4 changed files with 94 additions and 24 deletions

View File

@ -158,6 +158,22 @@ text="Проверка прав доступа при формировании
PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'OPER_DATE', PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'OPER_DATE',
SCONDITION_NAME_FROM => 'DOPER_DATEFrom', SCONDITION_NAME_FROM => 'DOPER_DATEFrom',
SCONDITION_NAME_TO => 'DOPER_DATETo'); SCONDITION_NAME_TO => 'DOPER_DATETo');
/* Состояние */
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE',
SCONDITION_NAME => 'SUSE_KINDFrom',
SJOINS => 'HLSTATETYPES <- RN;HLSTATETYPES');
/* Класс */
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'));
end if;
end EQCONFIG_THOBJ_LIST_COND; end EQCONFIG_THOBJ_LIST_COND;
/* Формирование списка технических объектов для выбранного узла состава оборудования */ /* Формирование списка технических объектов для выбранного узла состава оборудования */
@ -203,19 +219,27 @@ text="Проверка прав доступа при формировании
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCODE', SNAME => 'SCODE',
SCAPTION => 'Обозначение', SCAPTION => 'Обозначение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME', SNAME => 'SNAME',
SCAPTION => 'Наименование', SCAPTION => 'Наименование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DOPER_DATE', SNAME => 'DOPER_DATE',
SCAPTION => 'Дата ввода в эксплуатацию', SCAPTION => 'Дата ввода в эксплуатацию',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE); SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SUSE_KIND', SNAME => 'SUSE_KIND',
SCAPTION => 'Состояние', SCAPTION => 'Состояние',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NOBJ_KIND', SNAME => 'NOBJ_KIND',
SCAPTION => 'Рег. номер класса технического объекта', SCAPTION => 'Рег. номер класса технического объекта',
@ -224,11 +248,19 @@ text="Проверка прав доступа при формировании
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SOBJ_KIND', SNAME => 'SOBJ_KIND',
SCAPTION => 'Класс', SCAPTION => 'Класс',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEQUIPDSCMML', SNAME => 'SEQUIPDSCMML',
SCAPTION => 'Модели прогнозирования', SCAPTION => 'Модели прогнозирования',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); 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, PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NEQUIPDSCMML_ACTION', SNAME => 'NEQUIPDSCMML_ACTION',
SCAPTION => 'Действия с моделью', SCAPTION => 'Действия с моделью',
@ -248,7 +280,7 @@ text="Проверка прав доступа при формировании
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OPER_DATE DOPER_DATE,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OPER_DATE DOPER_DATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.CODE SUSE_KIND,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.CODE SUSE_KIND,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OBJ_KIND NOBJ_KIND,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OBJ_KIND NOBJ_KIND,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' OK.CODE SOBJ_KIND,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' 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_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_ACT_BY_EQCONFIG') || '(C.RN) NEQUIPDSCMML_ACTION');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from EQCONFIG C'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from EQCONFIG C');

View File

@ -7,13 +7,14 @@
//Подключение библиотек //Подключение библиотек
//--------------------- //---------------------
import React, { useState } from "react"; //Классы React import React, { useState, useContext } from "react"; //Классы React
import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты
import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; //Дерево 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 { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки import { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки
import { TechObjCard } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка import { TechObjCard, eqConfigTechObjTableValueFormatter } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка
//--------- //---------
//Константы //Константы
@ -28,6 +29,9 @@ const TABS_HEIGHT = "49px";
//Высота кнопки "Ещё" //Высота кнопки "Ещё"
const TABLE_MORE_HEIGHT = "49px"; const TABLE_MORE_HEIGHT = "49px";
//Высота фильтров таблицы
const TABLE_FILTERS_HEIGHT = "48px";
//Стили //Стили
const STYLES = { const STYLES = {
LEFT_SIDE_GRID: {}, LEFT_SIDE_GRID: {},
@ -37,13 +41,19 @@ const STYLES = {
maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT})`, maxHeight: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT})`,
overflowX: "hidden", overflowX: "hidden",
overflowY: "scroll", overflowY: "scroll",
scrollbarWidth: "thin" scrollbarWidth: "thin",
padding: "3px"
}, },
TECH_OBJ_TABLE: morePages => ({ height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TABS_HEIGHT} - ${morePages ? TABLE_MORE_HEIGHT : "0px"})` }) 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"
})
}; };
//Начальное состояние спецификации техничких объектов //Начальное состояние спецификации техничких объектов
const TECH_OBJ_SPEC_INIT = { parent: null, filters: null, orders: null, pageNumber: 1 }; const TECH_OBJ_SPEC_INIT = { parent: null, filters: [], orders: [], pageNumber: 1 };
//----------- //-----------
//Тело модуля //Тело модуля
@ -51,6 +61,9 @@ const TECH_OBJ_SPEC_INIT = { parent: null, filters: null, orders: null, pageNumb
//Закладка прогнозирования //Закладка прогнозирования
const ForecastTab = () => { const ForecastTab = () => {
//Подключение к контексту сообщений
const { InlineMsgInfo } = useContext(MessagingСtx);
//Собственное состояние - текущая загружаемая ветка //Собственное состояние - текущая загружаемая ветка
const [loadingTreeItem, setLoadingTreeItem] = useState(0); const [loadingTreeItem, setLoadingTreeItem] = useState(0);
@ -97,41 +110,50 @@ const ForecastTab = () => {
//При изменении количества отображаемых страниц спецификации технических объектов //При изменении количества отображаемых страниц спецификации технических объектов
const handleTechObjSpecPagesCountChanged = () => setTechObjSpec(pv => ({ ...pv, pageNumber: pv.pageNumber + 1 })); const handleTechObjSpecPagesCountChanged = () => setTechObjSpec(pv => ({ ...pv, pageNumber: pv.pageNumber + 1 }));
//Текст при отсутствии данных в списке технических объектов
const noDataFoundText =
techObjsDataGridIsLoading || !techObjsDataGrid.init
? "Минуточку..."
: techObjSpec.filters.length > 0
? "Нет данных, соответствующих условиям отбора"
: "Выбранный уровень структуры не содержит данных о технических объектах";
//Генерация содержимого //Генерация содержимого
return ( return (
<div> <div>
<Grid container> <Grid container>
<Grid item xs={4} sx={STYLES.LEFT_SIDE_GRID}> <Grid item xs={3} sx={STYLES.LEFT_SIDE_GRID}>
<Box sx={STYLES.TREE_BOX}> <Box sx={STYLES.TREE_BOX}>
<RichTreeView items={tree} onItemExpansionToggle={handleTreeItemExpansionToggle} onItemFocus={handleTreeItemFocus} /> <RichTreeView items={tree} onItemExpansionToggle={handleTreeItemExpansionToggle} onItemFocus={handleTreeItemFocus} />
</Box> </Box>
</Grid> </Grid>
<Grid item xs={8} sx={STYLES.RIGHT_SIDE_GRID}> <Grid item xs={9} sx={STYLES.RIGHT_SIDE_GRID}>
{techObjCardId ? ( {techObjCardId ? (
!techObjCardIsLoading ? ( !techObjCardIsLoading ? (
<TechObjCard cardData={techObjCard} /> <TechObjCard cardData={techObjCard} />
) : null ) : null
) : techObjsDataGrid.init ? ( ) : techObjsDataGrid.init ? (
<P8PDataGrid <P8PDataGrid
{...{ {...{ ...P8P_DATA_GRID_CONFIG_PROPS, noDataFoundText }}
...P8P_DATA_GRID_CONFIG_PROPS, containerComponentProps={{
noDataFoundText: sx: STYLES.TECH_OBJ_TABLE(techObjsDataGrid.morePages, techObjSpec.filters.length > 0),
techObjsDataGridIsLoading || !techObjsDataGrid.init elevation: 0
? "Минуточку..."
: "Выбранный уровень структуры не содержит данных о технических объектах"
}} }}
containerComponentProps={{ sx: STYLES.TECH_OBJ_TABLE(techObjsDataGrid.morePages), elevation: 0 }} filtersInitial={techObjSpec.filters}
columnsDef={techObjsDataGrid.columnsDef} columnsDef={techObjsDataGrid.columnsDef}
rows={techObjsDataGrid.rows} rows={techObjsDataGrid.rows}
size={P8P_DATA_GRID_SIZE.SMALL} size={P8P_DATA_GRID_SIZE.SMALL}
morePages={techObjsDataGrid.morePages} morePages={techObjsDataGrid.morePages}
fixedHeader={true} fixedHeader={true}
reloading={false} reloading={false}
valueFormatter={eqConfigTechObjTableValueFormatter}
onFilterChanged={handleTechObjSpecFilterChanged} onFilterChanged={handleTechObjSpecFilterChanged}
onOrderChanged={handleTechObjSpecOrderChanged} onOrderChanged={handleTechObjSpecOrderChanged}
onPagesCountChanged={handleTechObjSpecPagesCountChanged} onPagesCountChanged={handleTechObjSpecPagesCountChanged}
/> />
) : null} ) : (
<InlineMsgInfo okBtn={false} text={"Укажите элемент структуры состава оборудования для отображения данных"} />
)}
</Grid> </Grid>
</Grid> </Grid>
</div> </div>

View File

@ -16,7 +16,7 @@ import { deepCopyObject, object2Base64XML } from "../../core/utils"; //Вспо
//--------- //---------
//Размер страницы данных //Размер страницы данных
const DATA_GRID_PAGE_SIZE = 5; const DATA_GRID_PAGE_SIZE = 50;
//----------------------- //-----------------------
//Вспомогательные функции //Вспомогательные функции

View File

@ -8,7 +8,9 @@
//--------------------- //---------------------
import React from "react"; //Классы React import React from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Card, CardContent, Typography, CardActions, Button } from "@mui/material"; //Интерфейсные компоненты import { Box, Card, CardContent, Typography, CardActions, Button } from "@mui/material"; //Интерфейсные компоненты
import { formatDateRF } from "../../core/utils"; //Вспомогательные функции
//----------- //-----------
//Тело модуля //Тело модуля
@ -42,8 +44,22 @@ const TechObjCard = ({ cardData }) => {
); );
}; };
//Контроль свойств - Карточка технического объекта
TechObjCard.propTypes = {
cardData: PropTypes.object
};
//Форматирование значений колонок таблицы технических объектов
const eqConfigTechObjTableValueFormatter = ({ value, columnDef }) => {
switch (columnDef.name) {
case "DOPER_DATE":
return formatDateRF(value);
}
return value;
};
//---------------- //----------------
//Интерфейс модуля //Интерфейс модуля
//---------------- //----------------
export { TechObjCard }; export { TechObjCard, eqConfigTechObjTableValueFormatter };