From e1eb6c99de37519987043baaf52f29256cbe0ea3 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Thu, 30 Jul 2026 13:19:09 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20change=20BlockNo?= =?UTF-8?q?teSideMenu=20to=20DocsSideMenu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to have our own side menu, so we can add more features to it and display the ui as we want. The new side menu is called DocsSideMenu and it will be used in the BlockNoteEditor. --- .../__tests__/app-impress/doc-editor.spec.ts | 25 +++++-- .../impress/src/assets/icons/ui-kit/color.svg | 15 ++++ .../src/assets/icons/ui-kit/present.svg | 18 +++++ .../icons/ui-kit/table-header-column.svg | 31 ++++++++ .../assets/icons/ui-kit/table-header-row.svg | 7 ++ .../separators/HorizontalSeparator.tsx | 1 + .../doc-editor/components/BlockNoteEditor.tsx | 4 +- .../components/BlockNoteSideMenu.tsx | 36 ---------- .../components/DocsSideMenu/DocsSideMenu.tsx | 72 +++++++++++++++++++ .../DocsSideMenu/TableHeaderSeparator.tsx | 24 +++++++ .../components/PresentBlockItem.tsx | 7 +- 11 files changed, 197 insertions(+), 43 deletions(-) create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/color.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/present.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-column.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-row.svg delete mode 100644 src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSideMenu.tsx create mode 100644 src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/DocsSideMenu.tsx create mode 100644 src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/TableHeaderSeparator.tsx diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 052416722..3ad995ec2 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -23,12 +23,8 @@ test.describe('Doc Editor', () => { }) => { await createDoc(page, 'doc-toolbar', browserName, 1); - await verifyDocName(page, 'doc-toolbar'); - const editor = await writeInEditor({ page, text: 'test content' }); - await page.waitForTimeout(1500); - await editor .getByText('test content', { exact: true, @@ -106,6 +102,27 @@ test.describe('Doc Editor', () => { ).toBeVisible(); }); + test('it checks side menu buttons are displayed', async ({ + page, + browserName, + }) => { + await createDoc(page, 'doc-side-menu', browserName, 1); + + const { editor } = await openSuggestionMenu({ page, suggestion: 'Table' }); + + await editor.locator('.tableWrapper').first().hover(); + + await page.locator('.bn-side-menu > button').last().click(); + await expect(page.getByRole('menuitem', { name: 'Colors' })).toBeVisible(); + await expect( + page.getByRole('menuitem', { name: 'Header row' }), + ).toBeVisible(); + await expect( + page.getByRole('menuitem', { name: 'Header column' }), + ).toBeVisible(); + await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible(); + }); + test('markdown button converts from markdown to the editor syntax json', async ({ page, browserName, diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/color.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/color.svg new file mode 100644 index 000000000..e629d51d2 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/color.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/present.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/present.svg new file mode 100644 index 000000000..d92075506 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/present.svg @@ -0,0 +1,18 @@ + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-column.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-column.svg new file mode 100644 index 000000000..e801a932f --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-column.svg @@ -0,0 +1,31 @@ + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-row.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-row.svg new file mode 100644 index 000000000..a4ce9e912 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/table-header-row.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/frontend/apps/impress/src/components/separators/HorizontalSeparator.tsx b/src/frontend/apps/impress/src/components/separators/HorizontalSeparator.tsx index 91d3d06d6..c3c43ba6f 100644 --- a/src/frontend/apps/impress/src/components/separators/HorizontalSeparator.tsx +++ b/src/frontend/apps/impress/src/components/separators/HorizontalSeparator.tsx @@ -3,6 +3,7 @@ import { Box, BoxType } from '../Box'; export const HorizontalSeparator = (props: BoxType) => { return ( { )} - + {showComments && } {showComments && !isCommentSideBarOpen && } {threadsSidebarTarget && diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSideMenu.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSideMenu.tsx deleted file mode 100644 index 352bda265..000000000 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSideMenu.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - BlockColorsItem, - DragHandleMenu, - RemoveBlockItem, - SideMenu, - SideMenuController, - TableColumnHeaderItem, - TableRowHeaderItem, - useDictionary, -} from '@blocknote/react'; - -import { PresentBlockItem } from '@/docs/doc-presenter/components/PresentBlockItem'; - -const DocsDragHandleMenu = () => { - const dict = useDictionary(); - - return ( - - {dict.drag_handle.delete_menuitem} - - {dict.drag_handle.colors_menuitem} - - {dict.drag_handle.header_row_menuitem} - - - {dict.drag_handle.header_column_menuitem} - - - ); -}; - -const DocsSideMenu = () => ; - -export const BlockNoteSideMenu = () => ( - -); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/DocsSideMenu.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/DocsSideMenu.tsx new file mode 100644 index 000000000..7d330616a --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/DocsSideMenu.tsx @@ -0,0 +1,72 @@ +/** + * Overrides the default DragHandleMenu with a custom implementation for the Docs editor. + * See: https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/SideMenu/DragHandleMenu/DragHandleMenu.tsx + */ +import { + BlockColorsItem, + DragHandleMenu, + RemoveBlockItem, + SideMenu, + SideMenuController, + TableColumnHeaderItem, + TableRowHeaderItem, + useComponentsContext, + useDictionary, +} from '@blocknote/react'; + +import { Box, HorizontalSeparator } from '@/components'; +import { PresentBlockItem } from '@/docs/doc-presenter/components/PresentBlockItem'; +import ColorIcon from '@/icons/color.svg'; +import TableHeaderColumnIcon from '@/icons/table-header-column.svg'; +import TableHeaderRowIcon from '@/icons/table-header-row.svg'; +import TrashIcon from '@/icons/trash.svg'; + +import { TableHeaderSeparator } from './TableHeaderSeparator'; + +const DocsDragHandleMenu = () => { + const Components = useComponentsContext(); + const dict = useDictionary(); + + if (Components === undefined) { + return null; + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export const DocsSideMenu = () => ( + } + /> +); diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/TableHeaderSeparator.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/TableHeaderSeparator.tsx new file mode 100644 index 000000000..bae9030f2 --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocsSideMenu/TableHeaderSeparator.tsx @@ -0,0 +1,24 @@ +import { SideMenuExtension } from '@blocknote/core/extensions'; +import { useBlockNoteEditor, useExtensionState } from '@blocknote/react'; + +import { HorizontalSeparator } from '@/components'; + +import type { DocsBlockNoteEditor } from '../../types'; + +export const TableHeaderSeparator = () => { + const editor: DocsBlockNoteEditor = useBlockNoteEditor(); + const block = useExtensionState(SideMenuExtension, { + editor, + selector: (state) => state?.block, + }); + + if ( + block === undefined || + block.type !== 'table' || + !editor.settings.tables.headers + ) { + return null; + } + + return ; +}; diff --git a/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresentBlockItem.tsx b/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresentBlockItem.tsx index 03cfb4dbc..534309253 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresentBlockItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresentBlockItem.tsx @@ -6,7 +6,9 @@ import { } from '@blocknote/react'; import { useTranslation } from 'react-i18next'; +import { Box } from '@/components'; import type { DocsBlockNoteEditor } from '@/docs/doc-editor/types'; +import PresentIcon from '@/icons/present.svg'; import { useResponsiveStore } from '@/stores'; import { getContentSlideIndexForBlock } from '../hooks/useSlides'; @@ -44,7 +46,10 @@ export const PresentBlockItem = () => { openPresenter(contentSlideIndex + 1); }} > - {t('Present from here')} + + ); };