diff --git a/app/panels/mech_rec_dept_cost_prod_plans/hooks.js b/app/panels/mech_rec_dept_cost_prod_plans/hooks.js index 38b4e2c..4f8244a 100644 --- a/app/panels/mech_rec_dept_cost_prod_plans/hooks.js +++ b/app/panels/mech_rec_dept_cost_prod_plans/hooks.js @@ -7,7 +7,7 @@ //Подключение библиотек //--------------------- -import React, { useState, useEffect, useContext } from "react"; //Классы React +import React, { useState, useEffect, useContext, useCallback } from "react"; //Классы React import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { object2Base64XML, formatDateRF } from "../../core/utils"; //Вспомогательные функции @@ -32,17 +32,60 @@ export const useFilteredPlans = (plans, filter) => { return filteredPlans; }; -//Хук для основной таблицы -const useDeptCostProdPlans = () => { +//Хук для планов +const useDeptCostProdPlans = month => { + //Собственное состояние - таблица данных + const [state, setState] = useState({ + init: false, + loaded: false, + showPlanList: false, + rows: [], + reload: true, + selected: {}, + currentMonth: "" + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //При подключении компонента к странице + useEffect(() => { + const initPlans = async () => { + const data = await executeStored({ + stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_DEPT_INIT", + args: { SMONTH: month }, + respArg: "COUT", + isArray: name => name === "XFCPRODPLANS", + attributeValueProcessor: (name, val) => (name === "SPERIOD" ? undefined : val) + }); + setState(pv => ({ + ...pv, + init: true, + rows: [...(data?.XFCPRODPLANS || [])], + loaded: true, + reload: false, + selected: {}, + currentMonth: month + })); + }; + //Если месяц указан и он не соответствует текущим данным + if (month && month !== state.currentMonth) { + initPlans(); + } + }, [executeStored, month, state.currentMonth]); + + //Возвращаем данные + return [state, setState]; +}; + +//Хук для информации о плане +const useDeptCostProdPlanInfo = plan => { //Собственное состояние - таблица данных const [state, setState] = useState({ init: false, showPlanList: false, showIncomeFromDeps: null, showFcroutelst: null, - planList: [], - planListLoaded: false, - selectedPlan: {}, dataLoaded: false, columnsDef: [], orders: null, @@ -57,14 +100,43 @@ const useDeptCostProdPlans = () => { //Подключение к контексту взаимодействия с сервером const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx); + //При необходимости очистки данных о плане + const handleClear = useCallback( + () => + setState(pv => ({ + ...pv, + init: false, + showPlanList: false, + showIncomeFromDeps: null, + showFcroutelst: null, + dataLoaded: false, + columnsDef: [], + orders: null, + rows: [], + reload: true, + pageNumber: 1, + morePages: true, + fixedHeader: false, + fixedColumns: 0 + })), + [] + ); + + //При изменении состояния сортировки + const handleOrderChanged = ({ orders }) => setState(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true })); + + //При изменении количества отображаемых страниц + const handlePagesCountChanged = () => setState(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true })); + //При необходимости обновить данные таблицы useEffect(() => { - if (state.selectedPlan.NRN) { + //Если план выбран + if (plan.NRN) { const loadData = async () => { const data = await executeStored({ stored: "PKG_P8PANELS_MECHREC.FCPRODPLANSP_DEPT_DG_GET", args: { - NFCPRODPLAN: state.selectedPlan.NRN, + NFCPRODPLAN: plan.NRN, CORDERS: { VALUE: object2Base64XML(state.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB }, NPAGE_NUMBER: state.pageNumber, NPAGE_SIZE: DATA_GRID_PAGE_SIZE_LARGE, @@ -76,6 +148,7 @@ const useDeptCostProdPlans = () => { setState(pv => ({ ...pv, ...data.XDATA_GRID, + init: true, columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef, rows: pv.pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])], dataLoaded: true, @@ -83,31 +156,20 @@ const useDeptCostProdPlans = () => { morePages: (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE_LARGE })); }; + //Если необходимо перезагрузить if (state.reload) { loadData(); } } - }, [state.selectedPlan, state.reload, state.orders, state.pageNumber, state.dataLoaded, executeStored, SERV_DATA_TYPE_CLOB]); - - //При подключении компонента к странице - useEffect(() => { - const initPlans = async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_DEPT_INIT", - args: {}, - respArg: "COUT", - isArray: name => name === "XFCPRODPLANS", - attributeValueProcessor: (name, val) => (name === "SPERIOD" ? undefined : val) - }); - setState(pv => ({ ...pv, init: true, planList: [...(data?.XFCPRODPLANS || [])], planListLoaded: true })); - }; - if (!state.init) { - initPlans(); + //Если план не выбран и есть какие-то данные + if (!plan.NRN && state.dataLoaded) { + //Очищаем их + handleClear(); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [plan.NRN, state.reload, state.orders, state.pageNumber, state.dataLoaded, executeStored, SERV_DATA_TYPE_CLOB, handleClear]); - return [state, setState]; + //Возвращаем данные + return [state, setState, handleClear, handleOrderChanged, handlePagesCountChanged]; }; //Хук для таблицы маршрутных листов @@ -164,6 +226,7 @@ const useCostRouteLists = task => { task ]); + //Возвращаем данные return [costRouteLists, setCostRouteLists]; }; @@ -223,6 +286,7 @@ const useCostRouteListsSpecs = mainRowRN => { mainRowRN ]); + //Возвращаем данные return [costRouteListsSpecs, setCostRouteListsSpecs]; }; @@ -272,7 +336,8 @@ const useIncomFromDeps = task => { } }, [SERV_DATA_TYPE_CLOB, executeStored, incomFromDeps.dataLoaded, incomFromDeps.orders, incomFromDeps.pageNumber, incomFromDeps.reload, task]); + //Возвращаем данные return [incomFromDeps, setIncomFromDeps]; }; -export { useDeptCostProdPlans, useCostRouteLists, useCostRouteListsSpecs, useIncomFromDeps }; +export { useDeptCostProdPlans, useDeptCostProdPlanInfo, useCostRouteLists, useCostRouteListsSpecs, useIncomFromDeps }; diff --git a/app/panels/mech_rec_dept_cost_prod_plans/mech_rec_dept_cost_prod_plans.js b/app/panels/mech_rec_dept_cost_prod_plans/mech_rec_dept_cost_prod_plans.js index f037bb1..86f3c8a 100644 --- a/app/panels/mech_rec_dept_cost_prod_plans/mech_rec_dept_cost_prod_plans.js +++ b/app/panels/mech_rec_dept_cost_prod_plans/mech_rec_dept_cost_prod_plans.js @@ -12,7 +12,7 @@ import PropTypes from "prop-types"; //Контроль свойств компо import { Drawer, Fab, Box, List, ListItemButton, ListItemText, Typography, TextField, Link, Grid } from "@mui/material"; //Интерфейсные элементы import { APP_STYLES } from "../../../app.styles"; //Типовые стили import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы -import { useDeptCostProdPlans, useFilteredPlans } from "./hooks"; //Вспомогательные хуки +import { useDeptCostProdPlans, useFilteredPlans, useDeptCostProdPlanInfo } from "./hooks"; //Вспомогательные хуки import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений @@ -34,7 +34,8 @@ const TITLE_PADDING_BOTTOM = "20px"; //Стили const STYLES = { - PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" }, + PLANS_FILTER: { paddingTop: "20px", display: "flex", flexDirection: "column", alignItems: "center", gap: "5px" }, + PLANS_FILTER_ITEM: { margin: "0px 10px", width: "93%" }, PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" }, PLANS_BUTTON: { position: "absolute" }, PLANS_DRAWER: { @@ -60,10 +61,18 @@ const STYLES = { FACT_VALUE: { color: "blue" } }; +//Имена полей компонента +const SFIELD_MONTH = "month"; + //------------------------------------ //Вспомогательные функции и компоненты //------------------------------------ +//Считывание текущего года и месяца в формате "YYYY-MM" +const getCurrentYearMonth = () => { + return `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}`; +}; + //Генерация представления ячейки заголовка группы export const groupCellRender = ({ group }) => ({ cellStyle: STYLES.DATA_GRID_GROUP_CELL, @@ -88,7 +97,7 @@ const getRowBackgroudColor = row => { }; //Генерация заливки строки исходя от значений -const dataCellRender = ({ row, columnDef, handleProdOrderClick, handleMatresCodeClick }) => { +const dataCellRender = ({ row, columnDef, onProdOrderClick, onMatresCodeClick }) => { //Описываем общие свойства let cellProps = { title: row[columnDef.name] }; //Описываем общий стиль @@ -127,7 +136,7 @@ const dataCellRender = ({ row, columnDef, handleProdOrderClick, handleMatresCode cellProps, cellStyle, data: ( - handleProdOrderClick(row["NRN"])}> + onProdOrderClick(row["NRN"])}> {row[columnDef.name]} ) @@ -139,7 +148,7 @@ const dataCellRender = ({ row, columnDef, handleProdOrderClick, handleMatresCode cellProps, cellStyle: STYLES.DATA_GRID_CELL_MATRES_CODE(cellStyle, row), data: ( - handleMatresCodeClick(row["NRN"])}> + onMatresCodeClick(row["NRN"])}> {row[columnDef.name]} ) @@ -149,21 +158,38 @@ const dataCellRender = ({ row, columnDef, handleProdOrderClick, handleMatresCode }; //Список каталогов планов -const PlanList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}) => { +const PlanList = ({ plans = [], selectedPlan, filter, onFilterChange, onClick } = {}) => { + //При изменении фильтра + const handleFilterChange = e => { + onFilterChange && onFilterChange(e); + }; + //Генерация содержимого return (