From 87dc02dba548806b32e0f01bc294733c60391237 Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:32:57 +0300 Subject: [PATCH] Refactoring: implement aliases and use client --- .gitignore | 4 + rsconcept/frontend/.dockerignore | 3 +- rsconcept/frontend/src/App.tsx | 8 +- rsconcept/frontend/src/GlobalProviders.tsx | 53 +++++++++ .../frontend/src/components/Common/Button.tsx | 2 +- .../src/components/Common/ConceptLoader.tsx | 6 +- .../src/components/Common/ConceptTab.tsx | 3 +- .../src/components/Common/ConceptTooltip.tsx | 9 +- .../src/components/Common/FileInput.tsx | 2 + .../src/components/Common/GraphUI.tsx | 11 ++ .../frontend/src/components/Common/Modal.tsx | 5 +- .../src/components/Common/PDFViewer.tsx | 14 +-- .../src/components/Common/PageControls.tsx | 2 +- .../src/components/Common/PrettyJSON.tsx | 7 +- .../src/components/Common/SelectMulti.tsx | 13 +-- .../src/components/Common/SelectSingle.tsx | 8 +- .../src/components/Common/SelectorButton.tsx | 2 +- .../src/components/Common/SubmitButton.tsx | 2 +- .../src/components/Common/SwitchButton.tsx | 2 +- .../src/components/Common/TextArea.tsx | 4 +- .../src/components/Common/TextInput.tsx | 4 +- .../src/components/Common/TextURL.tsx | 3 +- .../src/components/Common/Tristate.tsx | 2 +- .../{ => Common}/commonInterfaces.ts | 0 .../src/components/ConceptToaster.tsx | 2 +- .../src/components/DataTable/DataTable.tsx | 6 +- .../components/DataTable/PaginationTools.tsx | 5 +- .../src/components/DataTable/SelectAll.tsx | 4 +- .../src/components/DataTable/SelectRow.tsx | 4 +- .../src/components/DataTable/SortingIcon.tsx | 2 +- .../frontend/src/components/ErrorFallback.tsx | 16 +-- .../src/components/ExpectedAnonymous.tsx | 11 +- rsconcept/frontend/src/components/Footer.tsx | 2 +- .../components/Help/ConstituentaTooltip.tsx | 8 +- .../frontend/src/components/Help/HelpAPI.tsx | 6 +- .../src/components/Help/HelpButton.tsx | 11 +- .../src/components/Help/HelpConstituenta.tsx | 6 +- .../src/components/Help/HelpExteor.tsx | 6 +- .../src/components/Help/HelpLibrary.tsx | 4 +- .../frontend/src/components/Help/HelpMain.tsx | 6 +- .../src/components/Help/HelpPrivacy.tsx | 6 +- .../src/components/Help/HelpRSFormItems.tsx | 6 +- .../src/components/Help/HelpRSFormMeta.tsx | 2 +- .../src/components/Help/HelpRSLang.tsx | 8 +- .../src/components/Help/HelpTermGraph.tsx | 8 +- .../Help/HelpTerminologyControl.tsx | 2 +- .../src/components/Help/InfoTopic.tsx | 5 +- .../{BackendError.tsx => InfoError.tsx} | 45 +++----- .../src/components/Navigation/Logo.tsx | 35 ++---- .../src/components/Navigation/Navigation.tsx | 22 ++-- .../components/Navigation/ThemeSwitcher.tsx | 5 +- .../Navigation/ToggleNavigationButton.tsx | 2 +- .../components/Navigation/UserDropdown.tsx | 16 +-- .../src/components/Navigation/UserMenu.tsx | 14 +-- .../src/components/RSInput/RSInput.tsx | 7 +- .../src/components/RSInput/bracketMatching.ts | 2 +- .../components/RSInput/rslang/parser.test.ts | 6 +- .../src/components/RSInput/rslang/parser.ts | 2 +- .../RSInput/rslang/rslangFull.grammar | 2 +- .../RSInput/rslang/rslangLex.grammar | 2 +- .../src/components/RSInput/textEditing.ts | 4 +- .../src/components/RSInput/tooltip.ts | 6 +- .../src/components/RefsInput/RefsInput.tsx | 21 ++-- .../src/components/RefsInput/parse/parser.ts | 2 +- .../RefsInput/parse/refsText.grammar | 2 +- .../src/components/RefsInput/tooltip.ts | 8 +- .../frontend/src/components/RequireAuth.tsx | 5 +- .../components/Shared/ConstituentaBadge.tsx | 12 +-- .../components/Shared/ConstituentaPicker.tsx | 17 +-- .../src/components/Shared/GrammemeBadge.tsx | 8 +- .../components/Shared/InfoConstituenta.tsx | 4 +- .../src/components/Shared/InfoCstClass.tsx | 10 +- .../src/components/Shared/InfoCstStatus.tsx | 10 +- .../src/components/Shared/InfoLibraryItem.tsx | 4 +- .../src/components/Shared/SelectGrammeme.tsx | 8 +- .../src/components/Shared/SelectedCounter.tsx | 2 +- .../src/components/Shared/WordFormBadge.tsx | 3 +- .../frontend/src/context/AuthContext.tsx | 27 ++--- .../frontend/src/context/LibraryContext.tsx | 25 +++-- .../src/context/NagivationContext.tsx | 75 +++++++++---- .../frontend/src/context/RSFormContext.tsx | 24 +++-- .../frontend/src/context/ThemeContext.tsx | 10 +- .../src/context/UserProfileContext.tsx | 19 ++-- .../frontend/src/context/UsersContext.tsx | 8 +- .../src/dialogs/DlgCloneLibraryItem.tsx | 26 ++--- .../DlgConstituentaTemplate/ArgumentsTab.tsx | 22 ++-- .../ConstituentaTab.tsx | 18 ++-- .../DlgConstituentaTemplate.tsx | 23 ++-- .../DlgConstituentaTemplate/TemplateTab.tsx | 18 ++-- .../frontend/src/dialogs/DlgCreateCst.tsx | 24 +++-- .../dialogs/DlgDeleteCst/ConstituentsList.tsx | 4 +- .../src/dialogs/DlgDeleteCst/DlgDeleteCst.tsx | 13 ++- .../DlgEditReference/DlgEditReference.tsx | 21 ++-- .../dialogs/DlgEditReference/EntityTab.tsx | 25 +++-- .../DlgEditReference/SelectWordForm.tsx | 9 +- .../dialogs/DlgEditReference/SyntacticTab.tsx | 9 +- .../DlgEditReference/WordformButton.tsx | 4 +- .../DlgEditWordForms/DlgEditWordForms.tsx | 33 +++--- .../DlgEditWordForms/WordFormsTable.tsx | 14 +-- .../frontend/src/dialogs/DlgGraphParams.tsx | 16 +-- .../frontend/src/dialogs/DlgRenameCst.tsx | 20 ++-- rsconcept/frontend/src/dialogs/DlgShowAST.tsx | 24 +++-- .../frontend/src/dialogs/DlgUploadRSForm.tsx | 14 +-- .../frontend/src/hooks/useCheckExpression.ts | 18 ++-- .../frontend/src/hooks/useClickedOutside.ts | 6 +- .../frontend/src/hooks/useConceptText.ts | 12 ++- rsconcept/frontend/src/hooks/useDropdown.ts | 6 +- rsconcept/frontend/src/hooks/useEscapeKey.ts | 4 +- .../frontend/src/hooks/useLocalStorage.ts | 4 +- .../src/hooks/useModificationPrompt.ts | 14 --- .../frontend/src/hooks/usePartialUpdate.tsx | 4 +- .../frontend/src/hooks/useQueryStrings.ts | 14 +++ .../frontend/src/hooks/useRSFormDetails.ts | 16 +-- .../frontend/src/hooks/useResolveText.ts | 14 +-- rsconcept/frontend/src/hooks/useWindowSize.ts | 2 + rsconcept/frontend/src/main.tsx | 46 ++------ rsconcept/frontend/src/models/language.ts | 2 +- rsconcept/frontend/src/models/libraryAPI.ts | 6 +- rsconcept/frontend/src/models/miscelanious.ts | 2 +- .../frontend/src/models/miscelaniousAPI.ts | 3 +- rsconcept/frontend/src/models/rsform.ts | 3 +- rsconcept/frontend/src/models/rsformAPI.ts | 8 +- .../frontend/src/models/rslangAPI.test.ts | 2 +- rsconcept/frontend/src/models/rslangAPI.ts | 3 +- .../frontend/src/pages/CreateRSFormPage.tsx | 52 ++++----- rsconcept/frontend/src/pages/HomePage.tsx | 16 +-- .../src/pages/LibraryPage/ItemIcons.tsx | 8 +- .../src/pages/LibraryPage/LibraryPage.tsx | 52 +++++++-- .../src/pages/LibraryPage/PickerStrategy.tsx | 22 ++-- .../src/pages/LibraryPage/SearchPanel.tsx | 55 +++------- .../src/pages/LibraryPage/ViewLibrary.tsx | 29 ++--- rsconcept/frontend/src/pages/LoginPage.tsx | 60 +++++------ .../src/pages/ManualsPage/ManualsPage.tsx | 42 +++----- .../src/pages/ManualsPage/TopicsList.tsx | 8 +- .../src/pages/ManualsPage/ViewTopic.tsx | 6 +- rsconcept/frontend/src/pages/NotFoundPage.tsx | 10 +- .../ConstituentaToolbar.tsx | 12 ++- .../EditorConstituenta/EditorConstituenta.tsx | 16 +-- .../EditorConstituenta/FormConstituenta.tsx | 26 ++--- .../EditorRSExpression/EditorRSExpression.tsx | 45 +++++--- .../EditorRSExpression/ParsingResult.tsx | 8 +- .../EditorRSExpression/RSAnalyzer.tsx | 11 +- .../EditorRSExpression/RSEditControls.tsx | 6 +- .../EditorRSExpression/RSLocalButton.tsx | 4 +- .../EditorRSExpression/RSTokenButton.tsx | 6 +- .../EditorRSExpression/StatusBar.tsx | 31 +++--- .../RSFormPage/EditorRSForm/EditorRSForm.tsx | 15 +-- .../RSFormPage/EditorRSForm/FormRSForm.tsx | 18 ++-- .../RSFormPage/EditorRSForm/RSFormStats.tsx | 8 +- .../RSFormPage/EditorRSForm/RSFormToolbar.tsx | 12 ++- .../RSFormPage/EditorRSList/EditorRSList.tsx | 13 ++- .../RSFormPage/EditorRSList/RSListToolbar.tsx | 26 ++--- .../pages/RSFormPage/EditorRSList/RSTable.tsx | 16 +-- .../EditorTermGraph/EditorTermGraph.tsx | 25 +++-- .../EditorTermGraph/GraphSidebar.tsx | 8 +- .../EditorTermGraph/GraphToolbar.tsx | 12 ++- .../RSFormPage/EditorTermGraph/TermGraph.tsx | 16 +-- .../RSFormPage/EditorTermGraph/ViewHidden.tsx | 14 +-- .../EditorTermGraph/useGraphFilter.ts | 8 +- .../src/pages/RSFormPage/RSFormPage.tsx | 9 +- .../frontend/src/pages/RSFormPage/RSTabs.tsx | 101 ++++++++---------- .../src/pages/RSFormPage/RSTabsMenu.tsx | 25 ++--- .../ViewConstituents/ConstituentsSearch.tsx | 30 +++--- .../ViewConstituents/ConstituentsTable.tsx | 18 ++-- .../ViewConstituents/ViewConstituents.tsx | 9 +- rsconcept/frontend/src/pages/RegisterPage.tsx | 48 ++++----- .../src/pages/RestorePasswordPage.tsx | 11 +- .../pages/UserProfilePage/EditorPassword.tsx | 31 +++--- .../pages/UserProfilePage/EditorProfile.tsx | 36 ++++--- .../pages/UserProfilePage/UserProfilePage.tsx | 18 ++-- .../src/pages/UserProfilePage/UserTabs.tsx | 21 ++-- .../UserProfilePage/ViewSubscriptions.tsx | 12 ++- rsconcept/frontend/src/utils/Graph.test.ts | 1 - rsconcept/frontend/src/utils/Graph.ts | 2 +- rsconcept/frontend/src/utils/backendAPI.ts | 15 +-- rsconcept/frontend/src/utils/codemirror.ts | 9 +- rsconcept/frontend/src/utils/color.ts | 10 +- rsconcept/frontend/src/utils/constants.ts | 2 +- rsconcept/frontend/src/utils/labels.ts | 11 +- rsconcept/frontend/src/utils/misc.ts | 12 +-- rsconcept/frontend/src/utils/selectors.ts | 11 +- rsconcept/frontend/src/utils/utils.tsx | 20 ++++ rsconcept/frontend/tsconfig.json | 13 ++- rsconcept/frontend/vite.config.ts | 6 ++ 184 files changed, 1372 insertions(+), 1130 deletions(-) create mode 100644 rsconcept/frontend/src/GlobalProviders.tsx create mode 100644 rsconcept/frontend/src/components/Common/GraphUI.tsx rename rsconcept/frontend/src/components/{ => Common}/commonInterfaces.ts (100%) rename rsconcept/frontend/src/components/{BackendError.tsx => InfoError.tsx} (51%) delete mode 100644 rsconcept/frontend/src/hooks/useModificationPrompt.ts create mode 100644 rsconcept/frontend/src/hooks/useQueryStrings.ts diff --git a/.gitignore b/.gitignore index 21082a0f..fa0da0f3 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,10 @@ bower_components *.sublime* +# NextJS +**/.next/ +**/out/ + # Environments venv/ diff --git a/rsconcept/frontend/.dockerignore b/rsconcept/frontend/.dockerignore index 409a5cb9..0441a02d 100644 --- a/rsconcept/frontend/.dockerignore +++ b/rsconcept/frontend/.dockerignore @@ -1,4 +1,5 @@ # Dev specific .gitignore node_modules -.env.local \ No newline at end of file +.env.local +.next \ No newline at end of file diff --git a/rsconcept/frontend/src/App.tsx b/rsconcept/frontend/src/App.tsx index 20b7c6ba..2f0e2fdb 100644 --- a/rsconcept/frontend/src/App.tsx +++ b/rsconcept/frontend/src/App.tsx @@ -1,4 +1,3 @@ -import { pdfjs } from 'react-pdf'; import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom'; import ConceptToaster from './components/ConceptToaster'; @@ -18,11 +17,6 @@ import RSFormPage from './pages/RSFormPage'; import UserProfilePage from './pages/UserProfilePage'; import { globalIDs } from './utils/constants'; -pdfjs.GlobalWorkerOptions.workerSrc = new URL( - 'pdfjs-dist/build/pdf.worker.min.js', - import.meta.url, -).toString(); - function Root() { const { noNavigation, noFooter, viewportHeight, mainHeight, showScroll } = useConceptTheme(); return ( @@ -45,7 +39,7 @@ function Root() { overflowY: showScroll ? 'scroll': 'auto' }} > -
+
diff --git a/rsconcept/frontend/src/GlobalProviders.tsx b/rsconcept/frontend/src/GlobalProviders.tsx new file mode 100644 index 00000000..05f1fd8f --- /dev/null +++ b/rsconcept/frontend/src/GlobalProviders.tsx @@ -0,0 +1,53 @@ +'use client'; + +import { ErrorBoundary } from 'react-error-boundary'; +import { IntlProvider } from 'react-intl'; +import { pdfjs } from 'react-pdf'; + +import { AuthState } from '@/context/AuthContext'; +import { LibraryState } from '@/context/LibraryContext'; +import { ThemeState } from '@/context/ThemeContext'; +import { UsersState } from '@/context/UsersContext'; + +import ErrorFallback from './components/ErrorFallback'; + +pdfjs.GlobalWorkerOptions.workerSrc = new URL( + 'pdfjs-dist/build/pdf.worker.min.js', + import.meta.url, +).toString(); + +const resetState = () => { + console.log('Resetting state after error fallback') +}; + +const logError = (error: Error, info: { componentStack?: string | null | undefined }) => { + console.log('Error fallback: ' + error.message); + if (info.componentStack) { + console.log('Component stack: ' + info.componentStack); + } +}; + +function GlobalProviders({ children }: { children: React.ReactNode }) { + return ( + + + + + + + + {children} + + + + + + + ); +} + +export default GlobalProviders; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/Button.tsx b/rsconcept/frontend/src/components/Common/Button.tsx index c4d4c206..40e38e69 100644 --- a/rsconcept/frontend/src/components/Common/Button.tsx +++ b/rsconcept/frontend/src/components/Common/Button.tsx @@ -1,4 +1,4 @@ -import { IColorsProps, IControlProps } from '../commonInterfaces'; +import { IColorsProps, IControlProps } from './commonInterfaces'; interface ButtonProps extends IControlProps, IColorsProps, Omit, 'className' | 'children' | 'title'| 'type'> { diff --git a/rsconcept/frontend/src/components/Common/ConceptLoader.tsx b/rsconcept/frontend/src/components/Common/ConceptLoader.tsx index 05ac1c10..c19bec4a 100644 --- a/rsconcept/frontend/src/components/Common/ConceptLoader.tsx +++ b/rsconcept/frontend/src/components/Common/ConceptLoader.tsx @@ -1,13 +1,15 @@ +'use client'; + import { ThreeDots } from 'react-loader-spinner'; -import { useConceptTheme } from '../../context/ThemeContext'; +import { useConceptTheme } from '@/context/ThemeContext'; interface ConceptLoaderProps { size?: number } export function ConceptLoader({size=10}: ConceptLoaderProps) { - const {colors} = useConceptTheme() + const {colors} = useConceptTheme(); return (
diff --git a/rsconcept/frontend/src/components/Common/ConceptTab.tsx b/rsconcept/frontend/src/components/Common/ConceptTab.tsx index 67c59d18..26a3bbb6 100644 --- a/rsconcept/frontend/src/components/Common/ConceptTab.tsx +++ b/rsconcept/frontend/src/components/Common/ConceptTab.tsx @@ -16,8 +16,7 @@ function ConceptTab({ label, tooltip, className, ...otherProps }: ConceptTabProp {...otherProps} > {label} - - ); + ); } ConceptTab.tabsRole = 'Tab'; diff --git a/rsconcept/frontend/src/components/Common/ConceptTooltip.tsx b/rsconcept/frontend/src/components/Common/ConceptTooltip.tsx index 9d874041..d93cc884 100644 --- a/rsconcept/frontend/src/components/Common/ConceptTooltip.tsx +++ b/rsconcept/frontend/src/components/Common/ConceptTooltip.tsx @@ -1,7 +1,9 @@ +'use client'; + import { createPortal } from 'react-dom'; import { ITooltip, Tooltip } from 'react-tooltip'; -import { useConceptTheme } from '../../context/ThemeContext'; +import { useConceptTheme } from '@/context/ThemeContext'; interface ConceptTooltipProps extends Omit { @@ -17,6 +19,9 @@ function ConceptTooltip({ }: ConceptTooltipProps) { const { darkMode } = useConceptTheme(); + if (typeof window === 'undefined') { + return null; + } return createPortal( , document.body); } -export default ConceptTooltip; +export default ConceptTooltip; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/FileInput.tsx b/rsconcept/frontend/src/components/Common/FileInput.tsx index 47bc6433..83c7feaa 100644 --- a/rsconcept/frontend/src/components/Common/FileInput.tsx +++ b/rsconcept/frontend/src/components/Common/FileInput.tsx @@ -1,3 +1,5 @@ +'use client'; + import { useRef, useState } from 'react'; import { UploadIcon } from '../Icons'; diff --git a/rsconcept/frontend/src/components/Common/GraphUI.tsx b/rsconcept/frontend/src/components/Common/GraphUI.tsx new file mode 100644 index 00000000..162a0275 --- /dev/null +++ b/rsconcept/frontend/src/components/Common/GraphUI.tsx @@ -0,0 +1,11 @@ +'use client'; + +import { GraphCanvas as GraphUI } from 'reagraph'; + +export { + type GraphEdge, type GraphNode, type GraphCanvasRef, + type LayoutTypes, + Sphere, useSelection +} from 'reagraph'; + +export default GraphUI; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/Modal.tsx b/rsconcept/frontend/src/components/Common/Modal.tsx index b3364017..1cf7d070 100644 --- a/rsconcept/frontend/src/components/Common/Modal.tsx +++ b/rsconcept/frontend/src/components/Common/Modal.tsx @@ -1,6 +1,9 @@ +'use client'; + import { useRef } from 'react'; -import useEscapeKey from '../../hooks/useEscapeKey'; +import useEscapeKey from '@/hooks/useEscapeKey'; + import { CrossIcon } from '../Icons'; import Button from './Button'; import MiniButton from './MiniButton'; diff --git a/rsconcept/frontend/src/components/Common/PDFViewer.tsx b/rsconcept/frontend/src/components/Common/PDFViewer.tsx index 6ca4169f..ebf1a27f 100644 --- a/rsconcept/frontend/src/components/Common/PDFViewer.tsx +++ b/rsconcept/frontend/src/components/Common/PDFViewer.tsx @@ -1,9 +1,12 @@ +'use client'; + import type { PDFDocumentProxy } from 'pdfjs-dist'; import { useMemo, useState } from 'react'; import { Document, Page } from 'react-pdf'; -import useWindowSize from '../../hooks/useWindowSize'; -import { graphLightT } from '../../utils/color'; +import useWindowSize from '@/hooks/useWindowSize'; +import { graphLightT } from '@/utils/color'; + import Overlay from './Overlay'; import PageControls from './PageControls'; @@ -14,15 +17,12 @@ interface PDFViewerProps { file?: string | ArrayBuffer | Blob } -function PDFViewer({ - file -}: PDFViewerProps) { +function PDFViewer({ file }: PDFViewerProps) { const windowSize = useWindowSize(); const [pageCount, setPageCount] = useState(0); const [pageNumber, setPageNumber] = useState(1); - const pageWidth = useMemo( () => { return Math.max(MINIMUM_WIDTH, (Math.min((windowSize?.width ?? 0) - 300, MAXIMUM_WIDTH))); @@ -48,7 +48,7 @@ function PDFViewer({ /> {JSON.stringify(data, null, 2)}); + return ( +
+    {JSON.stringify(data, null, 2)}
+  
); } -export default PrettyJson; +export default PrettyJson; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/SelectMulti.tsx b/rsconcept/frontend/src/components/Common/SelectMulti.tsx index a3a0484a..ef072dd9 100644 --- a/rsconcept/frontend/src/components/Common/SelectMulti.tsx +++ b/rsconcept/frontend/src/components/Common/SelectMulti.tsx @@ -1,8 +1,10 @@ +'use client'; + import { useMemo } from 'react'; import Select, { GroupBase, Props, StylesConfig } from 'react-select'; -import { useConceptTheme } from '../../context/ThemeContext'; -import { selectDarkT, selectLightT } from '../../utils/color'; +import { useConceptTheme } from '@/context/ThemeContext'; +import { selectDarkT, selectLightT } from '@/utils/color'; export interface SelectMultiProps< Option, @@ -45,12 +47,11 @@ function SelectMulti = GroupBase
); } -export default TextArea; +export default TextArea; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/TextInput.tsx b/rsconcept/frontend/src/components/Common/TextInput.tsx index 99d010fb..d42d6274 100644 --- a/rsconcept/frontend/src/components/Common/TextInput.tsx +++ b/rsconcept/frontend/src/components/Common/TextInput.tsx @@ -1,4 +1,4 @@ -import { IColorsProps, IEditorProps } from '../commonInterfaces'; +import { IColorsProps, IEditorProps } from './commonInterfaces'; import Label from './Label'; interface TextInputProps @@ -37,4 +37,4 @@ function TextInput({ ); } -export default TextInput; +export default TextInput; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/TextURL.tsx b/rsconcept/frontend/src/components/Common/TextURL.tsx index 45404c2a..1ff58628 100644 --- a/rsconcept/frontend/src/components/Common/TextURL.tsx +++ b/rsconcept/frontend/src/components/Common/TextURL.tsx @@ -1,5 +1,6 @@ import { Link } from 'react-router-dom'; + interface TextURLProps { text: string tooltip?: string @@ -35,4 +36,4 @@ function TextURL({ text, href, tooltip, color='text-url', onClick }: TextURLProp } } -export default TextURL; +export default TextURL; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Common/Tristate.tsx b/rsconcept/frontend/src/components/Common/Tristate.tsx index 5f89b919..7eb0e0c9 100644 --- a/rsconcept/frontend/src/components/Common/Tristate.tsx +++ b/rsconcept/frontend/src/components/Common/Tristate.tsx @@ -67,4 +67,4 @@ function Tristate({ ); } -export default Tristate; +export default Tristate; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/commonInterfaces.ts b/rsconcept/frontend/src/components/Common/commonInterfaces.ts similarity index 100% rename from rsconcept/frontend/src/components/commonInterfaces.ts rename to rsconcept/frontend/src/components/Common/commonInterfaces.ts diff --git a/rsconcept/frontend/src/components/ConceptToaster.tsx b/rsconcept/frontend/src/components/ConceptToaster.tsx index b69822dc..884a6cf8 100644 --- a/rsconcept/frontend/src/components/ConceptToaster.tsx +++ b/rsconcept/frontend/src/components/ConceptToaster.tsx @@ -1,6 +1,6 @@ import { ToastContainer, type ToastContainerProps } from 'react-toastify'; -import { useConceptTheme } from '../context/ThemeContext'; +import { useConceptTheme } from '@/context/ThemeContext'; interface ToasterThemedProps extends Omit{} diff --git a/rsconcept/frontend/src/components/DataTable/DataTable.tsx b/rsconcept/frontend/src/components/DataTable/DataTable.tsx index cb88b401..7c763f88 100644 --- a/rsconcept/frontend/src/components/DataTable/DataTable.tsx +++ b/rsconcept/frontend/src/components/DataTable/DataTable.tsx @@ -1,3 +1,5 @@ +'use client'; + import { Cell, ColumnSort, createColumnHelper, flexRender, getCoreRowModel, @@ -55,7 +57,7 @@ extends Pick, * @param headPosition - Top position of sticky header (0 if no other sticky elements are present). * No sticky header if omitted */ -export default function DataTable({ +function DataTable({ dense, headPosition, conditionalRowStyles, noFooter, noHeader, onRowClicked, onRowDoubleClicked, noDataComponent, @@ -212,3 +214,5 @@ export default function DataTable({ {isEmpty ? (noDataComponent ?? ) : null} ); } + +export default DataTable; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/DataTable/PaginationTools.tsx b/rsconcept/frontend/src/components/DataTable/PaginationTools.tsx index caf58885..43fd3ae8 100644 --- a/rsconcept/frontend/src/components/DataTable/PaginationTools.tsx +++ b/rsconcept/frontend/src/components/DataTable/PaginationTools.tsx @@ -1,7 +1,10 @@ +'use client'; + import { Table } from '@tanstack/react-table'; import { useCallback } from 'react'; -import { prefixes } from '../../utils/constants'; +import { prefixes } from '@/utils/constants'; + import { GotoFirstIcon, GotoLastIcon, GotoNextIcon, GotoPrevIcon } from '../Icons'; interface PaginationToolsProps { diff --git a/rsconcept/frontend/src/components/DataTable/SelectAll.tsx b/rsconcept/frontend/src/components/DataTable/SelectAll.tsx index 0eef0194..d49dfcae 100644 --- a/rsconcept/frontend/src/components/DataTable/SelectAll.tsx +++ b/rsconcept/frontend/src/components/DataTable/SelectAll.tsx @@ -1,6 +1,6 @@ import { Table } from '@tanstack/react-table'; -import Tristate from '../Common/Tristate'; +import Tristate from '@/components/Common/Tristate'; interface SelectAllProps { table: Table @@ -19,4 +19,4 @@ function SelectAll({ table }: SelectAllProps) { />); } -export default SelectAll; +export default SelectAll; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/DataTable/SelectRow.tsx b/rsconcept/frontend/src/components/DataTable/SelectRow.tsx index 40313513..e2f31089 100644 --- a/rsconcept/frontend/src/components/DataTable/SelectRow.tsx +++ b/rsconcept/frontend/src/components/DataTable/SelectRow.tsx @@ -1,6 +1,6 @@ import { Row } from '@tanstack/react-table'; -import Checkbox from '../Common/Checkbox'; +import Checkbox from '@/components/Common/Checkbox'; interface SelectRowProps { row: Row @@ -14,4 +14,4 @@ function SelectRow({ row }: SelectRowProps) { />); } -export default SelectRow; +export default SelectRow; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/DataTable/SortingIcon.tsx b/rsconcept/frontend/src/components/DataTable/SortingIcon.tsx index eff755d3..1c47770c 100644 --- a/rsconcept/frontend/src/components/DataTable/SortingIcon.tsx +++ b/rsconcept/frontend/src/components/DataTable/SortingIcon.tsx @@ -1,6 +1,6 @@ import { Column } from '@tanstack/react-table'; -import { AscendingIcon, DescendingIcon } from '../Icons'; +import { AscendingIcon, DescendingIcon } from '@/components/Icons'; interface SortingIconProps { column: Column diff --git a/rsconcept/frontend/src/components/ErrorFallback.tsx b/rsconcept/frontend/src/components/ErrorFallback.tsx index a2a9a886..cae3eb9f 100644 --- a/rsconcept/frontend/src/components/ErrorFallback.tsx +++ b/rsconcept/frontend/src/components/ErrorFallback.tsx @@ -1,16 +1,18 @@ import { type FallbackProps } from 'react-error-boundary'; import Button from './Common/Button'; +import InfoError from './InfoError'; function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) { - reportError(error); return ( -
-

Что-то пошло не так!

- {error} -
- ); +
+

Что-то пошло не так!

+
); } export default ErrorFallback; diff --git a/rsconcept/frontend/src/components/ExpectedAnonymous.tsx b/rsconcept/frontend/src/components/ExpectedAnonymous.tsx index 020e0067..b09c0fba 100644 --- a/rsconcept/frontend/src/components/ExpectedAnonymous.tsx +++ b/rsconcept/frontend/src/components/ExpectedAnonymous.tsx @@ -1,20 +1,21 @@ -import { useAuth } from '../context/AuthContext'; -import { useConceptNavigation } from '../context/NagivationContext'; +import { useAuth } from '@/context/AuthContext'; +import { useConceptNavigation } from '@/context/NagivationContext'; + import TextURL from './Common/TextURL'; function ExpectedAnonymous() { const { user, logout } = useAuth(); - const { navigateTo } = useConceptNavigation(); + const router = useConceptNavigation(); function logoutAndRedirect() { - logout(() => navigateTo('/login/')); + logout(() => router.push('/login/')); } return (

{`Вы вошли в систему как ${user?.username ?? ''}`}

- + | | diff --git a/rsconcept/frontend/src/components/Footer.tsx b/rsconcept/frontend/src/components/Footer.tsx index 2c9a4cde..1d18c363 100644 --- a/rsconcept/frontend/src/components/Footer.tsx +++ b/rsconcept/frontend/src/components/Footer.tsx @@ -1,4 +1,4 @@ -import { urls } from '../utils/constants'; +import { urls } from '@/utils/constants'; import TextURL from './Common/TextURL'; function Footer() { diff --git a/rsconcept/frontend/src/components/Help/ConstituentaTooltip.tsx b/rsconcept/frontend/src/components/Help/ConstituentaTooltip.tsx index eefaa18c..b97a70ee 100644 --- a/rsconcept/frontend/src/components/Help/ConstituentaTooltip.tsx +++ b/rsconcept/frontend/src/components/Help/ConstituentaTooltip.tsx @@ -1,6 +1,6 @@ -import { IConstituenta } from '../../models/rsform'; -import ConceptTooltip from '../Common/ConceptTooltip'; -import InfoConstituenta from '../Shared/InfoConstituenta'; +import ConceptTooltip from '@/components/Common/ConceptTooltip'; +import InfoConstituenta from '@/components/Shared/InfoConstituenta'; +import { IConstituenta } from '@/models/rsform'; interface ConstituentaTooltipProps { data: IConstituenta @@ -17,4 +17,4 @@ function ConstituentaTooltip({ data, anchor }: ConstituentaTooltipProps) { ); } -export default ConstituentaTooltip; +export default ConstituentaTooltip; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpAPI.tsx b/rsconcept/frontend/src/components/Help/HelpAPI.tsx index 3ba0ac84..eacb3bf0 100644 --- a/rsconcept/frontend/src/components/Help/HelpAPI.tsx +++ b/rsconcept/frontend/src/components/Help/HelpAPI.tsx @@ -1,5 +1,5 @@ -import { urls } from '../../utils/constants'; -import TextURL from '../Common/TextURL'; +import TextURL from '@/components/Common/TextURL'; +import { urls } from '@/utils/constants'; function HelpAPI() { return ( @@ -12,4 +12,4 @@ function HelpAPI() {
); } -export default HelpAPI; +export default HelpAPI; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpButton.tsx b/rsconcept/frontend/src/components/Help/HelpButton.tsx index 9d43208b..e7feaf6b 100644 --- a/rsconcept/frontend/src/components/Help/HelpButton.tsx +++ b/rsconcept/frontend/src/components/Help/HelpButton.tsx @@ -1,7 +1,8 @@ -import { HelpTopic } from '../../models/miscelanious'; -import ConceptTooltip from '../Common/ConceptTooltip'; -import TextURL from '../Common/TextURL'; -import { HelpIcon } from '../Icons'; +import ConceptTooltip from '@/components/Common/ConceptTooltip'; +import TextURL from '@/components/Common/TextURL'; +import { HelpIcon } from '@/components/Icons'; +import { HelpTopic } from '@/models/miscelanious'; + import InfoTopic from './InfoTopic'; interface HelpButtonProps { @@ -35,4 +36,4 @@ function HelpButton({ topic, offset, dimensions }: HelpButtonProps) { ); } -export default HelpButton; +export default HelpButton; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpConstituenta.tsx b/rsconcept/frontend/src/components/Help/HelpConstituenta.tsx index bc77b45d..647b4089 100644 --- a/rsconcept/frontend/src/components/Help/HelpConstituenta.tsx +++ b/rsconcept/frontend/src/components/Help/HelpConstituenta.tsx @@ -1,5 +1,5 @@ -import Divider from '../Common/Divider'; -import InfoCstStatus from '../Shared/InfoCstStatus'; +import Divider from '@/components/Common/Divider'; +import InfoCstStatus from '@/components/Shared/InfoCstStatus'; function HelpConstituenta() { return ( @@ -22,4 +22,4 @@ function HelpConstituenta() {
); } -export default HelpConstituenta; +export default HelpConstituenta; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpExteor.tsx b/rsconcept/frontend/src/components/Help/HelpExteor.tsx index 39fa20b6..dd31db0d 100644 --- a/rsconcept/frontend/src/components/Help/HelpExteor.tsx +++ b/rsconcept/frontend/src/components/Help/HelpExteor.tsx @@ -1,5 +1,5 @@ -import { urls } from '../../utils/constants'; -import TextURL from '../Common/TextURL'; +import TextURL from '@/components/Common/TextURL'; +import { urls } from '@/utils/constants'; function HelpExteor() { return ( @@ -24,4 +24,4 @@ function HelpExteor() { ); } -export default HelpExteor; +export default HelpExteor; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpLibrary.tsx b/rsconcept/frontend/src/components/Help/HelpLibrary.tsx index 67de891a..1148f376 100644 --- a/rsconcept/frontend/src/components/Help/HelpLibrary.tsx +++ b/rsconcept/frontend/src/components/Help/HelpLibrary.tsx @@ -1,4 +1,4 @@ -import { EducationIcon, GroupIcon,SubscribedIcon } from '../Icons'; +import { EducationIcon, GroupIcon,SubscribedIcon } from '@/components/Icons'; function HelpLibrary() { return ( @@ -23,4 +23,4 @@ function HelpLibrary() { ); } -export default HelpLibrary; +export default HelpLibrary; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpMain.tsx b/rsconcept/frontend/src/components/Help/HelpMain.tsx index b39ddfab..35dead1f 100644 --- a/rsconcept/frontend/src/components/Help/HelpMain.tsx +++ b/rsconcept/frontend/src/components/Help/HelpMain.tsx @@ -1,5 +1,5 @@ -import { urls } from '../../utils/constants'; -import TextURL from '../Common/TextURL'; +import TextURL from '@/components/Common/TextURL'; +import { urls } from '@/utils/constants'; function HelpMain() { return ( @@ -20,4 +20,4 @@ function HelpMain() { ); } -export default HelpMain; +export default HelpMain; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpPrivacy.tsx b/rsconcept/frontend/src/components/Help/HelpPrivacy.tsx index 4131da3a..edd5dbea 100644 --- a/rsconcept/frontend/src/components/Help/HelpPrivacy.tsx +++ b/rsconcept/frontend/src/components/Help/HelpPrivacy.tsx @@ -1,5 +1,5 @@ -import { resources } from '../../utils/constants'; -import PDFViewer from '../Common/PDFViewer'; +import PDFViewer from '@/components/Common/PDFViewer'; +import { resources } from '@/utils/constants'; function HelpPrivacy() { return ( @@ -8,4 +8,4 @@ function HelpPrivacy() { />); } -export default HelpPrivacy; +export default HelpPrivacy; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpRSFormItems.tsx b/rsconcept/frontend/src/components/Help/HelpRSFormItems.tsx index 664266ee..02f0f3ab 100644 --- a/rsconcept/frontend/src/components/Help/HelpRSFormItems.tsx +++ b/rsconcept/frontend/src/components/Help/HelpRSFormItems.tsx @@ -1,5 +1,5 @@ -import Divider from '../Common/Divider'; -import InfoCstStatus from '../Shared/InfoCstStatus'; +import Divider from '@/components/Common/Divider'; +import InfoCstStatus from '@/components/Shared/InfoCstStatus'; function HelpRSFormItems() { return ( @@ -15,4 +15,4 @@ function HelpRSFormItems() { ); } -export default HelpRSFormItems; +export default HelpRSFormItems; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx b/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx index 9d19e8f7..787a44fa 100644 --- a/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx +++ b/rsconcept/frontend/src/components/Help/HelpRSFormMeta.tsx @@ -12,4 +12,4 @@ function HelpRSFormMeta() { ); } -export default HelpRSFormMeta; +export default HelpRSFormMeta; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpRSLang.tsx b/rsconcept/frontend/src/components/Help/HelpRSLang.tsx index ae556f07..44705628 100644 --- a/rsconcept/frontend/src/components/Help/HelpRSLang.tsx +++ b/rsconcept/frontend/src/components/Help/HelpRSLang.tsx @@ -1,8 +1,8 @@ import { useMemo } from 'react'; -import useWindowSize from '../../hooks/useWindowSize'; -import { urls, youtube } from '../../utils/constants'; -import EmbedYoutube from '../Common/EmbedYoutube'; +import EmbedYoutube from '@/components/Common/EmbedYoutube'; +import useWindowSize from '@/hooks/useWindowSize'; +import { urls, youtube } from '@/utils/constants'; const OPT_VIDEO_H = 1080; @@ -38,4 +38,4 @@ function HelpRSLang() { ); } -export default HelpRSLang; +export default HelpRSLang; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpTermGraph.tsx b/rsconcept/frontend/src/components/Help/HelpTermGraph.tsx index 2f67c381..f3b0b7c6 100644 --- a/rsconcept/frontend/src/components/Help/HelpTermGraph.tsx +++ b/rsconcept/frontend/src/components/Help/HelpTermGraph.tsx @@ -1,6 +1,6 @@ -import Divider from '../Common/Divider'; -import InfoCstClass from '../Shared/InfoCstClass'; -import InfoCstStatus from '../Shared/InfoCstStatus'; +import Divider from '@/components/Common/Divider'; +import InfoCstClass from '@/components/Shared/InfoCstClass'; +import InfoCstStatus from '@/components/Shared/InfoCstStatus'; function HelpTermGraph() { return ( @@ -33,4 +33,4 @@ function HelpTermGraph() { ); } -export default HelpTermGraph; +export default HelpTermGraph; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/HelpTerminologyControl.tsx b/rsconcept/frontend/src/components/Help/HelpTerminologyControl.tsx index 03360fb3..262b9c48 100644 --- a/rsconcept/frontend/src/components/Help/HelpTerminologyControl.tsx +++ b/rsconcept/frontend/src/components/Help/HelpTerminologyControl.tsx @@ -13,4 +13,4 @@ function HelpTerminologyControl() { ); } -export default HelpTerminologyControl; +export default HelpTerminologyControl; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Help/InfoTopic.tsx b/rsconcept/frontend/src/components/Help/InfoTopic.tsx index 8f90107a..6933a78b 100644 --- a/rsconcept/frontend/src/components/Help/InfoTopic.tsx +++ b/rsconcept/frontend/src/components/Help/InfoTopic.tsx @@ -1,4 +1,5 @@ -import { HelpTopic } from '../../models/miscelanious'; +import { HelpTopic } from '@/models/miscelanious'; + import HelpAPI from './HelpAPI'; import HelpConstituenta from './HelpConstituenta'; import HelpExteor from './HelpExteor'; @@ -32,4 +33,4 @@ function InfoTopic({ topic }: InfoTopicProps) { return null; } -export default InfoTopic; +export default InfoTopic; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/BackendError.tsx b/rsconcept/frontend/src/components/InfoError.tsx similarity index 51% rename from rsconcept/frontend/src/components/BackendError.tsx rename to rsconcept/frontend/src/components/InfoError.tsx index 161bc68b..952cd82a 100644 --- a/rsconcept/frontend/src/components/BackendError.tsx +++ b/rsconcept/frontend/src/components/InfoError.tsx @@ -1,15 +1,16 @@ -import axios, { type AxiosError,AxiosHeaderValue } from 'axios'; +import axios, { type AxiosError } from 'axios'; + +import { isResponseHtml } from '@/utils/utils'; import PrettyJson from './Common/PrettyJSON'; -export type ErrorInfo = string | Error | AxiosError | undefined; +export type ErrorData = string | Error | AxiosError | undefined; -interface BackendErrorProps { - error: ErrorInfo +interface InfoErrorProps { + error: ErrorData } -function DescribeError(error: ErrorInfo) { - reportError(error); +function DescribeError({error} : {error: ErrorData}) { if (!error) { return

Ошибки отсутствуют

; } else if (typeof error === 'string') { @@ -22,28 +23,14 @@ function DescribeError(error: ErrorInfo) { } if (error.response.status === 404) { return ( -
-

{'Обращение к несуществующему API'}

- -
- ); +
+

{'Обращение к несуществующему API'}

+ +
); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const isHtml = (() => { - if (!error.response) { - return false; - } - const header = error.response.headers['content-type'] as AxiosHeaderValue; - if (!header) { - return false; - } - if (typeof header === 'number' || typeof header === 'boolean') { - return false; - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call - return header.includes('text/html'); - })(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + const isHtml = isResponseHtml(error.response); return (

Ошибка

@@ -57,11 +44,11 @@ function DescribeError(error: ErrorInfo) { ); } -function BackendError({ error }: BackendErrorProps) { +function InfoError({ error }: InfoErrorProps) { return (
- {DescribeError(error)} +
); } -export default BackendError; +export default InfoError; diff --git a/rsconcept/frontend/src/components/Navigation/Logo.tsx b/rsconcept/frontend/src/components/Navigation/Logo.tsx index a36aa8ea..18fa300a 100644 --- a/rsconcept/frontend/src/components/Navigation/Logo.tsx +++ b/rsconcept/frontend/src/components/Navigation/Logo.tsx @@ -1,34 +1,11 @@ -import { Link } from 'react-router-dom'; - -import { useConceptTheme } from '../../context/ThemeContext'; -import useWindowSize from '../../hooks/useWindowSize'; - -const HIDE_LOGO_TEXT_LIMIT = 700; +import { useConceptTheme } from '@/context/ThemeContext'; function Logo() { const { darkMode } = useConceptTheme(); - const windowSize = useWindowSize(); - return ( - - {(windowSize.width && windowSize.width >= HIDE_LOGO_TEXT_LIMIT && !darkMode) ? - : null} - {(windowSize.width && windowSize.width >= HIDE_LOGO_TEXT_LIMIT && darkMode) ? - : null} - {(!windowSize.width || windowSize.width < HIDE_LOGO_TEXT_LIMIT) ? - : null} - ); + Логотип КонцептПортал); } -export default Logo; +export default Logo; \ No newline at end of file diff --git a/rsconcept/frontend/src/components/Navigation/Navigation.tsx b/rsconcept/frontend/src/components/Navigation/Navigation.tsx index 416c526e..da306328 100644 --- a/rsconcept/frontend/src/components/Navigation/Navigation.tsx +++ b/rsconcept/frontend/src/components/Navigation/Navigation.tsx @@ -1,25 +1,27 @@ -import { useConceptNavigation } from '../../context/NagivationContext'; -import { useConceptTheme } from '../../context/ThemeContext'; -import { EducationIcon, LibraryIcon, PlusIcon } from '../Icons'; -import Logo from './Logo' +import { useConceptNavigation } from '@/context/NagivationContext'; +import { useConceptTheme } from '@/context/ThemeContext'; + +import { EducationIcon, LibraryIcon, PlusIcon } from '@/components/Icons'; +import Logo from './Logo'; import NavigationButton from './NavigationButton'; import ToggleNavigationButton from './ToggleNavigationButton'; import UserMenu from './UserMenu'; function Navigation () { - const { navigateTo } = useConceptNavigation(); + const router = useConceptNavigation(); const { noNavigation } = useConceptTheme(); - const navigateLibrary = () => navigateTo('/library'); - const navigateHelp = () => navigateTo('/manuals'); - const navigateCreateNew = () => navigateTo('/rsform-create'); + const navigateHome = () => router.push('/'); + const navigateLibrary = () => router.push('/library'); + const navigateHelp = () => router.push('/manuals'); + const navigateCreateNew = () => router.push('/library/create'); return ( -
); } -export default ViewTopic; +export default ViewTopic; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/NotFoundPage.tsx b/rsconcept/frontend/src/pages/NotFoundPage.tsx index 2fab2811..ea6ea064 100644 --- a/rsconcept/frontend/src/pages/NotFoundPage.tsx +++ b/rsconcept/frontend/src/pages/NotFoundPage.tsx @@ -1,12 +1,12 @@ -import TextURL from '../components/Common/TextURL'; +import TextURL from '@/components/Common/TextURL'; export function NotFoundPage() { return ( -
-

Ошибка 404 - Страница не найдена

-

Данная страница не существует или запрашиваемый объект отсутствует в базе данных

+
+

Ошибка 404 - Страница не найдена

+

Данная страница не существует или запрашиваемый объект отсутствует в базе данных

); } -export default NotFoundPage; +export default NotFoundPage; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/ConstituentaToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/ConstituentaToolbar.tsx index 88d3d0c5..8c824160 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/ConstituentaToolbar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/ConstituentaToolbar.tsx @@ -1,12 +1,14 @@ +'use client'; + import { useMemo } from 'react'; -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import HelpButton from '../../../components/Help/HelpButton'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import HelpButton from '@/components/Help/HelpButton'; import { ArrowsRotateIcon, CloneIcon, DiamondIcon, DumpBinIcon, SaveIcon, SmallPlusIcon -} from '../../../components/Icons'; -import { HelpTopic } from '../../../models/miscelanious'; +} from '@/components/Icons'; +import { HelpTopic } from '@/models/miscelanious'; interface ConstituentaToolbarProps { isMutable: boolean diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx index caf56d90..41bd4b2c 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx @@ -1,10 +1,12 @@ +'use client'; + import { Dispatch, SetStateAction, useMemo, useState } from 'react'; -import { useRSForm } from '../../../context/RSFormContext'; -import useWindowSize from '../../../hooks/useWindowSize'; -import { CstType, IConstituenta, ICstCreateData, ICstRenameData } from '../../../models/rsform'; -import { SyntaxTree } from '../../../models/rslang'; -import { globalIDs } from '../../../utils/constants'; +import { useRSForm } from '@/context/RSFormContext'; +import useWindowSize from '@/hooks/useWindowSize'; +import { CstType, IConstituenta, ICstCreateData, ICstRenameData } from '@/models/rsform'; +import { globalIDs } from '@/utils/constants'; + import ViewConstituents from '../ViewConstituents'; import ConstituentaToolbar from './ConstituentaToolbar'; import FormConstituenta from './FormConstituenta'; @@ -22,7 +24,6 @@ interface EditorConstituentaProps { setIsModified: Dispatch> onOpenEdit: (cstID: number) => void - onShowAST: (expression: string, ast: SyntaxTree) => void onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void onRenameCst: (initial: ICstRenameData) => void onEditTerm: () => void @@ -32,7 +33,7 @@ interface EditorConstituentaProps { function EditorConstituenta({ isModified, setIsModified, activeID, activeCst, onEditTerm, - onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst, onTemplates + onCreateCst, onRenameCst, onOpenEdit, onDeleteCst, onTemplates }: EditorConstituentaProps) { const windowSize = useWindowSize(); const { schema, isMutable } = useRSForm(); @@ -141,7 +142,6 @@ function EditorConstituenta({ toggleReset={toggleReset} setIsModified={setIsModified} - onShowAST={onShowAST} onEditTerm={onEditTerm} onRenameCst={onRenameCst} /> diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx index beaf11b4..e8efdb7e 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/FormConstituenta.tsx @@ -1,16 +1,18 @@ +'use client'; + import { Dispatch, SetStateAction, useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import SubmitButton from '../../../components/Common/SubmitButton'; -import TextArea from '../../../components/Common/TextArea'; -import { EditIcon, SaveIcon } from '../../../components/Icons'; -import RefsInput from '../../../components/RefsInput'; -import { useRSForm } from '../../../context/RSFormContext'; -import { IConstituenta, ICstRenameData, ICstUpdateData } from '../../../models/rsform'; -import { SyntaxTree } from '../../../models/rslang'; -import { labelCstTypification } from '../../../utils/labels'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import SubmitButton from '@/components/Common/SubmitButton'; +import TextArea from '@/components/Common/TextArea'; +import { EditIcon, SaveIcon } from '@/components/Icons'; +import RefsInput from '@/components/RefsInput'; +import { useRSForm } from '@/context/RSFormContext'; +import { IConstituenta, ICstRenameData, ICstUpdateData } from '@/models/rsform'; +import { labelCstTypification } from '@/utils/labels'; + import EditorRSExpression from '../EditorRSExpression'; interface FormConstituentaProps { @@ -22,14 +24,13 @@ interface FormConstituentaProps { setIsModified: Dispatch> onRenameCst: (initial: ICstRenameData) => void - onShowAST: (expression: string, ast: SyntaxTree) => void onEditTerm: () => void } function FormConstituenta({ id, isModified, setIsModified, constituenta, toggleReset, - onRenameCst, onShowAST, onEditTerm + onRenameCst, onEditTerm }: FormConstituentaProps) { const { schema, cstUpdate, isMutable, processing } = useRSForm(); @@ -153,7 +154,6 @@ function FormConstituenta({ value={expression} disabled={!readyForEdit} toggleReset={toggleReset} - onShowAST={onShowAST} onChange={newValue => setExpression(newValue)} setTypification={setTypification} /> diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx index fbc4f878..4504682f 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx @@ -1,19 +1,23 @@ +'use client'; + import { ReactCodeMirrorRef } from '@uiw/react-codemirror'; import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { toast } from 'react-toastify'; -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import { ASTNetworkIcon } from '../../../components/Icons'; -import RSInput from '../../../components/RSInput'; -import { RSTextWrapper } from '../../../components/RSInput/textEditing'; -import { useRSForm } from '../../../context/RSFormContext'; -import useCheckExpression from '../../../hooks/useCheckExpression'; -import { IConstituenta } from '../../../models/rsform'; -import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '../../../models/rslang'; -import { TokenID } from '../../../models/rslang'; -import { labelTypification } from '../../../utils/labels'; -import { getCstExpressionPrefix } from '../../../utils/misc'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import { ASTNetworkIcon } from '@/components/Icons'; +import RSInput from '@/components/RSInput'; +import { RSTextWrapper } from '@/components/RSInput/textEditing'; +import { useRSForm } from '@/context/RSFormContext'; +import DlgShowAST from '@/dialogs/DlgShowAST'; +import useCheckExpression from '@/hooks/useCheckExpression'; +import { IConstituenta } from '@/models/rsform'; +import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '@/models/rslang'; +import { TokenID } from '@/models/rslang'; +import { labelTypification } from '@/utils/labels'; +import { getCstExpressionPrefix } from '@/utils/misc'; + import RSAnalyzer from './RSAnalyzer'; import RSEditorControls from './RSEditControls'; @@ -24,14 +28,13 @@ interface EditorRSExpressionProps { disabled?: boolean toggleReset?: boolean placeholder?: string - onShowAST: (expression: string, ast: SyntaxTree) => void setTypification: (typificaiton: string) => void value: string onChange: (newValue: string) => void } function EditorRSExpression({ - activeCst, disabled, value, onShowAST, toggleReset, + activeCst, disabled, value, toggleReset, setTypification, onChange, ...restProps }: EditorRSExpressionProps) { const { schema } = useRSForm(); @@ -40,6 +43,10 @@ function EditorRSExpression({ const { parseData, checkExpression, resetParse, loading } = useCheckExpression({ schema }); const rsInput = useRef(null); + const [syntaxTree, setSyntaxTree] = useState([]); + const [expression, setExpression] = useState(''); + const [showAST, setShowAST] = useState(false); + useLayoutEffect(() => { setIsModified(false); resetParse(); @@ -109,13 +116,21 @@ function EditorRSExpression({ if (!parse.astText) { toast.error('Невозможно построить дерево разбора'); } else { - onShowAST(getCstExpressionPrefix(activeCst!) + value, parse.ast); + setSyntaxTree(parse.ast); + setExpression(getCstExpressionPrefix(activeCst!) + value); + setShowAST(true); } }); } return (
+ {showAST ? + setShowAST(false)} + /> : null} ); } -export default RSLocalButton; +export default RSLocalButton; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/RSTokenButton.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/RSTokenButton.tsx index 62f4be88..cc2891ad 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/RSTokenButton.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/RSTokenButton.tsx @@ -1,5 +1,5 @@ -import { TokenID } from '../../../models/rslang'; -import { describeToken, labelToken } from '../../../utils/labels'; +import { TokenID } from '@/models/rslang'; +import { describeToken, labelToken } from '@/utils/labels'; interface RSTokenButtonProps { token: TokenID @@ -21,4 +21,4 @@ function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps) { ); } -export default RSTokenButton; +export default RSTokenButton; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/StatusBar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/StatusBar.tsx index a4136228..c927aec7 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/StatusBar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSExpression/StatusBar.tsx @@ -1,12 +1,14 @@ +'use client'; + import { useMemo } from 'react'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import { ExpressionStatus } from '../../../models/rsform'; -import { type IConstituenta } from '../../../models/rsform'; -import { inferStatus } from '../../../models/rsformAPI'; -import { IExpressionParse, ParsingStatus } from '../../../models/rslang'; -import { colorbgCstStatus } from '../../../utils/color'; -import { describeExpressionStatus, labelExpressionStatus } from '../../../utils/labels'; +import { useConceptTheme } from '@/context/ThemeContext'; +import { ExpressionStatus } from '@/models/rsform'; +import { type IConstituenta } from '@/models/rsform'; +import { inferStatus } from '@/models/rsformAPI'; +import { IExpressionParse, ParsingStatus } from '@/models/rslang'; +import { colorbgCstStatus } from '@/utils/color'; +import { describeExpressionStatus, labelExpressionStatus } from '@/utils/labels'; interface StatusBarProps { isModified?: boolean @@ -28,13 +30,12 @@ function StatusBar({ isModified, constituenta, parseData }: StatusBarProps) { }, [isModified, constituenta, parseData]); return ( -
- {labelExpressionStatus(status)} -
- ) +
+ {labelExpressionStatus(status)} +
); } -export default StatusBar; +export default StatusBar; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/EditorRSForm.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/EditorRSForm.tsx index 7add61e1..12ae0f9f 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/EditorRSForm.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/EditorRSForm.tsx @@ -1,10 +1,13 @@ +'use client'; + import { Dispatch, SetStateAction } from 'react'; -import Divider from '../../../components/Common/Divider'; -import InfoLibraryItem from '../../../components/Shared/InfoLibraryItem'; -import { useAuth } from '../../../context/AuthContext'; -import { useRSForm } from '../../../context/RSFormContext'; -import { globalIDs } from '../../../utils/constants'; +import Divider from '@/components/Common/Divider'; +import InfoLibraryItem from '@/components/Shared/InfoLibraryItem'; +import { useAuth } from '@/context/AuthContext'; +import { useRSForm } from '@/context/RSFormContext'; +import { globalIDs } from '@/utils/constants'; + import FormRSForm from './FormRSForm'; import RSFormStats from './RSFormStats'; import RSFormToolbar from './RSFormToolbar'; @@ -73,4 +76,4 @@ function EditorRSForm({ onDestroy, onClaim, onShare, isModified, setIsModified,
); } -export default EditorRSForm; +export default EditorRSForm; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/FormRSForm.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/FormRSForm.tsx index 1e8bedaf..77b31977 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/FormRSForm.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/FormRSForm.tsx @@ -1,14 +1,16 @@ +'use client'; + import { Dispatch, SetStateAction, useLayoutEffect, useState } from 'react'; import { toast } from 'react-toastify'; -import Checkbox from '../../../components/Common/Checkbox'; -import SubmitButton from '../../../components/Common/SubmitButton'; -import TextArea from '../../../components/Common/TextArea'; -import TextInput from '../../../components/Common/TextInput'; -import { SaveIcon } from '../../../components/Icons'; -import { useRSForm } from '../../../context/RSFormContext'; -import { LibraryItemType } from '../../../models/library'; -import { IRSFormCreateData } from '../../../models/rsform'; +import Checkbox from '@/components/Common/Checkbox'; +import SubmitButton from '@/components/Common/SubmitButton'; +import TextArea from '@/components/Common/TextArea'; +import TextInput from '@/components/Common/TextInput'; +import { SaveIcon } from '@/components/Icons'; +import { useRSForm } from '@/context/RSFormContext'; +import { LibraryItemType } from '@/models/library'; +import { IRSFormCreateData } from '@/models/rsform'; interface FormRSFormProps { id?: string diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormStats.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormStats.tsx index 1ffc504e..5e6367c2 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormStats.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormStats.tsx @@ -1,6 +1,6 @@ -import Divider from '../../../components/Common/Divider'; -import LabeledText from '../../../components/Common/LabeledText'; -import { type IRSFormStats } from '../../../models/rsform'; +import Divider from '@/components/Common/Divider'; +import LabeledText from '@/components/Common/LabeledText'; +import { type IRSFormStats } from '@/models/rsform'; interface RSFormStatsProps { stats?: IRSFormStats @@ -91,4 +91,4 @@ function RSFormStats({ stats }: RSFormStatsProps) {
); } -export default RSFormStats; +export default RSFormStats; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormToolbar.tsx index 27a2fa57..7639050d 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormToolbar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSForm/RSFormToolbar.tsx @@ -1,10 +1,12 @@ +'use client'; + import { useMemo } from 'react'; -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import HelpButton from '../../../components/Help/HelpButton'; -import { DownloadIcon, DumpBinIcon, OwnerIcon, SaveIcon, ShareIcon } from '../../../components/Icons'; -import { HelpTopic } from '../../../models/miscelanious'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import HelpButton from '@/components/Help/HelpButton'; +import { DownloadIcon, DumpBinIcon, OwnerIcon, SaveIcon, ShareIcon } from '@/components/Icons'; +import { HelpTopic } from '@/models/miscelanious'; interface RSFormToolbarProps { isMutable: boolean diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/EditorRSList.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/EditorRSList.tsx index 14f705a8..c5d978d8 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/EditorRSList.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/EditorRSList.tsx @@ -1,10 +1,13 @@ +'use client'; + import { useLayoutEffect, useState } from 'react'; import { toast } from 'react-toastify'; -import { type RowSelectionState } from '../../../components/DataTable'; -import SelectedCounter from '../../../components/Shared/SelectedCounter'; -import { useRSForm } from '../../../context/RSFormContext'; -import { CstType, ICstCreateData, ICstMovetoData } from '../../../models/rsform'; +import { type RowSelectionState } from '@/components/DataTable'; +import SelectedCounter from '@/components/Shared/SelectedCounter'; +import { useRSForm } from '@/context/RSFormContext'; +import { CstType, ICstCreateData, ICstMovetoData } from '@/models/rsform'; + import RSListToolbar from './RSListToolbar'; import RSTable from './RSTable'; @@ -231,4 +234,4 @@ function EditorRSList({ onOpenEdit, onCreateCst, onDeleteCst, onTemplates }: Edi ); } -export default EditorRSList; +export default EditorRSList; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx index 50d16df7..7c804b3b 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx @@ -1,17 +1,19 @@ +'use client'; + import { useMemo } from 'react'; -import Dropdown from '../../../components/Common/Dropdown'; -import DropdownButton from '../../../components/Common/DropdownButton'; -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import HelpButton from '../../../components/Help/HelpButton'; -import { ArrowDownIcon, ArrowDropdownIcon, ArrowUpIcon, CloneIcon, DiamondIcon, DumpBinIcon, SmallPlusIcon, UpdateIcon } from '../../../components/Icons'; -import useDropdown from '../../../hooks/useDropdown'; -import { HelpTopic } from '../../../models/miscelanious'; -import { CstType } from '../../../models/rsform'; -import { prefixes } from '../../../utils/constants'; -import { labelCstType } from '../../../utils/labels'; -import { getCstTypePrefix, getCstTypeShortcut } from '../../../utils/misc'; +import Dropdown from '@/components/Common/Dropdown'; +import DropdownButton from '@/components/Common/DropdownButton'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import HelpButton from '@/components/Help/HelpButton'; +import { ArrowDownIcon, ArrowDropdownIcon, ArrowUpIcon, CloneIcon, DiamondIcon, DumpBinIcon, SmallPlusIcon, UpdateIcon } from '@/components/Icons'; +import useDropdown from '@/hooks/useDropdown'; +import { HelpTopic } from '@/models/miscelanious'; +import { CstType } from '@/models/rsform'; +import { prefixes } from '@/utils/constants'; +import { labelCstType } from '@/utils/labels'; +import { getCstTypePrefix, getCstTypeShortcut } from '@/utils/misc'; interface RSListToolbarProps { isMutable?: boolean diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSTable.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSTable.tsx index a7ba5b8d..3aa93bfc 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSTable.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSTable.tsx @@ -1,12 +1,14 @@ +'use client'; + import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import DataTable, { createColumnHelper,RowSelectionState,VisibilityState } from '../../../components/DataTable'; -import ConstituentaBadge from '../../../components/Shared/ConstituentaBadge'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import useWindowSize from '../../../hooks/useWindowSize'; -import { IConstituenta } from '../../../models/rsform'; -import { prefixes } from '../../../utils/constants'; -import { labelCstTypification } from '../../../utils/labels'; +import DataTable, { createColumnHelper,RowSelectionState,VisibilityState } from '@/components/DataTable'; +import ConstituentaBadge from '@/components/Shared/ConstituentaBadge'; +import { useConceptTheme } from '@/context/ThemeContext'; +import useWindowSize from '@/hooks/useWindowSize'; +import { IConstituenta } from '@/models/rsform'; +import { prefixes } from '@/utils/constants'; +import { labelCstTypification } from '@/utils/labels'; interface RSTableProps { items?: IConstituenta[] diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx index 11c46b8b..223b9454 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx @@ -1,17 +1,20 @@ +'use client'; + import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { GraphEdge, GraphNode, LayoutTypes } from 'reagraph'; -import Overlay from '../../../components/Common/Overlay'; -import InfoConstituenta from '../../../components/Shared/InfoConstituenta'; -import SelectedCounter from '../../../components/Shared/SelectedCounter'; -import { useRSForm } from '../../../context/RSFormContext'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import DlgGraphParams from '../../../dialogs/DlgGraphParams'; -import useLocalStorage from '../../../hooks/useLocalStorage'; -import { GraphColoringScheme, GraphFilterParams } from '../../../models/miscelanious'; -import { CstType, ICstCreateData } from '../../../models/rsform'; -import { colorbgGraphNode } from '../../../utils/color'; -import { TIMEOUT_GRAPH_REFRESH } from '../../../utils/constants'; +import Overlay from '@/components/Common/Overlay'; +import InfoConstituenta from '@/components/Shared/InfoConstituenta'; +import SelectedCounter from '@/components/Shared/SelectedCounter'; +import { useRSForm } from '@/context/RSFormContext'; +import { useConceptTheme } from '@/context/ThemeContext'; +import DlgGraphParams from '@/dialogs/DlgGraphParams'; +import useLocalStorage from '@/hooks/useLocalStorage'; +import { GraphColoringScheme, GraphFilterParams } from '@/models/miscelanious'; +import { CstType, ICstCreateData } from '@/models/rsform'; +import { colorbgGraphNode } from '@/utils/color'; +import { TIMEOUT_GRAPH_REFRESH } from '@/utils/constants'; + import GraphSidebar from './GraphSidebar'; import GraphToolbar from './GraphToolbar'; import TermGraph from './TermGraph'; diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphSidebar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphSidebar.tsx index 33b89a23..458941f7 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphSidebar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphSidebar.tsx @@ -1,9 +1,9 @@ import { LayoutTypes } from 'reagraph'; -import SelectSingle from '../../../components/Common/SelectSingle'; -import { GraphColoringScheme } from '../../../models/miscelanious'; -import { mapLabelColoring, mapLableLayout } from '../../../utils/labels'; -import { SelectorGraphColoring, SelectorGraphLayout } from '../../../utils/selectors'; +import SelectSingle from '@/components/Common/SelectSingle'; +import { GraphColoringScheme } from '@/models/miscelanious'; +import { mapLabelColoring, mapLableLayout } from '@/utils/labels'; +import { SelectorGraphColoring, SelectorGraphLayout } from '@/utils/selectors'; interface GraphSidebarProps { coloring: GraphColoringScheme diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx index 9c1b11f7..59e4e729 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx @@ -1,8 +1,10 @@ -import MiniButton from '../../../components/Common/MiniButton'; -import Overlay from '../../../components/Common/Overlay'; -import HelpButton from '../../../components/Help/HelpButton'; -import { ArrowsFocusIcon, DumpBinIcon, FilterIcon, LetterAIcon, LetterALinesIcon, PlanetIcon, SmallPlusIcon } from '../../../components/Icons'; -import { HelpTopic } from '../../../models/miscelanious'; +'use client'; + +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import HelpButton from '@/components/Help/HelpButton'; +import { ArrowsFocusIcon, DumpBinIcon, FilterIcon, LetterAIcon, LetterALinesIcon, PlanetIcon, SmallPlusIcon } from '@/components/Icons'; +import { HelpTopic } from '@/models/miscelanious'; interface GraphToolbarProps { isMutable: boolean diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx index 8db10d1c..7f9e49b2 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx @@ -1,9 +1,13 @@ -import { useCallback, useLayoutEffect, useMemo, useRef } from 'react'; -import { GraphCanvas, GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, Sphere, useSelection } from 'reagraph'; +'use client'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import { graphDarkT, graphLightT } from '../../../utils/color'; -import { resources } from '../../../utils/constants'; +import { useCallback, useLayoutEffect, useMemo, useRef } from 'react'; + +import GraphUI, { + GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, Sphere, useSelection +} from '@/components/Common/GraphUI'; +import { useConceptTheme } from '@/context/ThemeContext'; +import { graphDarkT, graphLightT } from '@/utils/color'; +import { resources } from '@/utils/constants'; interface TermGraphProps { nodes: GraphNode[] @@ -109,7 +113,7 @@ function TermGraph({ return (
- (new Graph()); @@ -54,4 +54,4 @@ function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams, return filtered; } -export default useGraphFilter; +export default useGraphFilter; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx index e2b6037c..66183448 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx @@ -1,12 +1,15 @@ +'use client'; + import { useParams } from 'react-router-dom'; -import { RSFormState } from '../../context/RSFormContext'; +import { RSFormState } from '@/context/RSFormContext'; + import RSTabs from './RSTabs'; function RSFormPage() { - const { id } = useParams(); + const params = useParams(); return ( - + ); } diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx index bba0ff58..8be3a507 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx @@ -1,31 +1,31 @@ +'use client'; + import axios from 'axios'; import fileDownload from 'js-file-download'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import { useLocation } from 'react-router-dom'; import { TabList, TabPanel, Tabs } from 'react-tabs'; import { toast } from 'react-toastify'; -import BackendError, { ErrorInfo } from '../../components/BackendError'; -import { ConceptLoader } from '../../components/Common/ConceptLoader'; -import ConceptTab from '../../components/Common/ConceptTab'; -import TextURL from '../../components/Common/TextURL'; -import { useLibrary } from '../../context/LibraryContext'; -import { useConceptNavigation } from '../../context/NagivationContext'; -import { useRSForm } from '../../context/RSFormContext'; -import { useConceptTheme } from '../../context/ThemeContext'; -import DlgCloneLibraryItem from '../../dialogs/DlgCloneLibraryItem'; -import DlgConstituentaTemplate from '../../dialogs/DlgConstituentaTemplate'; -import DlgCreateCst from '../../dialogs/DlgCreateCst'; -import DlgDeleteCst from '../../dialogs/DlgDeleteCst'; -import DlgEditWordForms from '../../dialogs/DlgEditWordForms'; -import DlgRenameCst from '../../dialogs/DlgRenameCst'; -import DlgShowAST from '../../dialogs/DlgShowAST'; -import DlgUploadRSForm from '../../dialogs/DlgUploadRSForm'; -import useModificationPrompt from '../../hooks/useModificationPrompt'; -import { IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData, TermForm } from '../../models/rsform'; -import { SyntaxTree } from '../../models/rslang'; -import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants'; -import { createAliasFor } from '../../utils/misc'; +import { ConceptLoader } from '@/components/Common/ConceptLoader'; +import ConceptTab from '@/components/Common/ConceptTab'; +import TextURL from '@/components/Common/TextURL'; +import InfoError, { ErrorData } from '@/components/InfoError'; +import { useLibrary } from '@/context/LibraryContext'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { useRSForm } from '@/context/RSFormContext'; +import { useConceptTheme } from '@/context/ThemeContext'; +import DlgCloneLibraryItem from '@/dialogs/DlgCloneLibraryItem'; +import DlgConstituentaTemplate from '@/dialogs/DlgConstituentaTemplate'; +import DlgCreateCst from '@/dialogs/DlgCreateCst'; +import DlgDeleteCst from '@/dialogs/DlgDeleteCst'; +import DlgEditWordForms from '@/dialogs/DlgEditWordForms'; +import DlgRenameCst from '@/dialogs/DlgRenameCst'; +import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm'; +import useQueryStrings from '@/hooks/useQueryStrings'; +import { IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData, TermForm } from '@/models/rsform'; +import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants'; +import { createAliasFor } from '@/utils/misc'; + import EditorConstituenta from './EditorConstituenta'; import EditorRSForm from './EditorRSForm'; import EditorRSList from './EditorRSList'; @@ -39,7 +39,7 @@ export enum RSTabID { TERM_GRAPH = 3 } -function ProcessError({error}: {error: ErrorInfo}): React.ReactElement { +function ProcessError({error}: {error: ErrorData}): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 404) { return (
@@ -48,13 +48,16 @@ function ProcessError({error}: {error: ErrorInfo}): React.ReactElement {
); } else { - return (); + return (); } } function RSTabs() { - const { navigateTo } = useConceptNavigation(); - const search = useLocation().search; + const router = useConceptNavigation(); + const query = useQueryStrings(); + const tabQuery = (Number(query.get('tab')) ?? RSTabID.CARD) as RSTabID; + const cstQuery = query.get('active'); + const { error, schema, loading, claim, download, isTracking, cstCreate, cstDelete, cstRename, subscribe, unsubscribe, cstUpdate @@ -62,7 +65,7 @@ function RSTabs() { const { destroyItem } = useLibrary(); const { setNoFooter, noNavigation } = useConceptTheme(); - const { isModified, setIsModified } = useModificationPrompt(); + const [isModified, setIsModified] = useState(false); const [activeTab, setActiveTab] = useState(RSTabID.CARD); const [activeID, setActiveID] = useState(undefined); @@ -73,10 +76,6 @@ function RSTabs() { const [showUpload, setShowUpload] = useState(false); const [showClone, setShowClone] = useState(false); - const [syntaxTree, setSyntaxTree] = useState([]); - const [expression, setExpression] = useState(''); - const [showAST, setShowAST] = useState(false); - const [afterDelete, setAfterDelete] = useState<((items: number[]) => void) | undefined>(undefined); const [toBeDeleted, setToBeDeleted] = useState([]); const [showDeleteCst, setShowDeleteCst] = useState(false); @@ -110,14 +109,12 @@ function RSTabs() { }, [schema]); useLayoutEffect(() => { - const activeTab = (Number(new URLSearchParams(search).get('tab')) ?? RSTabID.CARD) as RSTabID; - const cstQuery = new URLSearchParams(search).get('active'); - setActiveTab(activeTab); - setNoFooter(activeTab === RSTabID.CST_EDIT || activeTab === RSTabID.CST_LIST); + setActiveTab(tabQuery); + setNoFooter(tabQuery === RSTabID.CST_EDIT || tabQuery === RSTabID.CST_LIST); setActiveID(Number(cstQuery) ?? ((schema && schema?.items.length > 0) ? schema.items[0].id : undefined)); setIsModified(false); return () => setNoFooter(false); - }, [search, setActiveTab, setActiveID, schema, setNoFooter, setIsModified]); + }, [tabQuery, cstQuery, setActiveTab, setActiveID, schema, setNoFooter, setIsModified]); function onSelectTab(index: number) { navigateTab(index, activeID); @@ -129,16 +126,18 @@ function RSTabs() { return; } if (activeID) { - navigateTo(`/rsforms/${schema.id}?tab=${tab}&active=${activeID}`, { - replace: tab === activeTab && tab !== RSTabID.CST_EDIT - }); + if (tab === activeTab && tab !== RSTabID.CST_EDIT) { + router.replace(`/rsforms/${schema.id}?tab=${tab}&active=${activeID}`); + } else { + router.push(`/rsforms/${schema.id}?tab=${tab}&active=${activeID}`); + } } else if (tab !== activeTab && tab === RSTabID.CST_EDIT && schema.items.length > 0) { activeID = schema.items[0].id; - navigateTo(`/rsforms/${schema.id}?tab=${tab}&active=${activeID}`, { replace: true }); + router.replace(`/rsforms/${schema.id}?tab=${tab}&active=${activeID}`); } else { - navigateTo(`/rsforms/${schema.id}?tab=${tab}`); + router.push(`/rsforms/${schema.id}?tab=${tab}`); } - }, [navigateTo, schema, activeTab]); + }, [router, schema, activeTab]); const handleCreateCst = useCallback( (data: ICstCreateData) => { @@ -221,13 +220,6 @@ function RSTabs() { setShowDeleteCst(true) }, []); - const onShowAST = useCallback( - (expression: string, ast: SyntaxTree) => { - setSyntaxTree(ast); - setExpression(expression); - setShowAST(true); - }, []); - const onOpenCst = useCallback( (cstID: number) => { navigateTab(RSTabID.CST_EDIT, cstID) @@ -240,9 +232,9 @@ function RSTabs() { } destroyItem(schema.id, () => { toast.success('Схема удалена'); - navigateTo('/library'); + router.push('/library'); }); - }, [schema, destroyItem, navigateTo]); + }, [schema, destroyItem, router]); const onClaimSchema = useCallback( () => { @@ -341,12 +333,6 @@ function RSTabs() { base={schema!} hideWindow={() => setShowClone(false)} /> : null} - {showAST ? - setShowAST(false)} - /> : null} {showCreateCst ? setShowCreateCst(false)} @@ -448,7 +434,6 @@ function RSTabs() { activeID={activeID} activeCst={activeCst} onOpenEdit={onOpenCst} - onShowAST={onShowAST} onCreateCst={promptCreateCst} onDeleteCst={promptDeleteCst} onRenameCst={promptRenameCst} diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx index 5546f444..f4ba13bc 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx @@ -1,16 +1,17 @@ -import { useNavigate } from 'react-router-dom'; +'use client'; -import Button from '../../components/Common/Button'; -import Dropdown from '../../components/Common/Dropdown'; -import DropdownButton from '../../components/Common/DropdownButton'; -import DropdownCheckbox from '../../components/Common/DropdownCheckbox'; +import Button from '@/components/Common/Button'; +import Dropdown from '@/components/Common/Dropdown'; +import DropdownButton from '@/components/Common/DropdownButton'; +import DropdownCheckbox from '@/components/Common/DropdownCheckbox'; import { CloneIcon, DownloadIcon, DumpBinIcon, EditIcon, MenuIcon, NotSubscribedIcon, -OwnerIcon, ShareIcon, SmallPlusIcon, SubscribedIcon, UploadIcon -} from '../../components/Icons'; -import { useAuth } from '../../context/AuthContext'; -import { useRSForm } from '../../context/RSFormContext'; -import useDropdown from '../../hooks/useDropdown'; + OwnerIcon, ShareIcon, SmallPlusIcon, SubscribedIcon, UploadIcon +} from '@/components/Icons'; +import { useAuth } from '@/context/AuthContext'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { useRSForm } from '@/context/RSFormContext'; +import useDropdown from '@/hooks/useDropdown'; interface RSTabsMenuProps { showUploadDialog: () => void @@ -27,7 +28,7 @@ function RSTabsMenu({ showUploadDialog, showCloneDialog, onDestroy, onShare, onDownload, onClaim, onToggleSubscribe }: RSTabsMenuProps) { - const navigate = useNavigate(); + const router = useConceptNavigation(); const { user } = useAuth(); const { isOwned, isMutable, isTracking, readerMode, isClaimable, adminMode, @@ -67,7 +68,7 @@ function RSTabsMenu({ } function handleCreateNew() { - navigate('/rsform-create'); + router.push('/rsform-create'); } return ( diff --git a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx index 0ea76290..95c63fee 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx @@ -1,19 +1,21 @@ +'use client'; + import { useCallback, useLayoutEffect } from 'react'; -import ConceptSearch from '../../../components/Common/ConceptSearch'; -import Dropdown from '../../../components/Common/Dropdown'; -import DropdownButton from '../../../components/Common/DropdownButton'; -import SelectorButton from '../../../components/Common/SelectorButton'; -import { CogIcon, FilterIcon } from '../../../components/Icons'; -import useDropdown from '../../../hooks/useDropdown'; -import useLocalStorage from '../../../hooks/useLocalStorage'; -import { CstMatchMode, DependencyMode } from '../../../models/miscelanious'; -import { applyGraphFilter } from '../../../models/miscelaniousAPI'; -import { CstType, IConstituenta, IRSForm } from '../../../models/rsform'; -import { createMockConstituenta, matchConstituenta } from '../../../models/rsformAPI'; -import { extractGlobals } from '../../../models/rslangAPI'; -import { prefixes } from '../../../utils/constants'; -import { describeCstMathchMode, describeCstSource, labelCstMathchMode, labelCstSource } from '../../../utils/labels'; +import ConceptSearch from '@/components/Common/ConceptSearch'; +import Dropdown from '@/components/Common/Dropdown'; +import DropdownButton from '@/components/Common/DropdownButton'; +import SelectorButton from '@/components/Common/SelectorButton'; +import { CogIcon, FilterIcon } from '@/components/Icons'; +import useDropdown from '@/hooks/useDropdown'; +import useLocalStorage from '@/hooks/useLocalStorage'; +import { CstMatchMode, DependencyMode } from '@/models/miscelanious'; +import { applyGraphFilter } from '@/models/miscelaniousAPI'; +import { CstType, IConstituenta, IRSForm } from '@/models/rsform'; +import { createMockConstituenta, matchConstituenta } from '@/models/rsformAPI'; +import { extractGlobals } from '@/models/rslangAPI'; +import { prefixes } from '@/utils/constants'; +import { describeCstMathchMode, describeCstSource, labelCstMathchMode, labelCstSource } from '@/utils/labels'; interface ConstituentsSearchProps { schema?: IRSForm diff --git a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx index 34ff5316..223341d6 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx @@ -1,13 +1,15 @@ +'use client'; + import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import DataTable, { createColumnHelper,IConditionalStyle, VisibilityState } from '../../../components/DataTable'; -import ConstituentaBadge from '../../../components/Shared/ConstituentaBadge'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import useWindowSize from '../../../hooks/useWindowSize'; -import { IConstituenta } from '../../../models/rsform'; -import { isMockCst } from '../../../models/rsformAPI'; -import { prefixes } from '../../../utils/constants'; -import { describeConstituenta } from '../../../utils/labels'; +import DataTable, { createColumnHelper,IConditionalStyle, VisibilityState } from '@/components/DataTable'; +import ConstituentaBadge from '@/components/Shared/ConstituentaBadge'; +import { useConceptTheme } from '@/context/ThemeContext'; +import useWindowSize from '@/hooks/useWindowSize'; +import { IConstituenta } from '@/models/rsform'; +import { isMockCst } from '@/models/rsformAPI'; +import { prefixes } from '@/utils/constants'; +import { describeConstituenta } from '@/utils/labels'; interface ConstituentsTableProps { items: IConstituenta[] diff --git a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx index cf56780d..02d9ee29 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx @@ -1,7 +1,10 @@ +'use client'; + import { useMemo, useState } from 'react'; -import { useConceptTheme } from '../../../context/ThemeContext'; -import { IConstituenta, IRSForm } from '../../../models/rsform'; +import { useConceptTheme } from '@/context/ThemeContext'; +import { IConstituenta, IRSForm } from '@/models/rsform'; + import ConstituentsSearch from './ConstituentsSearch'; import ConstituentsTable from './ConstituentsTable'; @@ -50,4 +53,4 @@ function ViewConstituents({ expression, baseHeight, schema, activeID, onOpenEdit ); } -export default ViewConstituents; +export default ViewConstituents; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RegisterPage.tsx b/rsconcept/frontend/src/pages/RegisterPage.tsx index a32f6068..b668c12a 100644 --- a/rsconcept/frontend/src/pages/RegisterPage.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage.tsx @@ -1,25 +1,25 @@ +'use client'; + import { useEffect, useState } from 'react'; -import { useLocation } from 'react-router-dom'; import { toast } from 'react-toastify'; -import BackendError from '../components/BackendError'; -import Button from '../components/Common/Button'; -import Checkbox from '../components/Common/Checkbox'; -import ConceptTooltip from '../components/Common/ConceptTooltip'; -import Overlay from '../components/Common/Overlay'; -import SubmitButton from '../components/Common/SubmitButton'; -import TextInput from '../components/Common/TextInput'; -import TextURL from '../components/Common/TextURL'; -import ExpectedAnonymous from '../components/ExpectedAnonymous'; -import { HelpIcon } from '../components/Icons'; -import { useAuth } from '../context/AuthContext'; -import { useConceptNavigation } from '../context/NagivationContext'; -import { type IUserSignupData } from '../models/library'; -import { globalIDs, patterns } from '../utils/constants'; +import Button from '@/components/Common/Button'; +import Checkbox from '@/components/Common/Checkbox'; +import ConceptTooltip from '@/components/Common/ConceptTooltip'; +import Overlay from '@/components/Common/Overlay'; +import SubmitButton from '@/components/Common/SubmitButton'; +import TextInput from '@/components/Common/TextInput'; +import TextURL from '@/components/Common/TextURL'; +import ExpectedAnonymous from '@/components/ExpectedAnonymous'; +import { HelpIcon } from '@/components/Icons'; +import InfoError from '@/components/InfoError'; +import { useAuth } from '@/context/AuthContext'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { type IUserSignupData } from '@/models/library'; +import { globalIDs, patterns } from '@/utils/constants'; function RegisterPage() { - const location = useLocation(); - const { navigateTo, navigateHistory } = useConceptNavigation(); + const router = useConceptNavigation(); const { user, signup, loading, error, setError } = useAuth(); const [username, setUsername] = useState(''); @@ -36,10 +36,10 @@ function RegisterPage() { }, [username, email, password, password2, setError]); function handleCancel() { - if (location.key !== 'default') { - navigateHistory(-1); + if (router.canBack()) { + router.back(); } else { - navigateTo('/library'); + router.push('/library'); } } @@ -55,7 +55,7 @@ function RegisterPage() { last_name: lastName }; signup(data, createdUser => { - navigateTo(`/login?username=${createdUser.username}`); + router.push(`/login?username=${createdUser.username}`); toast.success(`Пользователь успешно создан: ${createdUser.username}`); }); } @@ -93,7 +93,7 @@ function RegisterPage() { pattern={patterns.login} tooltip='Минимум 3 знака. Латинские буквы и цифры. Не может начинаться с цифры' value={username} - dimensions='w-[12rem]' + dimensions='w-[15rem]' onChange={event => setUsername(event.target.value)} /> handleCancel()} />
- {error ? : null} + {error ? : null} ); } -export default RegisterPage; +export default RegisterPage; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx index c10467c2..01794b7e 100644 --- a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx +++ b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx @@ -1,7 +1,12 @@ +import TextURL from '@/components/Common/TextURL'; +import { urls } from '@/utils/constants'; + function RestorePasswordPage() { return ( - Функционал автоматического восстановления пароля не доступен. Обратитесь в адинистратору - ); +
+

Автоматическое восстановление пароля не доступно.

+

Возможно восстановление пароля через обращение на

+
); } -export default RestorePasswordPage; +export default RestorePasswordPage; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx index c2fccb35..ff39b427 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx @@ -1,28 +1,29 @@ +'use client'; + import axios from 'axios'; import { useEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; -import BackendError, { ErrorInfo } from '../../components/BackendError'; -import SubmitButton from '../../components/Common/SubmitButton'; -import TextInput from '../../components/Common/TextInput'; -import { useAuth } from '../../context/AuthContext'; -import { useConceptNavigation } from '../../context/NagivationContext'; -import { IUserUpdatePassword } from '../../models/library'; +import SubmitButton from '@/components/Common/SubmitButton'; +import TextInput from '@/components/Common/TextInput'; +import InfoError, { ErrorData } from '@/components/InfoError'; +import { useAuth } from '@/context/AuthContext'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { IUserUpdatePassword } from '@/models/library'; -function ProcessError({error}: {error: ErrorInfo}): React.ReactElement { +function ProcessError({error}: {error: ErrorData}): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 400) { return ( -
- Неверно введен старый пароль -
- ); +
+ Неверно введен старый пароль +
); } else { - return (); + return (); } } function EditorPassword() { - const { navigateTo } = useConceptNavigation(); + const router = useConceptNavigation(); const { updatePassword, error, setError, loading } = useAuth(); const [oldPassword, setOldPassword] = useState(''); @@ -59,7 +60,7 @@ function EditorPassword() { }; updatePassword(data, () => { toast.success('Изменения сохранены'); - navigateTo('/login'); + router.push('/login'); }); } @@ -106,4 +107,4 @@ function EditorPassword() { ); } -export default EditorPassword; +export default EditorPassword; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx index 30bf65fa..65348df0 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx @@ -1,33 +1,40 @@ -import { useLayoutEffect, useState } from 'react'; +'use client'; + +import { useEffect, useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; -import SubmitButton from '../../components/Common/SubmitButton'; -import TextInput from '../../components/Common/TextInput'; -import { useUserProfile } from '../../context/UserProfileContext'; -import useModificationPrompt from '../../hooks/useModificationPrompt'; -import { IUserUpdateData } from '../../models/library'; +import SubmitButton from '@/components/Common/SubmitButton'; +import TextInput from '@/components/Common/TextInput'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { useUserProfile } from '@/context/UserProfileContext'; +import { IUserUpdateData } from '@/models/library'; function EditorProfile() { const { updateUser, user, processing } = useUserProfile(); + const router = useConceptNavigation(); const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const [first_name, setFirstName] = useState(''); const [last_name, setLastName] = useState(''); - const { isModified, setIsModified } = useModificationPrompt(); - - useLayoutEffect(() => { + const isModified: boolean = useMemo( + () => { if (!user) { - setIsModified(false); - return; + return false; } - setIsModified( + return ( user.email !== email || user.first_name !== first_name || user.last_name !== last_name ); - }, [user, user?.email, user?.first_name, user?.last_name, email, first_name, last_name, setIsModified]); + }, [user, email, first_name, last_name]); + + useEffect( + () => { + router.setIsBlocked(isModified); + return () => router.setIsBlocked(false); + }, [router, isModified]); useLayoutEffect(() => { if (user) { @@ -83,5 +90,4 @@ function EditorProfile() { ); } - export default EditorProfile; - \ No newline at end of file +export default EditorProfile; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx index 764e7f96..e4a6e332 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx @@ -1,15 +1,15 @@ -import RequireAuth from '../../components/RequireAuth'; -import { UserProfileState } from '../../context/UserProfileContext'; +import RequireAuth from '@/components/RequireAuth'; +import { UserProfileState } from '@/context/UserProfileContext'; + import UserTabs from './UserTabs'; function UserProfilePage() { return ( - - - - - - ); + + + + + ); } -export default UserProfilePage; +export default UserProfilePage; \ No newline at end of file diff --git a/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx b/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx index 86d8ef9b..acd025e8 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx @@ -1,13 +1,16 @@ +'use client'; + import { useMemo, useState } from 'react'; -import BackendError from '../../components/BackendError'; -import { ConceptLoader } from '../../components/Common/ConceptLoader'; -import MiniButton from '../../components/Common/MiniButton'; -import Overlay from '../../components/Common/Overlay'; -import { NotSubscribedIcon,SubscribedIcon } from '../../components/Icons'; -import { useAuth } from '../../context/AuthContext'; -import { useLibrary } from '../../context/LibraryContext'; -import { useUserProfile } from '../../context/UserProfileContext'; +import { ConceptLoader } from '@/components/Common/ConceptLoader'; +import MiniButton from '@/components/Common/MiniButton'; +import Overlay from '@/components/Common/Overlay'; +import { NotSubscribedIcon,SubscribedIcon } from '@/components/Icons'; +import InfoError from '@/components/InfoError'; +import { useAuth } from '@/context/AuthContext'; +import { useLibrary } from '@/context/LibraryContext'; +import { useUserProfile } from '@/context/UserProfileContext'; + import EditorPassword from './EditorPassword'; import EditorProfile from './EditorProfile'; import ViewSubscriptions from './ViewSubscriptions'; @@ -27,7 +30,7 @@ function UserTabs() { return ( <> {loading ? : null} - {error ? : null} + {error ? : null} {user ?
diff --git a/rsconcept/frontend/src/pages/UserProfilePage/ViewSubscriptions.tsx b/rsconcept/frontend/src/pages/UserProfilePage/ViewSubscriptions.tsx index b110f0a2..2c36a5a9 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/ViewSubscriptions.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/ViewSubscriptions.tsx @@ -1,9 +1,11 @@ +'use client'; + import { useMemo } from 'react'; import { useIntl } from 'react-intl'; -import DataTable, { createColumnHelper } from '../../components/DataTable'; -import { useConceptNavigation } from '../../context/NagivationContext'; -import { ILibraryItem } from '../../models/library'; +import DataTable, { createColumnHelper } from '@/components/DataTable'; +import { useConceptNavigation } from '@/context/NagivationContext'; +import { ILibraryItem } from '@/models/library'; interface ViewSubscriptionsProps { items: ILibraryItem[] @@ -12,10 +14,10 @@ interface ViewSubscriptionsProps { const columnHelper = createColumnHelper(); function ViewSubscriptions({items}: ViewSubscriptionsProps) { - const { navigateTo } = useConceptNavigation(); + const router = useConceptNavigation(); const intl = useIntl(); - const openRSForm = (item: ILibraryItem) => navigateTo(`/rsforms/${item.id}`); + const openRSForm = (item: ILibraryItem) => router.push(`/rsforms/${item.id}`); const columns = useMemo(() => [ diff --git a/rsconcept/frontend/src/utils/Graph.test.ts b/rsconcept/frontend/src/utils/Graph.test.ts index 40371d6c..8d79ba0c 100644 --- a/rsconcept/frontend/src/utils/Graph.test.ts +++ b/rsconcept/frontend/src/utils/Graph.test.ts @@ -97,5 +97,4 @@ describe('Testing Graph queries', () => { expect(graph.expandInputs([7])).toStrictEqual([]); expect(graph.expandInputs([6])).toStrictEqual([5, 2, 1]); }); - }); \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/Graph.ts b/rsconcept/frontend/src/utils/Graph.ts index 011127ea..aa587c4d 100644 --- a/rsconcept/frontend/src/utils/Graph.ts +++ b/rsconcept/frontend/src/utils/Graph.ts @@ -256,4 +256,4 @@ export class Graph { } }); } -} +} \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/backendAPI.ts b/rsconcept/frontend/src/utils/backendAPI.ts index 96acbdba..84023197 100644 --- a/rsconcept/frontend/src/utils/backendAPI.ts +++ b/rsconcept/frontend/src/utils/backendAPI.ts @@ -5,22 +5,23 @@ import axios, { AxiosError, AxiosRequestConfig } from 'axios'; import { toast } from 'react-toastify'; -import { type ErrorInfo } from '../components/BackendError'; +import { type ErrorData } from '@/components/InfoError'; import { ILexemeData, IResolutionData, ITextRequest, ITextResult, IWordFormPlain -} from '../models/language'; +} from '@/models/language'; import { ICurrentUser, ILibraryItem, ILibraryUpdateData, IUserInfo, IUserLoginData, IUserProfile, IUserSignupData, IUserUpdateData, IUserUpdatePassword -} from '../models/library'; +} from '@/models/library'; import { IConstituentaList, IConstituentaMeta, ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstRenameData, ICstUpdateData, - IRSFormCreateData, IRSFormData, IRSFormUploadData} from '../models/rsform'; -import { IExpressionParse, IRSExpression } from '../models/rslang'; + IRSFormCreateData, IRSFormData, IRSFormUploadData} from '@/models/rsform'; +import { IExpressionParse, IRSExpression } from '@/models/rslang'; + import { buidConstants } from './constants'; const defaultOptions = { @@ -48,7 +49,7 @@ export type DataCallback = (data: ResponseData) => voi interface IFrontRequest { data?: RequestData onSuccess?: DataCallback - onError?: (error: ErrorInfo) => void + onError?: (error: ErrorData) => void setLoading?: (loading: boolean) => void showError?: boolean } @@ -400,4 +401,4 @@ function AxiosPatch( if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); -} +} \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/codemirror.ts b/rsconcept/frontend/src/utils/codemirror.ts index 245cee37..3cdd1b23 100644 --- a/rsconcept/frontend/src/utils/codemirror.ts +++ b/rsconcept/frontend/src/utils/codemirror.ts @@ -5,9 +5,10 @@ import { syntaxTree } from '@codemirror/language'; import { NodeType, Tree, TreeCursor } from '@lezer/common'; import { ReactCodeMirrorRef, SelectionRange } from '@uiw/react-codemirror'; -import { IEntityReference, ISyntacticReference } from '../models/language'; -import { parseGrammemes } from '../models/languageAPI'; -import { IConstituenta } from '../models/rsform'; +import { IEntityReference, ISyntacticReference } from '@/models/language'; +import { parseGrammemes } from '@/models/languageAPI'; +import { IConstituenta } from '@/models/rsform'; + import { colorfgGrammeme,IColorTheme } from './color'; import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels'; @@ -334,4 +335,4 @@ export class CodeMirrorWrapper { this.setSelection(startWord?.from ?? selection.from, endWord?.to ?? selection.to); } } -} +} \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/color.ts b/rsconcept/frontend/src/utils/color.ts index b96f42f5..62fe643b 100644 --- a/rsconcept/frontend/src/utils/color.ts +++ b/rsconcept/frontend/src/utils/color.ts @@ -2,16 +2,16 @@ * Module: Single place for all color definitions in code (see index.css for full defs). */ -import { GramData, Grammeme, NounGrams, PartOfSpeech, VerbGrams } from '../models/language'; -import { GraphColoringScheme } from '../models/miscelanious'; -import { CstClass, ExpressionStatus, IConstituenta } from '../models/rsform'; -import { ISyntaxTreeNode, TokenID } from '../models/rslang'; +import { GramData, Grammeme, NounGrams, PartOfSpeech, VerbGrams } from '@/models/language'; +import { GraphColoringScheme } from '@/models/miscelanious'; +import { CstClass, ExpressionStatus, IConstituenta } from '@/models/rsform'; +import { ISyntaxTreeNode, TokenID } from '@/models/rslang'; /** * Represents application color theme configuration. */ -export interface IColorTheme { +export interface IColorTheme { bgDefault: string bgInput: string bgControls: string diff --git a/rsconcept/frontend/src/utils/constants.ts b/rsconcept/frontend/src/utils/constants.ts index b9fb5ab1..05c11f02 100644 --- a/rsconcept/frontend/src/utils/constants.ts +++ b/rsconcept/frontend/src/utils/constants.ts @@ -94,4 +94,4 @@ export const prefixes = { library_list: 'library-list-', wordform_list: 'wordform-list-', rsedit_btn: 'rsedit-btn-' -}; +}; \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/labels.ts b/rsconcept/frontend/src/utils/labels.ts index 97f8cd26..86c772e0 100644 --- a/rsconcept/frontend/src/utils/labels.ts +++ b/rsconcept/frontend/src/utils/labels.ts @@ -4,10 +4,10 @@ * Label is a short text used to represent an entity. * Description is a long description used in tooltips. */ -import { GramData,Grammeme, ReferenceType } from '../models/language'; -import { CstMatchMode, DependencyMode, HelpTopic, LibraryFilterStrategy } from '../models/miscelanious'; -import { CstClass, CstType, ExpressionStatus, IConstituenta } from '../models/rsform'; -import { IArgumentInfo, IRSErrorDescription, ISyntaxTreeNode, ParsingStatus, RSErrorType, TokenID } from '../models/rslang'; +import { GramData,Grammeme, ReferenceType } from '@/models/language'; +import { CstMatchMode, DependencyMode, HelpTopic, LibraryFilterStrategy } from '@/models/miscelanious'; +import { CstClass, CstType, ExpressionStatus, IConstituenta } from '@/models/rsform'; +import { IArgumentInfo, IRSErrorDescription, ISyntaxTreeNode, ParsingStatus, RSErrorType, TokenID } from '@/models/rslang'; /** * Generates desription for {@link IConstituenta}. @@ -652,5 +652,4 @@ export function describeRSError(error: IRSErrorDescription): string { return `Типизация выражения не соответствует типу конституенты`; } return 'UNKNOWN ERROR'; -} - +} \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/misc.ts b/rsconcept/frontend/src/utils/misc.ts index 8846c3cc..39e43334 100644 --- a/rsconcept/frontend/src/utils/misc.ts +++ b/rsconcept/frontend/src/utils/misc.ts @@ -2,10 +2,11 @@ * Module: miscellaneous static functions to generate UI resources. */ -import { ILibraryItem } from '../models/library'; -import { CstType, IConstituenta, IRSForm } from '../models/rsform'; -import { IRSErrorDescription, RSErrorClass } from '../models/rslang'; -import { inferErrorClass } from '../models/rslangAPI'; +import { ILibraryItem } from '@/models/library'; +import { CstType, IConstituenta, IRSForm } from '@/models/rsform'; +import { IRSErrorDescription, RSErrorClass } from '@/models/rslang'; +import { inferErrorClass } from '@/models/rslangAPI'; + import { labelCstType } from './labels'; export function getCstTypePrefix(type: CstType) { @@ -78,5 +79,4 @@ export function getRSErrorPrefix(error: IRSErrorDescription): string { case RSErrorClass.SEMANTIC: return 'S' + id; case RSErrorClass.UNKNOWN: return 'U' + id; } -} - +} \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/selectors.ts b/rsconcept/frontend/src/utils/selectors.ts index 134c6838..16a76932 100644 --- a/rsconcept/frontend/src/utils/selectors.ts +++ b/rsconcept/frontend/src/utils/selectors.ts @@ -3,10 +3,11 @@ */ import { LayoutTypes } from 'reagraph'; -import { type GramData, Grammeme, ReferenceType } from '../models/language'; -import { grammemeCompare } from '../models/languageAPI'; -import { GraphColoringScheme } from '../models/miscelanious'; -import { CstType } from '../models/rsform'; +import { type GramData, Grammeme, ReferenceType } from '@/models/language'; +import { grammemeCompare } from '@/models/languageAPI'; +import { GraphColoringScheme } from '@/models/miscelanious'; +import { CstType } from '@/models/rsform'; + import { labelGrammeme, labelReferenceType } from './labels'; import { labelCstType } from './labels'; @@ -111,4 +112,4 @@ export const PremadeWordForms = [ { text: 'мн вин', example: 'ручки', grams: [Grammeme.plur, Grammeme.accs] }, { text: 'мн твор', example: 'ручками', grams: [Grammeme.plur, Grammeme.ablt] }, { text: 'мн пред', example: 'ручках', grams: [Grammeme.plur, Grammeme.loct] } -]; +]; \ No newline at end of file diff --git a/rsconcept/frontend/src/utils/utils.tsx b/rsconcept/frontend/src/utils/utils.tsx index 93ac1c2b..2a1efe1c 100644 --- a/rsconcept/frontend/src/utils/utils.tsx +++ b/rsconcept/frontend/src/utils/utils.tsx @@ -2,6 +2,8 @@ * Module: Utility functions. */ +import { AxiosHeaderValue, AxiosResponse } from 'axios'; + /** * Checks if arguments is Node. */ @@ -61,3 +63,21 @@ export function applyPattern(text: string, mapping: { [key: string]: string }, p output += text.substring(posInput); return output; } + +/** + * Check if Axios reponse is html. +*/ +export function isResponseHtml(response?: AxiosResponse) { + if (!response) { + return false; + } + const header = response.headers['content-type'] as AxiosHeaderValue; + if (!header) { + return false; + } + if (typeof header === 'number' || typeof header === 'boolean') { + return false; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call + return header.includes('text/html'); +} \ No newline at end of file diff --git a/rsconcept/frontend/tsconfig.json b/rsconcept/frontend/tsconfig.json index c19291ea..b70781c6 100644 --- a/rsconcept/frontend/tsconfig.json +++ b/rsconcept/frontend/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "es6", "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", + "lib": ["ES2020", "dom", "dom.iterable"], + "module": "esnext", "skipLibCheck": true, "esModuleInterop": true, @@ -19,7 +19,12 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + + "baseUrl": "./src/", + "paths": { + "@/*": ["*"] + }, }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] diff --git a/rsconcept/frontend/vite.config.ts b/rsconcept/frontend/vite.config.ts index 311ff046..fa3dbd7e 100644 --- a/rsconcept/frontend/vite.config.ts +++ b/rsconcept/frontend/vite.config.ts @@ -1,4 +1,5 @@ import react from '@vitejs/plugin-react'; +import path from 'path'; import { defineConfig, loadEnv } from 'vite'; import { dependencies } from './package.json'; @@ -41,6 +42,11 @@ export default (({ mode }: { mode: string }) => { }, }, }, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src') + } } }); });