diff --git a/app/panels/query_editor/components/argument/argument.js b/app/panels/query_editor/components/argument/argument.js
new file mode 100644
index 0000000..eec7b71
--- /dev/null
+++ b/app/panels/query_editor/components/argument/argument.js
@@ -0,0 +1,89 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компоненты: Аргумент запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { Stack, ListItem, IconButton, Icon, ListItemButton, ListItemText, Typography, ListItemIcon, Chip } from "@mui/material"; //Компоненты UI
+import { STYLES as COMMON_STYLES } from "../../../../components/editors/p8p_editors_common"; //Общие ресурсы редаторов
+import { DATA_TYPE, DATA_TYPE_ICON } from "../../common"; //Общие ресурсы и константы редактора запросов
+
+//---------
+//Константы
+//---------
+
+//Варианты представления
+const ARGUMENT_VARIANT = {
+ LIST_ITEM: "LIST_ITEM",
+ CHIP: "CHIP"
+};
+
+//Структура аргумента
+const ARGUMENT_SHAPE = PropTypes.shape({
+ name: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ dataType: PropTypes.oneOf(Object.values(DATA_TYPE)),
+ mandatory: PropTypes.oneOf([0, 1]).isRequired
+});
+
+//Иконки
+const ICONS = { ...DATA_TYPE_ICON, DEFAULT: "category" };
+
+//-----------
+//Тело модуля
+//-----------
+
+//Аргумент запроса
+const Argument = ({ arg, variant, onClick = null, onDelete = null }) => {
+ //Заголовок аргумента
+ const title = `${arg.mandatory == 1 ? "*" : ""}${arg.title}`;
+
+ //Иконка аргумента
+ const icon = ICONS[arg.dataType] || ICONS.DEFAULT;
+
+ //Формирование представления
+ return variant == ARGUMENT_VARIANT.LIST_ITEM ? (
+
+ onClick && onClick(arg)} dense>
+
+ {icon}
+
+
+ {arg.name}
+
+ }
+ />
+
+ onDelete && onDelete(e, arg)} title={"Удалить"}>
+ delete
+
+
+
+
+ ) : variant == ARGUMENT_VARIANT.CHIP ? (
+ {icon}} label={title} variant={"outlined"} sx={COMMON_STYLES.CHIP(true)} />
+ ) : null;
+};
+
+//Контроль свойств компонента - Аргумент запроса
+Argument.propTypes = {
+ arg: ARGUMENT_SHAPE,
+ variant: PropTypes.oneOf(Object.values(ARGUMENT_VARIANT)).isRequired,
+ onClick: PropTypes.func,
+ onDelete: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { Argument, ARGUMENT_VARIANT, ARGUMENT_SHAPE };
diff --git a/app/panels/query_editor/components/inspector/inspector.js b/app/panels/query_editor/components/inspector/inspector.js
new file mode 100644
index 0000000..7ecb070
--- /dev/null
+++ b/app/panels/query_editor/components/inspector/inspector.js
@@ -0,0 +1,62 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Инспектор свойств
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+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"; //Описание связи
+import { InspectorQueryArguments } from "../inspector_query_args/inspector_query_args"; //Управление аргументами запроса
+import { InspectorQueryEntities } from "../inspector_query_ents/inspector_query_ents"; //Управление сущностями запроса
+import { InspectorQueryRelations } from "../inspector_query_rls/inspector_query_rls"; //Управление связями запроса
+import { ARGUMENT_SHAPE } from "../argument/argument"; //Аргументы запроса
+
+//-----------
+//Тело модуля
+//-----------
+
+//Инспектор свойств
+const Inspector = ({ query, entity, relation, args = [], cond = null, onOptionsChanged = null }) => {
+ //При изменении настроек запроса
+ const handleOptionsChanged = () => onOptionsChanged && onOptionsChanged();
+
+ //Генерация содержимого
+ return (
+
+
+
+
+
+
+ {relation && (
+ <>
+
+
+ >
+ )}
+
+ );
+};
+
+//Контроль свойств компонента - Инспектор свойств
+Inspector.propTypes = {
+ query: PropTypes.number.isRequired,
+ entity: ENTITY_DATA_SHAPE,
+ relation: RELATION_DATA_SHAPE,
+ args: PropTypes.arrayOf(ARGUMENT_SHAPE),
+ cond: PropTypes.string,
+ onOptionsChanged: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { Inspector };
diff --git a/app/panels/query_editor/components/inspector_query_args/arg_iu_dialog.js b/app/panels/query_editor/components/inspector_query_args/arg_iu_dialog.js
new file mode 100644
index 0000000..de8e147
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_args/arg_iu_dialog.js
@@ -0,0 +1,76 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компонент: Диалог добавления/исправления аргумента запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { P8PDialog } from "../../../../components/p8p_dialog"; //Типовой диалог
+import { TITLES } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
+import { DATA_TYPE } from "../../common"; //Общие константы редактора
+
+//-----------
+//Тело модуля
+//-----------
+
+//Диалог добавления/исправления аргумента запроса
+const ArgIUDialog = ({ name = "", title = "", dataType = DATA_TYPE.NUMB, mandatory = 0, insert = true, onOk, onCancel }) => {
+ //Нажатие на кнопку "Ok"
+ const handleOk = values => onOk && onOk({ ...values });
+
+ //Нажатие на кнопку "Отмена"
+ const handleCancel = () => onCancel && onCancel();
+
+ //Генерация содержимого
+ return (
+
+ );
+};
+
+//Контроль свойств - Диалог добавления/исправления аргумента запроса
+ArgIUDialog.propTypes = {
+ name: PropTypes.string,
+ title: PropTypes.string,
+ dataType: PropTypes.number,
+ mandatory: PropTypes.number,
+ insert: PropTypes.bool,
+ onOk: PropTypes.func,
+ onCancel: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { ArgIUDialog };
diff --git a/app/panels/query_editor/components/inspector_query_args/args_list.js b/app/panels/query_editor/components/inspector_query_args/args_list.js
new file mode 100644
index 0000000..d5b8251
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_args/args_list.js
@@ -0,0 +1,63 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компонент: Список аргументов
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { List } from "@mui/material"; //Интерфейсные компоненты MUI
+import { APP_STYLES } from "../../../../../app.styles"; //Общие стили приложения
+
+import { Argument, ARGUMENT_VARIANT, ARGUMENT_SHAPE } from "../argument/argument"; //Аргумент запроса
+
+//---------
+//Константы
+//---------
+
+//Стили
+const STYLES = {
+ LIST: { height: "500px", width: "360px", bgcolor: "background.paper", overflowY: "auto", ...APP_STYLES.SCROLL }
+};
+
+//-----------
+//Тело модуля
+//-----------
+
+//Список аргументов
+const ArgsList = ({ args = [], onSelect = null, onDelete = null } = {}) => {
+ //При нажатии на элемент списка
+ const handleItemClick = arg => onSelect && onSelect(arg);
+
+ //При нажатии на удалении элемента списка
+ const handleItemDeleteClick = (e, arg) => {
+ e.stopPropagation();
+ onDelete && onDelete(arg);
+ };
+
+ //Формирование представления
+ return (
+
+ {args &&
+ args.map((arg, i) => (
+
+ ))}
+
+ );
+};
+
+//Контроль свойств компонента - Список аргументов
+ArgsList.propTypes = {
+ args: PropTypes.arrayOf(ARGUMENT_SHAPE),
+ onSelect: PropTypes.func,
+ onDelete: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { ArgsList };
diff --git a/app/panels/query_editor/components/inspector_query_args/hooks.js b/app/panels/query_editor/components/inspector_query_args/hooks.js
new file mode 100644
index 0000000..554d55e
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_args/hooks.js
@@ -0,0 +1,66 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Пользовательские хуки настройки аргументов запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import { useContext, useCallback } from "react"; //Классы React
+import { BackEndСtx } from "../../../../context/backend"; //Контекст взаимодействия с сервером
+
+//------------------------------------
+//Вспомогательные функции и компоненты
+//------------------------------------
+
+//-----------
+//Тело модуля
+//-----------
+
+//Работа с аргументами запроса
+const useQueryArgs = query => {
+ //Подключение к контексту взаимодействия с сервером
+ const { executeStored } = useContext(BackEndСtx);
+
+ //Добавление аргумента запроса
+ const addArg = useCallback(
+ async (name, title, dataType, mandatory) => {
+ await executeStored({
+ stored: "PKG_P8PANELS_QE.QUERY_OPT_ARG_ADD",
+ args: { NRN: query, SNAME: name, STITLE: title, NDATA_TYPE: dataType, NMANDATORY: mandatory },
+ loader: false
+ });
+ },
+ [query, executeStored]
+ );
+
+ //Исправление аргумента запроса
+ const editArg = useCallback(
+ async (name, title, dataType, mandatory) => {
+ await executeStored({
+ stored: "PKG_P8PANELS_QE.QUERY_OPT_ARG_EDIT",
+ args: { NRN: query, SNAME: name, STITLE: title, NDATA_TYPE: dataType, NMANDATORY: mandatory },
+ loader: false
+ });
+ },
+ [query, executeStored]
+ );
+
+ //Удаление аргумента запроса
+ const removeArg = useCallback(
+ async name => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_OPT_ARG_REMOVE", args: { NRN: query, SNAME: name }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Возвращаем интерфейс хука
+ return { addArg, editArg, removeArg };
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { useQueryArgs };
diff --git a/app/panels/query_editor/components/inspector_query_args/inspector_query_args.js b/app/panels/query_editor/components/inspector_query_args/inspector_query_args.js
new file mode 100644
index 0000000..4a75480
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_args/inspector_query_args.js
@@ -0,0 +1,107 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компонент инспектора - Аргументы запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React, { useState } from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { Stack, Icon, Button, Card, CardContent, CardActionArea } from "@mui/material"; //Интерфейсные элементы
+import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы
+import { useQueryArgs } from "./hooks"; //Хуки для работы с аргументами запроса на сервере
+import { QueryArgsDialog } from "./query_args_dialog"; //Диалог настройки состава атрибутов
+import { Argument, ARGUMENT_SHAPE, ARGUMENT_VARIANT } from "../argument/argument"; //Аргумент запроса
+
+//-----------
+//Тело модуля
+//-----------
+
+//Компонент инспектора - Аргументы запроса
+const InspectorQueryArguments = ({ query, args = [], onOptionsChanged = null }) => {
+ //Собственное состояние - отображение диалога настройки состава аргументов
+ const [openQueryArgsDialog, setOpenQueryArgsDialog] = useState(false);
+
+ //Хук для взаимодействия с сервером
+ const { addArg, editArg, removeArg } = useQueryArgs(query);
+
+ //Уведомление родителя об изменении свойств
+ const notifyOptionsChanged = () => onOptionsChanged && onOptionsChanged();
+
+ //При нажатии на настройку аргументов
+ const handleSetup = () => setOpenQueryArgsDialog(true);
+
+ //При добавлении аргумента
+ const handleArgAdd = async (arg, cb) => {
+ await addArg(arg.name, arg.title, arg.dataType, arg.mandatory);
+ cb && cb();
+ notifyOptionsChanged();
+ };
+
+ //При изменении аргумента
+ const handleArgEdit = async (arg, cb) => {
+ await editArg(arg.name, arg.title, arg.dataType, arg.mandatory);
+ cb && cb();
+ notifyOptionsChanged();
+ };
+
+ //При удалении аргумента
+ const handleArgRemove = async arg => {
+ await removeArg(arg.name);
+ notifyOptionsChanged();
+ };
+
+ //Закрытие диалога настройки состава аргументов по "Закрыть"
+ const handleQueryArgsDialogClose = () => setOpenQueryArgsDialog(false);
+
+ //Расчет флага "настроенности"
+ const configured = args && args.length > 0 ? true : false;
+
+ //Формирование представления
+ return (
+ <>
+ {openQueryArgsDialog && (
+
+ )}
+ {configured && (
+
+
+
+
+ {args.map((arg, i) => (
+
+ ))}
+
+
+
+
+ )}
+ {!configured && (
+
+ )}
+ >
+ );
+};
+
+//Контроль свойств компонента - Компонент инспектора - Аргументы запроса
+InspectorQueryArguments.propTypes = {
+ query: PropTypes.number.isRequired,
+ args: PropTypes.arrayOf(ARGUMENT_SHAPE),
+ onOptionsChanged: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { InspectorQueryArguments };
diff --git a/app/panels/query_editor/components/inspector_query_args/query_args_dialog.js b/app/panels/query_editor/components/inspector_query_args/query_args_dialog.js
new file mode 100644
index 0000000..86ba714
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_args/query_args_dialog.js
@@ -0,0 +1,80 @@
+/*
+ Парус 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 { P8PDialog } from "../../../../components/p8p_dialog"; //Типовой диалог
+import { ARGUMENT_SHAPE } from "../argument/argument"; //Аргумент запроса
+import { ArgsList } from "./args_list"; //Список аргументов запроса
+import { ArgIUDialog } from "./arg_iu_dialog"; //Диалог добавления/исправления аргумента
+
+//-----------
+//Тело модуля
+//-----------
+
+//Диалог настройки аргументов запроса
+const QueryArgsDialog = ({ args, onArgAdd, onArgEdit, onArgRemove, onClose }) => {
+ //Собственное состояние - изменяемый аргумент
+ const [modArg, setModArg] = useState(null);
+
+ //Подключение к контексту сообщений
+ const { showMsgWarn } = useContext(MessagingСtx);
+
+ //Нажатие на кнопку "Закрыть"
+ const handleClose = () => onClose && onClose();
+
+ //При выборе аргумента в списке
+ const handleArgSelect = arg => setModArg({ ...arg });
+
+ //При добавлении аргумента
+ const handleArgAdd = () => setModArg(true);
+
+ //Удаление аргумента
+ const handleArgRemove = arg => showMsgWarn("Удалить аргумент?", () => onArgRemove && onArgRemove(arg));
+
+ //При закрытии диалога добавления/исправления по "ОК"
+ const handleIUDialogOk = async values => {
+ if (modArg === true) onArgAdd && onArgAdd(values, handleIUDialogCancel);
+ else onArgEdit && onArgEdit(values, handleIUDialogCancel);
+ };
+
+ //При закрытии диалога добавления/исправления по "Отмена"
+ const handleIUDialogCancel = () => setModArg(null);
+
+ //Генерация содержимого
+ return (
+
+ {modArg && (
+
+ )}
+
+
+
+ );
+};
+
+//Контроль свойств - Диалог настройки аргументов запроса
+QueryArgsDialog.propTypes = {
+ args: PropTypes.arrayOf(ARGUMENT_SHAPE),
+ onArgAdd: PropTypes.func,
+ onArgEdit: PropTypes.func,
+ onArgRemove: PropTypes.func,
+ onClose: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { QueryArgsDialog };
diff --git a/app/panels/query_editor/components/entity_attrs_dialog/attrs_list.js b/app/panels/query_editor/components/inspector_query_ents/attrs_list.js
similarity index 100%
rename from app/panels/query_editor/components/entity_attrs_dialog/attrs_list.js
rename to app/panels/query_editor/components/inspector_query_ents/attrs_list.js
diff --git a/app/panels/query_editor/components/entity_add_dialog/entity_add_dialog.js b/app/panels/query_editor/components/inspector_query_ents/entity_add_dialog.js
similarity index 100%
rename from app/panels/query_editor/components/entity_add_dialog/entity_add_dialog.js
rename to app/panels/query_editor/components/inspector_query_ents/entity_add_dialog.js
diff --git a/app/panels/query_editor/components/entity_attrs_dialog/entity_attrs_dialog.js b/app/panels/query_editor/components/inspector_query_ents/entity_attrs_dialog.js
similarity index 100%
rename from app/panels/query_editor/components/entity_attrs_dialog/entity_attrs_dialog.js
rename to app/panels/query_editor/components/inspector_query_ents/entity_attrs_dialog.js
diff --git a/app/panels/query_editor/components/entity_attrs_dialog/hooks.js b/app/panels/query_editor/components/inspector_query_ents/hooks.js
similarity index 67%
rename from app/panels/query_editor/components/entity_attrs_dialog/hooks.js
rename to app/panels/query_editor/components/inspector_query_ents/hooks.js
index 5532430..3a8f03d 100644
--- a/app/panels/query_editor/components/entity_attrs_dialog/hooks.js
+++ b/app/panels/query_editor/components/inspector_query_ents/hooks.js
@@ -1,24 +1,53 @@
/*
Парус 8 - Панели мониторинга - Редактор запросов
- Пользовательские хуки диалога настройки атрибутов сущности
+ Пользовательские хуки для работы с сущностями
*/
//---------------------
//Подключение библиотек
//---------------------
-import { useState, useContext, useEffect, useCallback } from "react"; //Классы React
+import { useContext, useCallback, useEffect, useState } from "react"; //Классы React
import { BackEndСtx } from "../../../../context/backend"; //Контекст взаимодействия с сервером
import { object2Base64XML } from "../../../../core/utils"; //Вспомогательные функции
-//------------------------------------
-//Вспомогательные функции и компоненты
-//------------------------------------
-
//-----------
//Тело модуля
//-----------
+//Работа с сущностями запроса
+const useQueryEntities = query => {
+ //Подключение к контексту взаимодействия с сервером
+ const { executeStored } = useContext(BackEndСtx);
+
+ //Добавление сущности в запрос
+ const addEnt = useCallback(
+ async (name, type) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_ADD", args: { NRN: query, SNAME: name, STYPE: type }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Удаление сущности из запроса
+ const removeEnt = useCallback(
+ async ent => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_REMOVE", args: { NRN: query, SID: ent }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Сохранение координат сущности на диаграммем
+ const setEntPosition = useCallback(
+ async (ent, x, y) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_POSITION_SET", args: { NRN: query, SID: ent, NX: x, NY: y }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Возвращаем интерфейс хука
+ return { addEnt, removeEnt, setEntPosition };
+};
+
//Работа с атрибутами сущности
const useEntityAttrs = (query, entity) => {
//Собственное состояние - флаг загрузки
@@ -89,4 +118,4 @@ const useEntityAttrs = (query, entity) => {
//Интерфейс модуля
//----------------
-export { useEntityAttrs };
+export { useQueryEntities, useEntityAttrs };
diff --git a/app/panels/query_editor/components/inspector_query_ents/inspector_query_ents.js b/app/panels/query_editor/components/inspector_query_ents/inspector_query_ents.js
new file mode 100644
index 0000000..118e014
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_ents/inspector_query_ents.js
@@ -0,0 +1,112 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компонент инспектора - Сущности запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React, { useContext, useState } from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { Icon, Button } from "@mui/material"; //Интерфейсные элементы
+import { MessagingСtx } from "../../../../context/messaging"; //Контекст сообщений приложения
+import { P8PEditorSubHeader } from "../../../../components/editors/p8p_editor_sub_header"; //Подзаголовок группы параметров редактора
+import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы
+import { ENTITY_DATA_SHAPE } from "../entity/entity"; //Описание сущности
+import { EntityAddDialog } from "./entity_add_dialog"; //Диалог добавления сущности
+import { EntityAttrsDialog } from "./entity_attrs_dialog"; //Диалог настройки атрибутов сущности
+import { useQueryEntities } from "./hooks"; //Хуки для работы с сущностями на сервере
+
+//-----------
+//Тело модуля
+//-----------
+
+//Компонент инспектора - Сущности запроса
+const InspectorQueryEntities = ({ query, entity, onOptionsChanged }) => {
+ //Отображение диалога добавления сущности
+ const [openEntityAddDialog, setOpenEntityAddDialog] = useState(false);
+
+ //Отображение диалога настройки атрибутов сущности
+ const [openEntityAttrsDialog, setOpenEntityAttrsDialog] = useState(false);
+
+ //Работа с сущностями на сервере
+ const { addEnt, removeEnt } = useQueryEntities(query);
+
+ //Подключение к контексту сообщений
+ const { showMsgWarn } = useContext(MessagingСtx);
+
+ //Уведомление родителя об изменении свойств
+ const notifyOptionsChanged = () => onOptionsChanged && onOptionsChanged();
+
+ //При нажатии на кнопку добавлении сущности в запрос
+ const handleEntityAddClick = () => setOpenEntityAddDialog(true);
+
+ //При нажатии на кнопку настройки атрибутов сущности
+ const handleEntityAttrsClick = () => setOpenEntityAttrsDialog(true);
+
+ //При нажатии на кнопку даления сущности из запроса
+ const handleEntityRemoveClick = () =>
+ showMsgWarn(`Удалить сущность "${entity.title}"?`, async () => {
+ if (entity?.id) {
+ await removeEnt(entity.id);
+ notifyOptionsChanged();
+ }
+ });
+
+ //Закрытие диалога добавления сущности по "Отмена"
+ const handleEntityAddDialogCancel = () => setOpenEntityAddDialog(false);
+
+ //Закрытие диалога добавления сущности по "ОК"
+ const handleEntityAddDialogOk = async values => {
+ await addEnt(values.name, "VIEW");
+ setOpenEntityAddDialog(false);
+ notifyOptionsChanged();
+ };
+
+ //Закрытие диалога настройки атрибутов сущности по "Отмена"
+ const handleEntityAttrsDialogCancel = () => setOpenEntityAttrsDialog(false);
+
+ //Закрытие диалога настройки атрибутов сущности по "ОК"
+ const handleEntityAttrsDialogOk = () => {
+ notifyOptionsChanged();
+ setOpenEntityAttrsDialog();
+ };
+
+ //Формирование представления
+ return (
+ <>
+ {openEntityAddDialog && }
+ {openEntityAttrsDialog && (
+
+ )}
+
+ {entity && (
+ <>
+
+
+
+ >
+ )}
+ >
+ );
+};
+
+//Контроль свойств компонента - Компонент инспектора - Сущности запроса
+InspectorQueryEntities.propTypes = {
+ query: PropTypes.number.isRequired,
+ entity: ENTITY_DATA_SHAPE,
+ onOptionsChanged: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { InspectorQueryEntities };
diff --git a/app/panels/query_editor/components/inspector_query_rls/hooks.js b/app/panels/query_editor/components/inspector_query_rls/hooks.js
new file mode 100644
index 0000000..53af628
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_rls/hooks.js
@@ -0,0 +1,46 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Пользовательские хуки для работы со связями
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import { useContext, useCallback } from "react"; //Классы React
+import { BackEndСtx } from "../../../../context/backend"; //Контекст взаимодействия с сервером
+
+//-----------
+//Тело модуля
+//-----------
+
+//Работа со связами запроса
+const useQueryRelations = query => {
+ //Подключение к контексту взаимодействия с сервером
+ const { executeStored } = useContext(BackEndСtx);
+
+ //Добавление отношения сущностей в запрос
+ const addRl = useCallback(
+ async (source, target) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_RL_ADD", args: { NRN: query, SSOURCE: source, STARGET: target }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Удаление отношения сущностей из запроса
+ const removeRl = useCallback(
+ async rl => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_RL_REMOVE", args: { NRN: query, SID: rl }, loader: false });
+ },
+ [query, executeStored]
+ );
+
+ //Возвращаем интерфейс хука
+ return { addRl, removeRl };
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { useQueryRelations };
diff --git a/app/panels/query_editor/components/inspector_query_rls/inspector_query_rls.js b/app/panels/query_editor/components/inspector_query_rls/inspector_query_rls.js
new file mode 100644
index 0000000..7295c3c
--- /dev/null
+++ b/app/panels/query_editor/components/inspector_query_rls/inspector_query_rls.js
@@ -0,0 +1,61 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Компонент инспектора - Связи запроса
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import React, { useContext } from "react"; //Классы React
+import PropTypes from "prop-types"; //Контроль свойств компонента
+import { Icon, Button } from "@mui/material"; //Интерфейсные элементы
+import { MessagingСtx } from "../../../../context/messaging"; //Контекст сообщений приложения
+import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы
+import { RELATION_DATA_SHAPE } from "../relation/relation"; //Описание связи
+import { useQueryRelations } from "./hooks"; //Хуки для работы со связями
+
+//-----------
+//Тело модуля
+//-----------
+
+//Компонент инспектора - Связи запроса
+const InspectorQueryRelations = ({ query, relation, onOptionsChanged }) => {
+ //Подключение к контексту сообщений
+ const { showMsgWarn } = useContext(MessagingСtx);
+
+ //Работа со связями на сервере
+ const { removeRl } = useQueryRelations(query);
+
+ //Уведомление родителя об изменении свойств
+ const notifyOptionsChanged = () => onOptionsChanged && onOptionsChanged();
+
+ //При нажатии на кнопку даления связи из запроса
+ const handleRelationRemoveClick = () =>
+ showMsgWarn(`Удалить связь "${relation.source}" - "${relation.target}"?`, async () => {
+ if (relation?.id) {
+ await removeRl(relation.id);
+ notifyOptionsChanged();
+ }
+ });
+
+ //Формирование представления
+ return (
+
+ );
+};
+
+//Контроль свойств компонента - Компонент инспектора - Связи запроса
+InspectorQueryRelations.propTypes = {
+ query: PropTypes.number.isRequired,
+ relation: RELATION_DATA_SHAPE.isRequired,
+ onOptionsChanged: PropTypes.func
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { InspectorQueryRelations };
diff --git a/app/panels/query_editor/components/queries_manager/hooks.js b/app/panels/query_editor/components/queries_manager/hooks.js
new file mode 100644
index 0000000..6d6bb51
--- /dev/null
+++ b/app/panels/query_editor/components/queries_manager/hooks.js
@@ -0,0 +1,116 @@
+/*
+ Парус 8 - Панели мониторинга - Редактор запросов
+ Пользовательские хуки для работы с запросами
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import { useState, useContext, useEffect, useCallback } from "react"; //Классы React
+import { BackEndСtx } from "../../../../context/backend"; //Контекст взаимодействия с сервером
+
+//-----------
+//Тело модуля
+//-----------
+
+//Работа с запросами
+const useQueries = () => {
+ //Собственное состояние - флаг инициализированности
+ const [isInit, setInit] = useState(false);
+
+ //Собственное состояние - флаг загрузки
+ const [isLoading, setLoading] = useState(false);
+
+ //Собственное состояние - флаг необходимости обновления
+ const [refresh, setRefresh] = useState(true);
+
+ //Собственное состояние - данные
+ const [data, setData] = useState(null);
+
+ //Подключение к контексту взаимодействия с сервером
+ const { executeStored } = useContext(BackEndСtx);
+
+ //Обновление данных
+ const doRefresh = () => setRefresh(true);
+
+ //Добавление запроса
+ const insertQuery = useCallback(
+ async (code, name) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_INSERT", args: { SCODE: code, SNAME: name }, loader: false });
+ setRefresh(true);
+ },
+ [executeStored]
+ );
+
+ //Изменение запроса
+ const updateQuery = useCallback(
+ async (query, code, name) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_UPDATE", args: { NRN: query, SCODE: code, SNAME: name }, loader: false });
+ setRefresh(true);
+ },
+ [executeStored]
+ );
+
+ //Удаление запроса
+ const deleteQuery = useCallback(
+ async query => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_DELETE", args: { NRN: query }, loader: false });
+ setRefresh(true);
+ },
+ [executeStored]
+ );
+
+ //Установка флага готовности запроса
+ const setQueryReady = useCallback(
+ async (query, ready) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_READY_SET", args: { NRN: query, NREADY: ready }, loader: false });
+ setRefresh(true);
+ },
+ [executeStored]
+ );
+
+ //Установка флага публичности запроса
+ const setQueryPbl = useCallback(
+ async (query, pbl) => {
+ await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_PBL_SET", args: { NRN: query, NPBL: pbl }, loader: false });
+ setRefresh(true);
+ },
+ [executeStored]
+ );
+
+ //При необходимости получить/обновить данные
+ useEffect(() => {
+ //Загрузка данных с сервера
+ const loadData = async () => {
+ try {
+ setLoading(true);
+ const data = await executeStored({
+ stored: "PKG_P8PANELS_QE.QUERY_LIST",
+ respArg: "COUT",
+ isArray: name => ["XQUERY"].includes(name),
+ attributeValueProcessor: (name, val) => (["code", "name"].includes(name) ? undefined : val),
+ loader: true
+ });
+ setData(data?.XQUERIES?.XQUERY || []);
+ setInit(true);
+ } finally {
+ setRefresh(false);
+ setLoading(false);
+ }
+ };
+ //Если надо обновить
+ if (refresh)
+ //Получим данные
+ loadData();
+ }, [refresh, executeStored]);
+
+ //Возвращаем интерфейс хука
+ return [data, insertQuery, updateQuery, deleteQuery, setQueryReady, setQueryPbl, doRefresh, isLoading, isInit];
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { useQueries };
diff --git a/app/panels/query_editor/components/queries_manager/queries_manager.js b/app/panels/query_editor/components/queries_manager/queries_manager.js
index 3491408..2dbffea 100644
--- a/app/panels/query_editor/components/queries_manager/queries_manager.js
+++ b/app/panels/query_editor/components/queries_manager/queries_manager.js
@@ -13,7 +13,7 @@ import { Button, Icon } from "@mui/material"; //Интерфейсные ком
import { MessagingСtx } from "../../../../context/messaging"; //Контекст сообщений
import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
import { P8PConfigDialog } from "../../../../components/editors/p8p_config_dialog"; //Типовой диалог настройки
-import { useQuery } from "../../hooks"; //Пользовательские хуки
+import { useQueries } from "./hooks"; //Хуки для работы с запросами
import { QueriesList } from "./queries_list"; //Список запросов
import { QueryIUDialog } from "./query_iu_dialog"; //Диалог добавления/исправления запроса
@@ -27,7 +27,7 @@ const QueriesManager = ({ current = null, onQuerySelect = null, onCancel = null
const [modQuery, setModQuery] = useState(null);
//Работа со списком запросов
- const [queries, insertQuery, updateQuery, deleteQuery, setQueryReady, setQueryPbl] = useQuery();
+ const [queries, insertQuery, updateQuery, deleteQuery, setQueryReady, setQueryPbl] = useQueries();
//Подключение к контексту сообщений
const { showMsgWarn } = useContext(MessagingСtx);
diff --git a/app/panels/query_editor/components/query_options/query_options.js b/app/panels/query_editor/components/query_options/query_options.js
deleted file mode 100644
index 0fbb2f0..0000000
--- a/app/panels/query_editor/components/query_options/query_options.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- Парус 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 = ({ query, entity, relation, onEntityAdd, onEntityRemove, onRelationRemove, onQueryOptionsChanged }) => {
- //Отображение диалога добавления сущности
- 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 && }
- {openEntityAttrsDialog && (
-
- )}
-
-
-
-
-
- {entity && (
- <>
-
-
-
- >
- )}
- {relation && (
- <>
-
-
- >
- )}
-
- >
- );
-};
-
-//Контроль свойств компонента - Свойства запроса
-QueryOptions.propTypes = {
- query: PropTypes.number.isRequired,
- entity: ENTITY_DATA_SHAPE,
- relation: RELATION_DATA_SHAPE,
- onEntityAdd: PropTypes.func,
- onEntityRemove: PropTypes.func,
- onRelationRemove: PropTypes.func,
- onQueryOptionsChanged: PropTypes.func
-};
-
-//----------------
-//Интерфейс модуля
-//----------------
-
-export { QueryOptions };
diff --git a/app/panels/query_editor/hooks.js b/app/panels/query_editor/hooks.js
index eb6a9f9..594722c 100644
--- a/app/panels/query_editor/hooks.js
+++ b/app/panels/query_editor/hooks.js
@@ -1,13 +1,13 @@
/*
Парус 8 - Панели мониторинга - Редактор запросов
- Пользовательские хуки
+ Пользовательские хуки для работы с метаданными запроса
*/
//---------------------
//Подключение библиотек
//---------------------
-import { useState, useContext, useEffect, useCallback } from "react"; //Классы React
+import { useState, useContext, useEffect } from "react"; //Классы React
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { NODE_TYPE } from "./common"; //Общие ресурсы и константы редактора
@@ -88,8 +88,8 @@ const serverQueryData2QueryDiagram = (entities, relations) => {
//Тело модуля
//-----------
-//Работа с запросами
-const useQuery = () => {
+//Работа с метаданными запроса
+const useQuery = query => {
//Собственное состояние - флаг инициализированности
const [isInit, setInit] = useState(false);
@@ -99,8 +99,11 @@ const useQuery = () => {
//Собственное состояние - флаг необходимости обновления
const [refresh, setRefresh] = useState(true);
- //Собственное состояние - данные
- const [data, setData] = useState(null);
+ //Собственное состояние - данные диаграммы
+ const [queryDiagram, setQueryDiagram] = useState(null);
+
+ //Собственное состояние - данные настроек
+ const [queryOption, setQueryOption] = useState(null);
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
@@ -108,51 +111,6 @@ const useQuery = () => {
//Обновление данных
const doRefresh = () => setRefresh(true);
- //Добавление запроса
- const insertQuery = useCallback(
- async (code, name) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_INSERT", args: { SCODE: code, SNAME: name }, loader: false });
- setRefresh(true);
- },
- [executeStored]
- );
-
- //Изменение запроса
- const updateQuery = useCallback(
- async (query, code, name) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_UPDATE", args: { NRN: query, SCODE: code, SNAME: name }, loader: false });
- setRefresh(true);
- },
- [executeStored]
- );
-
- //Удаление запроса
- const deleteQuery = useCallback(
- async query => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_DELETE", args: { NRN: query }, loader: false });
- setRefresh(true);
- },
- [executeStored]
- );
-
- //Установка флага готовности запроса
- const setQueryReady = useCallback(
- async (query, ready) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_READY_SET", args: { NRN: query, NREADY: ready }, loader: false });
- setRefresh(true);
- },
- [executeStored]
- );
-
- //Установка флага публичности запроса
- const setQueryPbl = useCallback(
- async (query, pbl) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_PBL_SET", args: { NRN: query, NPBL: pbl }, loader: false });
- setRefresh(true);
- },
- [executeStored]
- );
-
//При необходимости получить/обновить данные
useEffect(() => {
//Загрузка данных с сервера
@@ -160,107 +118,14 @@ const useQuery = () => {
try {
setLoading(true);
const data = await executeStored({
- stored: "PKG_P8PANELS_QE.QUERY_LIST",
- respArg: "COUT",
- isArray: name => ["XQUERY"].includes(name),
- attributeValueProcessor: (name, val) => (["code", "name"].includes(name) ? undefined : val),
- loader: true
- });
- setData(data?.XQUERIES?.XQUERY || []);
- setInit(true);
- } finally {
- setRefresh(false);
- setLoading(false);
- }
- };
- //Если надо обновить
- if (refresh)
- //Получим данные
- loadData();
- }, [refresh, executeStored]);
-
- //Возвращаем интерфейс хука
- return [data, insertQuery, updateQuery, deleteQuery, setQueryReady, setQueryPbl, doRefresh, isLoading, isInit];
-};
-
-//Работа с содержимым запроса
-const useQueryDesc = query => {
- //Собственное состояние - флаг инициализированности
- const [isInit, setInit] = useState(false);
-
- //Собственное состояние - флаг загрузки
- const [isLoading, setLoading] = useState(false);
-
- //Собственное состояние - флаг необходимости обновления
- const [refresh, setRefresh] = useState(true);
-
- //Собственное состояние - данные
- const [data, setData] = useState(null);
-
- //Подключение к контексту взаимодействия с сервером
- const { executeStored } = useContext(BackEndСtx);
-
- //Обновление данных
- const doRefresh = () => setRefresh(true);
-
- //Добавление сущности в запрос
- const addEnt = useCallback(
- async (name, type) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_ADD", args: { NRN: query, SNAME: name, STYPE: type }, loader: false });
- setRefresh(true);
- },
- [query, executeStored]
- );
-
- //Удаление сущности из запроса
- const removeEnt = useCallback(
- async ent => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_REMOVE", args: { NRN: query, SID: ent }, loader: false });
- setRefresh(true);
- },
- [query, executeStored]
- );
-
- //Сохранение координат сущности на диаграммем
- const setEntPosition = useCallback(
- async (ent, x, y) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_ENT_POSITION_SET", args: { NRN: query, SID: ent, NX: x, NY: y }, loader: false });
- },
- [query, executeStored]
- );
-
- //Добавление отношения сущностей в запрос
- const addRl = useCallback(
- async (source, target) => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_RL_ADD", args: { NRN: query, SSOURCE: source, STARGET: target }, loader: false });
- setRefresh(true);
- },
- [query, executeStored]
- );
-
- //Удаление отношения сущностей из запроса
- const removeRl = useCallback(
- async rl => {
- await executeStored({ stored: "PKG_P8PANELS_QE.QUERY_RL_REMOVE", args: { NRN: query, SID: rl }, loader: false });
- setRefresh(true);
- },
- [query, executeStored]
- );
-
- //При необходимости получить/обновить данные
- useEffect(() => {
- //Загрузка данных с сервера
- const loadData = async () => {
- try {
- setLoading(true);
- const data = await executeStored({
- stored: "PKG_P8PANELS_QE.QUERY_DESC",
+ stored: "PKG_P8PANELS_QE.QUERY",
args: { NRN: query },
respArg: "COUT",
- isArray: name => ["XENT", "XATTR", "XRL"].includes(name),
+ isArray: name => ["XENT", "XATTR", "XRL", "XARG"].includes(name),
loader: true
});
- setData(serverQueryData2QueryDiagram(data?.XENTS?.XENT || [], data?.XRLS?.XRL || []));
+ setQueryDiagram(serverQueryData2QueryDiagram(data?.XENTS?.XENT || [], data?.XRLS?.XRL || []));
+ setQueryOption({ args: data?.XOPT?.XARGS?.XARG || [], cond: data?.XOPT?.XCOND || null });
setInit(true);
} finally {
setRefresh(false);
@@ -273,18 +138,21 @@ const useQueryDesc = query => {
//Если есть для чего получать данные
loadData();
//Нет идентификатора запроса - нет данных
- else setData(null);
+ else {
+ setQueryDiagram(null);
+ setQueryOption(null);
+ }
}, [refresh, query, executeStored]);
//При изменении входных свойств - поднимаем флаг обновления
useEffect(() => setRefresh(true), [query]);
//Возвращаем интерфейс хука
- return [data, addEnt, removeEnt, setEntPosition, addRl, removeRl, doRefresh, isLoading, isInit];
+ return [queryDiagram, queryOption, doRefresh, isLoading, isInit];
};
//----------------
//Интерфейс модуля
//----------------
-export { useQuery, useQueryDesc };
+export { useQuery };
diff --git a/app/panels/query_editor/query_editor.js b/app/panels/query_editor/query_editor.js
index e67d03d..a1b0e3e 100644
--- a/app/panels/query_editor/query_editor.js
+++ b/app/panels/query_editor/query_editor.js
@@ -13,9 +13,11 @@ import { ApplicationСtx } from "../../context/application"; //Контекст
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Компоненты рабочего стола
import { P8PEditorToolBar } from "../../components/editors/p8p_editor_toolbar"; //Панель инструментов редактора
import { QueryDiagram } from "./components/query_diagram/query_diagram"; //Диаграмма запроса
-import { QueryOptions } from "./components/query_options/query_options"; //Свойства запроса
+import { Inspector } from "./components/inspector/inspector"; //Инспектор свойств
import { QueriesManager } from "./components/queries_manager/queries_manager"; //Менеджер запросов
-import { useQueryDesc } from "./hooks"; //Пользовательские хуки
+import { useQuery } from "./hooks"; //Хуки для работы с метаданными запроса на сервере
+import { useQueryRelations } from "./components/inspector_query_rls/hooks"; //Хуки для работы со связями запроса на сервере
+import { useQueryEntities } from "./components/inspector_query_ents/hooks"; //Хуки для работы с сущностями запроса на сервере
//---------
//Константы
@@ -49,8 +51,14 @@ const QueryEditor = () => {
//Отображения менеджера запросов
const [openQueriesManager, setOpenQueriesManager] = useState(true);
- //Получение данных запроса
- const [queryDiagram, addEnt, removeEnt, setEntPosition, addRl, removeRl, doRefresh] = useQueryDesc(query);
+ //Получение метаданных с описанием запроса
+ const [queryDiagram, queryOption, doRefresh] = useQuery(query);
+
+ //Работа с сущностями на сервере
+ const { removeEnt, setEntPosition } = useQueryEntities(query);
+
+ //Работа со связями на сервере
+ const { addRl, removeRl } = useQueryRelations(query);
//Подключение к контексту приложения
const { setAppBarTitle } = useContext(ApplicationСtx);
@@ -78,16 +86,11 @@ const QueryEditor = () => {
//Обработка изменения положения сущности на диаграмме
const handleEntityPositionChange = (ent, position) => setEntPosition(ent, position.x, position.y);
- //Обработка добавления сущности в запрос
- const handleEntityAdd = async (entName, cb) => {
- await addEnt(entName, "VIEW");
- cb(true);
- };
-
//Обработка удаления сущности из запроса
const handleEntityRemove = async ent => {
await removeEnt(ent);
if (entity && entity?.id === ent) cleanupEnRlSelection();
+ doRefresh();
};
//Обработка выделения сущности
@@ -100,15 +103,17 @@ const QueryEditor = () => {
const handleRelationClick = rl => selectRelation(rl);
//Обработка добавления отношения cущностей
- const handleRelationAdd = (source, target) => {
+ const handleRelationAdd = async (source, target) => {
cleanupEnRlSelection();
- addRl(source, target);
+ await addRl(source, target);
+ doRefresh();
};
//Обработка удаления отношения cущностей
const handleRelationRemove = async rl => {
await removeRl(rl);
if (relation && relation?.id === rl) cleanupEnRlSelection();
+ doRefresh();
};
//При нажатии на панели (пустом месте) диаграммы запроса
@@ -173,15 +178,7 @@ const QueryEditor = () => {
{toolBar}
{query && (
-
+
)}