/*
Парус 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 };