From 276b6a6be6ecee8f270fc7d5c648acb128a8731c Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:18:20 +0300 Subject: [PATCH] F: Improve lazy loading and hydration --- rsconcept/frontend/src/app/Router.tsx | 56 +++++++++++-------- .../frontend/src/backend/auth/useAuth.tsx | 5 ++ rsconcept/frontend/src/backend/library/api.ts | 2 +- .../src/backend/library/useLibrary.tsx | 13 ++++- .../src/backend/library/useTemplates.tsx | 6 ++ rsconcept/frontend/src/backend/oss/useOSS.tsx | 8 +++ .../frontend/src/backend/rsform/useRSForm.tsx | 8 +++ .../frontend/src/backend/users/useProfile.tsx | 6 ++ .../frontend/src/backend/users/useUsers.tsx | 6 ++ rsconcept/frontend/src/main.tsx | 5 -- .../frontend/src/pages/DatabaseSchemaPage.tsx | 5 +- rsconcept/frontend/src/pages/IconsPage.tsx | 4 +- .../src/pages/LibraryPage/LibraryPage.tsx | 4 +- .../frontend/src/pages/LibraryPage/index.tsx | 2 +- rsconcept/frontend/src/pages/LoginPage.tsx | 5 +- .../src/pages/ManualsPage/ManualsPage.tsx | 15 ++--- .../frontend/src/pages/ManualsPage/index.tsx | 2 +- .../frontend/src/pages/OssPage/OssPage.tsx | 8 +-- .../frontend/src/pages/OssPage/index.tsx | 2 +- .../frontend/src/pages/PasswordChangePage.tsx | 9 +-- .../src/pages/RSFormPage/RSFormPage.tsx | 14 +---- .../frontend/src/pages/RSFormPage/index.tsx | 2 +- .../src/pages/RegisterPage/FormSignup.tsx | 4 +- .../src/pages/RegisterPage/RegisterPage.tsx | 4 +- .../frontend/src/pages/RegisterPage/index.tsx | 2 +- .../src/pages/RestorePasswordPage.tsx | 9 +-- .../pages/UserProfilePage/EditorPassword.tsx | 5 +- .../pages/UserProfilePage/EditorProfile.tsx | 4 +- .../pages/UserProfilePage/UserProfilePage.tsx | 4 +- .../src/pages/UserProfilePage/index.tsx | 2 +- 30 files changed, 118 insertions(+), 103 deletions(-) diff --git a/rsconcept/frontend/src/app/Router.tsx b/rsconcept/frontend/src/app/Router.tsx index 046ce09f..28c8bff2 100644 --- a/rsconcept/frontend/src/app/Router.tsx +++ b/rsconcept/frontend/src/app/Router.tsx @@ -1,30 +1,27 @@ -import React from 'react'; import { createBrowserRouter } from 'react-router'; +import { prefetchAuth } from '@/backend/auth/useAuth'; +import { prefetchLibrary } from '@/backend/library/useLibrary'; +import { prefetchOSS } from '@/backend/oss/useOSS'; +import { prefetchRSForm } from '@/backend/rsform/useRSForm'; +import { prefetchProfile } from '@/backend/users/useProfile'; +import { prefetchUsers } from '@/backend/users/useUsers'; +import Loader from '@/components/ui/Loader'; import CreateItemPage from '@/pages/CreateItemPage'; import HomePage from '@/pages/HomePage'; -import LibraryPage from '@/pages/LibraryPage'; import LoginPage from '@/pages/LoginPage'; import NotFoundPage from '@/pages/NotFoundPage'; -import OssPage from '@/pages/OssPage'; -import RSFormPage from '@/pages/RSFormPage'; import ApplicationLayout from './ApplicationLayout'; import { routes } from './urls'; -const UserProfilePage = React.lazy(() => import('@/pages/UserProfilePage')); -const RestorePasswordPage = React.lazy(() => import('@/pages/RestorePasswordPage')); -const PasswordChangePage = React.lazy(() => import('@/pages/PasswordChangePage')); -const RegisterPage = React.lazy(() => import('@/pages/RegisterPage')); -const ManualsPage = React.lazy(() => import('@/pages/ManualsPage')); -const IconsPage = React.lazy(() => import('@/pages/IconsPage')); -const DatabaseSchemaPage = React.lazy(() => import('@/pages/DatabaseSchemaPage')); - export const Router = createBrowserRouter([ { path: '/', element: , errorElement: , + loader: prefetchAuth, + hydrateFallbackElement: , children: [ { path: '', @@ -40,23 +37,25 @@ export const Router = createBrowserRouter([ }, { path: routes.signup, - element: + lazy: () => import('@/pages/RegisterPage') }, { path: routes.profile, - element: + loader: prefetchProfile, + lazy: () => import('@/pages/UserProfilePage') }, { path: routes.restore_password, - element: + lazy: () => import('@/pages/RestorePasswordPage') }, { path: routes.password_change, - element: + lazy: () => import('@/pages/PasswordChangePage') }, { path: routes.library, - element: + loader: () => Promise.allSettled([prefetchLibrary(), prefetchUsers()]), + lazy: () => import('@/pages/LibraryPage') }, { path: routes.create_schema, @@ -64,24 +63,37 @@ export const Router = createBrowserRouter([ }, { path: `${routes.rsforms}/:id`, - element: + loader: data => prefetchRSForm(parseRSFormURL(data.params.id, data.request.url)), + lazy: () => import('@/pages/RSFormPage') }, { path: `${routes.oss}/:id`, - element: + loader: data => prefetchOSS(parseOssURL(data.params.id)), + lazy: () => import('@/pages/OssPage') }, { path: routes.manuals, - element: + lazy: () => import('@/pages/ManualsPage') }, { path: `${routes.icons}`, - element: + lazy: () => import('@/pages/IconsPage') }, { path: `${routes.database_schema}`, - element: + lazy: () => import('@/pages/DatabaseSchemaPage') } ] } ]); + +// ======= Internals ========= +function parseRSFormURL(id: string | undefined, url: string) { + const params = new URLSearchParams(url.split('?')[1]); + const version = params.get('v'); + return { itemID: id ? Number(id) : undefined, version: version ? Number(version) : undefined }; +} + +function parseOssURL(id: string | undefined) { + return { itemID: id ? Number(id) : undefined }; +} diff --git a/rsconcept/frontend/src/backend/auth/useAuth.tsx b/rsconcept/frontend/src/backend/auth/useAuth.tsx index d04d215b..1aba50c3 100644 --- a/rsconcept/frontend/src/backend/auth/useAuth.tsx +++ b/rsconcept/frontend/src/backend/auth/useAuth.tsx @@ -1,5 +1,6 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; +import { queryClient } from '../queryClient'; import { authApi } from './api'; export function useAuth() { @@ -19,3 +20,7 @@ export function useAuthSuspense() { }); return { user, isAnonymous: user.id === null }; } + +export function prefetchAuth() { + return queryClient.prefetchQuery(authApi.getAuthQueryOptions()); +} diff --git a/rsconcept/frontend/src/backend/library/api.ts b/rsconcept/frontend/src/backend/library/api.ts index b9b04301..be076512 100644 --- a/rsconcept/frontend/src/backend/library/api.ts +++ b/rsconcept/frontend/src/backend/library/api.ts @@ -74,7 +74,7 @@ export const libraryApi = { }, getLibraryQueryOptions: ({ isAdmin }: { isAdmin: boolean }) => queryOptions({ - queryKey: libraryApi.libraryListKey, + queryKey: [...libraryApi.libraryListKey, isAdmin ? 'admin' : 'user'], staleTime: DELAYS.staleMedium, queryFn: meta => axiosGet({ diff --git a/rsconcept/frontend/src/backend/library/useLibrary.tsx b/rsconcept/frontend/src/backend/library/useLibrary.tsx index f7d3c703..b2dcfe9c 100644 --- a/rsconcept/frontend/src/backend/library/useLibrary.tsx +++ b/rsconcept/frontend/src/backend/library/useLibrary.tsx @@ -1,22 +1,29 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useAuthSuspense } from '@/backend/auth/useAuth'; +import { queryClient } from '@/backend/queryClient'; +import { usePreferencesStore } from '@/stores/preferences'; import { libraryApi } from './api'; export function useLibrarySuspense() { + const adminMode = usePreferencesStore(state => state.adminMode); const { user } = useAuthSuspense(); const { data: items } = useSuspenseQuery({ - ...libraryApi.getLibraryQueryOptions({ isAdmin: user?.is_staff ?? false }) + ...libraryApi.getLibraryQueryOptions({ isAdmin: user.is_staff && adminMode }) }); return { items }; } export function useLibrary() { - // NOTE: Using suspense here to avoid duplicated library data requests + const adminMode = usePreferencesStore(state => state.adminMode); const { user } = useAuthSuspense(); const { data: items, isLoading } = useQuery({ - ...libraryApi.getLibraryQueryOptions({ isAdmin: user.is_staff }) + ...libraryApi.getLibraryQueryOptions({ isAdmin: user.is_staff && adminMode }) }); return { items: items ?? [], isLoading }; } + +export function prefetchLibrary() { + return queryClient.prefetchQuery(libraryApi.getLibraryQueryOptions({ isAdmin: false })); +} diff --git a/rsconcept/frontend/src/backend/library/useTemplates.tsx b/rsconcept/frontend/src/backend/library/useTemplates.tsx index 3af2c235..0fa6b7df 100644 --- a/rsconcept/frontend/src/backend/library/useTemplates.tsx +++ b/rsconcept/frontend/src/backend/library/useTemplates.tsx @@ -1,5 +1,7 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; +import { queryClient } from '@/backend/queryClient'; + import { libraryApi } from './api'; export function useTemplatesSuspense() { @@ -15,3 +17,7 @@ export function useTemplates() { }); return { templates: templates ?? [] }; } + +export function prefetchTemplates() { + return queryClient.prefetchQuery(libraryApi.getTemplatesQueryOptions()); +} diff --git a/rsconcept/frontend/src/backend/oss/useOSS.tsx b/rsconcept/frontend/src/backend/oss/useOSS.tsx index b00e8d2f..70c88211 100644 --- a/rsconcept/frontend/src/backend/oss/useOSS.tsx +++ b/rsconcept/frontend/src/backend/oss/useOSS.tsx @@ -4,6 +4,7 @@ import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary'; import { LibraryItemID } from '@/models/library'; import { OssLoader } from '@/models/OssLoader'; +import { queryClient } from '../queryClient'; import { ossApi } from './api'; export function useOss({ itemID }: { itemID?: LibraryItemID }) { @@ -24,3 +25,10 @@ export function useOssSuspense({ itemID }: { itemID: LibraryItemID }) { const schema = new OssLoader(data!, libraryItems).produceOSS(); return { schema }; } + +export function prefetchOSS({ itemID }: { itemID?: LibraryItemID }) { + if (!itemID) { + return null; + } + return queryClient.prefetchQuery(ossApi.getOssQueryOptions({ itemID })); +} diff --git a/rsconcept/frontend/src/backend/rsform/useRSForm.tsx b/rsconcept/frontend/src/backend/rsform/useRSForm.tsx index 027793b9..ea7d03a0 100644 --- a/rsconcept/frontend/src/backend/rsform/useRSForm.tsx +++ b/rsconcept/frontend/src/backend/rsform/useRSForm.tsx @@ -3,6 +3,7 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { LibraryItemID, VersionID } from '@/models/library'; import { RSFormLoader } from '@/models/RSFormLoader'; +import { queryClient } from '../queryClient'; import { rsformsApi } from './api'; export function useRSForm({ itemID, version }: { itemID?: LibraryItemID; version?: VersionID }) { @@ -21,3 +22,10 @@ export function useRSFormSuspense({ itemID, version }: { itemID: LibraryItemID; const schema = new RSFormLoader(data!).produceRSForm(); return { schema }; } + +export function prefetchRSForm({ itemID, version }: { itemID?: LibraryItemID; version?: VersionID }) { + if (!itemID) { + return null; + } + return queryClient.prefetchQuery(rsformsApi.getRSFormQueryOptions({ itemID, version })); +} diff --git a/rsconcept/frontend/src/backend/users/useProfile.tsx b/rsconcept/frontend/src/backend/users/useProfile.tsx index f74802a3..a8cad840 100644 --- a/rsconcept/frontend/src/backend/users/useProfile.tsx +++ b/rsconcept/frontend/src/backend/users/useProfile.tsx @@ -1,5 +1,7 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; +import { queryClient } from '@/backend/queryClient'; + import { usersApi } from './api'; export function useProfile() { @@ -19,3 +21,7 @@ export function useProfileSuspense() { }); return { profile }; } + +export function prefetchProfile() { + return queryClient.prefetchQuery(usersApi.getProfileQueryOptions()); +} diff --git a/rsconcept/frontend/src/backend/users/useUsers.tsx b/rsconcept/frontend/src/backend/users/useUsers.tsx index 18222a1c..cbef4ce6 100644 --- a/rsconcept/frontend/src/backend/users/useUsers.tsx +++ b/rsconcept/frontend/src/backend/users/useUsers.tsx @@ -1,5 +1,7 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; +import { queryClient } from '@/backend/queryClient'; + import { usersApi } from './api'; export function useUsersSuspense() { @@ -15,3 +17,7 @@ export function useUsers() { }); return { users: users ?? [] }; } + +export function prefetchUsers() { + return queryClient.prefetchQuery(usersApi.getUsersQueryOptions()); +} diff --git a/rsconcept/frontend/src/main.tsx b/rsconcept/frontend/src/main.tsx index e28678d9..90bb9b99 100644 --- a/rsconcept/frontend/src/main.tsx +++ b/rsconcept/frontend/src/main.tsx @@ -4,11 +4,6 @@ import { createRoot } from 'react-dom/client'; import App from './app'; import GlobalProviders from './app/GlobalProviders'; -import { authApi } from './backend/auth/api'; -import { queryClient } from './backend/queryClient'; - -// Prefetch auth data -queryClient.prefetchQuery(authApi.getAuthQueryOptions()).catch(console.error); createRoot(document.getElementById('root')!).render( diff --git a/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx b/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx index dec3f68d..0a47cede 100644 --- a/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx +++ b/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx @@ -6,9 +6,8 @@ import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch'; import { useAppLayoutStore, useFitHeight } from '@/stores/appLayout'; import { resources } from '@/utils/constants'; -function DatabaseSchemaPage() { +export function Component() { const hideFooter = useAppLayoutStore(state => state.hideFooter); - const panelHeight = useFitHeight('0px'); useEffect(() => { @@ -26,5 +25,3 @@ function DatabaseSchemaPage() { ); } - -export default DatabaseSchemaPage; diff --git a/rsconcept/frontend/src/pages/IconsPage.tsx b/rsconcept/frontend/src/pages/IconsPage.tsx index 41988ede..fcdf91cc 100644 --- a/rsconcept/frontend/src/pages/IconsPage.tsx +++ b/rsconcept/frontend/src/pages/IconsPage.tsx @@ -3,7 +3,7 @@ // @ts-nocheck import * as icons from '@/components/Icons'; -export function IconsPage() { +export function Component() { const iconsList = Object.keys(icons).filter(key => key.startsWith('Icon')); return (
@@ -19,5 +19,3 @@ export function IconsPage() {
); } - -export default IconsPage; diff --git a/rsconcept/frontend/src/pages/LibraryPage/LibraryPage.tsx b/rsconcept/frontend/src/pages/LibraryPage/LibraryPage.tsx index 051fd2ce..98c4409e 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/LibraryPage.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/LibraryPage.tsx @@ -19,7 +19,7 @@ import TableLibraryItems from './TableLibraryItems'; import ToolbarSearch from './ToolbarSearch'; import ViewSideLocation from './ViewSideLocation'; -function LibraryPage() { +export function LibraryPage() { const { items: libraryItems } = useLibrarySuspense(); const { renameLocation } = useRenameLocation(); @@ -83,5 +83,3 @@ function LibraryPage() { ); } - -export default LibraryPage; diff --git a/rsconcept/frontend/src/pages/LibraryPage/index.tsx b/rsconcept/frontend/src/pages/LibraryPage/index.tsx index e5479bd8..70f15308 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/index.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/index.tsx @@ -1 +1 @@ -export { default } from './LibraryPage'; +export { LibraryPage as Component } from './LibraryPage'; diff --git a/rsconcept/frontend/src/pages/LoginPage.tsx b/rsconcept/frontend/src/pages/LoginPage.tsx index 27ac48e2..f3f73026 100644 --- a/rsconcept/frontend/src/pages/LoginPage.tsx +++ b/rsconcept/frontend/src/pages/LoginPage.tsx @@ -9,7 +9,7 @@ import { urls } from '@/app/urls'; import { useAuthSuspense } from '@/backend/auth/useAuth'; import { useLogin } from '@/backend/auth/useLogin'; import ExpectedAnonymous from '@/components/ExpectedAnonymous'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import SubmitButton from '@/components/ui/SubmitButton'; import TextInput from '@/components/ui/TextInput'; import TextURL from '@/components/ui/TextURL'; @@ -97,7 +97,6 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement { На Портале отсутствует такое сочетание имени пользователя и пароля ); - } else { - return ; } + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/ManualsPage/ManualsPage.tsx b/rsconcept/frontend/src/pages/ManualsPage/ManualsPage.tsx index ac493884..8de7bbb0 100644 --- a/rsconcept/frontend/src/pages/ManualsPage/ManualsPage.tsx +++ b/rsconcept/frontend/src/pages/ManualsPage/ManualsPage.tsx @@ -1,7 +1,5 @@ 'use client'; -import { useCallback } from 'react'; - import { useConceptNavigation } from '@/app/Navigation/NavigationContext'; import { urls } from '@/app/urls'; import useQueryStrings from '@/hooks/useQueryStrings'; @@ -12,19 +10,16 @@ import { PARAMETER } from '@/utils/constants'; import TopicsList from './TopicsList'; import ViewTopic from './ViewTopic'; -function ManualsPage() { +export function ManualsPage() { const router = useConceptNavigation(); const query = useQueryStrings(); const activeTopic = (query.get('topic') || HelpTopic.MAIN) as HelpTopic; const mainHeight = useMainHeight(); - const onSelectTopic = useCallback( - (newTopic: HelpTopic) => { - router.push(urls.help_topic(newTopic)); - }, - [router] - ); + function onSelectTopic(newTopic: HelpTopic) { + router.push(urls.help_topic(newTopic)); + } if (!Object.values(HelpTopic).includes(activeTopic)) { setTimeout(() => { @@ -40,5 +35,3 @@ function ManualsPage() { ); } - -export default ManualsPage; diff --git a/rsconcept/frontend/src/pages/ManualsPage/index.tsx b/rsconcept/frontend/src/pages/ManualsPage/index.tsx index 948b0de9..9ac8f78a 100644 --- a/rsconcept/frontend/src/pages/ManualsPage/index.tsx +++ b/rsconcept/frontend/src/pages/ManualsPage/index.tsx @@ -1 +1 @@ -export { default } from './ManualsPage'; +export { ManualsPage as Component } from './ManualsPage'; diff --git a/rsconcept/frontend/src/pages/OssPage/OssPage.tsx b/rsconcept/frontend/src/pages/OssPage/OssPage.tsx index ae870bfd..30bebf4f 100644 --- a/rsconcept/frontend/src/pages/OssPage/OssPage.tsx +++ b/rsconcept/frontend/src/pages/OssPage/OssPage.tsx @@ -6,14 +6,14 @@ import { useParams } from 'react-router'; import { useBlockNavigation, useConceptNavigation } from '@/app/Navigation/NavigationContext'; import { urls } from '@/app/urls'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import TextURL from '@/components/ui/TextURL'; import { useModificationStore } from '@/stores/modification'; import { OssEditState } from './OssEditContext'; import OssTabs from './OssTabs'; -function OssPage() { +export function OssPage() { const router = useConceptNavigation(); const params = useParams(); const itemID = params.id ? Number(params.id) : undefined; @@ -35,8 +35,6 @@ function OssPage() { ); } -export default OssPage; - // ====== Internals ========= function ProcessError({ error }: { error: ErrorData }): React.ReactElement { if (axios.isAxiosError(error) && error.response) { @@ -58,5 +56,5 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement { ); } } - return ; + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/OssPage/index.tsx b/rsconcept/frontend/src/pages/OssPage/index.tsx index 9f0c59d7..45263180 100644 --- a/rsconcept/frontend/src/pages/OssPage/index.tsx +++ b/rsconcept/frontend/src/pages/OssPage/index.tsx @@ -1 +1 @@ -export { default } from './OssPage'; +export { OssPage as Component } from './OssPage'; diff --git a/rsconcept/frontend/src/pages/PasswordChangePage.tsx b/rsconcept/frontend/src/pages/PasswordChangePage.tsx index f4d36b92..aa7ee837 100644 --- a/rsconcept/frontend/src/pages/PasswordChangePage.tsx +++ b/rsconcept/frontend/src/pages/PasswordChangePage.tsx @@ -8,13 +8,13 @@ import { useConceptNavigation } from '@/app/Navigation/NavigationContext'; import { urls } from '@/app/urls'; import { IResetPasswordDTO } from '@/backend/auth/api'; import { useResetPassword } from '@/backend/auth/useResetPassword'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import Loader from '@/components/ui/Loader'; import SubmitButton from '@/components/ui/SubmitButton'; import TextInput from '@/components/ui/TextInput'; import useQueryStrings from '@/hooks/useQueryStrings'; -function PasswordChangePage() { +export function Component() { const router = useConceptNavigation(); const token = useQueryStrings().get('token'); @@ -96,13 +96,10 @@ function PasswordChangePage() { ); } -export default PasswordChangePage; - // ====== Internals ========= function ProcessError({ error }: { error: ErrorData }): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 404) { return
Данная ссылка не действительна
; - } else { - return ; } + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx index c7d51103..39285576 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSFormPage.tsx @@ -16,7 +16,7 @@ import { useModificationStore } from '@/stores/modification'; import { RSEditState, RSTabID } from './RSEditContext'; import RSTabs from './RSTabs'; -function RSFormPage() { +export function RSFormPage() { const router = useConceptNavigation(); const query = useQueryStrings(); const params = useParams(); @@ -33,7 +33,6 @@ function RSFormPage() { } return ( ( )} @@ -45,16 +44,7 @@ function RSFormPage() { ); } -export default RSFormPage; - // ====== Internals ========= -const filterErrors = (error: Error) => { - if (axios.isAxiosError(error) && error.response && (error.response.status === 404 || error.response.status === 403)) { - return; - } - throw error; -}; - function ProcessError({ error, isArchive, @@ -85,5 +75,5 @@ function ProcessError({ ); } } - return null; + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/RSFormPage/index.tsx b/rsconcept/frontend/src/pages/RSFormPage/index.tsx index aa0dd14e..41e5359e 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/index.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/index.tsx @@ -1 +1 @@ -export { default } from './RSFormPage'; +export { RSFormPage as Component } from './RSFormPage'; diff --git a/rsconcept/frontend/src/pages/RegisterPage/FormSignup.tsx b/rsconcept/frontend/src/pages/RegisterPage/FormSignup.tsx index 21684d34..e821c132 100644 --- a/rsconcept/frontend/src/pages/RegisterPage/FormSignup.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage/FormSignup.tsx @@ -8,7 +8,7 @@ import { useConceptNavigation } from '@/app/Navigation/NavigationContext'; import { urls } from '@/app/urls'; import { useSignup } from '@/backend/users/useSignup'; import { IconHelp } from '@/components/Icons'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import Button from '@/components/ui/Button'; import Checkbox from '@/components/ui/Checkbox'; import FlexColumn from '@/components/ui/FlexColumn'; @@ -188,5 +188,5 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement { ); } } - return ; + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/RegisterPage/RegisterPage.tsx b/rsconcept/frontend/src/pages/RegisterPage/RegisterPage.tsx index 9712e1bb..6ab372dd 100644 --- a/rsconcept/frontend/src/pages/RegisterPage/RegisterPage.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage/RegisterPage.tsx @@ -3,7 +3,7 @@ import ExpectedAnonymous from '@/components/ExpectedAnonymous'; import FormSignup from './FormSignup'; -function RegisterPage() { +export function RegisterPage() { const { user } = useAuthSuspense(); if (user) { @@ -12,5 +12,3 @@ function RegisterPage() { return ; } } - -export default RegisterPage; diff --git a/rsconcept/frontend/src/pages/RegisterPage/index.tsx b/rsconcept/frontend/src/pages/RegisterPage/index.tsx index 1b9629b7..12d186bd 100644 --- a/rsconcept/frontend/src/pages/RegisterPage/index.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage/index.tsx @@ -1 +1 @@ -export { default } from './RegisterPage'; +export { RegisterPage as Component } from './RegisterPage'; diff --git a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx index 161e4549..5aa3b7d7 100644 --- a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx +++ b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx @@ -5,12 +5,12 @@ import clsx from 'clsx'; import { useEffect, useState } from 'react'; import { useRequestPasswordReset } from '@/backend/auth/useRequestPasswordReset'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import SubmitButton from '@/components/ui/SubmitButton'; import TextInput from '@/components/ui/TextInput'; import TextURL from '@/components/ui/TextURL'; -function RestorePasswordPage() { +export function Component() { const { requestPasswordReset, isPending, error, reset } = useRequestPasswordReset(); const [isCompleted, setIsCompleted] = useState(false); @@ -60,15 +60,12 @@ function RestorePasswordPage() { } } -export default RestorePasswordPage; - // ====== Internals ========= function ProcessError({ error }: { error: ErrorData }): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 400) { return (
Данный email не используется на Портале.
); - } else { - return ; } + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx index 8006aeac..2e6a2017 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx @@ -9,7 +9,7 @@ import { useConceptNavigation } from '@/app/Navigation/NavigationContext'; import { urls } from '@/app/urls'; import { IChangePasswordDTO } from '@/backend/auth/api'; import { useChangePassword } from '@/backend/auth/useChangePassword'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import FlexColumn from '@/components/ui/FlexColumn'; import SubmitButton from '@/components/ui/SubmitButton'; import TextInput from '@/components/ui/TextInput'; @@ -97,7 +97,6 @@ export default EditorPassword; function ProcessError({ error }: { error: ErrorData }): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 400) { return
Неверно введен старый пароль
; - } else { - return ; } + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx index 41b0c6ec..95a340c4 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx @@ -7,7 +7,7 @@ import { useBlockNavigation } from '@/app/Navigation/NavigationContext'; import { IUpdateProfileDTO } from '@/backend/users/api'; import { useProfileSuspense } from '@/backend/users/useProfile'; import { useUpdateProfile } from '@/backend/users/useUpdateProfile'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; +import { ErrorData } from '@/components/info/InfoError'; import SubmitButton from '@/components/ui/SubmitButton'; import TextInput from '@/components/ui/TextInput'; @@ -99,5 +99,5 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement { ); } } - return ; + throw error as Error; } diff --git a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx index 693b5aec..1aa936dc 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx @@ -3,7 +3,7 @@ import RequireAuth from '@/components/RequireAuth'; import EditorPassword from './EditorPassword'; import EditorProfile from './EditorProfile'; -function UserProfilePage() { +export function UserProfilePage() { return (
@@ -16,5 +16,3 @@ function UserProfilePage() { ); } - -export default UserProfilePage; diff --git a/rsconcept/frontend/src/pages/UserProfilePage/index.tsx b/rsconcept/frontend/src/pages/UserProfilePage/index.tsx index 29ca9916..0d6aed96 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/index.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/index.tsx @@ -1 +1 @@ -export { default } from './UserProfilePage'; +export { UserProfilePage as Component } from './UserProfilePage';