From e5581e52f7e9895fafe0c4425888a029cbba4450 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Fri, 7 Nov 2025 15:31:05 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20better=20handlin?= =?UTF-8?q?g=20css=20doc=20states?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We simplify the way we handle different doc states (deleted / readonly) in the CSS, we avoid props drilling and are more component focused. --- .../app-impress/doc-trashbin.spec.ts | 4 ++++ .../app-impress/doc-visibility.spec.ts | 4 ++++ .../doc-editor/components/BlockNoteEditor.tsx | 19 +++++++++++-------- .../docs/doc-editor/components/DocEditor.tsx | 18 +++++++++++------- .../InterlinkingLinkInlineContent.tsx | 4 ++++ .../src/features/docs/doc-editor/styles.tsx | 16 ++++++---------- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts index 5a445a60..babd5227 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts @@ -119,6 +119,10 @@ test.describe('Doc Trashbin', () => { await row.getByText(subDocName).click(); await verifyDocName(page, subDocName); + await expect( + page.locator('.--docs--editor-container.--docs--doc-deleted'), + ).toBeVisible(); + await expect(page.getByLabel('Alert deleted document')).toBeVisible(); await expect(page.getByRole('button', { name: 'Share' })).toBeDisabled(); await expect(page.locator('.bn-editor')).toHaveAttribute( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts index 88881e43..d240c7bf 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts @@ -260,6 +260,10 @@ test.describe('Doc Visibility: Public', () => { await expect(card).toBeVisible(); await expect(card.getByText('Reader')).toBeVisible(); + await expect( + otherPage.locator('.--docs--editor-container.--docs--doc-readonly'), + ).toBeVisible(); + const otherEditor = await getEditor({ page: otherPage }); await expect(otherEditor).toHaveAttribute('contenteditable', 'false'); await expect(otherEditor.getByText('Hello Public Viewonly')).toBeVisible(); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx index e2ee1543..4d23e1be 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx @@ -28,6 +28,7 @@ import { useUploadStatus, } from '../hook'; import { useEditorStore } from '../stores'; +import { cssEditor } from '../styles'; import { DocsBlockNoteEditor } from '../types'; import { randomColor } from '../utils'; @@ -169,7 +170,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => { }, [setEditor, editor]); return ( - + {errorAttachment && ( { useHeadings(editor); return ( - + + + ); }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx index 1ec11e91..a2d04ba2 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx @@ -1,3 +1,4 @@ +import clsx from 'clsx'; import { useEffect } from 'react'; import { css } from 'styled-components'; @@ -12,8 +13,6 @@ import { TableContent } from '@/docs/doc-table-content/'; import { useSkeletonStore } from '@/features/skeletons'; import { useResponsiveStore } from '@/stores'; -import { cssEditor } from '../styles'; - import { BlockNoteEditor, BlockNoteReader } from './BlockNoteEditor'; interface DocEditorContainerProps { @@ -55,10 +54,13 @@ export const DocEditorContainer = ({ > {docEditor} @@ -77,7 +79,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => { const { isDesktop } = useResponsiveStore(); const { provider, isReady } = useProviderStore(); const { isEditable, isLoading } = useIsCollaborativeEditable(doc); - const readOnly = !doc.abilities.partial_update || !isEditable || isLoading; + const isDeletedDoc = !!doc.deleted_at; + const readOnly = + !doc.abilities.partial_update || !isEditable || isLoading || isDeletedDoc; const { setIsSkeletonVisible } = useSkeletonStore(); const isProviderReady = isReady && provider; @@ -117,7 +121,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => { ) } - isDeletedDoc={!!doc.deleted_at} + isDeletedDoc={isDeletedDoc} readOnly={readOnly} /> diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx index 747e6e7c..28166de1 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx @@ -89,6 +89,10 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => { background-color: ${colorsTokens['greyscale-100']}; } transition: background-color 0.2s ease-in-out; + + .--docs--doc-deleted & { + pointer-events: none; + } `} > {emoji ? ( diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx index cb6c3a53..3bade52b 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx @@ -1,12 +1,13 @@ import { css } from 'styled-components'; -export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css` +export const cssEditor = css` &, & > .bn-container, & .ProseMirror { height: 100%; - padding-bottom: 2rem; + } + & .ProseMirror { /** * WCAG Accessibility contrast fixes for BlockNote editor */ @@ -131,13 +132,6 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css` .bn-block-outer:not([data-prev-depth-changed]):before { border-left: none; } - - ${isDeletedDoc && - ` - .node-interlinkingLinkInline button { - pointer-events: none; - } - `} } & .bn-editor { @@ -187,8 +181,10 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css` } @media screen and (width <= 560px) { + .--docs--doc-readonly & .bn-editor { + padding-left: 10px; + } & .bn-editor { - ${readonly && `padding-left: 10px;`} padding-right: 10px; } .bn-side-menu[data-block-type='heading'][data-level='1'] {