mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-13 06:34:39 -04:00
feat(async-loading-boundary): extract custom error component into separate component
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
6eb6b6a25f
commit
26c1f1bcaa
17 changed files with 265 additions and 37 deletions
|
@ -0,0 +1,41 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Async loading boundary shows a waiting spinner if loading 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="m-3 d-flex align-items-center justify-content-center"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-spinner fa-spin "
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Async loading boundary shows an error if error is given with loading 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="fade alert alert-danger show"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
common.errorWhileLoading
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Async loading boundary shows an error if error is given without loading 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="fade alert alert-danger show"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
common.errorWhileLoading
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Async loading boundary shows the children if not loading and no error 1`] = `
|
||||||
|
<div>
|
||||||
|
children
|
||||||
|
</div>
|
||||||
|
`;
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Custom error async loading boundary shows a waiting spinner if loading 1`] = `
|
||||||
|
<div>
|
||||||
|
wait
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Custom error async loading boundary shows an error if error is given with loading 1`] = `
|
||||||
|
<div>
|
||||||
|
error
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Custom error async loading boundary shows an error if error is given without loading 1`] = `
|
||||||
|
<div>
|
||||||
|
error
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Custom error async loading boundary shows the children if not loading and no error 1`] = `
|
||||||
|
<div>
|
||||||
|
children
|
||||||
|
</div>
|
||||||
|
`;
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { mockI18n } from '../../markdown-renderer/test-utils/mock-i18n'
|
||||||
|
import { AsyncLoadingBoundary } from './async-loading-boundary'
|
||||||
|
import { render } from '@testing-library/react'
|
||||||
|
|
||||||
|
describe('Async loading boundary', () => {
|
||||||
|
beforeAll(() => mockI18n())
|
||||||
|
|
||||||
|
it('shows the children if not loading and no error', () => {
|
||||||
|
const view = render(
|
||||||
|
<AsyncLoadingBoundary loading={false} componentName={'test'}>
|
||||||
|
children
|
||||||
|
</AsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows a waiting spinner if loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<AsyncLoadingBoundary loading={true} componentName={'test'}>
|
||||||
|
children
|
||||||
|
</AsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error if error is given without loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<AsyncLoadingBoundary loading={false} error={new Error('error')} componentName={'test'}>
|
||||||
|
children
|
||||||
|
</AsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error if error is given with loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<AsyncLoadingBoundary loading={true} error={new Error('error')} componentName={'test'}>
|
||||||
|
children
|
||||||
|
</AsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
|
@ -3,9 +3,10 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { WaitSpinner } from './wait-spinner/wait-spinner'
|
import { WaitSpinner } from '../wait-spinner/wait-spinner'
|
||||||
import type { PropsWithChildren, ReactNode } from 'react'
|
import { CustomAsyncLoadingBoundary } from './custom-async-loading-boundary'
|
||||||
import React, { Fragment } from 'react'
|
import type { PropsWithChildren } from 'react'
|
||||||
|
import React, { Fragment, useMemo } from 'react'
|
||||||
import { Alert } from 'react-bootstrap'
|
import { Alert } from 'react-bootstrap'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
@ -13,7 +14,6 @@ export interface AsyncLoadingBoundaryProps {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
error?: Error | boolean
|
error?: Error | boolean
|
||||||
componentName: string
|
componentName: string
|
||||||
errorComponent?: ReactNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,22 +30,27 @@ export const AsyncLoadingBoundary: React.FC<PropsWithChildren<AsyncLoadingBounda
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
componentName,
|
componentName,
|
||||||
errorComponent,
|
|
||||||
children
|
children
|
||||||
}) => {
|
}) => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
if (error !== undefined && error !== false) {
|
|
||||||
if (errorComponent) {
|
const errorComponent = useMemo(() => {
|
||||||
return <Fragment>{errorComponent}</Fragment>
|
return error ? (
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Alert variant={'danger'}>
|
<Alert variant={'danger'}>
|
||||||
<Trans i18nKey={'common.errorWhileLoading'} values={{ name: componentName }} />
|
<Trans i18nKey={'common.errorWhileLoading'} values={{ name: componentName }} />
|
||||||
</Alert>
|
</Alert>
|
||||||
|
) : (
|
||||||
|
<Fragment></Fragment>
|
||||||
|
)
|
||||||
|
}, [componentName, error])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomAsyncLoadingBoundary
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
errorComponent={errorComponent}
|
||||||
|
loadingComponent={<WaitSpinner />}>
|
||||||
|
{children}
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
)
|
)
|
||||||
} else if (loading) {
|
|
||||||
return <WaitSpinner />
|
|
||||||
} else {
|
|
||||||
return <Fragment>{children}</Fragment>
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { mockI18n } from '../../markdown-renderer/test-utils/mock-i18n'
|
||||||
|
import { CustomAsyncLoadingBoundary } from './custom-async-loading-boundary'
|
||||||
|
import { render } from '@testing-library/react'
|
||||||
|
|
||||||
|
describe('Custom error async loading boundary', () => {
|
||||||
|
beforeAll(() => mockI18n())
|
||||||
|
|
||||||
|
it('shows the children if not loading and no error', () => {
|
||||||
|
const view = render(
|
||||||
|
<CustomAsyncLoadingBoundary loading={false} errorComponent={'error'} loadingComponent={'wait'}>
|
||||||
|
children
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows a waiting spinner if loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<CustomAsyncLoadingBoundary loading={true} errorComponent={'error'} loadingComponent={'wait'}>
|
||||||
|
children
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error if error is given without loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<CustomAsyncLoadingBoundary
|
||||||
|
loading={false}
|
||||||
|
error={new Error('error')}
|
||||||
|
errorComponent={'error'}
|
||||||
|
loadingComponent={'wait'}>
|
||||||
|
children
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error if error is given with loading', () => {
|
||||||
|
const view = render(
|
||||||
|
<CustomAsyncLoadingBoundary
|
||||||
|
loading={true}
|
||||||
|
error={new Error('error')}
|
||||||
|
errorComponent={'error'}
|
||||||
|
loadingComponent={'wait'}>
|
||||||
|
children
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import type { PropsWithChildren, ReactNode } from 'react'
|
||||||
|
import React, { Fragment } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
export interface CustomErrorAsyncLoadingBoundaryProps {
|
||||||
|
loading: boolean
|
||||||
|
error?: Error | boolean
|
||||||
|
errorComponent: ReactNode
|
||||||
|
loadingComponent: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a component currently loading or an error occurred.
|
||||||
|
* It's meant to be used in combination with useAsync from react-use.
|
||||||
|
*
|
||||||
|
* @param loading Indicates that the component is currently loading. Setting this will show a spinner instead of the children.
|
||||||
|
* @param error Indicates that an error occurred during the loading process. Setting this to any non-null value will show an error message instead of the children.
|
||||||
|
* @param componentName The name of the component that is currently loading. It will be shown in the error message.
|
||||||
|
* @param errorComponent Optional component that will be used in case of an error instead of the default alert message.
|
||||||
|
* @param children The child {@link ReactElement elements} that are only shown if the component isn't in loading or error state
|
||||||
|
*/
|
||||||
|
export const CustomAsyncLoadingBoundary: React.FC<PropsWithChildren<CustomErrorAsyncLoadingBoundaryProps>> = ({
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
errorComponent,
|
||||||
|
loadingComponent,
|
||||||
|
children
|
||||||
|
}) => {
|
||||||
|
useTranslation()
|
||||||
|
if (error) {
|
||||||
|
return <Fragment>{errorComponent}</Fragment>
|
||||||
|
} else if (loading) {
|
||||||
|
return <Fragment>{loadingComponent}</Fragment>
|
||||||
|
} else {
|
||||||
|
return <Fragment>{children}</Fragment>
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,12 @@
|
||||||
*/
|
*/
|
||||||
import { LoadingScreen } from '../../application-loader/loading-screen/loading-screen'
|
import { LoadingScreen } from '../../application-loader/loading-screen/loading-screen'
|
||||||
import { CommonErrorPage } from '../../error-pages/common-error-page'
|
import { CommonErrorPage } from '../../error-pages/common-error-page'
|
||||||
|
import { CustomAsyncLoadingBoundary } from '../async-loading-boundary/custom-async-loading-boundary'
|
||||||
import { ShowIf } from '../show-if/show-if'
|
import { ShowIf } from '../show-if/show-if'
|
||||||
import { CreateNonExistingNoteHint } from './create-non-existing-note-hint'
|
import { CreateNonExistingNoteHint } from './create-non-existing-note-hint'
|
||||||
import { useLoadNoteFromServer } from './hooks/use-load-note-from-server'
|
import { useLoadNoteFromServer } from './hooks/use-load-note-from-server'
|
||||||
import type { PropsWithChildren } from 'react'
|
import type { PropsWithChildren } from 'react'
|
||||||
import React, { Fragment, useEffect } from 'react'
|
import React, { useEffect, useMemo } from 'react'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the note identified by the note-id in the URL.
|
* Loads the note identified by the note-id in the URL.
|
||||||
|
@ -18,16 +19,17 @@ import React, { Fragment, useEffect } from 'react'
|
||||||
*
|
*
|
||||||
* @param children The react elements that will be shown when the loading was successful.
|
* @param children The react elements that will be shown when the loading was successful.
|
||||||
*/
|
*/
|
||||||
export const NoteLoadingBoundary: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
export const NoteLoadingBoundary: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
const [{ error, loading }, loadNoteFromServer] = useLoadNoteFromServer()
|
const [{ error, loading, value }, loadNoteFromServer] = useLoadNoteFromServer()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadNoteFromServer()
|
loadNoteFromServer()
|
||||||
}, [loadNoteFromServer])
|
}, [loadNoteFromServer])
|
||||||
|
|
||||||
if (loading) {
|
const errorComponent = useMemo(() => {
|
||||||
return <LoadingScreen />
|
if (error === undefined) {
|
||||||
} else if (error) {
|
return <></>
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<CommonErrorPage titleI18nKey={`${error.message}.title`} descriptionI18nKey={`${error.message}.description`}>
|
<CommonErrorPage titleI18nKey={`${error.message}.title`} descriptionI18nKey={`${error.message}.description`}>
|
||||||
<ShowIf condition={error.message === 'api.note.notFound'}>
|
<ShowIf condition={error.message === 'api.note.notFound'}>
|
||||||
|
@ -35,7 +37,15 @@ export const NoteLoadingBoundary: React.FC<PropsWithChildren<unknown>> = ({ chil
|
||||||
</ShowIf>
|
</ShowIf>
|
||||||
</CommonErrorPage>
|
</CommonErrorPage>
|
||||||
)
|
)
|
||||||
} else {
|
}, [error, loadNoteFromServer])
|
||||||
return <Fragment>{children}</Fragment>
|
|
||||||
}
|
return (
|
||||||
|
<CustomAsyncLoadingBoundary
|
||||||
|
loading={loading || !value}
|
||||||
|
error={error}
|
||||||
|
errorComponent={errorComponent}
|
||||||
|
loadingComponent={<LoadingScreen />}>
|
||||||
|
{children}
|
||||||
|
</CustomAsyncLoadingBoundary>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
import { getUser } from '../../../api/users'
|
import { getUser } from '../../../api/users'
|
||||||
import type { UserInfo } from '../../../api/users/types'
|
import type { UserInfo } from '../../../api/users/types'
|
||||||
import { AsyncLoadingBoundary } from '../async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../async-loading-boundary/async-loading-boundary'
|
||||||
import type { UserAvatarProps } from './user-avatar'
|
import type { UserAvatarProps } from './user-avatar'
|
||||||
import { UserAvatar } from './user-avatar'
|
import { UserAvatar } from './user-avatar'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
import { getAllRevisions } from '../../../../api/revisions'
|
import { getAllRevisions } from '../../../../api/revisions'
|
||||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||||
import { AsyncLoadingBoundary } from '../../../common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../common/async-loading-boundary/async-loading-boundary'
|
||||||
import { RevisionListEntry } from './revision-list-entry'
|
import { RevisionListEntry } from './revision-list-entry'
|
||||||
import { DateTime } from 'luxon'
|
import { DateTime } from 'luxon'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { getRevision } from '../../../../api/revisions'
|
import { getRevision } from '../../../../api/revisions'
|
||||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||||
import { useDarkModeState } from '../../../../hooks/common/use-dark-mode-state'
|
import { useDarkModeState } from '../../../../hooks/common/use-dark-mode-state'
|
||||||
import { AsyncLoadingBoundary } from '../../../common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../common/async-loading-boundary/async-loading-boundary'
|
||||||
import { invertUnifiedPatch } from './invert-unified-patch'
|
import { invertUnifiedPatch } from './invert-unified-patch'
|
||||||
import { Optional } from '@mrdrogdrog/optional'
|
import { Optional } from '@mrdrogdrog/optional'
|
||||||
import { applyPatch, parsePatch } from 'diff'
|
import { applyPatch, parsePatch } from 'diff'
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { Logger } from '../../utils/logger'
|
import { Logger } from '../../utils/logger'
|
||||||
import { AsyncLoadingBoundary } from '../common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../common/async-loading-boundary/async-loading-boundary'
|
||||||
import { RenderIframe } from '../editor-page/renderer-pane/render-iframe'
|
import { RenderIframe } from '../editor-page/renderer-pane/render-iframe'
|
||||||
import { RendererType } from '../render-page/window-post-message-communicator/rendering-message'
|
import { RendererType } from '../render-page/window-post-message-communicator/rendering-message'
|
||||||
import { fetchFrontPageContent } from './requests'
|
import { fetchFrontPageContent } from './requests'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary'
|
||||||
import { ShowIf } from '../../../components/common/show-if/show-if'
|
import { ShowIf } from '../../../components/common/show-if/show-if'
|
||||||
import { WaitSpinner } from '../../../components/common/wait-spinner/wait-spinner'
|
import { WaitSpinner } from '../../../components/common/wait-spinner/wait-spinner'
|
||||||
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import fontStyles from '../../../../global-styles/variables.module.scss'
|
import fontStyles from '../../../../global-styles/variables.module.scss'
|
||||||
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary'
|
||||||
import { ShowIf } from '../../../components/common/show-if/show-if'
|
import { ShowIf } from '../../../components/common/show-if/show-if'
|
||||||
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
||||||
import { useDarkModeState } from '../../../hooks/common/use-dark-mode-state'
|
import { useDarkModeState } from '../../../hooks/common/use-dark-mode-state'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary'
|
||||||
import { ShowIf } from '../../../components/common/show-if/show-if'
|
import { ShowIf } from '../../../components/common/show-if/show-if'
|
||||||
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
||||||
import { cypressId } from '../../../utils/cypress-attribute'
|
import { cypressId } from '../../../utils/cypress-attribute'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary'
|
||||||
import { CopyToClipboardButton } from '../../../components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button'
|
import { CopyToClipboardButton } from '../../../components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button'
|
||||||
import { cypressAttribute, cypressId } from '../../../utils/cypress-attribute'
|
import { cypressAttribute, cypressId } from '../../../utils/cypress-attribute'
|
||||||
import { testId } from '../../../utils/test-id'
|
import { testId } from '../../../utils/test-id'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary'
|
import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary'
|
||||||
import { ShowIf } from '../../../components/common/show-if/show-if'
|
import { ShowIf } from '../../../components/common/show-if/show-if'
|
||||||
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer'
|
||||||
import { Logger } from '../../../utils/logger'
|
import { Logger } from '../../../utils/logger'
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { createNote } from '../api/notes'
|
import { createNote } from '../api/notes'
|
||||||
import { AsyncLoadingBoundary } from '../components/common/async-loading-boundary'
|
import { LoadingScreen } from '../components/application-loader/loading-screen/loading-screen'
|
||||||
|
import { CustomAsyncLoadingBoundary } from '../components/common/async-loading-boundary/custom-async-loading-boundary'
|
||||||
import { Redirect } from '../components/common/redirect'
|
import { Redirect } from '../components/common/redirect'
|
||||||
import { CommonErrorPage } from '../components/error-pages/common-error-page'
|
import { CommonErrorPage } from '../components/error-pages/common-error-page'
|
||||||
import { useSingleStringUrlParameter } from '../hooks/common/use-single-string-url-parameter'
|
import { useSingleStringUrlParameter } from '../hooks/common/use-single-string-url-parameter'
|
||||||
|
@ -22,10 +23,10 @@ export const NewNotePage: NextPage = () => {
|
||||||
}, [newContent])
|
}, [newContent])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncLoadingBoundary
|
<CustomAsyncLoadingBoundary
|
||||||
loading={loading}
|
loading={loading}
|
||||||
componentName={'NewNotePage'}
|
|
||||||
error={error}
|
error={error}
|
||||||
|
loadingComponent={<LoadingScreen />}
|
||||||
errorComponent={
|
errorComponent={
|
||||||
<CommonErrorPage
|
<CommonErrorPage
|
||||||
titleI18nKey={'errors.noteCreationFailed.title'}
|
titleI18nKey={'errors.noteCreationFailed.title'}
|
||||||
|
@ -33,7 +34,7 @@ export const NewNotePage: NextPage = () => {
|
||||||
/>
|
/>
|
||||||
}>
|
}>
|
||||||
{value ? <Redirect to={`/n/${value.metadata.primaryAddress}`} /> : null}
|
{value ? <Redirect to={`/n/${value.metadata.primaryAddress}`} /> : null}
|
||||||
</AsyncLoadingBoundary>
|
</CustomAsyncLoadingBoundary>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue