From b84bc82c029f56f38ffed3f8805927e62fc11d8b Mon Sep 17 00:00:00 2001
From: IRBorisov <8611739+IRBorisov@users.noreply.github.com>
Date: Thu, 31 Aug 2023 17:25:42 +0300
Subject: [PATCH] Minor UI fixes
---
.../src/components/Help/HelpLibrary.tsx | 2 +-
.../src/components/Help/HelpRSFormMeta.tsx | 2 +-
.../frontend/src/components/RSInput/index.tsx | 4 +--
.../src/components/RSInput/tooltip.ts | 7 ++--
.../src/pages/LibraryPage/PickerStrategy.tsx | 4 +--
.../src/pages/LibraryPage/SearchPanel.tsx | 2 +-
.../pages/RSFormPage/EditorConstituenta.tsx | 13 +++++---
.../src/pages/RSFormPage/EditorRSForm.tsx | 14 ++++----
.../frontend/src/pages/RSFormPage/RSTabs.tsx | 32 ++++++++++++++++---
.../src/pages/RSFormPage/RSTabsMenu.tsx | 2 +-
rsconcept/frontend/src/utils/staticUI.ts | 1 +
11 files changed, 54 insertions(+), 29 deletions(-)
diff --git a/rsconcept/frontend/src/components/Help/HelpLibrary.tsx b/rsconcept/frontend/src/components/Help/HelpLibrary.tsx
index 2ff0030d..ab60fd76 100644
--- a/rsconcept/frontend/src/components/Help/HelpLibrary.tsx
+++ b/rsconcept/frontend/src/components/Help/HelpLibrary.tsx
@@ -18,7 +18,7 @@ function HelpLibrary() {
- Аттрибут библиотечная выделяет неизменяемые стандартные схемы.
+ Аттрибут неизменная выделяет неизменяемые стандартные схемы.
);
diff --git a/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx b/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx
index 611dadf9..7ab71366 100644
--- a/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx
+++ b/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx
@@ -4,7 +4,7 @@ function HelpRSFormMeta() {
Концептуальная схема
Владелец - пользователь, обладающий правом редактирования
Для общедоступных схем владельцем может стать любой пользователь
- Для библиотечных схем правом редактирования обладают только администраторы
+ Для не схем правом редактирования обладают только администраторы
Клонировать - создать копию схемы для дальнейшего редактирования
Отслеживание - возможность видеть схему в Библиотеке и использовать фильтры
Загрузить/Выгрузить схему - взаимодействие с Экстеор через файлы формата TRS
diff --git a/rsconcept/frontend/src/components/RSInput/index.tsx b/rsconcept/frontend/src/components/RSInput/index.tsx
index 4071a29d..81c9e25a 100644
--- a/rsconcept/frontend/src/components/RSInput/index.tsx
+++ b/rsconcept/frontend/src/components/RSInput/index.tsx
@@ -13,7 +13,7 @@ import Label from '../Common/Label';
import { ccBracketMatching } from './bracketMatching';
import { RSLanguage } from './rslang';
import { getSymbolSubstitute,TextWrapper } from './textEditing';
-import { rshoverTooltip } from './tooltip';
+import { rshoverTooltip as rsHoverTooltip } from './tooltip';
const editorSetup: BasicSetupOptions = {
highlightSpecialChars: false,
@@ -111,7 +111,7 @@ function RSInput({
EditorView.lineWrapping,
RSLanguage,
ccBracketMatching(darkMode),
- rshoverTooltip(schema?.items || []),
+ rsHoverTooltip(schema?.items || []),
], [darkMode, schema?.items]);
const handleInput = useCallback(
diff --git a/rsconcept/frontend/src/components/RSInput/tooltip.ts b/rsconcept/frontend/src/components/RSInput/tooltip.ts
index de5762a8..4f19ef82 100644
--- a/rsconcept/frontend/src/components/RSInput/tooltip.ts
+++ b/rsconcept/frontend/src/components/RSInput/tooltip.ts
@@ -6,10 +6,9 @@ import { getCstTypificationLabel } from '../../utils/staticUI';
function createTooltipFor(cst: IConstituenta) {
const dom = document.createElement('div');
- dom.className = 'overflow-y-auto border shadow-md max-h-[25rem] max-w-[25rem] min-w-[10rem] w-fit z-20 text-sm';
- const alias = document.createElement('h1');
- alias.className = 'text-sm text-left';
- alias.textContent = `${cst.alias}: ${getCstTypificationLabel(cst)}`;
+ dom.className = 'overflow-y-auto border shadow-md max-h-[25rem] max-w-[25rem] min-w-[10rem] w-fit z-20 text-sm clr-border px-2 py-2';
+ const alias = document.createElement('p');
+ alias.innerHTML = `${cst.alias}: ${getCstTypificationLabel(cst)}`;
dom.appendChild(alias);
if (cst.term_resolved) {
const term = document.createElement('p');
diff --git a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx
index 3eac2f97..42738157 100644
--- a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx
+++ b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx
@@ -54,9 +54,9 @@ function PickerStrategy({ value, onChange }: PickerStrategyProps) {
handleChange(LibraryFilterStrategy.CANONICAL)}>
handleChange(LibraryFilterStrategy.PERSONAL)}>
diff --git a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx
index c6b12108..dcaa1e7c 100644
--- a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx
+++ b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx
@@ -64,7 +64,7 @@ function SearchPanel({ total, filtered, setFilter }: SearchPanelProps) {
}, [strategy, navigate]);
return (
-
+
Фильтр
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
index a39f62d3..53a31557 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
@@ -1,4 +1,4 @@
-import { useLayoutEffect, useMemo, useState } from 'react';
+import { Dispatch, SetStateAction, useLayoutEffect, useMemo, useState } from 'react';
import { toast } from 'react-toastify';
import ConceptTooltip from '../../components/Common/ConceptTooltip';
@@ -9,7 +9,6 @@ import TextArea from '../../components/Common/TextArea';
import HelpConstituenta from '../../components/Help/HelpConstituenta';
import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
-import useModificationPrompt from '../../hooks/useModificationPrompt';
import { CstType, EditMode, ICstCreateData, ICstRenameData, ICstUpdateData, SyntaxTree } from '../../utils/models';
import { getCstTypificationLabel } from '../../utils/staticUI';
import EditorRSExpression from './EditorRSExpression';
@@ -25,16 +24,19 @@ interface EditorConstituentaProps {
onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void
onRenameCst: (initial: ICstRenameData) => void
onDeleteCst: (selected: number[], callback?: (items: number[]) => void) => void
+ isModified: boolean
+ setIsModified: Dispatch>
}
-function EditorConstituenta({ activeID, onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst }: EditorConstituentaProps) {
+function EditorConstituenta({
+ isModified, setIsModified, activeID,
+ onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst
+}: EditorConstituentaProps) {
const { schema, processing, isEditable, cstUpdate } = useRSForm();
const activeCst = useMemo(
() => {
return schema?.items?.find((cst) => cst.id === activeID);
}, [schema?.items, activeID]);
-
- const { isModified, setIsModified } = useModificationPrompt();
const [editMode, setEditMode] = useState(EditMode.TEXT);
@@ -59,6 +61,7 @@ function EditorConstituenta({ activeID, onShowAST, onCreateCst, onRenameCst, onO
activeCst.convention !== convention ||
activeCst.definition_formal !== expression
);
+ return () => setIsModified(false);
}, [activeCst, activeCst?.term_raw, activeCst?.definition_formal,
activeCst?.definition_raw, activeCst?.convention,
term, textDefinition, expression, convention, setIsModified]);
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm.tsx
index ef1d81aa..682a1255 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm.tsx
@@ -1,4 +1,4 @@
-import { useLayoutEffect, useState } from 'react';
+import { Dispatch, SetStateAction, useLayoutEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { toast } from 'react-toastify';
@@ -13,7 +13,6 @@ import { CrownIcon, DownloadIcon, DumpBinIcon, HelpIcon, SaveIcon, ShareIcon } f
import { useAuth } from '../../context/AuthContext';
import { useRSForm } from '../../context/RSFormContext';
import { useUsers } from '../../context/UsersContext';
-import useModificationPrompt from '../../hooks/useModificationPrompt';
import { IRSFormCreateData, LibraryItemType } from '../../utils/models';
interface EditorRSFormProps {
@@ -21,9 +20,11 @@ interface EditorRSFormProps {
onClaim: () => void
onShare: () => void
onDownload: () => void
+ isModified: boolean
+ setIsModified: Dispatch>
}
-function EditorRSForm({ onDestroy, onClaim, onShare, onDownload }: EditorRSFormProps) {
+function EditorRSForm({ onDestroy, onClaim, onShare, isModified, setIsModified, onDownload }: EditorRSFormProps) {
const intl = useIntl();
const { getUserLabel } = useUsers();
const {
@@ -38,8 +39,6 @@ function EditorRSForm({ onDestroy, onClaim, onShare, onDownload }: EditorRSFormP
const [common, setCommon] = useState(false);
const [canonical, setCanonical] = useState(false);
- const { isModified, setIsModified } = useModificationPrompt();
-
useLayoutEffect(() => {
if (!schema) {
setIsModified(false);
@@ -52,6 +51,7 @@ function EditorRSForm({ onDestroy, onClaim, onShare, onDownload }: EditorRSFormP
schema.is_common !== common ||
schema.is_canonical !== canonical
);
+ return () => setIsModified(false);
}, [schema, schema?.title, schema?.alias, schema?.comment,
schema?.is_common, schema?.is_canonical,
title, alias, comment, common, canonical, setIsModified]);
@@ -138,10 +138,10 @@ function EditorRSForm({ onDestroy, onClaim, onShare, onDownload }: EditorRSFormP
disabled={!isEditable}
onChange={event => setCommon(event.target.checked)}
/>
- setCanonical(event.target.checked)}
/>
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
index d25b1db3..4453e26d 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
@@ -10,6 +10,7 @@ import { Loader } from '../../components/Common/Loader';
import { useLibrary } from '../../context/LibraryContext';
import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext';
+import useModificationPrompt from '../../hooks/useModificationPrompt';
import { prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants';
import { ICstCreateData, ICstRenameData, LibraryFilterStrategy, SyntaxTree } from '../../utils/models';
import { createAliasFor } from '../../utils/staticUI';
@@ -43,6 +44,8 @@ function RSTabs() {
const { destroySchema } = useLibrary();
const { setNoFooter } = useConceptTheme();
+ const { isModified, setIsModified } = useModificationPrompt();
+
const [activeTab, setActiveTab] = useState(RSTabID.CARD);
const [activeID, setActiveID] = useState(undefined);
@@ -226,6 +229,11 @@ function RSTabs() {
const onDownloadSchema = useCallback(
() => {
+ if (isModified) {
+ if (!window.confirm('Присутствуют несохраненные изменения. Продолжить без их учета?')) {
+ return;
+ }
+ }
const fileName = (schema?.alias ?? 'Schema') + '.trs';
download(
(data) => {
@@ -235,8 +243,18 @@ function RSTabs() {
console.error(error);
}
});
- }, [schema?.alias, download]);
-
+ }, [schema?.alias, download, isModified]);
+
+ const handleShowClone = useCallback(
+ () => {
+ if (isModified) {
+ if (!window.confirm('Присутствуют несохраненные изменения. Продолжить без их учета?')) {
+ return;
+ }
+ }
+ setShowClone(true);
+ }, [isModified]);
+
const handleToggleSubscribe = useCallback(
() => {
if (isTracking) {
@@ -302,7 +320,7 @@ function RSTabs() {
onClaim={onClaimSchema}
onShare={onShareSchema}
onToggleSubscribe={handleToggleSubscribe}
- showCloneDialog={() => setShowClone(true)}
+ showCloneDialog={handleShowClone}
showUploadDialog={() => setShowUpload(true)}
/>
Паспорт схемы
@@ -315,7 +333,9 @@ function RSTabs() {
-
-
diff --git a/rsconcept/frontend/src/utils/staticUI.ts b/rsconcept/frontend/src/utils/staticUI.ts
index cf50fce1..d5f3e883 100644
--- a/rsconcept/frontend/src/utils/staticUI.ts
+++ b/rsconcept/frontend/src/utils/staticUI.ts
@@ -624,6 +624,7 @@ export function getNodeLabel(node: ISyntaxTreeNode): string {
case TokenID.NT_ENUM_DECL: return 'ENUM_DECLARATION'
case TokenID.NT_TUPLE_DECL: return 'TUPLE_DECLARATION'
case TokenID.PUNC_DEFINE: return 'DEFINITION'
+ case TokenID.PUNC_STRUCT: return 'STRUCTURE_DEFITION'
case TokenID.NT_ARG_DECL: return 'ARG'
case TokenID.NT_FUNC_CALL: return 'CALL'