ЦИТК-979 - Область просмотра сформированного запроса вынесена в отдельный компонент

This commit is contained in:
Mikhail Chechnev 2025-09-25 14:12:27 +03:00
parent be22cde138
commit 0767a12fa6
2 changed files with 156 additions and 36 deletions

View File

@ -7,10 +7,8 @@
//Подключение библиотек
//---------------------
import React, { useState } from "react"; //Классы React
import React from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Fab, Icon, Drawer, Button, TextField } from "@mui/material"; //Компоненты MUI
import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
import { P8PEditorBox } from "../../../../components/editors/p8p_editor_box"; //Контейнер параметров редактора
import { P8PEditorSubHeader } from "../../../../components/editors/p8p_editor_sub_header"; //Подзаголовок группы параметров редактора
import { ENTITY_SHAPE } from "../entity/entity"; //Описание сущности
@ -20,38 +18,17 @@ import { InspectorQueryArguments } from "../inspector_query_args/inspector_query
import { InspectorQueryConditions } from "../inspector_query_cond/inspector_query_cond"; //Управление условиями отбора запроса
import { InspectorQueryEntities } from "../inspector_query_ents/inspector_query_ents"; //Управление сущностями запроса
import { InspectorQueryRelations } from "../inspector_query_rls/inspector_query_rls"; //Управление связями запроса
//---------
//Константы
//---------
//Стили
const STYLES = {
SQL_FAB: {
position: "absolute",
bottom: 16,
right: 16
}
};
import { QueryArea } from "./query_area"; //Область запроса
//-----------
//Тело модуля
//-----------
//Инспектор свойств
const Inspector = ({ query, entity, relation, entities = [], args = [], cond = null, qry = null, qryMsg = null, onOptionsChanged = null }) => {
//Собственное состояние - отображение области SQL запроса
const [displaySQL, setDisplaySQL] = useState(false);
const Inspector = ({ query, entity, relation, entities = [], args = [], cond = null, qry = "", qryMsg = "", onOptionsChanged = null }) => {
//При изменении настроек запроса
const handleOptionsChanged = () => onOptionsChanged && onOptionsChanged();
//При нажатии на кнопку отображения SQL запроса
const handleShowSQLClick = () => setDisplaySQL(true);
//При нажатии на кнопку сокрытия SQL запроса
const handleCloseSQLClick = () => setDisplaySQL(false);
//Генерация содержимого
return (
<P8PEditorBox title={"Настройки запроса"}>
@ -67,16 +44,7 @@ const Inspector = ({ query, entity, relation, entities = [], args = [], cond = n
<InspectorQueryRelations query={query} relation={relation} onOptionsChanged={handleOptionsChanged} />
</>
)}
<Fab sx={STYLES.SQL_FAB} title={"Показать текст SQL запроса"} onClick={handleShowSQLClick}>
<Icon>join_left</Icon>
</Fab>
{displaySQL && (
<Drawer open variant={"persistent"} anchor={"bottom"}>
<Button onClick={handleCloseSQLClick}>{BUTTONS.HIDE}</Button>
<TextField multiline fullWidth value={qry} disabled />
{qryMsg && <TextField multiline fullWidth value={qryMsg} disabled />}
</Drawer>
)}
<QueryArea qry={qry} qryMsg={qryMsg} />
</P8PEditorBox>
);
};

View File

@ -0,0 +1,152 @@
/*
Парус 8 - Панели мониторинга - Редактор запросов
Область запроса
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Fab, Icon, Drawer, IconButton, TextField, Stack, Box, Snackbar, Alert } from "@mui/material"; //Компоненты MUI
import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения
import { APP_STYLES } from "../../../../../app.styles"; //Общие стили приложения
//---------
//Константы
//---------
//Стили
const STYLES = {
SQL_FAB: {
position: "absolute",
bottom: 16,
right: 16
},
SQL_TEXT_FIELD: {
fontSize: "0.9rem",
...APP_STYLES.SCROLL
},
SNACKBAR_ALERT: { width: "100%" }
};
//Начальное состояние всплывающего сообщения
const SNACK_BAR_MESSAGE_INIT = { text: null, type: null };
//-----------
//Тело модуля
//-----------
//Область запроса
const QueryArea = ({ qry = "", qryMsg = "" }) => {
//Собственное состояние - текст всплывающего сообщения
const [snackBarMessage, setSnackBarMessage] = useState(SNACK_BAR_MESSAGE_INIT);
//Собственное состояние - отображение области SQL запроса
const [displaySQL, setDisplaySQL] = useState(true);
//Собственное состояние - развёрнутость
const [expanded, setExpanded] = useState(false);
//При нажатии на кнопку копирования текста запроса
const handleCopyClick = async () => {
try {
await navigator.clipboard.writeText(qry);
setSnackBarMessage({ text: `Текст запроса скопирован в буфер обмена` });
} catch (e) {
setSnackBarMessage({ text: `Ошибка копирования текста запроса в буфер обмена: ${e.message}`, type: "error" });
}
};
//При нажатии на кнопку развёртывания
const handleExpandClick = () => setExpanded(!expanded);
//При нажатии на кнопку отображения SQL запроса
const handleShowSQLClick = () => setDisplaySQL(true);
//При нажатии на кнопку сокрытия SQL запроса
const handleCloseSQLClick = () => setDisplaySQL(false);
//При закрытии всплывающего сообщения
const handleSnackBarClose = () => setSnackBarMessage(SNACK_BAR_MESSAGE_INIT);
//Расчет размеров тектовых полей
const [qryRows, qryMsgRows] = expanded ? [15, 6] : [5, 3];
//Генерация содержимого
return (
<>
{(qry || qryMsg) && (
<Fab color={qryMsg ? "warning" : "default"} sx={STYLES.SQL_FAB} title={"Показать текст SQL запроса"} onClick={handleShowSQLClick}>
<Icon>join_left</Icon>
</Fab>
)}
{displaySQL && (
<Drawer open onClose={handleCloseSQLClick} anchor={"bottom"}>
<Box p={2}>
<Stack direction={"row"} justifyContent={"right"} spacing={2}>
{qry && (
<IconButton onClick={handleCopyClick} title={"Скопировать текст запроса"}>
<Icon>content_copy</Icon>
</IconButton>
)}
<IconButton onClick={handleExpandClick} title={expanded ? "Свернуть" : "Развернуть"}>
<Icon>{expanded ? "expand_more" : "expand_less"}</Icon>
</IconButton>
<IconButton onClick={handleCloseSQLClick} title={BUTTONS.HIDE}>
<Icon>close</Icon>
</IconButton>
</Stack>
<Stack direction={"column"} spacing={2}>
{qry && (
<TextField
label={"Текст запроса"}
multiline
fullWidth
value={qry}
minRows={qryRows}
maxRows={qryRows}
variant={"standard"}
focused
inputProps={{ sx: STYLES.SQL_TEXT_FIELD, disabled: true }}
/>
)}
{qryMsg && (
<TextField
label={"Предупреждения"}
color={"warning"}
multiline
fullWidth
value={qryMsg}
minRows={qryMsgRows}
maxRows={qryMsgRows}
variant={"standard"}
focused
inputProps={{ sx: STYLES.SQL_TEXT_FIELD, disabled: true }}
/>
)}
</Stack>
</Box>
</Drawer>
)}
<Snackbar open={Boolean(snackBarMessage.text)} autoHideDuration={3000} onClose={handleSnackBarClose}>
<Alert severity={snackBarMessage.type || "success"} sx={STYLES.SNACKBAR_ALERT} onClose={handleSnackBarClose}>
{snackBarMessage.text}
</Alert>
</Snackbar>
</>
);
};
//Контроль свойств компонента - Область запроса
QueryArea.propTypes = {
qry: PropTypes.string,
qryMsg: PropTypes.string
};
//----------------
//Интерфейс модуля
//----------------
export { QueryArea };