From 192fa76b5477bdce2e0494316419526e265c963b Mon Sep 17 00:00:00 2001 From: Olivier Laurendeau Date: Mon, 15 Sep 2025 15:43:11 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20can=20remove=20emoji=20in?= =?UTF-8?q?=20the=20tree=20item=20actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add action button to remove emoji from a document title from the document tree. --- .../__tests__/app-impress/doc-tree.spec.ts | 24 ++++++++++++++++++- .../components/DocTreeItemActions.tsx | 19 +++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts index 7a66acdb..8b9ce931 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts @@ -321,8 +321,20 @@ test.describe('Doc Tree', () => { 'doc-child-emoji-child', ); - // Update the emoji from the tree const row = await getTreeRow(page, docChild); + + // Check Remove emoji is not present initially + await row.hover(); + const menu = row.getByText(`more_horiz`); + await menu.click(); + await expect( + page.getByRole('menuitem', { name: 'Remove emoji' }), + ).toBeHidden(); + + // Close the menu + await page.keyboard.press('Escape'); + + // Update the emoji from the tree await row.locator('.--docs--doc-icon').click(); await page.getByRole('button', { name: '😀' }).first().click(); @@ -331,6 +343,16 @@ test.describe('Doc Tree', () => { await expect( page.getByRole('textbox', { name: 'Document title' }), ).toContainText('😀'); + + // Now remove the emoji using the new action + await row.hover(); + await menu.click(); + await page.getByRole('menuitem', { name: 'Remove emoji' }).click(); + + await expect(row.getByText('😀')).toBeHidden(); + await expect( + page.getByRole('textbox', { name: 'Document title' }), + ).not.toContainText('😀'); }); }); diff --git a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx index 0ed7b8b7..da056301 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-tree/components/DocTreeItemActions.tsx @@ -13,8 +13,10 @@ import { Doc, ModalRemoveDoc, Role, + getEmojiAndTitle, useCopyDocLink, useCreateChildDoc, + useDocTitleUpdate, useDuplicateDoc, } from '@/docs/doc-management'; @@ -44,6 +46,7 @@ export const DocTreeItemActions = ({ const copyLink = useCopyDocLink(doc.id); const { mutate: detachDoc } = useDetachDoc(); const treeContext = useTreeContext(); + const { mutate: duplicateDoc } = useDuplicateDoc({ onSuccess: (duplicatedDoc) => { // Reset the tree context root will reset the full tree view. @@ -52,6 +55,13 @@ export const DocTreeItemActions = ({ }, }); + // Emoji Management + const { emoji } = getEmojiAndTitle(doc.title ?? ''); + const { updateDocEmoji } = useDocTitleUpdate(); + const removeEmoji = () => { + updateDocEmoji(doc.id, doc.title ?? '', ''); + }; + const handleDetachDoc = () => { if (!treeContext?.root) { return; @@ -82,6 +92,15 @@ export const DocTreeItemActions = ({ }, ...(!isRoot ? [ + ...(emoji && doc.abilities.partial_update + ? [ + { + label: t('Remove emoji'), + icon: , + callback: removeEmoji, + }, + ] + : []), { label: t('Move to my docs'), isDisabled: doc.user_role !== Role.OWNER,