152 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Парус 8 - Панели мониторинга - Редактор запросов
Компоненты: Атрибут сущности
*/
//---------------------
//Подключение библиотек
//---------------------
import React from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Handle, Position, useStore } from "reactflow"; //Библиотека редактора диаграмм
import { Box, Stack, Icon, Typography } from "@mui/material"; //Компоненты UI
import { DATA_TYPE } from "../../common"; //Общие ресурсы и константы редактора
//---------
//Константы
//---------
//Типовые цвета точек привязки
const HANDLE_BORDER_COLOR = "#69db7c";
const HANDLE_BORDER_COLOR_INVALID = "#ff0000";
const HANDLE_BORDER_COLOR_DISABLED = "#adb5bd";
//Стили
const STYLES = {
CONTAINER: { display: "flex", width: "100%", height: "100%", cursor: "default" },
HANDLE_SOURCE: isConnecting => ({
width: 14,
height: 14,
right: -10,
border: `2px solid ${isConnecting ? HANDLE_BORDER_COLOR_DISABLED : HANDLE_BORDER_COLOR}`,
borderRadius: 7,
background: "white"
}),
HANDLE_TARGET: (isConnecting, isValidConnection) => ({
width: isConnecting ? 14 : 0,
height: 14,
left: isConnecting ? -7 : 0,
border: `2px solid ${isValidConnection ? HANDLE_BORDER_COLOR : HANDLE_BORDER_COLOR_INVALID}`,
borderRadius: 7,
background: "white",
visibility: isConnecting ? "visible" : "hidden"
}),
CONTENT_STACK: { width: "100%" },
TITLE_NAME_STACK: { width: "100%", containerType: "inline-size" },
ATTR_PROP_ICON: { fontSize: "0.9rem" }
};
//Иконки
const ICONS = {
[DATA_TYPE.STR]: "format_align_left",
[DATA_TYPE.NUMB]: "pin",
[DATA_TYPE.DATE]: "calendar_month",
DEFAULT: "category"
};
//Структура данных об атрибуте сущности
const ATTRIBUTE_DATA_SHAPE = PropTypes.shape({
id: PropTypes.string.isRequired,
parentEntity: PropTypes.string,
name: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
dataType: PropTypes.oneOf(Object.values(DATA_TYPE)),
agg: PropTypes.string,
alias: PropTypes.string,
use: PropTypes.oneOf([0, 1]).isRequired,
show: PropTypes.oneOf([0, 1]).isRequired
});
//-----------------------
//Вспомогательные функции
//-----------------------
//Получение атрибутики состояния включения атрибута в запрос
const attrGetUse = (attr, callToAction = false) => {
return [attr.use === 1, `${attr.use === 1 ? "Включен в запрос" : "Не включен в запрос"}${callToAction ? "- нажмите, чтобы изменить" : ""}`];
};
//Получение атрибутики состояния отображения атрибута в результатах запроса
const attrGetShow = (attr, callToAction = false) => {
return [
`${attr.show == 1 ? "Отображается в результатах запроса" : "Не отображается в результатах запроса"}${
callToAction ? "- нажмите, чтобы изменить" : ""
}`,
attr.show == 1 ? "visibility" : "visibility_off"
];
};
//-----------
//Тело модуля
//-----------
//Атрибут сущности
const Attribute = ({ data }) => {
//Поиск идентификатора соединяемого элемента
const [connectionNodeId, targetConnectionNode, connectionStatus] = useStore(state => [
state.connectionNodeId,
state?.connectionEndHandle?.nodeId,
state.connectionStatus
]);
//Флаг выполнения соединения сущностей
const isConnecting = Boolean(connectionNodeId);
//Флаг корректности соединения сущностей
const isValidConnection = !(data.id == targetConnectionNode && connectionStatus == "invalid");
//Получим атрибуты состояния отображения
const [showTitle, showIcon] = attrGetShow(data);
//Формирование представления
return (
<Box p={1} sx={STYLES.CONTAINER}>
<Handle type={"source"} position={Position.Right} style={STYLES.HANDLE_SOURCE(isConnecting)} />
<Handle
type={"target"}
position={Position.Left}
isConnectableStart={false}
style={STYLES.HANDLE_TARGET(isConnecting, isValidConnection)}
/>
<Stack direction={"row"} alignItems={"center"} spacing={1} sx={STYLES.CONTENT_STACK}>
<Icon color={"action"}>{ICONS[data.dataType] || ICONS.DEFAULT}</Icon>
<Stack direction={"column"} alignItems={"left"} sx={STYLES.TITLE_NAME_STACK}>
<Typography variant={"body2"} noWrap title={data.title}>
{data.title}
</Typography>
<Stack direction={"row"} alignItems={"center"} spacing={0.5}>
<Typography component={"div"} variant={"caption"} color={"text.secondary"} noWrap title={data.name}>
{`${data.name},`}
</Typography>
<Icon color={"action"} sx={STYLES.ATTR_PROP_ICON} title={showTitle}>
{showIcon}
</Icon>
</Stack>
</Stack>
</Stack>
</Box>
);
};
//Контроль свойств компонента - Атрибут сущности
Attribute.propTypes = {
data: ATTRIBUTE_DATA_SHAPE
};
//----------------
//Интерфейс модуля
//----------------
export { Attribute, ATTRIBUTE_DATA_SHAPE, attrGetUse, attrGetShow };