From 3f539065ba4ce412555889d214885cca6f71d458 Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Mon, 21 Jul 2025 10:09:27 +0300 Subject: [PATCH] =?UTF-8?q?WEBAPP:=20=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D1=8B=20?= =?UTF-8?q?P8PDialog=20=D0=B8=20P8PInput?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/p8p_dialog.js | 76 +++++++++++++++++++ app/components/p8p_input.js | 137 +++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 app/components/p8p_dialog.js create mode 100644 app/components/p8p_input.js diff --git a/app/components/p8p_dialog.js b/app/components/p8p_dialog.js new file mode 100644 index 0000000..30ab288 --- /dev/null +++ b/app/components/p8p_dialog.js @@ -0,0 +1,76 @@ +/* + Парус 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 P8PDialog = ({ title, inputs = [], children, onOk, onCancel, onClose }) => { + //Состояние диалога + const [state, setState] = useState({}); + + //При изменении элемента ввода + const handleInputChange = (name, value) => setState(pv => ({ ...pv, [name]: value })); + + //При нажатии на "ОК" диалога + const handleOk = () => onOk && onOk(state); + + //При нажатии на "Отмена" диалога + const handleCancel = () => onCancel && onCancel(); + + //При нажатии на "Закрыть" диалога + const handleClose = () => (onClose ? onClose() : onCancel ? onCancel() : null); + + //При подключении к старнице + useEffect(() => { + setState(inputs.reduce((res, input) => ({ ...res, [input.name]: input.value == undefined ? null : input.value }), {})); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + //Формирование представления + return ( + + {title} + + {inputs.map((input, i) => ( + + ))} + {children} + + + {onOk && } + {onCancel && } + {onClose && } + + + ); +}; + +//Контроль свойств - Диалог +P8PDialog.propTypes = { + title: PropTypes.string.isRequired, + 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 +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { P8PDialog }; diff --git a/app/components/p8p_input.js b/app/components/p8p_input.js new file mode 100644 index 0000000..2adc568 --- /dev/null +++ b/app/components/p8p_input.js @@ -0,0 +1,137 @@ +/* + Парус 8 - Панели мониторинга + Компонент: Поле ввода +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useEffect } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, Icon, Input, InputAdornment, FormControl, Select, InputLabel, MenuItem, IconButton, Autocomplete, TextField } from "@mui/material"; //Интерфейсные компоненты + +//--------- +//Константы +//--------- + +//Формат свойств поля ввода +const P8P_INPUT = { + name: PropTypes.string.isRequired, + value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.instanceOf(Date)]), + label: PropTypes.string.isRequired, + onChange: PropTypes.func, + dictionary: PropTypes.func, + list: PropTypes.array, + type: PropTypes.string, + freeSolo: PropTypes.bool, + disabled: PropTypes.bool, + formValues: PropTypes.object +}; + +//----------- +//Тело модуля +//----------- + +//Поле ввода +const P8PInput = ({ name, value, label, onChange, dictionary, list, type, freeSolo = false, disabled = false, formValues, ...other }) => { + //Значение элемента + const [currentValue, setCurrentValue] = useState(value); + + //При получении нового значения из вне + useEffect(() => { + setCurrentValue(value); + }, [value]); + + //Выбор значения из словаря + const handleDictionaryClick = () => dictionary && dictionary(formValues, res => (res ? res.map(i => handleChangeByName(i.name, i.value)) : null)); + + //Изменение значения элемента (по событию) + const handleChange = e => { + setCurrentValue(e.target.value); + if (onChange) onChange(e.target.name, e.target.value); + }; + + //Изменение значения элемента (по имени и значению) + const handleChangeByName = (targetName, value) => { + if (targetName === name) setCurrentValue(value); + if (onChange) onChange(targetName, value); + }; + + //Генерация содержимого + return ( + + + {list ? ( + freeSolo ? ( + handleChangeByName(name, newValue)} + onInputChange={(event, newInputValue) => handleChangeByName(name, newInputValue)} + options={list} + renderInput={params => } + /> + ) : ( + <> + + {label} + + + + ) + ) : ( + <> + + {label} + + + + list + + + ) : null + } + {...(type ? { type } : {})} + onChange={handleChange} + disabled={disabled} + /> + + )} + + + ); +}; + +//Контроль свойств - Поле ввода +P8PInput.propTypes = P8P_INPUT; + +//---------------- +//Интерфейс модуля +//---------------- + +export { P8P_INPUT, P8PInput };