175 lines
7.0 KiB
JavaScript
175 lines
7.0 KiB
JavaScript
/*
|
|
Парус 8 - Панели мониторинга - Редактор панелей
|
|
Компоненты: Форма (представление)
|
|
*/
|
|
|
|
//---------------------
|
|
//Подключение библиотек
|
|
//---------------------
|
|
|
|
import React, { useEffect, useState, useContext } from "react"; //Классы React
|
|
import PropTypes from "prop-types"; //Контроль свойств компонента
|
|
import { Paper, Stack, Typography, Icon, TextField, IconButton, InputAdornment } from "@mui/material"; //Интерфейсные элементы
|
|
import { ApplicationCtx } from "../../../../context/application"; //Контекст приложения
|
|
import { P8P_COMPONENT_INLINE_MESSAGE, P8PComponentInlineMessage } from "../../../../components/editors/p8p_component_inline_message"; //Информационное сообщение внутри компонента
|
|
import { ITEM_SHAPE, ITEMS_INITIAL, ORIENTATION } from "./common"; //Общие ресурсы и константы формы
|
|
import { APP_STYLES } from "../../../../../app.styles";
|
|
|
|
//---------
|
|
//Константы
|
|
//---------
|
|
|
|
//Стили
|
|
const STYLES = {
|
|
CONTAINER: { overflow: "auto", ...APP_STYLES.SCROLL }
|
|
};
|
|
|
|
//Иконка компонента
|
|
const COMPONENT_ICON = "fact_check";
|
|
|
|
//Наименование компонента
|
|
const COMPONENT_NAME = "Форма";
|
|
|
|
//------------------------------------
|
|
//Вспомогательные функции и компоненты
|
|
//------------------------------------
|
|
|
|
//Элемент формы
|
|
const FormItem = ({ item = null, fullWidth = false, value = "", onChange = null } = {}) => {
|
|
//Подключение к контексту приложения
|
|
const { pOnlineShowDictionary } = useContext(ApplicationCtx);
|
|
|
|
//При изменении значения элемента
|
|
const handleChange = e => onChange && onChange(e.target.id, e.target.value);
|
|
|
|
//При очистке значения элемента
|
|
const handleClear = () => onChange(item.name, "");
|
|
|
|
//При выборе значения из словаря
|
|
const handleDictionary = () =>
|
|
item.unitCode &&
|
|
item.showMethod &&
|
|
pOnlineShowDictionary({
|
|
unitCode: item.unitCode,
|
|
showMethod: item.showMethod,
|
|
inputParameters: [{ name: item.inputParameter, value }],
|
|
callBack: res => res.success && onChange && onChange(item.name, res.outParameters[item.outputParameter])
|
|
});
|
|
|
|
//Формирование представления
|
|
return (
|
|
item && (
|
|
<TextField
|
|
fullWidth={fullWidth}
|
|
type={"text"}
|
|
variant={"standard"}
|
|
value={value}
|
|
label={item.caption}
|
|
id={item.name}
|
|
onChange={handleChange}
|
|
{...(item.unitCode && {
|
|
InputLabelProps: { shrink: true },
|
|
InputProps: {
|
|
readOnly: true,
|
|
endAdornment: (
|
|
<InputAdornment position="end">
|
|
<IconButton onClick={handleClear}>
|
|
<Icon>clear</Icon>
|
|
</IconButton>
|
|
<IconButton onClick={handleDictionary}>
|
|
<Icon>list</Icon>
|
|
</IconButton>
|
|
</InputAdornment>
|
|
)
|
|
}
|
|
})}
|
|
/>
|
|
)
|
|
);
|
|
};
|
|
|
|
//Контроль свойств - элемент формы
|
|
FormItem.propTypes = {
|
|
item: ITEM_SHAPE,
|
|
fullWidth: PropTypes.bool,
|
|
value: PropTypes.any,
|
|
onChange: PropTypes.func
|
|
};
|
|
|
|
//-----------
|
|
//Тело модуля
|
|
//-----------
|
|
|
|
//Форма (представление)
|
|
const Form = ({ title = null, orientation = ORIENTATION.V, autoApply = false, items = ITEMS_INITIAL, values = {}, onValuesChange = null } = {}) => {
|
|
//Собственное состояние - значения элементов
|
|
const [selfValues, setSelfValues] = useState({});
|
|
|
|
//При изменении состава элементов или значений
|
|
useEffect(() => setSelfValues(items.reduce((sV, item) => ({ ...sV, [item.name]: values[item.name] }), {})), [items, values]);
|
|
|
|
//При изменении значения элемента формы
|
|
const handleItemChange = (name, value) => {
|
|
setSelfValues(pv => ({ ...pv, [name]: value }));
|
|
autoApply && onValuesChange && onValuesChange({ ...selfValues, [name]: value });
|
|
};
|
|
|
|
//При подтверждении изменений формы
|
|
const handleOkClick = () => onValuesChange && onValuesChange({ ...selfValues });
|
|
|
|
//Флаг настроенности формы
|
|
const haveConfing = items && Array.isArray(items) && items.length > 0;
|
|
|
|
//Формирование представления
|
|
return (
|
|
<Paper className={`component-view__container ${!haveConfing && "component-view__container__empty"}`} sx={STYLES.CONTAINER} elevation={6}>
|
|
{haveConfing ? (
|
|
<Stack direction={"column"}>
|
|
<Stack direction={"row"} justifyContent={"space-between"} alignItems={"center"}>
|
|
{title && (
|
|
<Typography align={"left"} color={"text.primary"} variant={"subtitle2"} noWrap={true}>
|
|
{title}
|
|
</Typography>
|
|
)}
|
|
{!autoApply && (
|
|
<IconButton onClick={handleOkClick}>
|
|
<Icon>done</Icon>
|
|
</IconButton>
|
|
)}
|
|
</Stack>
|
|
<Stack direction={orientation == ORIENTATION.V ? "column" : "row"} spacing={1} pt={1} pb={1}>
|
|
{items.map((item, i) => (
|
|
<FormItem
|
|
key={i}
|
|
item={item}
|
|
value={selfValues?.[item.name] || ""}
|
|
onChange={handleItemChange}
|
|
fullWidth={orientation == ORIENTATION.V}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
</Stack>
|
|
) : (
|
|
<P8PComponentInlineMessage icon={COMPONENT_ICON} name={COMPONENT_NAME} message={P8P_COMPONENT_INLINE_MESSAGE.NO_SETTINGS} />
|
|
)}
|
|
</Paper>
|
|
);
|
|
};
|
|
|
|
//Контроль свойств компонента - Форма (представление)
|
|
Form.propTypes = {
|
|
id: PropTypes.string.isRequired,
|
|
title: PropTypes.string,
|
|
orientation: PropTypes.oneOf(Object.values(ORIENTATION)),
|
|
autoApply: PropTypes.bool,
|
|
items: PropTypes.arrayOf(ITEM_SHAPE),
|
|
values: PropTypes.object,
|
|
onValuesChange: PropTypes.func
|
|
};
|
|
|
|
//----------------
|
|
//Интерфейс модуля
|
|
//----------------
|
|
|
|
export default Form;
|