ЦИТК-979 - Компонент для настройки свойств запроса, настройка атрибутов сущностей (начало, клиент)
This commit is contained in:
parent
836a3db5e2
commit
f9b2f1ae34
@ -101,4 +101,4 @@ Attribute.propTypes = {
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { Attribute };
|
||||
export { Attribute, ATTRIBUTE_DATA_SHAPE };
|
||||
|
@ -17,6 +17,7 @@ import "./entity.css"; //Стили компомнента
|
||||
|
||||
//Структура данных о сущности запроса
|
||||
const ENTITY_DATA_SHAPE = PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired
|
||||
});
|
||||
@ -26,7 +27,7 @@ const ENTITY_DATA_SHAPE = PropTypes.shape({
|
||||
//-----------
|
||||
|
||||
//Сущность запроса
|
||||
const Entity = ({ data, selected }) => {
|
||||
const Entity = ({ data, selected = false }) => {
|
||||
return (
|
||||
<div className="entity__wrapper" data-selected={selected}>
|
||||
<div className="entity__title">
|
||||
@ -47,4 +48,4 @@ Entity.propTypes = {
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { Entity };
|
||||
export { Entity, ENTITY_DATA_SHAPE };
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - Редактор запросов
|
||||
Компонент: Диалог настройки атрибутов сущности
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { P8PDialog } from "../../../../components/p8p_dialog"; //Типовой диалог
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Диалог настройки атрибутов сущности
|
||||
const EntityAttrsDialog = ({ id, title, onOk, onCancel }) => {
|
||||
//Нажатие на кнопку "Ok"
|
||||
const handleOk = values => onOk && onOk({ ...values });
|
||||
|
||||
//Нажатие на кнопку "Отмена"
|
||||
const handleCancel = () => onCancel && onCancel();
|
||||
|
||||
//Генерация содержимого
|
||||
return <P8PDialog title={`Атрибуты сущности "${title}"`} onOk={handleOk} onCancel={handleCancel} />;
|
||||
};
|
||||
|
||||
//Контроль свойств - Диалог настройки атрибутов сущности
|
||||
EntityAttrsDialog.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
onOk: PropTypes.func,
|
||||
onCancel: PropTypes.func
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { EntityAttrsDialog };
|
@ -10,6 +10,7 @@
|
||||
import React from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Stack, List, ListItem, IconButton, Icon, ListItemButton, ListItemText, Typography } from "@mui/material"; //Интерфейсные компоненты MUI
|
||||
import { APP_STYLES } from "../../../../../app.styles"; //Общие стили приложения
|
||||
import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
|
||||
|
||||
//---------
|
||||
@ -20,7 +21,8 @@ import { BUTTONS } from "../../../../../app.text"; //Общие текстовы
|
||||
const STYLES = {
|
||||
SMALL_TOOL_ICON: {
|
||||
fontSize: 20
|
||||
}
|
||||
},
|
||||
LIST: { height: "500px", width: "360px", bgcolor: "background.paper", overflowY: "auto", ...APP_STYLES.SCROLL }
|
||||
};
|
||||
|
||||
//---------
|
||||
@ -76,7 +78,7 @@ const QueriesList = ({ queries = [], current = null, onSelect = null, onPbl = nu
|
||||
|
||||
//Формирование представления
|
||||
return (
|
||||
<List sx={{ height: "500px", width: "360px", bgcolor: "background.paper", overflowY: "auto" }}>
|
||||
<List sx={STYLES.LIST}>
|
||||
{queries.map((query, i) => {
|
||||
const selected = query.rn === current;
|
||||
const disabled = !query.modify;
|
||||
|
@ -36,7 +36,7 @@ const QueriesManager = ({ current = null, onQuerySelect = null, onCancel = null
|
||||
const handleQueryAdd = () => setModQuery(true);
|
||||
|
||||
//При выборе запроса
|
||||
const handleQuerySelect = query => onQuerySelect && onQuerySelect(query.rn);
|
||||
const handleQuerySelect = query => onQuerySelect && onQuerySelect({ ...query });
|
||||
|
||||
//При установке признака публичности
|
||||
const handleQueryPblSet = query => setQueryPbl(query.rn, query.pbl === 1 ? 0 : 1);
|
||||
|
@ -8,10 +8,11 @@
|
||||
//---------------------
|
||||
|
||||
import React, { useState, useCallback, useEffect } from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import ReactFlow, { addEdge, Controls, getOutgoers, applyNodeChanges, applyEdgeChanges } from "reactflow"; //Библиотека редактора диаграмм
|
||||
import { NODE_TYPE } from "../../common"; //Общие ресурсы и константы редактора
|
||||
import { Entity } from "../entity/entity"; //Сущность запроса
|
||||
import { Attribute } from "../attribute/attribute"; //Атрибут сущности
|
||||
import { Entity, ENTITY_DATA_SHAPE } from "../entity/entity"; //Сущность запроса
|
||||
import { Attribute, ATTRIBUTE_DATA_SHAPE } from "../attribute/attribute"; //Атрибут сущности
|
||||
import "reactflow/dist/style.css"; //Типовые стили библиотеки редактора диаграмм
|
||||
import "./query_diagram.css"; //Стили компонента
|
||||
|
||||
@ -36,42 +37,44 @@ const NODE_TYPES_COMPONENTS = {
|
||||
[NODE_TYPE.ATTRIBUTE]: Attribute
|
||||
};
|
||||
|
||||
//Структура сущности запроса
|
||||
const ENTITY_SHAPE = PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
type: PropTypes.oneOf([NODE_TYPE.ENTITY, NODE_TYPE.ATTRIBUTE]).isRequired,
|
||||
style: PropTypes.object,
|
||||
position: PropTypes.shape({ x: PropTypes.number.isRequired, y: PropTypes.number.isRequired }),
|
||||
draggable: PropTypes.bool.isRequired,
|
||||
data: PropTypes.oneOfType([ENTITY_DATA_SHAPE, ATTRIBUTE_DATA_SHAPE])
|
||||
});
|
||||
|
||||
//Структура связи запроса
|
||||
const RELATION_SHAPE = PropTypes.shape({ id: PropTypes.string.isRequired, source: PropTypes.string.isRequired, target: PropTypes.string.isRequired });
|
||||
|
||||
//------------------------------------
|
||||
//Вспомогательные функции и компоненты
|
||||
//------------------------------------
|
||||
|
||||
//Проверка зацикленности связи
|
||||
const hasCycle = (connection, target, nodes, edges, visited = new Set()) => {
|
||||
if (visited.has(target.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (visited.has(target.id)) return false;
|
||||
visited.add(target.id);
|
||||
|
||||
for (const outgoer of getOutgoers(target, nodes, edges)) {
|
||||
if (outgoer.id === connection.source || hasCycle(connection, outgoer, nodes, edges, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const outgoer of getOutgoers(target, nodes, edges))
|
||||
if (outgoer.id === connection.source || hasCycle(connection, outgoer, nodes, edges, visited)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
//Проверка корректности связи
|
||||
const isValidConnection = (connection, nodes, edges) => {
|
||||
if (!connection.source || !connection.target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const tableId = connection.source.split("-")[0];
|
||||
//Должны быть заданы источник и приёмник
|
||||
if (!connection.source || !connection.target) return false;
|
||||
//Нельзя ссылаться на самого себя
|
||||
const tableId = connection.source.split(".")[0];
|
||||
const isSameTable = connection.target.startsWith(tableId);
|
||||
if (isSameTable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSameTable) return false;
|
||||
//Приёмник должен быть среди элементов диаграммы и не должен быть источником
|
||||
const target = nodes.find(node => node.id === connection.target);
|
||||
if (!target || target.id === connection.source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target || target.id === connection.source) return false;
|
||||
//Нельзя зацикливаться
|
||||
return !hasCycle(connection, target, nodes, edges);
|
||||
};
|
||||
|
||||
@ -80,7 +83,16 @@ const isValidConnection = (connection, nodes, edges) => {
|
||||
//-----------
|
||||
|
||||
//Диаграмма запроса
|
||||
const QueryDiagram = ({ entities, relations, onEntityPositionChange, onEntityRemove, onRelationAdd, onRelationRemove }) => {
|
||||
const QueryDiagram = ({
|
||||
entities = [],
|
||||
relations = [],
|
||||
onEntityClick,
|
||||
onEntityPositionChange,
|
||||
onEntityRemove,
|
||||
onRelactionClick,
|
||||
onRelationAdd,
|
||||
onRelationRemove
|
||||
}) => {
|
||||
//Собственное состояние - элементы
|
||||
const [nodes, setNodes] = useState(entities);
|
||||
|
||||
@ -98,20 +110,27 @@ const QueryDiagram = ({ entities, relations, onEntityPositionChange, onEntityRem
|
||||
setMovedNode({ id: changes[0].id, position: { ...changes[0].position } });
|
||||
if (changes.length == 1 && changes[0].type == "position" && !changes[0].dragging && movedNode) {
|
||||
if (onEntityPositionChange) onEntityPositionChange(movedNode.id, movedNode.position);
|
||||
if (onEntityClick) onEntityClick(movedNode.id);
|
||||
setMovedNode(null);
|
||||
}
|
||||
if (changes[0].type == "remove" && entities.find(e => e.id == changes[0].id && e.type == NODE_TYPE.ENTITY) && onEntityRemove)
|
||||
onEntityRemove(changes[0].id);
|
||||
},
|
||||
[movedNode, entities, onEntityPositionChange, onEntityRemove]
|
||||
[movedNode, entities, onEntityClick, onEntityPositionChange, onEntityRemove]
|
||||
);
|
||||
|
||||
//При выборе элемента диаграммы
|
||||
const handleNodeClick = useCallback((e, node) => onEntityClick && onEntityClick(node.id), [onEntityClick]);
|
||||
|
||||
//При связывании элементов на диаграмме
|
||||
const handleConnect = connection => {
|
||||
setEdges(state => addEdge({ ...connection, id: `${connection.source}-${connection.target}` }, state));
|
||||
onRelationAdd && onRelationAdd(connection.source, connection.target);
|
||||
};
|
||||
|
||||
//При выборе связи диаграммы
|
||||
const handleEdgeClick = useCallback((e, edge) => onRelactionClick && onRelactionClick(edge.id), [onRelactionClick]);
|
||||
|
||||
//При изменении связей на диаграмме
|
||||
const handleEdgesChange = useCallback(
|
||||
changes => {
|
||||
@ -121,9 +140,8 @@ const QueryDiagram = ({ entities, relations, onEntityPositionChange, onEntityRem
|
||||
[onRelationRemove]
|
||||
);
|
||||
|
||||
const validateConnection = connection => {
|
||||
return isValidConnection(connection, nodes, edges);
|
||||
};
|
||||
//Валидация связи
|
||||
const validateConnection = connection => isValidConnection(connection, nodes, edges);
|
||||
|
||||
//При изменении состава сущностей
|
||||
useEffect(() => setNodes(entities), [entities]);
|
||||
@ -137,7 +155,9 @@ const QueryDiagram = ({ entities, relations, onEntityPositionChange, onEntityRem
|
||||
nodes={nodes}
|
||||
nodeTypes={NODE_TYPES_COMPONENTS}
|
||||
edges={edges}
|
||||
onNodeClick={handleNodeClick}
|
||||
onNodesChange={handleNodesChange}
|
||||
onEdgeClick={handleEdgeClick}
|
||||
onEdgesChange={handleEdgesChange}
|
||||
defaultEdgeOptions={{
|
||||
animated: true,
|
||||
@ -153,6 +173,18 @@ const QueryDiagram = ({ entities, relations, onEntityPositionChange, onEntityRem
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств компонента - Диаграмма запроса
|
||||
QueryDiagram.propTypes = {
|
||||
entities: PropTypes.arrayOf(ENTITY_SHAPE),
|
||||
relations: PropTypes.arrayOf(RELATION_SHAPE),
|
||||
onEntityClick: PropTypes.func,
|
||||
onEntityPositionChange: PropTypes.func,
|
||||
onEntityRemove: PropTypes.func,
|
||||
onRelactionClick: PropTypes.func,
|
||||
onRelationAdd: PropTypes.func,
|
||||
onRelationRemove: PropTypes.func
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - Редактор запросов
|
||||
Свойства запроса
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React, { useState, useContext } from "react"; //Классы React
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
import { Button, Icon } from "@mui/material"; //Интерфейсные компоненты MUI
|
||||
import { MessagingСtx } from "../../../../context/messaging"; //Контекст сообщений приложения
|
||||
import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
|
||||
import { EntityAddDialog } from "../entity_add_dialog/entity_add_dialog"; //Диалог добавления сущности
|
||||
import { EntityAttrsDialog } from "../entity_attrs_dialog/entity_attrs_dialog"; //Диалог настройки атрибутов сущности
|
||||
import { P8PEditorBox } from "../../../../components/editors/p8p_editor_box"; //Контейнер параметров редактора
|
||||
import { P8PEditorSubHeader } from "../../../../components/editors/p8p_editor_sub_header"; //Подзаголовок группы параметров редактора
|
||||
import { ENTITY_DATA_SHAPE } from "../entity/entity"; //Описание сущности
|
||||
import { RELATION_DATA_SHAPE } from "../relation/relation"; //Описание связи
|
||||
|
||||
//-----------
|
||||
//Тело модуля
|
||||
//-----------
|
||||
|
||||
//Свойства запроса
|
||||
const QueryOptions = ({ onEntityAdd, onEntityRemove, onRelationRemove, onQueryOptionsChanged, entity, relation }) => {
|
||||
//Отображение диалога добавления сущности
|
||||
const [openEntityAddDialog, setOpenEntityAddDialog] = useState(false);
|
||||
|
||||
//Отображение диалога настройки атрибутов сущности
|
||||
const [openEntityAttrsDialog, setOpenEntityAttrsDialog] = useState(false);
|
||||
|
||||
//Подключение к контексту сообщений
|
||||
const { showMsgWarn } = useContext(MessagingСtx);
|
||||
|
||||
//При нажатии на кнопку добавлении сущности в запрос
|
||||
const handleEntityAddClick = () => setOpenEntityAddDialog(true);
|
||||
|
||||
//При нажатии на кнопку настройки атрибутов сущности
|
||||
const handleEntityAttrsClick = () => setOpenEntityAttrsDialog(true);
|
||||
|
||||
//При нажатии на кнопку даления сущности из запроса
|
||||
const handleEntityRemoveClick = () =>
|
||||
showMsgWarn(`Удалить сущность "${entity.title}"?`, () => entity?.id && onEntityRemove && onEntityRemove(entity.id));
|
||||
|
||||
//При нажатии на кнопку даления связи из запроса
|
||||
const handleRelationRemoveClick = () =>
|
||||
showMsgWarn(
|
||||
`Удалить связь "${relation.source}" - "${relation.target}"?`,
|
||||
() => relation?.id && onRelationRemove && onRelationRemove(relation.id)
|
||||
);
|
||||
|
||||
//Закрытие диалога добавления сущности по "Отмена"
|
||||
const handleEntityAddDialogCancel = () => setOpenEntityAddDialog(false);
|
||||
|
||||
//Закрытие диалога добавления сущности по "ОК"
|
||||
const handleEntityAddDialogOk = values => onEntityAdd && onEntityAdd(values.name, res => res && setOpenEntityAddDialog(false));
|
||||
|
||||
//Закрытие диалога настройки атрибутов сущности по "Отмена"
|
||||
const handleEntityAttrsDialogCancel = () => setOpenEntityAttrsDialog(false);
|
||||
|
||||
//Закрытие диалога настройки атрибутов сущности по "ОК"
|
||||
const handleEntityAttrsDialogOk = () => {
|
||||
onQueryOptionsChanged && onQueryOptionsChanged();
|
||||
setOpenEntityAttrsDialog();
|
||||
};
|
||||
|
||||
//Генерация содержимого
|
||||
return (
|
||||
<>
|
||||
{openEntityAddDialog && <EntityAddDialog onOk={handleEntityAddDialogOk} onCancel={handleEntityAddDialogCancel} />}
|
||||
{openEntityAttrsDialog && <EntityAttrsDialog {...entity} onOk={handleEntityAttrsDialogOk} onCancel={handleEntityAttrsDialogCancel} />}
|
||||
<P8PEditorBox title={"Параметры запроса"}>
|
||||
<P8PEditorSubHeader title={"Сущности"} />
|
||||
<Button startIcon={<Icon>add</Icon>} onClick={handleEntityAddClick}>
|
||||
{BUTTONS.INSERT}
|
||||
</Button>
|
||||
{entity && (
|
||||
<>
|
||||
<P8PEditorSubHeader title={entity.title} />
|
||||
<Button startIcon={<Icon>edit_attributes</Icon>} onClick={handleEntityAttrsClick}>
|
||||
Атрибуты
|
||||
</Button>
|
||||
<Button startIcon={<Icon>delete</Icon>} onClick={handleEntityRemoveClick}>
|
||||
{BUTTONS.DELETE}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{relation && (
|
||||
<>
|
||||
<P8PEditorSubHeader title={"Связь"} />
|
||||
<Button startIcon={<Icon>delete</Icon>} onClick={handleRelationRemoveClick}>
|
||||
{BUTTONS.DELETE}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</P8PEditorBox>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
//Контроль свойств компонента - Свойства запроса
|
||||
QueryOptions.propTypes = {
|
||||
onEntityAdd: PropTypes.func,
|
||||
onEntityRemove: PropTypes.func,
|
||||
onRelationRemove: PropTypes.func,
|
||||
onQueryOptionsChanged: PropTypes.func,
|
||||
entity: ENTITY_DATA_SHAPE,
|
||||
relation: RELATION_DATA_SHAPE
|
||||
};
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { QueryOptions };
|
27
app/panels/query_editor/components/relation/relation.js
Normal file
27
app/panels/query_editor/components/relation/relation.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Парус 8 - Панели мониторинга - Редактор запросов
|
||||
Компоненты: Связь сущностей запроса
|
||||
*/
|
||||
|
||||
//---------------------
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Структура данных о связи сущностей запроса
|
||||
const RELATION_DATA_SHAPE = PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
source: PropTypes.string.isRequired,
|
||||
target: PropTypes.string.isRequired
|
||||
});
|
||||
|
||||
//----------------
|
||||
//Интерфейс модуля
|
||||
//----------------
|
||||
|
||||
export { RELATION_DATA_SHAPE };
|
@ -7,22 +7,23 @@
|
||||
//Подключение библиотек
|
||||
//---------------------
|
||||
|
||||
import React, { useState } from "react"; //Классы React
|
||||
import { Box, Grid, Button, Icon } from "@mui/material"; //Интерфейсные компоненты MUI
|
||||
import React, { useState, useContext } from "react"; //Классы React
|
||||
import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты MUI
|
||||
import { ApplicationСtx } from "../../context/application"; //Контекст взаимодействия с приложением
|
||||
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Компоненты рабочего стола
|
||||
import { P8PEditorToolBar } from "../../components/editors/p8p_editor_toolbar"; //Панель инструментов редактора
|
||||
import { BUTTONS } from "../../../app.text"; //Общие текстовые ресурсы приложения
|
||||
import { QueryDiagram } from "./components/query_diagram/query_diagram"; //Диаграмма запроса
|
||||
import { QueryOptions } from "./components/query_options/query_options"; //Свойства запроса
|
||||
import { QueriesManager } from "./components/queries_manager/queries_manager"; //Менеджер запросов
|
||||
import { EntityAddDialog } from "./components/entity_add_dialog/entity_add_dialog"; //Диалог добавления сущности
|
||||
import { P8PEditorBox } from "../../components/editors/p8p_editor_box"; //Контейнер параметров редактора
|
||||
import { P8PEditorSubHeader } from "../../components/editors/p8p_editor_sub_header"; //Подзаголовок группы параметров редактора
|
||||
import { useQueryDesc } from "./hooks"; //Пользовательские хуки
|
||||
|
||||
//---------
|
||||
//Константы
|
||||
//---------
|
||||
|
||||
//Заголовок панели по умолчанию
|
||||
const APP_BAR_TITLE_DEFAULT = "Редактор запросов";
|
||||
|
||||
//Стили
|
||||
const STYLES = {
|
||||
CONTAINER: { display: "flex" },
|
||||
@ -39,26 +40,62 @@ const QueryEditor = () => {
|
||||
//Текущий запрос
|
||||
const [query, setQuery] = useState(null);
|
||||
|
||||
//Текущая сущность
|
||||
const [entity, setEntity] = useState(null);
|
||||
|
||||
//Текущая связь
|
||||
const [relation, setRelation] = useState(null);
|
||||
|
||||
//Отображения менеджера запросов
|
||||
const [openQueriesManager, setOpenQueriesManager] = useState(true);
|
||||
|
||||
//Отображение диалога добавления сущности
|
||||
const [openEntityAddDialog, setOpenEntityAddDialog] = useState(false);
|
||||
|
||||
//Получение данных запроса
|
||||
const [queryDiagram, addEnt, removeEnt, setEntPosition, addRl, removeRl] = useQueryDesc(query);
|
||||
const [queryDiagram, addEnt, removeEnt, setEntPosition, addRl, removeRl, doRefresh] = useQueryDesc(query);
|
||||
|
||||
//Подключение к контексту приложения
|
||||
const { setAppBarTitle } = useContext(ApplicationСtx);
|
||||
|
||||
//Обработка изменения положения сущности на диаграмме
|
||||
const handleEntityPositionChange = (ent, position) => setEntPosition(ent, position.x, position.y);
|
||||
|
||||
//Обработка добавления сущности в запрос
|
||||
const handleEntityAdd = async (entName, cb) => {
|
||||
await addEnt(entName, "VIEW");
|
||||
cb(true);
|
||||
};
|
||||
|
||||
//Обработка удаления сущности из запроса
|
||||
const handleEntityRemove = ent => removeEnt(ent);
|
||||
const handleEntityRemove = async ent => {
|
||||
await removeEnt(ent);
|
||||
if (entity && entity?.id === ent) setEntity(null);
|
||||
};
|
||||
|
||||
//Обработка выделения сущности
|
||||
const handleEntityClick = ent => {
|
||||
setRelation(null);
|
||||
const queryEnt = queryDiagram.entities.find(e => e.id === ent);
|
||||
if (queryEnt)
|
||||
if (entity?.id == queryEnt.id) setEntity(null);
|
||||
else setEntity({ ...queryEnt.data });
|
||||
};
|
||||
|
||||
//Обработка выделения связи
|
||||
const handleRelationClick = rl => {
|
||||
setEntity(null);
|
||||
const queryRl = queryDiagram.relations.find(r => r.id === rl);
|
||||
if (queryRl)
|
||||
if (relation?.id == queryRl.id) setRelation(null);
|
||||
else setRelation({ ...queryRl });
|
||||
};
|
||||
|
||||
//Обработка добавления отношения cущностей
|
||||
const handleRelationAdd = (source, target) => addRl(source, target);
|
||||
|
||||
//Обработка удаления отношения cущностей
|
||||
const handleRelationRemove = rl => removeRl(rl);
|
||||
const handleRelationRemove = async rl => {
|
||||
await removeRl(rl);
|
||||
if (relation && relation?.id === rl) setRelation(null);
|
||||
};
|
||||
|
||||
//Открытие менеджера запросов
|
||||
const handleOpenQueriesManager = () => setOpenQueriesManager(true);
|
||||
@ -67,25 +104,22 @@ const QueryEditor = () => {
|
||||
const handleCancelQueriesManager = () => setOpenQueriesManager(false);
|
||||
|
||||
//Закрытие запроса
|
||||
const handleQueryClose = () => setQuery(null);
|
||||
const handleQueryClose = () => {
|
||||
setAppBarTitle(APP_BAR_TITLE_DEFAULT);
|
||||
setEntity(null);
|
||||
setRelation(null);
|
||||
setQuery(null);
|
||||
};
|
||||
|
||||
//При выборе запроса
|
||||
const handleQuerySelect = query => {
|
||||
setQuery(query);
|
||||
const handleQuerySelect = ({ rn, name }) => {
|
||||
setAppBarTitle(`Запрос [${name}]`);
|
||||
setQuery(rn);
|
||||
setOpenQueriesManager(false);
|
||||
};
|
||||
|
||||
//При добавлении сущности в запрос
|
||||
const handleEntityAdd = () => setOpenEntityAddDialog(true);
|
||||
|
||||
//Закрытие диалога добавления сущности по "ОК"
|
||||
const handleEntityAddDialogOk = async values => {
|
||||
await addEnt(values.name, "VIEW");
|
||||
setOpenEntityAddDialog(false);
|
||||
};
|
||||
|
||||
//Закрытие диалога добавления сущности по "ОК"
|
||||
const handleEntityAddDialogCancel = () => setOpenEntityAddDialog(false);
|
||||
//При изменении свойств запроса
|
||||
const handleQueryOptionsChanged = () => doRefresh();
|
||||
|
||||
//Панель инструмментов
|
||||
const toolBar = (
|
||||
@ -101,14 +135,15 @@ const QueryEditor = () => {
|
||||
return (
|
||||
<Box sx={STYLES.CONTAINER}>
|
||||
{openQueriesManager && <QueriesManager current={query} onQuerySelect={handleQuerySelect} onCancel={handleCancelQueriesManager} />}
|
||||
{openEntityAddDialog && <EntityAddDialog onOk={handleEntityAddDialogOk} onCancel={handleEntityAddDialogCancel} />}
|
||||
<Grid container sx={STYLES.GRID_CONTAINER} columns={25}>
|
||||
<Grid item xs={20}>
|
||||
{queryDiagram && (
|
||||
<QueryDiagram
|
||||
{...queryDiagram}
|
||||
onEntityClick={handleEntityClick}
|
||||
onEntityPositionChange={handleEntityPositionChange}
|
||||
onEntityRemove={handleEntityRemove}
|
||||
onRelactionClick={handleRelationClick}
|
||||
onRelationAdd={handleRelationAdd}
|
||||
onRelationRemove={handleRelationRemove}
|
||||
/>
|
||||
@ -117,12 +152,14 @@ const QueryEditor = () => {
|
||||
<Grid item xs={5} sx={STYLES.GRID_ITEM_INSPECTOR}>
|
||||
{toolBar}
|
||||
{query && (
|
||||
<P8PEditorBox title={"Параметры запроса"}>
|
||||
<P8PEditorSubHeader title={"Сущности"} />
|
||||
<Button startIcon={<Icon>add</Icon>} onClick={handleEntityAdd}>
|
||||
{BUTTONS.INSERT}
|
||||
</Button>
|
||||
</P8PEditorBox>
|
||||
<QueryOptions
|
||||
onEntityAdd={handleEntityAdd}
|
||||
onEntityRemove={handleEntityRemove}
|
||||
onRelationRemove={handleRelationRemove}
|
||||
onQueryOptionsChanged={handleQueryOptionsChanged}
|
||||
entity={entity}
|
||||
relation={relation}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
Loading…
x
Reference in New Issue
Block a user