diff --git a/rsconcept/frontend/src/pages/LoginPage.tsx b/rsconcept/frontend/src/pages/LoginPage.tsx index ece4bd3c..ea875c9f 100644 --- a/rsconcept/frontend/src/pages/LoginPage.tsx +++ b/rsconcept/frontend/src/pages/LoginPage.tsx @@ -17,18 +17,6 @@ import useQueryStrings from '@/hooks/useQueryStrings'; import { IUserLoginData } from '@/models/user'; import { resources } from '@/utils/constants'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 400) { - return ( -
- На Портале отсутствует такое сочетание имени пользователя и пароля -
- ); - } else { - return ; - } -} - function LoginPage() { const router = useConceptNavigation(); const query = useQueryStrings(); @@ -105,3 +93,16 @@ function LoginPage() { } export default LoginPage; + +// ====== Internals ========= +function ProcessError({ error }: { error: ErrorData }): React.ReactElement { + if (axios.isAxiosError(error) && error.response && error.response.status === 400) { + return ( +
+ На Портале отсутствует такое сочетание имени пользователя и пароля +
+ ); + } else { + return ; + } +} diff --git a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx index 5b1be546..8bf50c57 100644 --- a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx +++ b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx @@ -1,13 +1,9 @@ 'use client'; -import axios from 'axios'; import { AnimatePresence } from 'framer-motion'; import { createContext, useCallback, useContext, useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; -import Loader from '@/components/ui/Loader'; -import TextURL from '@/components/ui/TextURL'; import { useAccessMode } from '@/context/AccessModeContext'; import { useAuth } from '@/context/AuthContext'; import { useConceptOptions } from '@/context/OptionsContext'; @@ -174,25 +170,7 @@ export const OssEditState = ({ children }: OssEditStateProps) => { ) : null} - {model.loading ? : null} - {model.errorLoading ? : null} - {model.schema && !model.loading ? children : null} + {children} ); }; - -// ====== Internals ========= -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 404) { - return ( -
-

{`Схема с указанным идентификатором отсутствует`}

-
- -
-
- ); - } else { - return ; - } -} diff --git a/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx b/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx index 2a3188ed..460b605c 100644 --- a/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx +++ b/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx @@ -1,12 +1,16 @@ 'use client'; +import axios from 'axios'; import clsx from 'clsx'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { TabList, TabPanel, Tabs } from 'react-tabs'; import { toast } from 'react-toastify'; import { urls } from '@/app/urls'; +import InfoError, { ErrorData } from '@/components/info/InfoError'; +import Loader from '@/components/ui/Loader'; import TabLabel from '@/components/ui/TabLabel'; +import TextURL from '@/components/ui/TextURL'; import AnimateFade from '@/components/wrap/AnimateFade'; import { useLibrary } from '@/context/LibraryContext'; import { useBlockNavigation, useConceptNavigation } from '@/context/NavigationContext'; @@ -30,7 +34,7 @@ function OssTabs() { const activeTab = (Number(query.get('tab')) ?? OssTabID.CARD) as OssTabID; const { calculateHeight } = useConceptOptions(); - const { schema, loading } = useOSS(); + const { schema, loading, errorLoading } = useOSS(); const { destroyItem } = useLibrary(); const [isModified, setIsModified] = useState(false); @@ -115,6 +119,8 @@ function OssTabs() { return ( + {loading ? : null} + {errorLoading ? : null} {schema && !loading ? ( +

{`Схема с указанным идентификатором отсутствует`}

+
+ +
+ + ); + } else if (error.response.status === 403) { + return ( +
+

Владелец ограничил доступ к данной схеме

+ +
+ ); + } + } + return ; +} diff --git a/rsconcept/frontend/src/pages/OssPage/ProcessError.tsx b/rsconcept/frontend/src/pages/OssPage/ProcessError.tsx new file mode 100644 index 00000000..9cca24f0 --- /dev/null +++ b/rsconcept/frontend/src/pages/OssPage/ProcessError.tsx @@ -0,0 +1,27 @@ +'use client'; +import axios from 'axios'; +import { ErrorData } from '@/components/info/InfoError'; +import TextURL from '@/components/ui/TextURL'; + +function ProcessError({ error }: { error: ErrorData }): React.ReactElement { + if (axios.isAxiosError(error) && error.response) { + if (error.response.status === 404) { + return ( +
+

{`Схема с указанным идентификатором отсутствует`}

+
+ +
+
+ ); + } else if (error.response.status === 403) { + return ( +
+

Владелец ограничил доступ к данной схеме

+ +
+ ); + } + } + return ; +} diff --git a/rsconcept/frontend/src/pages/PasswordChangePage.tsx b/rsconcept/frontend/src/pages/PasswordChangePage.tsx index e6128010..49ca49a4 100644 --- a/rsconcept/frontend/src/pages/PasswordChangePage.tsx +++ b/rsconcept/frontend/src/pages/PasswordChangePage.tsx @@ -14,14 +14,6 @@ import { useConceptNavigation } from '@/context/NavigationContext'; import useQueryStrings from '@/hooks/useQueryStrings'; import { IPasswordTokenData, IResetPasswordData } from '@/models/user'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 404) { - return
Данная ссылка не действительна
; - } else { - return ; - } -} - function PasswordChangePage() { const router = useConceptNavigation(); const token = useQueryStrings().get('token'); @@ -117,3 +109,12 @@ 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 ; + } +} diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx index 63b5e09f..d774a8cb 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx @@ -1,16 +1,11 @@ 'use client'; -import axios from 'axios'; import { AnimatePresence } from 'framer-motion'; import fileDownload from 'js-file-download'; import { createContext, useCallback, useContext, useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; import { urls } from '@/app/urls'; -import InfoError, { ErrorData } from '@/components/info/InfoError'; -import Divider from '@/components/ui/Divider'; -import Loader from '@/components/ui/Loader'; -import TextURL from '@/components/ui/TextURL'; import { useAccessMode } from '@/context/AccessModeContext'; import { useAuth } from '@/context/AuthContext'; import { useConceptNavigation } from '@/context/NavigationContext'; @@ -719,41 +714,12 @@ export const RSEditState = ({ ) : null} - {model.loading ? : null} - {model.errorLoading ? ( - - ) : null} - {model.schema && !model.loading ? children : null} + {children} ); }; // ====== Internals ========= -function ProcessError({ - error, - isArchive, - itemID -}: { - error: ErrorData; - isArchive: boolean; - itemID: string; -}): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 404) { - return ( -
-

{`Схема с указанным идентификатором ${isArchive ? 'и версией ' : ''}отсутствует`}

-
- - {isArchive ? : null} - {isArchive ? : null} -
-
- ); - } else { - return ; - } -} - function getNextActiveOnDelete( activeID: ConstituentaID | undefined, items: IConstituenta[], diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx index e40f5877..89c2c4b1 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx @@ -1,12 +1,17 @@ 'use client'; +import axios from 'axios'; import clsx from 'clsx'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { TabList, TabPanel, Tabs } from 'react-tabs'; import { toast } from 'react-toastify'; import { urls } from '@/app/urls'; +import InfoError, { ErrorData } from '@/components/info/InfoError'; +import Divider from '@/components/ui/Divider'; +import Loader from '@/components/ui/Loader'; import TabLabel from '@/components/ui/TabLabel'; +import TextURL from '@/components/ui/TextURL'; import AnimateFade from '@/components/wrap/AnimateFade'; import { useLibrary } from '@/context/LibraryContext'; import { useBlockNavigation, useConceptNavigation } from '@/context/NavigationContext'; @@ -39,7 +44,7 @@ function RSTabs() { const cstQuery = query.get('active'); const { setNoFooter, calculateHeight } = useConceptOptions(); - const { schema, loading } = useRSForm(); + const { schema, loading, errorLoading, isArchive, itemID } = useRSForm(); const { destroyItem } = useLibrary(); const [isModified, setIsModified] = useState(false); @@ -233,13 +238,15 @@ function RSTabs() { onCreateCst={onCreateCst} onDeleteCst={onDeleteCst} > + {loading ? : null} + {errorLoading ? : null} {schema && !loading ? ( @@ -269,3 +276,37 @@ function RSTabs() { } export default RSTabs; + +// ====== Internals ========= +function ProcessError({ + error, + isArchive, + itemID +}: { + error: ErrorData; + isArchive: boolean; + itemID: string; +}): React.ReactElement { + if (axios.isAxiosError(error) && error.response) { + if (error.response.status === 404) { + return ( +
+

{`Схема с указанным идентификатором ${isArchive ? 'и версией ' : ''}отсутствует`}

+
+ + {isArchive ? : null} + {isArchive ? : null} +
+
+ ); + } else if (error.response.status === 403) { + return ( +
+

Владелец ограничил доступ к данной схеме

+ +
+ ); + } + } + return ; +} diff --git a/rsconcept/frontend/src/pages/RegisterPage.tsx b/rsconcept/frontend/src/pages/RegisterPage.tsx index 1fadf108..ecf60832 100644 --- a/rsconcept/frontend/src/pages/RegisterPage.tsx +++ b/rsconcept/frontend/src/pages/RegisterPage.tsx @@ -25,24 +25,6 @@ import { HelpTopic } from '@/models/miscellaneous'; import { IUserSignupData } from '@/models/user'; import { globals, patterns } from '@/utils/constants'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 400) { - if ('email' in error.response.data) { - return ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -
{error.response.data.email}.
- ); - } else { - return ( -
- -
- ); - } - } - return ; -} - function RegisterPage() { const router = useConceptNavigation(); const { user, signup, loading, error, setError } = useAuth(); @@ -203,3 +185,22 @@ function RegisterPage() { } export default RegisterPage; + +// ====== Internals ========= +function ProcessError({ error }: { error: ErrorData }): React.ReactElement { + if (axios.isAxiosError(error) && error.response && error.response.status === 400) { + if ('email' in error.response.data) { + return ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +
{error.response.data.email}.
+ ); + } else { + return ( +
+ +
+ ); + } + } + return ; +} diff --git a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx index 5bb74b94..beaef1f0 100644 --- a/rsconcept/frontend/src/pages/RestorePasswordPage.tsx +++ b/rsconcept/frontend/src/pages/RestorePasswordPage.tsx @@ -12,14 +12,6 @@ import AnimateFade from '@/components/wrap/AnimateFade'; import { useAuth } from '@/context/AuthContext'; import { IRequestPasswordData } from '@/models/user'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 400) { - return
Данный email не используется на Портале.
; - } else { - return ; - } -} - function RestorePasswordPage() { const { requestPasswordReset, loading, error, setError } = useAuth(); @@ -73,3 +65,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 ; + } +} diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx index 07df7f73..890a7972 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorPassword.tsx @@ -14,14 +14,6 @@ import { useAuth } from '@/context/AuthContext'; import { useConceptNavigation } from '@/context/NavigationContext'; import { IUserUpdatePassword } from '@/models/user'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 400) { - return
Неверно введен старый пароль
; - } else { - return ; - } -} - function EditorPassword() { const router = useConceptNavigation(); const { updatePassword, error, setError, loading } = useAuth(); @@ -109,3 +101,12 @@ function EditorPassword() { } export default EditorPassword; + +// ====== Internals ========= +function ProcessError({ error }: { error: ErrorData }): React.ReactElement { + if (axios.isAxiosError(error) && error.response && error.response.status === 400) { + return
Неверно введен старый пароль
; + } else { + return ; + } +} diff --git a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx index bc94bc93..4b06b5aa 100644 --- a/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx +++ b/rsconcept/frontend/src/pages/UserProfilePage/EditorProfile.tsx @@ -12,18 +12,6 @@ import { useBlockNavigation } from '@/context/NavigationContext'; import { useUserProfile } from '@/context/UserProfileContext'; import { IUserUpdateData } from '@/models/user'; -function ProcessError({ error }: { error: ErrorData }): React.ReactElement { - if (axios.isAxiosError(error) && error.response && error.response.status === 400) { - if ('email' in error.response.data) { - return ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -
{error.response.data.email}.
- ); - } - } - return ; -} - function EditorProfile() { const { updateUser, user, errorProcessing, processing } = useUserProfile(); @@ -106,3 +94,16 @@ function EditorProfile() { } export default EditorProfile; + +// ====== Internals ========= +function ProcessError({ error }: { error: ErrorData }): React.ReactElement { + if (axios.isAxiosError(error) && error.response && error.response.status === 400) { + if ('email' in error.response.data) { + return ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +
{error.response.data.email}.
+ ); + } + } + return ; +}