/* Парус 8 - Панели мониторинга Компонент: Диалог */ //--------------------- //Подключение библиотек //--------------------- import React, { useEffect, useState } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты import { BUTTONS } from "../../app.text"; //Общие текстовые ресурсы import { P8P_INPUT, P8PInput } from "./p8p_input"; //Поле ввода //--------- //Константы //--------- //Типовая ширина диалога const P8P_DIALOG_WIDTH = { XS: "xs", SM: "sm", MD: "md", LG: "lg", XL: "xl" }; //----------------------- //Вспомогательные функции //----------------------- //Формирование объекта вида {ключ: значение} из текущего состояния элементов ввода формы const buildFormValues = inputsState => inputsState.reduce((res, input) => ({ ...res, [input.name]: input.value == undefined ? null : input.value }), {}); //----------- //Тело модуля //----------- //Диалог const P8PDialog = ({ title, width, fullWidth, inputs, children, onOk, onCancel, onClose, onInputChange }) => { //Состояние элементов ввода диалога const [inputsState, setInputsState] = useState([]); //При изменении элемента ввода const handleInputChange = (name, value) => { //Если есть функция пересчета формы - вызовем её const doNotChangeInputsState = onInputChange ? onInputChange(name, value, inputsState) : false; //И ориентируясь на то, пересчитала ли она элементы ввода обновим собственное состояние. //Если функция пересчета вернула "true", значит она пересчитала что-то, тогда новые настройки элементов придут через свойство inputs и будут обработаны в useEffect ниже. //Следовательно, и нам здесь не надо состояние выставлять, т.к. всё будет перезаписано useEffectом. if (!doNotChangeInputsState) setInputsState(pv => pv.reduce((accum, cur) => [...accum, { ...cur, value: cur.name === name ? value : cur.value }], [])); }; //При нажатии на "ОК" диалога const handleOk = () => onOk && onOk(buildFormValues(inputsState)); //При нажатии на "Отмена" диалога const handleCancel = () => onCancel && onCancel(); //При нажатии на "Закрыть" диалога const handleClose = () => (onClose ? onClose() : onCancel ? onCancel() : null); //При изменении полей для ввода useEffect(() => { if (inputs && Array.isArray(inputs) && inputs.length > 0) setInputsState(inputs.map(input => ({ ...input }))); }, [inputs]); //Расчет объектного представления текущих значений формы const formValues = buildFormValues(inputsState); //Формирование представления return ( {title} {inputsState.map((input, i) => ( ))} {children} {onOk && } {onCancel && } {onClose && } ); }; //Контроль свойств - Диалог P8PDialog.propTypes = { title: PropTypes.string.isRequired, width: PropTypes.oneOf(Object.values(P8P_DIALOG_WIDTH)), fullWidth: PropTypes.bool, inputs: PropTypes.arrayOf(PropTypes.shape(P8P_INPUT)), children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]), onOk: PropTypes.func, onCancel: PropTypes.func, onClose: PropTypes.func, onInputChange: PropTypes.func }; //---------------- //Интерфейс модуля //---------------- export { P8PDialog, P8P_DIALOG_WIDTH };