/*
Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания
Компонент панели: Таблица информации о строках сменного задания
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import {
Typography,
Box,
Checkbox,
Grid,
Icon,
Button,
Dialog,
DialogContent,
TextField,
DialogActions,
Tooltip,
Stack,
DialogTitle
} from "@mui/material"; //Интерфейсные элементы
import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_MORE_HEIGHT } from "../../components/p8p_data_grid"; //Таблица данных
import { APP_STYLES } from "../../../app.styles"; //Типовые стили
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { useCostJobsSpecs, useEquipConfiguration } from "./hooks"; //Собственные хуки таблиц
import { MAIN_HEADER_HEIGHT, SUB_HEADER_HEIGHT } from "./mech_rec_cost_jobs_manage"; //Заглавный компонент панели
//---------
//Константы
//---------
//Мнемокод раздела операций
const UNIT_COST_JOBS_SPECS = "CostJobsSpecs";
//Мнемокод раздела рабочих центров
const UNIT_COST_EQUIPMENT = "CostEquipment";
//Высота заголовка таблицы
const TABLE_HEADER_HEIGHT = "35px";
//Высота панели кнопок таблицы
const TABLE_BUTTONS_HEIGHT = "35px";
//Отступ таблицы
const TABLE_PADDING_TOP = "15px";
//Стили
const STYLES = {
CONTAINER: { textAlign: "center" },
DATA_GRID_CONTAINER: morePages => ({
height: `calc(100vh - ${APP_BAR_HEIGHT} - ${MAIN_HEADER_HEIGHT} - ${SUB_HEADER_HEIGHT} - ${TABLE_HEADER_HEIGHT} - ${TABLE_BUTTONS_HEIGHT} - ${TABLE_PADDING_TOP} - 32px - ${
morePages ? P8P_DATA_GRID_MORE_HEIGHT : "0px"
})`,
...APP_STYLES.SCROLL
}),
TABLE: { paddingTop: TABLE_PADDING_TOP },
TABLE_HEADER: { height: TABLE_HEADER_HEIGHT, overflow: "hidden" },
TABLE_BUTTONS: { display: "flex", justifyContent: "flex-end", height: TABLE_BUTTONS_HEIGHT, overflow: "hidden" },
CHECK_BOX: { textAlign: "center" },
JOBS_INFO: { textAlign: "center" },
EQUIPMENT_INFO: { textAlign: "center" }
};
//Цвета
const colors = {
LINKED: "#bce0de",
UNAVAILABLE: "#949494",
WITH_EQCONFIG: "#82df83"
};
//---------------------------------------------
//Вспомогательные функции и компоненты
//---------------------------------------------
//Форматирование значения ячейки
const dataCellRender = ({ row, columnDef, handleSelectChange, sUnit, selectedRow, selectedJobSpec }) => {
//Стиль
let cellStyle = {};
//Если это рабочие центры
if (sUnit === UNIT_COST_EQUIPMENT) {
//Признак недоступности
let disabled = true;
//Если в выбранной строке смены указано рабочее место
if (selectedJobSpec.NEQCONFIG) {
//Если это текущее рабочее место
if (row["NRN"] === selectedJobSpec.NEQCONFIG) {
//Подсвечиваем строку рабочего места
cellStyle = { backgroundColor: colors.LINKED };
}
} else {
//Если выбрана строка смены
if (selectedJobSpec.NRN) {
//Если на текущее рабочее место возможно добавить задание
if (row["NLOADING"] < 100 && row["NEQUIPMENT"] === selectedJobSpec.NEQUIP_PLAN) {
//Подсвечиваем строку рабочего места
cellStyle = { backgroundColor: colors.LINKED };
disabled = false;
}
}
}
//Если рабочий центр загружен
if (row["NLOADING"] >= 100) {
//Если поле не поле выбора
if (columnDef.name !== "NSELECT") {
//Указываем, что рабочее место недоступно
cellStyle = { ...cellStyle, color: colors.UNAVAILABLE };
}
}
//Для колонки выбора
if (columnDef.name === "NSELECT") {
return {
cellStyle,
data: (
handleSelectChange({ NRN: row["NRN"], SUNIT: sUnit, BFULL_LOADED: row["NLOADING"] >= 100 })}
/>
)
};
}
//Отформатированная колонка
return {
cellStyle,
data: row[columnDef.name]
};
}
//Если это сменное задание
if (sUnit === UNIT_COST_JOBS_SPECS) {
//Если указан станок
if (row["SEQCONFIG"]) {
//Подсвечиваем сменное задание зеленым
cellStyle = { ...cellStyle, backgroundColor: colors.WITH_EQCONFIG };
}
//Для колонки выбора
if (columnDef.name === "NSELECT") {
return {
cellStyle,
data: (
handleSelectChange({
NRN: row["NRN"],
SUNIT: sUnit,
NEQCONFIG: row["NEQCONFIG"],
NEQUIP_PLAN: row["NEQUIP_PLAN"],
NQUANT_PLAN: row["NQUANT_PLAN"]
})
}
/>
)
};
}
//Отформатированная колонка
return {
cellStyle,
data: row[columnDef.name]
};
}
//Необрабатываемый раздел
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 CostJobsSpecsInclude = ({ includeEquipment, setIncludeEquipment, setCostJobsSpecs, setEquipConfiguration, includeEquipConfiguration }) => {
//Собственное состояние - Значение приоритета
const [state, setState] = useState(includeEquipment.NVALUE);
//При закрытии включения станка
const handlePriorEditClose = () => {
setIncludeEquipment({
NFCJOBSSP: null,
NEQCONFIG: null,
NVALUE: 0
});
};
//При включении станка в строку сменного задания
const costJobsSpecIncludeCostEquipment = () => {
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
const includeAsync = async () => {
//Включаем станок в строку сменного задания
try {
await includeEquipConfiguration({
NEQCONFIG: includeEquipment.NEQCONFIG,
NFCJOBSSP: includeEquipment.NFCJOBSSP,
NQUANT_PLAN: state
});
//Необходимо обновить все данные
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
setEquipConfiguration(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
handlePriorEditClose();
} catch (e) {
throw new Error(e.message);
}
};
//Включаем станок асинхронно
includeAsync();
};
return (
);
};
//Контроль свойств - Диалог включения станка в сменное задание
CostJobsSpecsInclude.propTypes = {
includeEquipment: PropTypes.object.isRequired,
setIncludeEquipment: PropTypes.func.isRequired,
setCostJobsSpecs: PropTypes.func.isRequired,
setEquipConfiguration: PropTypes.func.isRequired,
includeEquipConfiguration: PropTypes.func.isRequired
};
//-----------
//Тело модуля
//-----------
//Таблица информации о строках сменного задания
const CostJobsSpecsDataGrid = ({ task, haveNote, fromAction }) => {
//Собственное состояние - Включение в задание
const [includeEquipment, setIncludeEquipment] = useState({ NFCJOBSSP: null, NEQCONFIG: null, NVALUE: 0 });
//Собственное состояние - таблица данных сменных заданий
const [costJobsSpecs, setCostJobsSpecs, issueCostJobsSpecs] = useCostJobsSpecs(task);
//Собственное состояние - таблица рабочих центров
const [equipConfiguration, setEquipConfiguration, includeEquipConfiguration, excludeEquipConfiguration] = useEquipConfiguration(task, fromAction);
//При изменении состояния сортировки операций
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 }) => setEquipConfiguration(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true }));
//При изменении количества отображаемых страниц рабочих центров
const costEquipmentPagesCountChanged = () => setEquipConfiguration(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true }));
//При исключении станка из строки сменного задания
const costJobsSpecExcludeCostEquipment = () => {
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
const excludeAsync = async () => {
//Исключаем станок из строки сменного задания
try {
await excludeEquipConfiguration({
NFCJOBSSP: costJobsSpecs.selectedRow.NRN
});
//Необходимо обновить данные
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
setEquipConfiguration(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
} catch (e) {
throw new Error(e.message);
}
};
//Исключаем станок асинхронно
excludeAsync();
};
//Выдача задания операции
const costJobsSpecIssue = () => {
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
const issueAsync = async () => {
//Включаем оборудование в операции
try {
await issueCostJobsSpecs({ NFCJOBS: task });
//Необходимо обновить данные
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
setEquipConfiguration(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
} catch (e) {
throw new Error(e.message);
}
};
//Выдаем задание асинхронно
issueAsync();
};
//При изменение состояния выбора
const handleSelectChange = prms => {
//Выбранный элемент
let selectedRow = null;
//Исходим от раздела
switch (prms.SUNIT) {
//Сменное задание
case UNIT_COST_JOBS_SPECS:
//Определяем это новое отмеченное сменное задание или сброс старого
selectedRow = costJobsSpecs.selectedRow.NRN ? (costJobsSpecs.selectedRow.NRN === prms.NRN ? null : prms.NRN) : prms.NRN;
//Актуализируем строки
setCostJobsSpecs(pv => ({
...pv,
selectedRow: selectedRow
? { NRN: selectedRow, NEQCONFIG: prms.NEQCONFIG, NEQUIP_PLAN: prms.NEQUIP_PLAN, NQUANT_PLAN: prms.NQUANT_PLAN }
: { NRN: null, NEQCONFIG: null, NEQUIP_PLAN: null, NQUANT_PLAN: null }
}));
//Выходим
break;
//Рабочие центры
case UNIT_COST_EQUIPMENT:
//Определяем это новое отмеченное сменное задание или сброс старого
selectedRow = equipConfiguration.selectedRow.NRN ? (equipConfiguration.selectedRow.NRN === prms.NRN ? null : prms.NRN) : prms.NRN;
//Актуализируем строки
setEquipConfiguration(pv => ({
...pv,
selectedRow: selectedRow ? { NRN: selectedRow, BFULL_LOADED: prms.BFULL_LOADED } : { NRN: null, BFULL_LOADED: null }
}));
//Выходим
break;
default:
return;
}
};
//При открытии окна включения в задание
const handleIncludeEquipmentOpen = () => {
//Актуализируем строки
setIncludeEquipment({
NFCJOBSSP: costJobsSpecs.selectedRow.NRN,
NEQCONFIG: equipConfiguration.selectedRow.NRN,
NVALUE: costJobsSpecs.selectedRow.NQUANT_PLAN
});
};
//Генерация содержимого
return (
Сменное задание
{costJobsSpecs.dataLoaded ? (
<>
dataCellRender({
...prms,
handleSelectChange,
sUnit: UNIT_COST_JOBS_SPECS,
selectedRow: costJobsSpecs.selectedRow.NRN,
selectedJobSpec: costJobsSpecs.selectedRow
})
}
headCellRender={prms => headCellRender({ ...prms })}
fixedHeader={true}
/>
>
) : null}
Рабочие центры
{equipConfiguration.dataLoaded ? (
<>
dataCellRender({
...prms,
handleSelectChange,
sUnit: UNIT_COST_EQUIPMENT,
selectedRow: equipConfiguration.selectedRow.NRN,
selectedJobSpec: costJobsSpecs.selectedRow
})
}
headCellRender={prms => headCellRender({ ...prms })}
fixedHeader={true}
/>
>
) : null}
{includeEquipment.NFCJOBSSP && includeEquipment.NFCJOBSSP ? (
) : null}
);
};
//Контроль свойств - Таблица информации о строках сменного задания
CostJobsSpecsDataGrid.propTypes = {
task: PropTypes.number.isRequired,
haveNote: PropTypes.bool.isRequired,
fromAction: PropTypes.bool.isRequired
};
//----------------
//Интерфейс модуля
//----------------
export { CostJobsSpecsDataGrid };