/*
Парус 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 };