/* Парус 8 - Панели мониторинга - ПУП - Мониторинг сборки изделий Панель мониторинга: Детализация по объекту */ //--------------------- //Подключение библиотек //--------------------- import React, { useEffect, useState } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Box, Grid, Container, Button, Typography, Icon, Stack, IconButton } from "@mui/material"; //Интерфейсные элементы 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 "../hooks"; //Вспомогательные хуки import { ProgressBox } from "./progress_box"; //Информация по прогрессу объекта //--------- //Константы //--------- //Стили const STYLES = { BOX_INFO_MAIN: { border: "1px solid", borderRadius: "25px", height: "35vh" }, BOX_INFO_SUB: isMessage => ({ overflow: "hidden", textAlign: "center", width: "100%", height: "100%", display: "flex", flexDirection: "column", justifyContent: isMessage ? "center" : "flex-start", paddingLeft: "5px", paddingRight: "5px", ...(isMessage ? { padding: "5px" } : { paddingTop: "10px" }) }), DETAIL_INFO: { display: "flex", justifyContent: "space-around", alignItems: "center", border: "1px solid", borderRadius: "25px", height: "17vh" }, PRODUCT_SELECTOR_CONTAINER: { display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column", border: "1px solid", borderRadius: "25px", height: "53vh", marginTop: "16px" }, PRODUCT_SELECTOR_MODEL: { width: "70%" }, PLAN_INFO_MAIN: { display: "flex", flexDirection: "column", gap: "16px" }, PLAN_INFO_SUB: { display: "flex", justifyContent: "space-between", width: "280px", borderBottom: "1px solid" }, TABLE_DETAILS: { height: "230px" }, TABLE_DETAILS_HEADER_CELL: maxWidth => ({ padding: "2px 2px", fontSize: "11px", textAlign: "center", lineHeight: "1rem", ...(maxWidth ? { maxWidth } : {}) }), TABLE_DETAILS_DATA_CELL: textAlign => ({ padding: "2px 2px", fontSize: "11px", ...(textAlign ? { textAlign } : {}) }), TABLE_DETAILS_MORE_BUTTON: { borderRadius: "25px" }, CARD_DETAILS_CONTAINER: { minWidth: "1200px", maxWidth: "1400px" }, CARD_DETAILS_NAVIGATION_STACK: { width: "100%" } }; //------------------------------------ //Вспомогательные функции и компоненты //------------------------------------ //Информация о плане const PlanInfo = ({ plan }) => { return ( <> Номер борта: {plan.SNUMB} Год выпуска: {plan.NYEAR} ); }; //Контроль свойств - Информация о плане PlanInfo.propTypes = { plan: PropTypes.object }; //Модель выпуска плана const PlanProductCompositionModel = ({ model, products, onProductSelect }) => { //При выборе детали на модели const handleProductClick = ({ item }) => { const product = products.find(p => p.SMODEL_ID == item.id); if (product && onProductSelect) onProductSelect(product); }; //Генерация содержимого return ( <> {model ? ( ({ id: p.SMODEL_ID, backgroundColor: p.SMODEL_BG_COLOR || "red", desc: p.SNAME, title: p.SNAME }))} fillOpacity={"0.3"} onItemClick={handleProductClick} /> ) : ( Модель изделия не загружена )} ); }; //Контроль свойств - Модель выпуска плана PlanProductCompositionModel.propTypes = { model: PropTypes.any, products: PropTypes.array, onProductSelect: PropTypes.func }; //Генерация представления ячейки заголовка const headCellRender = ({ columnDef }) => ({ stackProps: { justifyContent: "center" }, cellStyle: STYLES.TABLE_DETAILS_HEADER_CELL( ["NREMN_LABOUR", "NAPPLICABILITY"].includes(columnDef.name) ? "90px" : ["NDEFICIT"].includes(columnDef.name) ? "55px" : null ) }); //Генерация заливки строки исходя от значений const dataCellRender = ({ row, columnDef }) => ({ cellStyle: STYLES.TABLE_DETAILS_DATA_CELL(["SOPERATION", "SNOMEN"].includes(columnDef.name) ? null : "center"), data: row[columnDef] }); //Таблица детализации изделия const ProductDetailsTable = ({ plan, product, stored, noProductMessage, noDataFoundMessage, title }) => { //Собственное состояние const [state, setState] = useState({ plan: null, product: null, orders: null, pageNumber: 1 }); //Собственное состояние - данные таблицы const { data, isLoading } = useProductDetailsTable(state.plan, state.product, state.orders, state.pageNumber, stored); //При изменении состояния сортировки const handleOrderChanged = ({ orders }) => setState(pv => ({ ...pv, orders: [...orders], pageNumber: 1 })); //При изменении количества отображаемых страниц const handlePagesCountChanged = () => setState(pv => ({ ...pv, pageNumber: pv.pageNumber + 1 })); //При изменении изделия useEffect(() => { setState(pv => ({ ...pv, plan, product, orders: null, pageNumber: 1 })); }, [product, plan]); //Генерация содержимого return ( {!product ? ( {noProductMessage} ) : ( <> {title} )} ); }; //Контроль свойств - Таблица детализации изделия ProductDetailsTable.propTypes = { plan: PropTypes.number.isRequired, product: PropTypes.number, stored: PropTypes.string.isRequired, noProductMessage: PropTypes.string.isRequired, noDataFoundMessage: PropTypes.string.isRequired, title: PropTypes.string.isRequired }; //----------- //Тело модуля //----------- //Детализация по объекту const PlanDetail = ({ plan, disableNavigatePrev = false, disableNavigateNext = false, onNavigate, onBack }) => { //Собственное состояние - данные производственных составов SVG const [costProductComposition, setCostProductComposition] = useCostProductComposition(plan.NRN); //Выбор элемента изделия const setProduct = product => { setCostProductComposition(pv => ({ ...pv, selectedProduct: product ? { ...product } : null })); }; //При навигации между карточками const handleNavigate = direction => { setProduct(null); if (onNavigate) onNavigate(direction); }; //Формируем представление return ( handleNavigate(-1)}> navigate_before handleNavigate(1)}> navigate_next ); }; //Контроль свойств - Детализация по объекту PlanDetail.propTypes = { plan: PropTypes.object, disableNavigatePrev: PropTypes.bool, disableNavigateNext: PropTypes.bool, onNavigate: PropTypes.func, onBack: PropTypes.func }; //---------------- //Интерфейс модуля //---------------- export { PlanDetail };