From a457181a0db2f2a259f0c78e171c2910c509369c Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Thu, 23 May 2024 16:29:32 +0300 Subject: [PATCH] =?UTF-8?q?WEB=20APP:=20=D0=9F=D0=B0=D0=BD=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=20"=D0=9C=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20=D0=B8?= =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D0=BB=D0=B8=D0=B9"=20-=20=D0=BE=D0=B1=D1=8A?= =?UTF-8?q?=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D1=8B=20backend.js=20?= =?UTF-8?q?=D0=B8=20hooks.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/panels/mech_rec_assembly_mon/backend.js | 200 ------------------ .../components/plan_detail.js | 2 +- app/panels/mech_rec_assembly_mon/hooks.js | 193 ++++++++++++++++- .../mech_rec_assembly_mon.js | 11 +- 4 files changed, 199 insertions(+), 207 deletions(-) delete mode 100644 app/panels/mech_rec_assembly_mon/backend.js diff --git a/app/panels/mech_rec_assembly_mon/backend.js b/app/panels/mech_rec_assembly_mon/backend.js deleted file mode 100644 index 7264b6b..0000000 --- a/app/panels/mech_rec_assembly_mon/backend.js +++ /dev/null @@ -1,200 +0,0 @@ -//--------------------- -//Подключение библиотек -//--------------------- - -import { useState, useCallback, useEffect, useContext } from "react"; //Классы React -import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером -import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции - -//--------- -//Константы -//--------- - -//Размер страницы данных -const DATA_GRID_PAGE_SIZE = 0; - -//----------- -//Тело модуля -//----------- - -//Хук для основной таблицы панели -const useMechRecAssemblyMon = () => { - //Собственное состояние - let [state, setState] = useState({ - init: false, - showPlanList: false, - planCtlgs: [], - planCtlgsLoaded: false, - selectedPlanCtlg: {}, - plans: [], - plansLoaded: false, - selectedPlan: {} - }); - - //Подключение к контексту взаимодействия с сервером - const { executeStored } = useContext(BackEndСtx); - - //Инициализация каталогов планов - const initPlanCtlgs = useCallback(async () => { - if (!state.init) { - const data = await executeStored({ - stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_CTLG_INIT", - args: {}, - respArg: "COUT", - isArray: name => name === "XFCPRODPLAN_CRNS" - }); - setState(pv => ({ ...pv, init: true, planCtlgs: [...(data?.XFCPRODPLAN_CRNS || [])], planCtlgsLoaded: true })); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [state.init, executeStored]); - - //Получение информации о планах каталога - const loadPlans = useCallback( - async NCRN => { - if (NCRN) { - const data = await executeStored({ - stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_GET", - args: { NCRN: NCRN }, - respArg: "COUT", - isArray: name => name === "XFCPRODPLAN_INFO" - }); - setState(pv => ({ ...pv, init: true, plans: [...(data?.XFCPRODPLAN_INFO || [])], plansLoaded: true })); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, - [executeStored] - ); - - //Выбор каталога планов - const selectPlanCtlg = planCtlg => { - setState(pv => ({ - ...pv, - selectedPlanCtlg: { ...planCtlg }, - selectedPlan: {}, - showPlanList: false - })); - }; - - //Сброс выбора каталога планов - const unselectPlanCtlg = () => - setState(pv => ({ - ...pv, - selectedPlanCtlg: {}, - selectedPlan: {}, - showPlanList: false - })); - - //При подключении компонента к странице - useEffect(() => { - initPlanCtlgs(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - //При изменении каталога - useEffect(() => { - //Если каталог выбран - if (state.selectedPlanCtlg) { - loadPlans(state.selectedPlanCtlg.NRN); - } else { - setState(pv => ({ ...pv, plans: [], plansLoaded: false })); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [state.selectedPlanCtlg]); - - return [state, setState, selectPlanCtlg, unselectPlanCtlg]; -}; - -//Хук для информации по производственным составам -const useCostProductComposition = nProdPlan => { - //Собственное состояние - let [costProductComposition, setCostProductComposition] = useState({ - init: false, - showPlanList: false, - products: [], - productsLoaded: false, - model: null, - selectedProduct: null - }); - - //Подключение к контексту взаимодействия с сервером - const { executeStored } = useContext(BackEndСtx); - - //Инициализация производственных составов - const initCostProductComposition = useCallback(async () => { - if (!costProductComposition.init) { - const data = await executeStored({ - stored: "PKG_P8PANELS_MECHREC.FCPRODCMP_DETAILS_GET", - args: { NFCPRODPLAN: nProdPlan }, - respArg: "COUT", - isArray: name => name === "XFCPRODCMP" - }); - setCostProductComposition(pv => ({ - ...pv, - init: true, - products: [...(data?.XFCPRODCMP || [])], - productsLoaded: true, - model: data?.BMODEL - })); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [costProductComposition.init, executeStored]); - - //При подключении компонента к странице - useEffect(() => { - initCostProductComposition(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return [costProductComposition, setCostProductComposition]; -}; - -//Хук для таблицы детализации изделия -const useProductDetailsTable = (plan, product, orders, pageNumber, stored) => { - //Собственное состояние - флаг загрузки - const [isLoading, setLoading] = useState(true); - - //Собственное состояние - таблица данных - const [data, setData] = useState({ - columnsDef: [], - rows: [], - morePages: true - }); - - //Подключение к контексту взаимодействия с сервером - const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx); - - //Загрузка данных при изменении зависимостей - useEffect(() => { - const loadData = async () => { - try { - setLoading(true); - const data = await executeStored({ - stored, - args: { - NPRODCMPSP: product, - NFCPRODPLAN: plan, - CORDERS: { VALUE: object2Base64XML(orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB }, - NPAGE_NUMBER: pageNumber, - NPAGE_SIZE: DATA_GRID_PAGE_SIZE, - NINCLUDE_DEF: 1 - }, - respArg: "COUT" - }); - setData(pv => ({ - ...pv, - columnsDef: data.XCOLUMNS_DEF ? [...data.XCOLUMNS_DEF] : pv.columnsDef, - rows: pageNumber == 1 ? [...(data.XROWS || [])] : [...pv.rows, ...(data.XROWS || [])], - morePages: DATA_GRID_PAGE_SIZE == 0 ? false : (data.XROWS || []).length >= DATA_GRID_PAGE_SIZE - })); - } finally { - setLoading(false); - } - }; - if (plan && product) loadData(); - }, [plan, product, orders, pageNumber, stored, executeStored, SERV_DATA_TYPE_CLOB]); - - //Вернём данные - return { data, isLoading }; -}; - -export { useMechRecAssemblyMon, useCostProductComposition, useProductDetailsTable }; diff --git a/app/panels/mech_rec_assembly_mon/components/plan_detail.js b/app/panels/mech_rec_assembly_mon/components/plan_detail.js index 7068b2a..305928d 100644 --- a/app/panels/mech_rec_assembly_mon/components/plan_detail.js +++ b/app/panels/mech_rec_assembly_mon/components/plan_detail.js @@ -13,7 +13,7 @@ import { Box, Grid, Container, Button, Typography, Icon, Stack, IconButton } fro import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../../components/p8p_data_grid"; //Таблица данных import { P8PSVG } from "../../../components/p8p_svg"; //Интерактивные изображения import { P8P_DATA_GRID_CONFIG_PROPS } from "../../../config_wrapper"; //Подключение компонентов к настройкам приложения -import { useCostProductComposition, useProductDetailsTable } from "../backend"; //Взаимодействие с сервером +import { useCostProductComposition, useProductDetailsTable } from "../hooks"; //Вспомогательные хуки import { ProgressBox } from "./progress_box"; //Информация по прогрессу объекта //--------- diff --git a/app/panels/mech_rec_assembly_mon/hooks.js b/app/panels/mech_rec_assembly_mon/hooks.js index 136c16c..c8ace98 100644 --- a/app/panels/mech_rec_assembly_mon/hooks.js +++ b/app/panels/mech_rec_assembly_mon/hooks.js @@ -7,7 +7,16 @@ //Подключение библиотек //--------------------- -import React from "react"; //Классы React +import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React +import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером +import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции + +//--------- +//Константы +//--------- + +//Размер страницы данных +const DATA_GRID_PAGE_SIZE = 0; //----------- //Тело модуля @@ -25,3 +34,185 @@ export const useFilteredPlanCtlgs = (planCtlgs, filter) => { return filteredPlanCtlgs; }; + +//Хук для основной таблицы панели +const useMechRecAssemblyMon = () => { + //Собственное состояние + let [state, setState] = useState({ + init: false, + showPlanList: false, + planCtlgs: [], + planCtlgsLoaded: false, + selectedPlanCtlg: {}, + plans: [], + plansLoaded: false, + selectedPlan: {} + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Инициализация каталогов планов + const initPlanCtlgs = useCallback(async () => { + if (!state.init) { + const data = await executeStored({ + stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_AM_CTLG_INIT", + args: {}, + respArg: "COUT", + isArray: name => name === "XFCPRODPLAN_CRNS" + }); + setState(pv => ({ ...pv, init: true, planCtlgs: [...(data?.XFCPRODPLAN_CRNS || [])], planCtlgsLoaded: true })); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [state.init, executeStored]); + + //Получение информации о планах каталога + const loadPlans = useCallback( + async NCRN => { + if (NCRN) { + const data = await executeStored({ + stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_GET", + args: { NCRN: NCRN }, + respArg: "COUT", + isArray: name => name === "XFCPRODPLAN_INFO" + }); + setState(pv => ({ ...pv, init: true, plans: [...(data?.XFCPRODPLAN_INFO || [])], plansLoaded: true })); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, + [executeStored] + ); + + //Выбор каталога планов + const selectPlanCtlg = planCtlg => { + setState(pv => ({ + ...pv, + selectedPlanCtlg: { ...planCtlg }, + selectedPlan: {}, + showPlanList: false + })); + }; + + //Сброс выбора каталога планов + const unselectPlanCtlg = () => + setState(pv => ({ + ...pv, + selectedPlanCtlg: {}, + selectedPlan: {}, + showPlanList: false + })); + + //При подключении компонента к странице + useEffect(() => { + initPlanCtlgs(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + //При изменении каталога + useEffect(() => { + //Если каталог выбран + if (state.selectedPlanCtlg) { + loadPlans(state.selectedPlanCtlg.NRN); + } else { + setState(pv => ({ ...pv, plans: [], plansLoaded: false })); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [state.selectedPlanCtlg]); + + return [state, setState, selectPlanCtlg, unselectPlanCtlg]; +}; + +//Хук для информации по производственным составам +const useCostProductComposition = nProdPlan => { + //Собственное состояние + let [costProductComposition, setCostProductComposition] = useState({ + init: false, + showPlanList: false, + products: [], + productsLoaded: false, + model: null, + selectedProduct: null + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Инициализация производственных составов + const initCostProductComposition = useCallback(async () => { + if (!costProductComposition.init) { + const data = await executeStored({ + stored: "PKG_P8PANELS_MECHREC.FCPRODCMP_DETAILS_GET", + args: { NFCPRODPLAN: nProdPlan }, + respArg: "COUT", + isArray: name => name === "XFCPRODCMP" + }); + setCostProductComposition(pv => ({ + ...pv, + init: true, + products: [...(data?.XFCPRODCMP || [])], + productsLoaded: true, + model: data?.BMODEL + })); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [costProductComposition.init, executeStored]); + + //При подключении компонента к странице + useEffect(() => { + initCostProductComposition(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return [costProductComposition, setCostProductComposition]; +}; + +//Хук для таблицы детализации изделия +const useProductDetailsTable = (plan, product, orders, pageNumber, stored) => { + //Собственное состояние - флаг загрузки + const [isLoading, setLoading] = useState(true); + + //Собственное состояние - таблица данных + const [data, setData] = useState({ + columnsDef: [], + rows: [], + morePages: true + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx); + + //Загрузка данных при изменении зависимостей + useEffect(() => { + const loadData = async () => { + try { + setLoading(true); + const data = await executeStored({ + stored, + args: { + NPRODCMPSP: product, + NFCPRODPLAN: plan, + CORDERS: { VALUE: object2Base64XML(orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB }, + NPAGE_NUMBER: pageNumber, + NPAGE_SIZE: DATA_GRID_PAGE_SIZE, + NINCLUDE_DEF: 1 + }, + respArg: "COUT" + }); + setData(pv => ({ + ...pv, + columnsDef: data.XCOLUMNS_DEF ? [...data.XCOLUMNS_DEF] : pv.columnsDef, + rows: pageNumber == 1 ? [...(data.XROWS || [])] : [...pv.rows, ...(data.XROWS || [])], + morePages: DATA_GRID_PAGE_SIZE == 0 ? false : (data.XROWS || []).length >= DATA_GRID_PAGE_SIZE + })); + } finally { + setLoading(false); + } + }; + if (plan && product) loadData(); + }, [plan, product, orders, pageNumber, stored, executeStored, SERV_DATA_TYPE_CLOB]); + + //Вернём данные + return { data, isLoading }; +}; + +export { useMechRecAssemblyMon, useCostProductComposition, useProductDetailsTable }; diff --git a/app/panels/mech_rec_assembly_mon/mech_rec_assembly_mon.js b/app/panels/mech_rec_assembly_mon/mech_rec_assembly_mon.js index 18e560e..972afc7 100644 --- a/app/panels/mech_rec_assembly_mon/mech_rec_assembly_mon.js +++ b/app/panels/mech_rec_assembly_mon/mech_rec_assembly_mon.js @@ -15,8 +15,7 @@ import { MessagingСtx } from "../../context/messaging"; //Контекст со import { PlansList } from "./components/plans_list"; //Список планов import { PlanDetail } from "./components/plan_detail"; //Детали плана import { theme } from "./styles/themes"; //Стиль темы -import { useFilteredPlanCtlgs } from "./hooks"; //Вспомогательные хуки -import { useMechRecAssemblyMon } from "./backend"; //Хук корневой панели мониторинга сборки изделий +import { useMechRecAssemblyMon, useFilteredPlanCtlgs } from "./hooks"; //Вспомогательные хуки //--------- //Константы @@ -194,9 +193,11 @@ const MechRecAssemblyMon = () => { state.selectedPlanCtlg.NRN ? ( <> - {`${state.selectedPlanCtlg.SNAME} ${ - state.selectedPlanCtlg.NMIN_YEAR ? `с ${state.selectedPlanCtlg.NMIN_YEAR} г` : "" - } ${state.selectedPlanCtlg.NMAX_YEAR ? `по ${state.selectedPlanCtlg.NMAX_YEAR}` : ""}`} + {`${state.selectedPlanCtlg.SNAME} на ${state.selectedPlanCtlg.NMIN_YEAR} ${ + state.selectedPlanCtlg.NMIN_YEAR == state.selectedPlanCtlg.NMAX_YEAR + ? "г." + : `- ${state.selectedPlanCtlg.NMAX_YEAR} г.г.` + } `} {state.plansLoaded == true ? ( state.selectedPlan.NRN ? (