138 lines
5.5 KiB
JavaScript
138 lines
5.5 KiB
JavaScript
/*
|
|
Парус 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 (
|
|
<Box p={1}>
|
|
<FormControl variant={"standard"} fullWidth {...other}>
|
|
{list ? (
|
|
freeSolo ? (
|
|
<Autocomplete
|
|
id={name}
|
|
name={name}
|
|
freeSolo
|
|
disabled={disabled}
|
|
inputValue={currentValue ? currentValue : ""}
|
|
onChange={(event, newValue) => handleChangeByName(name, newValue)}
|
|
onInputChange={(event, newInputValue) => handleChangeByName(name, newInputValue)}
|
|
options={list}
|
|
renderInput={params => <TextField {...params} label={label} name={name} variant={"standard"} />}
|
|
/>
|
|
) : (
|
|
<>
|
|
<InputLabel id={`${name}Lable`} shrink>
|
|
{label}
|
|
</InputLabel>
|
|
<Select
|
|
labelId={`${name}Lable`}
|
|
id={name}
|
|
name={name}
|
|
label={label}
|
|
value={[undefined, null].includes(currentValue) ? "" : currentValue}
|
|
onChange={handleChange}
|
|
disabled={disabled}
|
|
displayEmpty
|
|
>
|
|
{list.map((item, i) => (
|
|
<MenuItem key={i} value={[undefined, null].includes(item.value) ? "" : item.value}>
|
|
{item.name}
|
|
</MenuItem>
|
|
))}
|
|
</Select>
|
|
</>
|
|
)
|
|
) : (
|
|
<>
|
|
<InputLabel {...(type == "date" ? { shrink: true } : {})} htmlFor={name}>
|
|
{label}
|
|
</InputLabel>
|
|
<Input
|
|
id={name}
|
|
name={name}
|
|
value={currentValue ? currentValue : ""}
|
|
endAdornment={
|
|
dictionary ? (
|
|
<InputAdornment position="end">
|
|
<IconButton aria-label={`${name} select`} onClick={handleDictionaryClick} edge="end">
|
|
<Icon>list</Icon>
|
|
</IconButton>
|
|
</InputAdornment>
|
|
) : null
|
|
}
|
|
{...(type ? { type } : {})}
|
|
onChange={handleChange}
|
|
disabled={disabled}
|
|
/>
|
|
</>
|
|
)}
|
|
</FormControl>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
//Контроль свойств - Поле ввода
|
|
P8PInput.propTypes = P8P_INPUT;
|
|
|
|
//----------------
|
|
//Интерфейс модуля
|
|
//----------------
|
|
|
|
export { P8P_INPUT, P8PInput };
|