/* Парус 8 - Панели мониторинга - Редактор панелей Редактор глобальных свойств панели */ //--------------------- //Подключение библиотек //--------------------- import React, { useState, useContext } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Chip, Stack, TextField, Button, Icon } from "@mui/material"; //Интерфейсные элементы import { P8PConfigDialog } from "../../components/editors/p8p_config_dialog"; //Диалог настройки import { isElementNameCorrect } from "../../components/editors/p8p_editors_common"; //Общие ресурсы редакторов import { P8PEditorSubHeader } from "../../components/editors/p8p_editor_sub_header"; //Заголовок раздела редактора import { P8PEditorBox } from "../../components/editors/p8p_editor_box"; //Контейнер редактора import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений import { APP_STYLES } from "../../../app.styles"; //Типовые стили import { STYLES as COMMON_STYLES } from "../../components/editors/p8p_editors_common"; //Общие ресурсы редакторов import { P8PChipList } from "../../components/editors/p8p_chip_list"; //Дополнительные настройки редактора //--------- //Константы //--------- //Стили const STYLES = { STACK_DEPENENCIES: { gap: "5px", ...APP_STYLES.SCROLL, overflow: "auto", maxHeight: "160px", width: "260px" }, CHIP_DEPENDENCY: { ...COMMON_STYLES.CHIP(true, false), minHeight: "32px" } }; //Начальное состояние переменной const VARIABLE_INITIAL = { dependencies: [], description: "", value: "" }; //Структура переменной export const VARIABLE_SHAPE = PropTypes.shape({ dependencies: PropTypes.arrayOf(PropTypes.string), description: PropTypes.string.isRequired, value: PropTypes.string }); //------------------------------------ //Вспомогательные функции и компоненты //------------------------------------ //Редактор переменной const VariableEditor = ({ variableName = "", variable = null, dependencies = [], onDependencyClick, onOk, onCancel } = {}) => { //Собственное состояние - имя переменной const [name, setName] = useState(variableName || ""); //Собственное состояние - параметры переменной const [state, setState] = useState({ ...VARIABLE_INITIAL, ...variable }); //При закрытии редактора с сохранением const handleOk = () => onOk(name, { ...state }); //При закрытии редактора с отменой const handleCancel = () => onCancel(); //При изменении параметра переменной const handleChange = e => { //Если это поле наименования, то проверяем корректность if (e.target.id === "name" && isElementNameCorrect(e.target.value)) setName(e.target.value); //Устанавливаем значение else setState(pv => ({ ...pv, [e.target.id]: e.target.value })); }; //Доступность сохранения настроек элемента const okDisabled = !name || !state.description ? true : false; //Формирование представления return ( {dependencies.length !== 0 ? ( <> {dependencies.map((item, i) => ( onDependencyClick && onDependencyClick(item)} sx={STYLES.CHIP_DEPENDENCY} /> ))} ) : null} ); }; //Контроль свойств - редактор переменной VariableEditor.propTypes = { variableName: PropTypes.string, variable: VARIABLE_SHAPE, dependencies: PropTypes.array, onDependencyClick: PropTypes.func.isRequired, onOk: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired }; //----------- //Тело модуля //----------- //Редактор глобальных свойств панели const PanelPropsEditor = ({ valueProviders = {}, onSettingsChange, onDependencyClick } = {}) => { //Собственное состояние - редактор переменных панели const [variableEditor, setVariableEditor] = useState({ display: false, item: null }); //Подключение к контексту сообщений const { showMsgErr } = useContext(MessagingСtx); //При добавлении новой переменной const handleVariableAdd = () => setVariableEditor({ display: true, item: null }); //При нажатии на переменную const handleVariableClick = index => setVariableEditor({ display: true, item: variables[index] }); //При отмене сохранения изменений переменной const handleVariableCancel = () => setVariableEditor({ display: false, index: null }); //При сохранении изменений переменной const handleVariableSave = (variableName, variable) => { //Текст ошибки let msgError = ""; //Если это добавление или изменилось наименование - проверяем на дублирование if ((!variableEditor.item || variableEditor.item !== variableName) && Object.prototype.hasOwnProperty.call(valueProviders, variableName)) { msgError = `Дублирование наименования параметра "${variableName}".`; } //Если это исправление наименования параметра, но он используется if (variableEditor.item && variableEditor.item !== variableName && valueProviders[variableEditor.item].dependencies.length !== 0) { msgError = `Переменная имеет связи с компонентами. Изменение наименования запрещено.`; } //Если есть ошибка - выводим if (msgError) { showMsgErr(msgError); } else { //Копируем параметры let newValueProviders = { ...valueProviders }; //Удаляем старое значение, если требуется variableEditor.item && variableEditor.item !== variableName ? delete newValueProviders[variableEditor.item] : null; //Добавляем новый параметр newValueProviders = { ...newValueProviders, [variableName]: { ...variable } }; //Обновляем проводники панели onSettingsChange({ valueProviders: { ...newValueProviders } }); //Закрываем редактирование setVariableEditor({ display: false, index: null }); } }; //При удалении переменной const handleVariableDelete = index => { const variable = variables[index]; //Если переменная не используется в компонентах - удаляем if (valueProviders[variable].dependencies.length === 0) { const newValueProviders = { ...valueProviders }; delete newValueProviders[variable]; onSettingsChange({ valueProviders: { ...newValueProviders } }); } else { showMsgErr(`Переменная имеет связи с компонентами. Удаление запрещено.`); } }; //При нажатии на зависимый компонент const handleDependencyClick = id => { //Закрываем редактирование setVariableEditor({ display: false, index: null }); //Открываем настройку компонента onDependencyClick(id); }; //Текущие переменные панели const variables = Object.keys(valueProviders).reduce((res, key) => [...res, key], []); //Определяем структуру переменных для отображения const variableChips = variables.map(item => ({ text: item, title: item })); //Формирование представления return ( {variableEditor.display && ( )} ); }; //Контроль свойств компонента - редактор глобальных свойств панели PanelPropsEditor.propTypes = { valueProviders: PropTypes.object, onSettingsChange: PropTypes.func.isRequired, onDependencyClick: PropTypes.func.isRequired }; //---------------- //Интерфейс модуля //---------------- export { PanelPropsEditor };