forked from CITKParus/P8-Panels
154 lines
7.0 KiB
JavaScript
154 lines
7.0 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга
|
||
Компонент: Диалог отображения параметров
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useState, useContext, useMemo } from "react"; //Классы React
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { Stack, List, ListItem, ListItemButton, ListItemText, Typography, Box, Divider } from "@mui/material"; //Интерфейсные элементы
|
||
import { P8PDialog, P8P_DIALOG_WIDTH } from "./p8p_dialog"; //Типовой диалог
|
||
import { APP_STYLES } from "../../app.styles"; //Типовые стили
|
||
import { P8PSettingsList } from "./p8p_settings_list"; //Список параметров
|
||
import { ApplicationCtx } from "../context/application"; //Контекст приложения
|
||
import { deepCopyObject, hasValue } from "../core/utils"; //Вспомогательные функции
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Стили
|
||
const STYLES = {
|
||
CONTAINER: { display: "flex", flexDirection: "row", alignItems: "flex-start" },
|
||
BOX_PANELS: { width: "300px", height: "500px", overflow: "auto", ...APP_STYLES.SCROLL },
|
||
BOX_SETTINGS: { width: "520px", height: "500px", overflow: "auto", ...APP_STYLES.SCROLL }
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Диалог отображения параметров
|
||
const P8PSettingsDialog = ({ settings, panel = null, onOk, onClose }) => {
|
||
//Собственное состояние - параметры панелей
|
||
const [panelSettings, setPanelSettings] = useState(settings);
|
||
|
||
//Собственное состояние - мнемокод выбранной панели
|
||
const [selectedPanel, setSelectedPanel] = useState(panel);
|
||
|
||
//Собственное состояние - наличие отображаемых данных
|
||
const isSettingsExists = useMemo(() => {
|
||
return selectedPanel
|
||
? panelSettings && Object.keys(panelSettings).length > 0 && Object.keys(panelSettings[selectedPanel]).length > 0
|
||
: Object.keys(panelSettings).length > 0;
|
||
}, [selectedPanel, panelSettings]);
|
||
|
||
//Подключение к контексту приложения
|
||
const { appState } = useContext(ApplicationCtx);
|
||
|
||
//При нажатии на "ОК"
|
||
const handleOk = () => onOk && onOk(panelSettings);
|
||
|
||
//При нажатии на "Отменить"
|
||
const handleCancel = () => onClose && onClose();
|
||
|
||
//При изменении параметра
|
||
const handleSettingChange = (settingCode, newSettings) => {
|
||
//Определяем панели
|
||
const newPanelSettings = deepCopyObject(panelSettings);
|
||
//Изменяем настройку у панели
|
||
newPanelSettings[selectedPanel][settingCode] = deepCopyObject(newSettings);
|
||
//Обновляем панели
|
||
setPanelSettings(newPanelSettings);
|
||
};
|
||
|
||
//При нажатии на панель
|
||
const handlePanelSelect = panelName => setSelectedPanel(selectedPanel === panelName ? null : panelName);
|
||
|
||
//Генерация области выбора панели
|
||
const panelsListRender = () => {
|
||
//Генерация содержимого
|
||
return (
|
||
<>
|
||
<Box sx={STYLES.BOX_PANELS}>
|
||
<List>
|
||
{Object.keys(panelSettings).map((panel, i) => {
|
||
//Считываем информацию о панели
|
||
const panelInfo = appState.panels.find(appPanel => appPanel.name == panel);
|
||
//Элемент панели
|
||
return (
|
||
<ListItem key={i}>
|
||
<ListItemButton onClick={() => handlePanelSelect(panel)} selected={panel === selectedPanel}>
|
||
<ListItemText
|
||
primary={panelInfo.name}
|
||
secondaryTypographyProps={{ component: "div" }}
|
||
secondary={
|
||
<Stack direction={"row"} justifyContent={"space-between"} gap={2}>
|
||
<Typography
|
||
variant={"caption"}
|
||
noWrap={true}
|
||
title={panelInfo.desc ? panelInfo.desc : "Описание отсутствует"}
|
||
>{`${panelInfo.desc ? panelInfo.desc : "Описание отсутствует"}`}</Typography>
|
||
</Stack>
|
||
}
|
||
/>
|
||
</ListItemButton>
|
||
</ListItem>
|
||
);
|
||
})}
|
||
</List>
|
||
</Box>
|
||
<Divider orientation="vertical" flexItem />
|
||
</>
|
||
);
|
||
};
|
||
|
||
//Формирование представления
|
||
return (
|
||
<P8PDialog
|
||
title={`Параметры ${panel ? `"${appState.panels.find(appPanel => appPanel.name == panel).caption}"` : "панелей"}`}
|
||
width={P8P_DIALOG_WIDTH.LG}
|
||
onCancel={handleCancel}
|
||
onOk={handleOk}
|
||
scrollContent={false}
|
||
okDisabled={Object.keys(panelSettings).length === 0}
|
||
>
|
||
{isSettingsExists ? (
|
||
<Box sx={STYLES.CONTAINER}>
|
||
{!hasValue(panel) ? panelsListRender() : null}
|
||
<Box sx={STYLES.BOX_SETTINGS}>
|
||
{hasValue(selectedPanel) ? (
|
||
<P8PSettingsList settings={panelSettings[selectedPanel]} onSettingChange={handleSettingChange} />
|
||
) : (
|
||
<Typography align="center" variant="subtitle1">
|
||
Выберите панель для отображения параметров
|
||
</Typography>
|
||
)}
|
||
</Box>
|
||
</Box>
|
||
) : (
|
||
<Typography align="center" variant="subtitle1">
|
||
Отсутствуют доступные параметры
|
||
</Typography>
|
||
)}
|
||
</P8PDialog>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств компонента - Диалог отображения параметров
|
||
P8PSettingsDialog.propTypes = {
|
||
settings: PropTypes.object.isRequired,
|
||
panel: PropTypes.string,
|
||
onOk: PropTypes.func,
|
||
onClose: PropTypes.func
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { P8PSettingsDialog };
|