mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-22 03:05:19 -04:00
fix: extract app bar into layout slot
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
18a1e79d9f
commit
b3fb1bbf30
35 changed files with 258 additions and 207 deletions
9
frontend/src/app/(editor)/@appBar/cheatsheet/page.tsx
Normal file
9
frontend/src/app/(editor)/@appBar/cheatsheet/page.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export default function AppBar() {
|
||||
return null
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/default.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/default.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { BaseAppBar } from '../../../components/layout/app-bar/base-app-bar'
|
||||
import React from 'react'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar />
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/history/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/history/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React from 'react'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar>History</BaseAppBar>
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/intro/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/intro/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React from 'react'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar>Landing</BaseAppBar>
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/login/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/login/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React from 'react'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar>Login</BaseAppBar>
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`app bar contains alert when editor is not synced 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<span>
|
||||
first part
|
||||
</span>
|
||||
<div>
|
||||
<div
|
||||
class="fade w-100 m-0 px-2 py-1 border-top-0 border-bottom-0 d-flex align-items-center alert alert-warning show"
|
||||
role="alert"
|
||||
>
|
||||
realtime.connecting
|
||||
BootstrapIconMock_ArrowRepeat
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
last part
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`app bar contains note title and read-only marker when having only read permissions 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<span>
|
||||
first part
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="m-0 text-truncate"
|
||||
>
|
||||
<span
|
||||
class="text-secondary me-2"
|
||||
>
|
||||
BootstrapIconMock_Lock
|
||||
</span>
|
||||
Note Title Test
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
last part
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`app bar contains note title when editor is synced 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<span>
|
||||
first part
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="m-0 text-truncate"
|
||||
>
|
||||
Note Title Test
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
last part
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import * as UseApplicationStateModule from '../../../../../hooks/common/use-application-state'
|
||||
import type { ApplicationState } from '../../../../../redux/application-state'
|
||||
import { mockI18n } from '../../../../../test-utils/mock-i18n'
|
||||
import { EditorAppBar } from './editor-app-bar'
|
||||
import type { NoteGroupPermissionEntry, NoteUserPermissionEntry } from '@hedgedoc/commons'
|
||||
import { render } from '@testing-library/react'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
jest.mock('../../../../../components/layout/app-bar/base-app-bar', () => ({
|
||||
__esModule: true,
|
||||
BaseAppBar: ({ children }: PropsWithChildren) => (
|
||||
<div>
|
||||
<span>first part</span>
|
||||
<div>{children}</div>
|
||||
<span>last part</span>
|
||||
</div>
|
||||
)
|
||||
}))
|
||||
jest.mock('../../../../../hooks/common/use-application-state')
|
||||
|
||||
const mockedCommonAppState = {
|
||||
noteDetails: {
|
||||
title: 'Note Title Test',
|
||||
permissions: {
|
||||
owner: 'test',
|
||||
sharedToGroups: [
|
||||
{
|
||||
groupName: '_EVERYONE',
|
||||
canEdit: false
|
||||
}
|
||||
] as NoteGroupPermissionEntry[],
|
||||
sharedToUsers: [] as NoteUserPermissionEntry[]
|
||||
}
|
||||
},
|
||||
user: {
|
||||
username: 'test'
|
||||
}
|
||||
}
|
||||
|
||||
describe('app bar', () => {
|
||||
beforeAll(mockI18n)
|
||||
afterAll(() => jest.restoreAllMocks())
|
||||
|
||||
it('contains note title when editor is synced', () => {
|
||||
jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => {
|
||||
return fn({
|
||||
...mockedCommonAppState,
|
||||
realtimeStatus: {
|
||||
isSynced: true
|
||||
}
|
||||
} as ApplicationState)
|
||||
})
|
||||
const view = render(<EditorAppBar />)
|
||||
expect(view.container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('contains alert when editor is not synced', () => {
|
||||
jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => {
|
||||
return fn({
|
||||
...mockedCommonAppState,
|
||||
realtimeStatus: {
|
||||
isSynced: false
|
||||
}
|
||||
} as ApplicationState)
|
||||
})
|
||||
const view = render(<EditorAppBar />)
|
||||
expect(view.container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('contains note title and read-only marker when having only read permissions', () => {
|
||||
jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => {
|
||||
return fn({
|
||||
...mockedCommonAppState,
|
||||
realtimeStatus: {
|
||||
isSynced: true
|
||||
},
|
||||
user: null
|
||||
} as ApplicationState)
|
||||
})
|
||||
const view = render(<EditorAppBar />)
|
||||
expect(view.container).toMatchSnapshot()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
'use client'
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { RealtimeConnectionAlert } from '../../../../../components/editor-page/realtime-connection-alert/realtime-connection-alert'
|
||||
import { NoteTitleElement } from '../../../../../components/layout/app-bar/app-bar-elements/note-title-element/note-title-element'
|
||||
import { BaseAppBar } from '../../../../../components/layout/app-bar/base-app-bar'
|
||||
import { useApplicationState } from '../../../../../hooks/common/use-application-state'
|
||||
import React from 'react'
|
||||
|
||||
/**
|
||||
* Renders the EditorAppBar that extends the {@link BaseAppBar} with the note title or realtime connection alert.
|
||||
*/
|
||||
export const EditorAppBar: React.FC = () => {
|
||||
const isSynced = useApplicationState((state) => state.realtimeStatus.isSynced)
|
||||
|
||||
return <BaseAppBar>{isSynced ? <NoteTitleElement /> : <RealtimeConnectionAlert />}</BaseAppBar>
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/n/[noteId]/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/n/[noteId]/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { EditorAppBar } from './editor-app-bar'
|
||||
import React from 'react'
|
||||
|
||||
export default function AppBar() {
|
||||
return <EditorAppBar />
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/not-found.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/not-found.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { BaseAppBar } from '../../../components/layout/app-bar/base-app-bar'
|
||||
import React from 'react'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar />
|
||||
}
|
9
frontend/src/app/(editor)/@appBar/p/[noteId]/page.tsx
Normal file
9
frontend/src/app/(editor)/@appBar/p/[noteId]/page.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export default function AppBar() {
|
||||
return null
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/profile/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/profile/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React from 'react'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar>Profile</BaseAppBar>
|
||||
}
|
11
frontend/src/app/(editor)/@appBar/register/page.tsx
Normal file
11
frontend/src/app/(editor)/@appBar/register/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React from 'react'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
|
||||
export default function AppBar() {
|
||||
return <BaseAppBar>Register</BaseAppBar>
|
||||
}
|
16
frontend/src/app/(editor)/@appBar/s/[noteId]/page.tsx
Normal file
16
frontend/src/app/(editor)/@appBar/s/[noteId]/page.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { NoteTitleElement } from '../../../../../components/layout/app-bar/app-bar-elements/note-title-element/note-title-element'
|
||||
import { BaseAppBar } from '../../../../../components/layout/app-bar/base-app-bar'
|
||||
import React from 'react'
|
||||
|
||||
export default function AppBar() {
|
||||
return (
|
||||
<BaseAppBar>
|
||||
<NoteTitleElement />
|
||||
</BaseAppBar>
|
||||
)
|
||||
}
|
|
@ -13,7 +13,7 @@ import { LandingLayout } from '../../../components/landing-layout/landing-layout
|
|||
import type { NextPage } from 'next'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Row } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
/**
|
||||
* The page that shows the local and remote note history.
|
||||
|
@ -29,9 +29,6 @@ const HistoryPage: NextPage = () => {
|
|||
return (
|
||||
<LandingLayout>
|
||||
<HistoryToolbarStateContextProvider>
|
||||
<h1 className='mb-4'>
|
||||
<Trans i18nKey={'landing.navigation.history'} />
|
||||
</h1>
|
||||
<Row className={'justify-content-center mt-5 mb-3'}>
|
||||
<HistoryToolbar />
|
||||
</Row>
|
||||
|
|
|
@ -9,7 +9,6 @@ import { CustomBranding } from '../../../components/common/custom-branding/custo
|
|||
import { HedgeDocLogoVertical } from '../../../components/common/hedge-doc-logo/hedge-doc-logo-vertical'
|
||||
import { LogoSize } from '../../../components/common/hedge-doc-logo/logo-size'
|
||||
import { EditorToRendererCommunicatorContextProvider } from '../../../components/editor-page/render-context/editor-to-renderer-communicator-context-provider'
|
||||
import { CoverButtons } from '../../../components/intro-page/cover-buttons/cover-buttons'
|
||||
import { IntroCustomContent } from '../../../components/intro-page/intro-custom-content'
|
||||
import { LandingLayout } from '../../../components/landing-layout/landing-layout'
|
||||
import type { NextPage } from 'next'
|
||||
|
@ -33,7 +32,6 @@ const IntroPage: NextPage = () => {
|
|||
<div className={'mb-5'}>
|
||||
<CustomBranding />
|
||||
</div>
|
||||
<CoverButtons />
|
||||
<IntroCustomContent />
|
||||
</div>
|
||||
</EditorToRendererCommunicatorContextProvider>
|
||||
|
|
|
@ -14,12 +14,17 @@ import { StoreProvider } from '../../redux/store-provider'
|
|||
import { baseUrlFromEnvExtractor } from '../../utils/base-url-from-env-extractor'
|
||||
import { configureLuxon } from '../../utils/configure-luxon'
|
||||
import type { Metadata } from 'next'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import React from 'react'
|
||||
import { getConfig } from '../../api/config'
|
||||
|
||||
configureLuxon()
|
||||
|
||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
interface RootLayoutProps extends PropsWithChildren {
|
||||
appBar: React.ReactNode
|
||||
}
|
||||
|
||||
export default async function RootLayout({ children, appBar }: RootLayoutProps) {
|
||||
const baseUrls = baseUrlFromEnvExtractor.extractBaseUrls()
|
||||
const frontendConfig = await getConfig(baseUrls.editor)
|
||||
|
||||
|
@ -35,7 +40,12 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|||
<ApplicationLoader>
|
||||
<DarkMode />
|
||||
<MotdModal />
|
||||
<UiNotificationBoundary>{children}</UiNotificationBoundary>
|
||||
<UiNotificationBoundary>
|
||||
<div className={'d-flex flex-column vh-100'}>
|
||||
{appBar}
|
||||
{children}
|
||||
</div>
|
||||
</UiNotificationBoundary>
|
||||
</ApplicationLoader>
|
||||
</StoreProvider>
|
||||
</FrontendConfigContextProvider>
|
||||
|
|
|
@ -9,7 +9,6 @@ import { NoteLoadingBoundary } from '../../../../components/common/note-loading-
|
|||
import { DocumentReadOnlyPageContent } from '../../../../components/document-read-only-page/document-read-only-page-content'
|
||||
import { useNoteAndAppTitle } from '../../../../components/editor-page/head-meta-properties/use-note-and-app-title'
|
||||
import { EditorToRendererCommunicatorContextProvider } from '../../../../components/editor-page/render-context/editor-to-renderer-communicator-context-provider'
|
||||
import { BaseAppBar } from '../../../../components/layout/app-bar/base-app-bar'
|
||||
import type { NextPage } from 'next'
|
||||
import React from 'react'
|
||||
|
||||
|
@ -26,10 +25,7 @@ const DocumentReadOnlyPage: NextPage<PageParams> = ({ params }) => {
|
|||
return (
|
||||
<EditorToRendererCommunicatorContextProvider>
|
||||
<NoteLoadingBoundary noteId={params.noteId}>
|
||||
<div className={'d-flex flex-column mvh-100'}>
|
||||
<BaseAppBar />
|
||||
<DocumentReadOnlyPageContent />
|
||||
</div>
|
||||
<DocumentReadOnlyPageContent />
|
||||
</NoteLoadingBoundary>
|
||||
</EditorToRendererCommunicatorContextProvider>
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue