/* Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания Компонент панели: Таблица информации об операциях сменного задания */ //--------------------- //Подключение библиотек //--------------------- import React from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Typography, Box, Checkbox, Grid, Icon, Button } from "@mui/material"; //Интерфейсные элементы import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { useCostRouteLists, useCostJobsSpecs, useCostEquipment } from "./backend"; //Собственные хуки таблиц //--------- //Константы //--------- const sUnitCostRouteLists = "CostRouteLists"; //Мнемокод раздела маршрутных листов const sUnitCostJobsSpecs = "CostJobsSpecs"; //Мнемокод раздела операций const sUnitCostEquipment = "CostEquipment"; //Мнемокод раздела рабочих центров //Стили const STYLES = { CONTAINER: { textAlign: "center" }, TABLE: { paddingTop: "15px" }, TABLE_SUM: { textAlign: "right", paddingTop: "5px", paddingRight: "15px" }, TABLE_BUTTONS: { display: "flex", justifyContent: "flex-end" }, CHECK_BOX: { textAlign: "center" }, OPERATIONS_SEPARATOR: { padding: "3px 0px", backgroundColor: "lightblue" }, INFORMATION_HALF: { minWidth: "50%", maxWidth: "50%", textAlign: "center" } }; //--------------------------------------------- //Вспомогательные функции форматирования данных //--------------------------------------------- //Формирование списка отмеченных записей function selectedReducer(accumulator, current) { if (current.NSELECT == 1) { accumulator.push(current.NRN); } return accumulator; } //Форматирование значения ячейки const dataCellRender = ({ row, columnDef, handleSelectChange, sUnit, selectedEquip }) => { //Инициализируем доступность выбора let disabled = false; //Если это рабочие центры if (sUnit === sUnitCostEquipment) { //Для колонки выбора if (columnDef.name === "NSELECT") { return { data: ( handleSelectChange(row["NRN"], sUnit, row["NCOEFF"] <= row["NLOADING"])} /> ) }; } //Если оборудование загружено if (row["NCOEFF"] <= row["NLOADING"]) { //Если поле не поле выбора if (columnDef.name !== "NSELECT") { return { cellStyle: { color: "lightgrey" }, data: row[columnDef.name] }; } } } //Если это операции if (sUnit === sUnitCostJobsSpecs) { //Если "Оборудование план" операции сходится с выбранным оборудованием if (selectedEquip.includes(row["NEQUIP_PLAN"])) { //Если колонка выбора if (columnDef.name === "NSELECT") { return { cellStyle: { backgroundColor: "#bce0de" }, data: ( handleSelectChange(row["NRN"], sUnit)} /> ) }; } else { return { cellStyle: { backgroundColor: "#bce0de" }, data: row[columnDef.name] }; } } } //Для колонки выбора if (columnDef.name === "NSELECT") { return { data: ( handleSelectChange(row["NRN"], sUnit)} /> ) }; } return { data: row[columnDef.name] }; }; //Генерация представления ячейки заголовка группы export const headCellRender = ({ columnDef }) => { if (columnDef.name === "NSELECT") { return { stackStyle: { padding: "2px", justifyContent: "space-around" }, data: done }; } else { return { stackStyle: { padding: "2px" }, data: columnDef.caption }; } }; //----------- //Тело модуля //----------- //Таблица информации об операциях сменного задания const CostJobsSpecsDataGrid = ({ task, processIdent, clearSelectlist }) => { //Собственное состояние - таблица данных маршрутных листов const [costRouteLists, setCostRouteLists, modifySelectList] = useCostRouteLists(task, processIdent); //Собственное состояние - таблица данных операций const [costJobsSpecs, setCostJobsSpecs, issueCostJobsSpecs] = useCostJobsSpecs(task, costRouteLists.selectedRows, processIdent); //Собственное состояние - таблица рабочих центров const [costEquipment, setCostEquipment, includeCostEquipment, excludeCostEquipment] = useCostEquipment(); //При изменении состояния сортировки маршрутных листов const costRouteListOrderChanged = ({ orders }) => setCostRouteLists(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true })); //При изменении количества отображаемых страниц маршрутных листов const costRouteListPagesCountChanged = () => setCostRouteLists(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true })); //При изменении состояния сортировки операций const costJobsSpecOrderChanged = ({ orders }) => setCostJobsSpecs(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true })); //При изменении количества отображаемых страниц операций const costJobsSpecPagesCountChanged = () => setCostJobsSpecs(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true })); //При изменении состояния сортировки рабочих центров const costEquipmentOrderChanged = ({ orders }) => setCostEquipment(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true })); //При изменении количества отображаемых страниц рабочих центров const costEquipmentPagesCountChanged = () => setCostEquipment(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true })); //При включении оборудования в операции const costJobsSpecIncludeCostEquipment = () => { //Делаем асинхронно, чтобы при ошибке ничего не обновлять const includeAsync = async () => { //Включаем оборудование в операции try { await includeCostEquipment({ NFCEQUIPMENT: costEquipment.selectedRows[0], NFCJOBS: task, SFCJOBSSP_LIST: costJobsSpecs.selectedRows.join(";") }); //Необходимо обновить все данные setCostJobsSpecs(pv => ({ ...pv, selectedRows: [], reload: true })); setCostEquipment(pv => ({ ...pv, selectedRows: [], selectedLoaded: false, reload: true })); } catch (e) { throw new Error(e.message); } }; //Включаем оборудование асинхронно includeAsync(); }; //При исключении оборудования из операции const costJobsSpecExcludeCostEquipment = () => { //Делаем асинхронно, чтобы при ошибке ничего не обновлять const excludeAsync = async () => { //Включаем оборудование в операции try { await excludeCostEquipment({ NFCEQUIPMENT: costEquipment.selectedRows[0], NFCJOBS: task, SFCJOBSSP_LIST: costJobsSpecs.selectedRows.join(";") }); //Необходимо обновить данные о маршрутных листах и оборудовании setCostJobsSpecs(pv => ({ ...pv, selectedRows: [], reload: true })); setCostEquipment(pv => ({ ...pv, selectedRows: [], reload: true })); } catch (e) { throw new Error(e.message); } }; //Исключаем операции асинхронно excludeAsync(); }; //Выдача задания операции const costJobsSpecIssue = () => { //Делаем асинхронно, чтобы при ошибке ничего не обновлять const issueAsync = async () => { //Включаем оборудование в операции try { await issueCostJobsSpecs({ NFCJOBS: task, SFCJOBSSP_LIST: costJobsSpecs.selectedRows.join(";") }); //Необходимо обновить данные о маршрутных листах и оборудовании clearSelectlist(processIdent); setCostRouteLists(pv => ({ ...pv, selectedRows: [], reload: true })); setCostEquipment(pv => ({ ...pv, selectedRows: [], reload: true })); } catch (e) { throw new Error(e.message); } }; //Выдаем задание асинхронно issueAsync(); }; //При изменение состояния выбора const handleSelectChange = (NRN, sUnit, selectedLoaded) => { //Инициализируем строки таблицы let rows = []; //Индекс элемента в массиве let indexRow = null; //Исходим от раздела switch (sUnit) { //Маршрутные листы case sUnitCostRouteLists: //Инициализируем маршрутными листами rows = costRouteLists.rows; //Определяем индекс элемента в массиве indexRow = rows.findIndex(obj => obj.NRN == NRN); //Изменяем значение выбора rows[indexRow].NSELECT = !rows[indexRow].NSELECT; //Добавляем/удаляем маршрутный лист из селектлиста modifySelectList({ NFCROUTLST: NRN, NSELECT: rows[indexRow].NSELECT }); //Актуализируем строки setCostRouteLists(pv => ({ ...pv, rows: rows, selectedRows: rows.reduce(selectedReducer, []) })); //Выходим break; //Операции case sUnitCostJobsSpecs: //Инициализируем операциями rows = costJobsSpecs.rows; //Определяем индекс элемента в массиве indexRow = rows.findIndex(obj => obj.NRN == NRN); //Изменяем значение выбора rows[indexRow].NSELECT = !rows[indexRow].NSELECT; //Актуализируем строки setCostJobsSpecs(pv => ({ ...pv, rows: rows, selectedRows: rows.reduce(selectedReducer, []) })); //Выходим break; //Рабочие центры case sUnitCostEquipment: //Инициализируем рабочими центрами rows = costEquipment.rows; //Определяем индекс элемента в массиве indexRow = rows.findIndex(obj => obj.NRN == NRN); //Изменяем значение выбора rows[indexRow].NSELECT = !rows[indexRow].NSELECT; //Актуализируем строки setCostEquipment(pv => ({ ...pv, rows: rows, selectedRows: rows.reduce(selectedReducer, []), selectedLoaded: selectedLoaded })); //Выходим break; default: return; } }; //Генерация содержимого return (
Маршрутные листы {costRouteLists.dataLoaded ? ( <> dataCellRender({ ...prms, handleSelectChange, sUnit: sUnitCostRouteLists })} headCellRender={prms => headCellRender({ ...prms })} /> {costRouteLists.selectedRows.length > 0 ? ( <> Операции выбранных маршрутных листов dataCellRender({ ...prms, handleSelectChange, sUnit: sUnitCostJobsSpecs, selectedEquip: costEquipment.selectedRows }) } headCellRender={prms => headCellRender({ ...prms })} /> ) : null} ) : null} Рабочие центры {costEquipment.dataLoaded ? ( <> dataCellRender({ ...prms, handleSelectChange, sUnit: sUnitCostEquipment, selectedEquip: costEquipment.selectedRows }) } headCellRender={prms => headCellRender({ ...prms })} /> ) : null}
); }; //Контроль свойств - Таблица информации об операциях сменного задания CostJobsSpecsDataGrid.propTypes = { task: PropTypes.number.isRequired, processIdent: PropTypes.number, clearSelectlist: PropTypes.func }; //---------------- //Интерфейс модуля //---------------- export { CostJobsSpecsDataGrid };