145 lines
5.0 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 { Box, Stack, ListItem, Icon, ListItemButton, Typography } from "@mui/material"; //Компоненты UI
import { ENTITY_TYPE, ENTITY_TYPE_ICON } from "../../common"; //Общие ресурсы и константы редактора запросов
import { ATTRIBUTE_SHAPE } from "../attribute/attribute"; //Описание атрибута сущности
//---------
//Константы
//---------
//Варианты представления сущности
const ENTITY_VARIANT = {
LIST_ITEM: "LIST_ITEM",
DIAGRAM: "DIAGRAM"
};
//Иконки
const ICONS = { ...ENTITY_TYPE_ICON, DEFAULT: "border_clear" };
//Структура данных о сущности запроса
const ENTITY_SHAPE = PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
type: PropTypes.oneOf(Object.values(ENTITY_TYPE)).isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
attrs: PropTypes.arrayOf(ATTRIBUTE_SHAPE).isRequired
});
//Структура данных о сущности запроса (краткая)
const ENTITY_BRIEF_SHAPE = PropTypes.shape({
name: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
type: PropTypes.oneOf(Object.values(ENTITY_TYPE)).isRequired
});
//Стили
const STYLES = {
CONTAINER: selected => ({
width: "100%",
height: "100%",
border: "1px solid var(--border-color-dark)",
borderRadius: "6px",
boxShadow: "var(--shadow-entity)",
overflow: "hidden",
backgroundColor: "white",
cursor: "move",
...(selected
? {
outline: "1px solid var(--outline-color)",
borderColor: "var(--outline-color)"
}
: {})
}),
CONTENT_STACK: variant => ({
width: "100%",
backgroundColor: "var(--entity-title-bg)",
...(variant === ENTITY_VARIANT.DIAGRAM ? { height: "50px" } : {})
}),
CAPTIONS_TYPOGRAPHY: variant => ({ ...(variant === ENTITY_VARIANT.DIAGRAM ? { maxWidth: "100px", overflow: "hidden" } : {}) })
};
//-----------
//Тело модуля
//-----------
//Сущность запроса
const Entity = ({ data, variant = ENTITY_VARIANT.DIAGRAM, selected = false, onClick = null }) => {
//Иконка
const icon = ICONS[data.type] || ICONS.DEFAULT;
//Всплывающая подсказка
const iconTitle = data.type === ENTITY_TYPE.VIEW ? "Представление" : "Таблица";
//Содержимое самой сущности
const entContent = (
<Stack
direction={"row"}
alignItems={"center"}
justifyContent={variant === ENTITY_VARIANT.DIAGRAM ? "center" : "left"}
p={1}
sx={STYLES.CONTENT_STACK(variant)}
>
<Icon color={"action"} title={iconTitle}>
{icon}
</Icon>
<Stack direction={"column"} alignItems={"left"} pl={1}>
<Typography
variant={variant === ENTITY_VARIANT.DIAGRAM ? "subtitle2" : "body2"}
noWrap={variant === ENTITY_VARIANT.DIAGRAM ? true : false}
title={data.title}
sx={STYLES.CAPTIONS_TYPOGRAPHY(variant)}
>
{data.title}
</Typography>
<Typography
component={"div"}
variant={"caption"}
color={"text.secondary"}
noWrap={variant === ENTITY_VARIANT.DIAGRAM ? true : false}
title={data.name}
sx={STYLES.CAPTIONS_TYPOGRAPHY(variant)}
>
{data.name}
</Typography>
</Stack>
</Stack>
);
//Формирование представления
return variant == ENTITY_VARIANT.LIST_ITEM ? (
<ListItem disablePadding>
<ListItemButton onClick={() => onClick && onClick(data)} dense>
{entContent}
</ListItemButton>
</ListItem>
) : variant == ENTITY_VARIANT.DIAGRAM ? (
<Box sx={STYLES.CONTAINER(selected)}>{entContent}</Box>
) : null;
};
//Контроль свойств компонента - Сущность запроса
Entity.propTypes = {
data: PropTypes.oneOfType([ENTITY_SHAPE, ENTITY_BRIEF_SHAPE]).isRequired,
variant: PropTypes.string,
selected: PropTypes.bool,
onClick: PropTypes.func
};
//----------------
//Интерфейс модуля
//----------------
export { Entity, ENTITY_VARIANT, ENTITY_SHAPE, ENTITY_BRIEF_SHAPE };