P8-Panels/app/components/p8p_header/p8p_header_selector.js

104 lines
4.2 KiB
JavaScript

/*
Парус 8 - Панели мониторинга - Заголовок
Компонент: Выбор из выпадающего списка
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useMemo } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { FormControl, Select, MenuItem, Stack, Checkbox } from "@mui/material"; //Интерфейсные элементы
import { P8P_SELECT_VARIANT } from "../../theme/variants/p8p_select_variants"; //Варианты полей выбора (Select)
import { P8P_MENU_ITEM_VARIANT } from "../../theme/variants/p8p_menu_item_variants"; //Варианты элементов меню
import { P8P_FORM_CONTROL_HEADER_SELECTOR } from "../../theme/styles/form_control"; //Стили контекста полей ввода
import { P8PHeaderItem } from "./components/p8p_header_item"; //Элемент заголовка
//---------
//Константы
//---------
//Структура элемента выпадающего списка
const P8P_HEADER_SELECTOR_OPTION = PropTypes.shape({
value: PropTypes.any.isRequired,
title: PropTypes.string.isRequired
});
//-----------
//Тело модуля
//-----------
//Выбор из выпадающего списка
const P8PHeaderSelector = ({ value, placeholder, options = [], multiple = false, width, onSelect }) => {
//При нажатии на текст
const handleChange = e => onSelect && onSelect(e.target.value);
//Отображаемое значение
const displayValue = useMemo(() => {
//Если это множественный выбор
if (multiple) {
//Нет значения
if (!value || value.length === 0) return placeholder;
//Собираем выбранные значения
return options
.filter(option => value.includes(option.value))
.map(option => option.title)
.join(", ");
} else {
//Нет значения
if (!value) return placeholder;
//Определяем отображаемое
const option = options.find(option => option.value === value);
return option ? option.title : placeholder;
}
}, [value, placeholder, options, multiple]);
//Генерация содержимого
return (
<P8PHeaderItem width={width}>
<FormControl variant="outlined" sx={P8P_FORM_CONTROL_HEADER_SELECTOR}>
<Select
name={"header-selector"}
value={value}
displayEmpty
multiple={multiple}
onChange={handleChange}
title={displayValue}
data-variant={P8P_SELECT_VARIANT.HEADER}
renderValue={() => displayValue}
>
{options.map((option, index) => (
<MenuItem value={option.value} key={index} variant={P8P_MENU_ITEM_VARIANT.HEADER}>
{multiple ? (
<Stack direction={"row"} alignItems={"center"}>
<Checkbox checked={value && value.indexOf(option.value) > -1} />
{option.title}
</Stack>
) : (
option.title
)}
</MenuItem>
))}
</Select>
</FormControl>
</P8PHeaderItem>
);
};
//Контроль свойств - Выбор из выпадающего списка
P8PHeaderSelector.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
placeholder: PropTypes.string.isRequired,
options: PropTypes.arrayOf(P8P_HEADER_SELECTOR_OPTION).isRequired,
multiple: PropTypes.bool,
width: PropTypes.string,
onSelect: PropTypes.func
};
//----------------
//Интерфейс модуля
//----------------
export { P8PHeaderSelector };