+ {dialogs.makeEqRpSheet ?
: null}
@@ -155,12 +209,15 @@ const ForecastTab = ({ onGoToAdmin }) => {
{techObjCardId ? (
- !techObjCardIsLoading && !techObjModelsListIsLoading ? (
+ !techObjCardIsLoading ? (
) : null
) : techObjsDataGrid.init ? (
diff --git a/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js b/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js
index 3cb34c1..61d3ccd 100644
--- a/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js
+++ b/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js
@@ -225,8 +225,59 @@ const useTechObjModelsList = (id, refresh) => {
return { techObjModelsList: data, techObjModelsListIsLoading: isLoading };
};
+//Загрузка истории запросов к модели единицы оборудования
+const useTechObjForecastHistList = (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.CMMLH_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 { techObjForecastHistList: data, techObjForecastHistListIsLoading: isLoading };
+};
+
//----------------
//Интерфейс модуля
//----------------
-export { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel, useTechObjModelsList };
+export {
+ useEqConfigTree,
+ useEqConfigTechObjTable,
+ useEqConfigTechObjCard,
+ findTreeItem,
+ needLoadLevel,
+ useTechObjModelsList,
+ useTechObjForecastHistList
+};
diff --git a/panels/eqs_tech_cond_forecast/forecast_tab_layout.js b/panels/eqs_tech_cond_forecast/forecast_tab_layout.js
index 4803d16..f8022d8 100644
--- a/panels/eqs_tech_cond_forecast/forecast_tab_layout.js
+++ b/panels/eqs_tech_cond_forecast/forecast_tab_layout.js
@@ -7,15 +7,33 @@
//Подключение библиотек
//---------------------
-import React from "react"; //Классы React
+import React, { useState, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
-import { Stack, Icon, Box, Card, CardContent, Typography, CardActions, Button, IconButton, Divider } from "@mui/material"; //Интерфейсные компоненты
+import {
+ Stack,
+ Icon,
+ Box,
+ Card,
+ CardContent,
+ Typography,
+ CardActions,
+ Button,
+ IconButton,
+ Divider,
+ Link,
+ Dialog,
+ DialogTitle,
+ DialogContent,
+ DialogActions
+} from "@mui/material"; //Интерфейсные компоненты
import { useTheme } from "@mui/material/styles"; //Темы оформления
+import { ApplicationСtx } from "../../context/application"; //Контекст приложения
+import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы
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";
+import { formatDateRF, xml2JSON } from "../../core/utils"; //Вспомогательные функции
+import { SCROLL_STYLES, formatModelStateValue, IUDFormTextField } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка
+import { P8PChart } from "../../components/p8p_chart"; //График
//---------
//Константы
@@ -28,7 +46,13 @@ const STYLES = {
EQ_ML_TABLE: {
maxHeight: "200px",
...SCROLL_STYLES
- }
+ },
+ EQ_FORECAST_TABLE: {
+ maxHeight: "200px",
+ ...SCROLL_STYLES
+ },
+ EQ_FORECAST_DETAIL_DIALOG: { maxWidth: "600px" },
+ EQ_FORECAST_DETAIL_CHART: { width: "550px", display: "flex", justifyContent: "center" }
};
//------------------------------------
@@ -48,7 +72,7 @@ const techObjCardModelsTableHeadCellRender = ({ columnDef }) => {
}
};
-//Форматирование колонок таблицы моделей класса оборудования выборки данных
+//Форматирование колонок таблицы моделей единицы оборудования
const techObjCardModelsTableDataCellRender = ({ row, columnDef, theme, onGoToModel, onGetPrediction }) => {
switch (columnDef.name) {
case "SNEQUIPDS":
@@ -79,15 +103,71 @@ const techObjCardModelsTableDataCellRender = ({ row, columnDef, theme, onGoToMod
}
};
+//Форматирование колонок таблицы истории прогнозов класса оборудования выборки данных
+const techObjCardForecastListTableDataCellRender = ({ row, columnDef, onShowForecastDetail }) => {
+ switch (columnDef.name) {
+ case "NFORECAST":
+ return {
+ data: (
+
+ )
+ };
+ }
+};
+
+//Детали прогноза
+const ForecastDetail = ({ date, forecast, onClose }) => {
+ //Собственное состояние - график
+ const [chart, setChart] = useState({ loaded: false, labels: [], datasets: [] });
+
+ //При подключении к странице
+ useEffect(() => {
+ const loadChart = async () => {
+ const chart = await xml2JSON({ xmlDoc: forecast });
+ console.log(chart);
+ setChart(pv => ({ ...pv, loaded: true, ...chart.XDATA.XCHART }));
+ };
+ loadChart();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ //Генерация содержимого
+ return (
+
+ );
+};
+
+//Контроль свойств - Детали прогноза
+ForecastDetail.propTypes = {
+ date: PropTypes.string.isRequired,
+ forecast: PropTypes.string.isRequired,
+ onClose: PropTypes.func
+};
+
//-----------
//Тело модуля
//-----------
//Карточка технического объекта
-const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => {
+const TechObjCard = ({ cardData, modelsList, forecastHistList, onClose, onGoToModel, onGetPrediction, onMakeEqRpSheet }) => {
//Подключаемся к теме
const theme = useTheme();
+ //Собственное состояние
+ const [state, setState] = useState({ forecastDetail: null, forecastDate: null });
+
//При нажатии на кнопку закрытия карточки
const handleClose = () => (onClose ? onClose() : null);
@@ -95,13 +175,25 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => {
const handleGoToModelClick = model => (onGoToModel ? onGoToModel(model) : null);
//При нажатии на запрос предсказания
- const handleGetPredictionClick = model => {
- console.log(model);
+ const handleGetPredictionClick = model => (onGetPrediction ? onGetPrediction(model) : null);
+
+ //При нажатии на формирование ремонтной ведомости
+ const handleMakeEqRpSheetClick = () => (onMakeEqRpSheet ? onMakeEqRpSheet() : null);
+
+ //При нажатии на отображение деталей прогноза
+ const handleShowForecastDetailClick = modelHist => {
+ setState(pv => ({ ...pv, forecastDetail: modelHist.SFORECAST, forecastDate: modelHist.SRQ_DATE }));
};
+ //При нажатии на закрытие деталей прогноза
+ const handleCloseForecastDetailClick = () => setState(pv => ({ ...pv, forecastDetail: null, forecastDate: null }));
+
//Генерация содержимого
return (
+ {state.forecastDetail ? (
+
+ ) : null}
@@ -122,33 +214,61 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => {
{cardData.SNAME}
-
-
- Модели
-
-
- techObjCardModelsTableDataCellRender({
- ...prms,
- theme,
- onGoToModel: handleGoToModelClick,
- onGetPrediction: handleGetPredictionClick
- })
- }
- />
-
+ {modelsList.init ? (
+ <>
+
+
+ Модели
+
+
+ techObjCardModelsTableDataCellRender({
+ ...prms,
+ theme,
+ onGoToModel: handleGoToModelClick,
+ onGetPrediction: handleGetPredictionClick
+ })
+ }
+ />
+ >
+ ) : null}
+ {forecastHistList.init ? (
+ <>
+
+
+ Прогнозы
+
+
+ techObjCardForecastListTableDataCellRender({
+ ...prms,
+ theme,
+ onShowForecastDetail: handleShowForecastDetailClick
+ })
+ }
+ />
+ >
+ ) : null}
-
+
@@ -159,8 +279,11 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => {
TechObjCard.propTypes = {
cardData: PropTypes.object.isRequired,
modelsList: PropTypes.object.isRequired,
+ forecastHistList: PropTypes.object.isRequired,
onClose: PropTypes.func,
- onGoToModel: PropTypes.func
+ onGoToModel: PropTypes.func,
+ onGetPrediction: PropTypes.func,
+ onMakeEqRpSheet: PropTypes.func
};
//Формирование значения для колонки "Медель" таблицы технических объектов
@@ -198,8 +321,81 @@ const eqConfigTechObjTableDataCellRender = ({ row, columnDef, onCMMLStatus }) =>
}
};
+//Диалог формирование ремонтной ведомости
+const TechObjMakeEqRpSheet = ({ onOk, onCancel }) => {
+ //Подключение к контексту приложения
+ const { pOnlineShowDictionary } = useContext(ApplicationСtx);
+
+ //Собственное состояние - значения формы
+ const [values, setValues] = useState({
+ acatalog: "",
+ eQTecSrvKind: "",
+ planDateFrom: ""
+ });
+
+ //Отработка воода значения в форму
+ const handleValueChanged = (name, value) => setValues(pv => ({ ...pv, [name]: value }));
+
+ //Выбор каталога размещения ремонтной ведомости
+ const selectEquipRepairSheetsCatalog = (name, callBack) => {
+ pOnlineShowDictionary({
+ unitCode: "EquipRepairSheets",
+ showMethod: "catalog",
+ callBack: res => callBack(res.success ? [{ name, value: res.outParameters.ctlgname }] : null)
+ });
+ };
+
+ //Выбор вида технического обслуживания
+ const selectEquipTechServiceKinds = (name, callBack) => {
+ pOnlineShowDictionary({
+ unitCode: "EquipTechServiceKinds",
+ callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_CODE }] : null)
+ });
+ };
+
+ //Генерация содержимого
+ return (
+
+ );
+};
+
+//Контроль свойств - Диалог формирование ремонтной ведомости
+TechObjMakeEqRpSheet.propTypes = {
+ onOk: PropTypes.func,
+ onCancel: PropTypes.func
+};
+
//----------------
//Интерфейс модуля
//----------------
-export { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender };
+export { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender, TechObjMakeEqRpSheet };