ЦИТК-979 - Диалог настройки атрибутов сущности - фиксированная ширина, сообщение об отсутствии данных при поиске

This commit is contained in:
Mikhail Chechnev 2025-09-04 15:50:33 +03:00
parent 538643591f
commit ef1a63b4b6
2 changed files with 61 additions and 40 deletions

View File

@ -22,7 +22,7 @@ const STYLES = {
SMALL_TOOL_ICON: {
fontSize: 20
},
LIST: { height: "500px", width: "360px", bgcolor: "background.paper", overflowY: "auto", ...APP_STYLES.SCROLL }
LIST: { height: "100%", width: "100%", bgcolor: "background.paper", overflowY: "auto", ...APP_STYLES.SCROLL }
};
//-----------
@ -30,54 +30,49 @@ const STYLES = {
//-----------
//Список атрибутов сущности
const AttrsList = ({ attrs = [], filter, onSelect = null, onShow = null } = {}) => {
const AttrsList = ({ attrs = [], onSelect = null, onShow = null } = {}) => {
//При выборе элемента списка
const handleSelectClick = attr => {
onSelect && onSelect(attr);
};
//При нажатии на исправлении
//При нажатии на кнопку изменения видимости атрибута
const handleShowClick = (e, attr) => {
e.stopPropagation();
onShow && onShow(attr);
};
//Рег. выражение для фильтра
const filterRegExp = filter ? new RegExp(filter, "i") : null;
//Формирование представления
return (
<List sx={STYLES.LIST}>
{attrs &&
attrs
.filter(attr => (filterRegExp ? filterRegExp.test(attr.name) || filterRegExp.test(attr.title) : true))
.map((attr, i) => {
const [selected, selectedTitle] = attrGetUse(attr, true);
const [showTitle, showIcon] = attrGetShow(attr, true);
return (
<ListItem key={i} disablePadding>
<ListItemButton onClick={() => handleSelectClick(attr)} selected={selected} dense>
<ListItemIcon>
<Checkbox edge="start" checked={selected} tabIndex={-1} disableRipple title={selectedTitle} />
</ListItemIcon>
<ListItemText
primary={attr.title}
secondaryTypographyProps={{ component: "div" }}
secondary={
<Stack direction={"column"}>
<Typography variant={"caption"}>{`${attr.alias || attr.name}`}</Typography>
</Stack>
}
/>
<Stack direction={"row"}>
<IconButton onClick={e => handleShowClick(e, attr)} title={showTitle}>
<Icon>{showIcon}</Icon>
</IconButton>
</Stack>
</ListItemButton>
</ListItem>
);
})}
attrs.map((attr, i) => {
const [selected, selectedTitle] = attrGetUse(attr, true);
const [showTitle, showIcon] = attrGetShow(attr, true);
return (
<ListItem key={i} disablePadding>
<ListItemButton onClick={() => handleSelectClick(attr)} selected={selected} dense>
<ListItemIcon>
<Checkbox edge={"start"} checked={selected} tabIndex={-1} disableRipple title={selectedTitle} />
</ListItemIcon>
<ListItemText
primary={attr.title}
secondaryTypographyProps={{ component: "div" }}
secondary={
<Stack direction={"column"}>
<Typography variant={"caption"}>{`${attr.alias || attr.name}`}</Typography>
</Stack>
}
/>
<Stack direction={"row"}>
<IconButton onClick={e => handleShowClick(e, attr)} title={showTitle}>
<Icon>{showIcon}</Icon>
</IconButton>
</Stack>
</ListItemButton>
</ListItem>
);
})}
</List>
);
};
@ -85,7 +80,6 @@ const AttrsList = ({ attrs = [], filter, onSelect = null, onShow = null } = {})
//Контроль свойств компонента - Список атрибутов сущности
AttrsList.propTypes = {
attrs: PropTypes.arrayOf(ATTRIBUTE_SHAPE),
filter: PropTypes.string,
onSelect: PropTypes.func,
onShow: PropTypes.func
};

View File

@ -9,11 +9,21 @@
import React, { useState, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { TextField, InputAdornment, Icon, IconButton } from "@mui/material"; //Интерфейсные элементы MUI
import { P8PDialog } from "../../../../components/p8p_dialog"; //Типовой диалог
import { Box, TextField, InputAdornment, Icon, IconButton } from "@mui/material"; //Интерфейсные элементы MUI
import { P8PDialog, P8P_DIALOG_WIDTH } from "../../../../components/p8p_dialog"; //Типовой диалог
import { P8PComponentInlineMessage } from "../../../../components/editors/p8p_component_inline_message"; //Типовое встраиваемое сообщение
import { AttrsList } from "./attrs_list"; //Список атрибутов сущности
import { useEntityAttrs } from "./hooks"; //Хуки диалога настройки атрибутов сущности
//---------
//Константы
//---------
//Стили
const STYLES = {
LIST_CONTAINER: { width: "100%", height: "500px" }
};
//-----------
//Тело модуля
//-----------
@ -65,9 +75,18 @@ const EntityAttrsDialog = ({ query, id, title, onOk, onCancel }) => {
if (srvAttrs) setAttrs(srvAttrs.map(srvAttr => ({ ...srvAttr })));
}, [srvAttrs]);
//Рег. выражение для фильтра
const filterRegExp = filter ? new RegExp(filter, "i") : null;
//Отфильтрованные для отображения атрибуты
const filteredAttrs = attrs.filter(attr => (filterRegExp ? filterRegExp.test(attr.name) || filterRegExp.test(attr.title) : true));
//Флаг отображения списка атрибутов
const displayAttrsList = attrs.length == 0 ? null : filteredAttrs.length > 0 ? true : false;
//Генерация содержимого
return (
<P8PDialog title={`Атрибуты сущности "${title}"`} onOk={handleOk} onCancel={handleCancel}>
<P8PDialog title={`Атрибуты сущности "${title}"`} width={P8P_DIALOG_WIDTH.SM} fullWidth onOk={handleOk} onCancel={handleCancel}>
<TextField
margin={"normal"}
variant={"standard"}
@ -90,7 +109,15 @@ const EntityAttrsDialog = ({ query, id, title, onOk, onCancel }) => {
)
}}
/>
<AttrsList attrs={attrs} filter={filter} onSelect={handleAttrSelect} onShow={handleAttrShow} />
<Box sx={STYLES.LIST_CONTAINER} justifyContent={"center"} alignItems={"center"} display={"flex"}>
{displayAttrsList === true && <AttrsList attrs={filteredAttrs} filter={filter} onSelect={handleAttrSelect} onShow={handleAttrShow} />}
{displayAttrsList === false && (
<P8PComponentInlineMessage
name={"Нет данных, соответствующих фильтру"}
message={"Измените значение фильтра для повторного поиска"}
/>
)}
</Box>
</P8PDialog>
);
};