From e8cc19b74e8c37656e212ea1ea61f89ce1f5f236 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 27 May 2026 15:28:09 +0200 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=9A=9A(frontend)=20move=20Button=20Sh?= =?UTF-8?q?are=20to=20Floating=20Bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are modifying the doc header, we are moving elements to a floating bar. In this case, we are moving the Button Share to the floating bar. --- env.d/development/common.e2e | 1 + .../__tests__/app-impress/doc-export.spec.ts | 9 +- .../__tests__/app-impress/doc-grid.spec.ts | 13 +-- .../__tests__/app-impress/doc-header.spec.ts | 4 +- .../app-impress/doc-member-create.spec.ts | 17 +-- .../app-impress/doc-member-list.spec.ts | 29 +++-- .../app-impress/doc-trashbin.spec.ts | 4 +- .../e2e/__tests__/app-impress/utils-common.ts | 12 ++- .../src/assets/icons/ui-kit/shared.svg | 24 ++++- .../doc-header/components/BoutonShare.tsx | 97 ----------------- .../docs/doc-header/components/DocHeader.tsx | 9 -- .../docs/doc-header/components/DocToolBox.tsx | 35 ------ .../doc-header/components/FloatingBar.tsx | 11 +- .../doc-share/components/DocShareButton.tsx | 100 ++++++++++++++++++ .../components/DocEditorSkeleton.tsx | 2 - 15 files changed, 176 insertions(+), 191 deletions(-) delete mode 100644 src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx create mode 100644 src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareButton.tsx diff --git a/env.d/development/common.e2e b/env.d/development/common.e2e index 73fb517dde..6a2131c78b 100644 --- a/env.d/development/common.e2e +++ b/env.d/development/common.e2e @@ -6,4 +6,5 @@ Y_PROVIDER_API_BASE_URL=http://y-provider-converter:4444/api/ # Throttle API_DOCUMENT_THROTTLE_RATE=1000/min +API_DOCUMENT_ACCESS_THROTTLE_RATE=1000/min API_CONFIG_THROTTLE_RATE=1000/min diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts index ba2945eae5..71fb3dccd7 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts @@ -288,14 +288,9 @@ test.describe('Doc Export', () => { }); await page - .getByRole('button', { - name: 'Exporter le document', - }) + .getByRole('button', { name: 'Ouvrir les options du document' }) .click(); - - await expect( - page.getByTestId('doc-open-modal-download-button'), - ).toBeVisible(); + await page.getByRole('menuitem', { name: 'Télécharger' }).click(); const downloadPromise = page.waitForEvent('download', (download) => { return download.suggestedFilename().includes(`${randomDocFrench}.pdf`); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts index 9b900e0f2f..02605f7bd7 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts @@ -1,6 +1,11 @@ import { expect, test } from '@playwright/test'; -import { createDoc, getGridRow, verifyDocName } from './utils-common'; +import { + clickInEditorShareButton, + createDoc, + getGridRow, + verifyDocName, +} from './utils-common'; import { addNewMember, connectOtherUserToDoc } from './utils-share'; type SmallDoc = { @@ -212,9 +217,7 @@ test.describe('Documents filters', () => { test('it checks the left panel filters', async ({ page, browserName }) => { void page.goto('/'); - // Create my doc const [docName] = await createDoc(page, 'my-doc', browserName, 1); - await verifyDocName(page, docName); // Another user create a doc and share it with me const { cleanup, otherPage, otherBrowserName } = @@ -230,9 +233,7 @@ test.describe('Documents filters', () => { 1, ); - await verifyDocName(otherPage, docShareName); - - await otherPage.getByRole('button', { name: 'Share' }).click(); + await clickInEditorShareButton(otherPage); await addNewMember(otherPage, 0, 'Editor', browserName); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts index 5e812dad79..20c2bd1551 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts @@ -1,6 +1,7 @@ import { expect, test } from '@playwright/test'; import { + clickInEditorShareButton, createDoc, getGridRow, goToGridDoc, @@ -733,8 +734,7 @@ test.describe('Documents Header mobile', () => { await goToGridDoc(page); - await page.getByLabel('Open the document options').click(); - await page.getByRole('menuitem', { name: 'Share' }).click(); + await clickInEditorShareButton(page); const shareModal = page.getByRole('dialog', { name: 'Share the document', diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts index 23eabde581..c6c804e8cb 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts @@ -1,6 +1,12 @@ import { expect, test } from '@playwright/test'; -import { BROWSERS, createDoc, randomName, verifyDocName } from './utils-common'; +import { + BROWSERS, + clickInEditorShareButton, + createDoc, + randomName, + verifyDocName, +} from './utils-common'; import { writeInEditor } from './utils-editor'; import { connectOtherUserToDoc, updateRoleUser } from './utils-share'; import { SignIn } from './utils-signin'; @@ -271,8 +277,6 @@ test.describe('Document create member', () => { 1, ); - await verifyDocName(page, docTitle); - await writeInEditor({ page, text: 'Hello World' }); const docUrl = page.url(); @@ -294,8 +298,7 @@ test.describe('Document create member', () => { ).toBeVisible(); // First user approves the request - await page.getByRole('button', { name: 'Share' }).click(); - + await clickInEditorShareButton(page); await expect(page.getByText('Access Requests')).toBeVisible(); await expect( page.getByText( @@ -330,7 +333,9 @@ test.describe('Document create member', () => { await updateRoleUser(page, 'Remove access', emailRequest); await expect( otherPage.getByText('Insufficient access rights to view the document.'), - ).toBeVisible(); + ).toBeVisible({ + timeout: 10000, + }); // Cleanup: other user logout await cleanup(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts index efe7b2100c..abf7e26736 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts @@ -1,6 +1,10 @@ import { expect, test } from '@playwright/test'; -import { createDoc, verifyDocName } from './utils-common'; +import { + clickInEditorShareButton, + createDoc, + verifyDocName, +} from './utils-common'; import { addNewMember } from './utils-share'; test.beforeEach(async ({ page }) => { @@ -114,14 +118,8 @@ test.describe('Document list members', () => { }, ); - const [docTitle] = await createDoc( - page, - 'members-big-invitation-list', - browserName, - 1, - ); - await verifyDocName(page, docTitle); - await page.getByRole('button', { name: 'Share' }).click(); + await createDoc(page, 'members-big-invitation-list', browserName, 1); + await clickInEditorShareButton(page); const prefix = 'doc-share-invitation'; const elements = page.locator(`[data-testid^="${prefix}"]`); @@ -142,11 +140,10 @@ test.describe('Document list members', () => { }); test('it checks the role rules', async ({ page, browserName }) => { - const [docTitle] = await createDoc(page, 'Doc role rules', browserName, 1); + await createDoc(page, 'Doc role rules', browserName, 1); - await verifyDocName(page, docTitle); + await clickInEditorShareButton(page); - await page.getByRole('button', { name: 'Share' }).click(); const list = page.getByTestId('doc-share-quick-search'); await expect(list).toBeVisible(); const emailRequest = @@ -208,11 +205,9 @@ test.describe('Document list members', () => { }); test('it checks the delete members', async ({ page, browserName }) => { - const [docTitle] = await createDoc(page, 'Doc role rules', browserName, 1); + await createDoc(page, 'Doc role rules', browserName, 1); - await verifyDocName(page, docTitle); - - await page.getByRole('button', { name: 'Share' }).click(); + await clickInEditorShareButton(page); const list = page.getByTestId('doc-share-quick-search'); @@ -227,7 +222,7 @@ test.describe('Document list members', () => { ); await page.getByRole('button', { name: 'close' }).first().click(); - await page.getByRole('button', { name: 'Share' }).first().click(); + await clickInEditorShareButton(page); const userReaderEmail = await addNewMember(page, 0, 'Reader'); 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 9e60c1bc09..456df240ce 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 @@ -127,7 +127,7 @@ test.describe('Doc Trashbin', () => { await navigateToPageFromTree({ page, title: subDocName }); await verifyDocName(page, subDocName); - await clickInEditorMenu(page, 'Delete sub-document'); + await clickInEditorMenu(page, 'Delete'); await page.getByRole('button', { name: 'Delete document' }).click(); await verifyDocName(page, topParent); @@ -152,7 +152,7 @@ test.describe('Doc Trashbin', () => { ).toBeVisible(); await expect(page.getByLabel('Alert deleted document')).toBeVisible(); - await expect(page.getByRole('button', { name: 'Share' })).toBeDisabled(); + await expect(page.getByRole('button', { name: 'Share' })).toBeHidden(); await expect(page.locator('.bn-editor')).toHaveAttribute( 'contenteditable', 'false', diff --git a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts index 782792fcb2..0e49902638 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts @@ -425,8 +425,18 @@ export async function waitForLanguageSwitch( await page.getByRole('menuitemradio', { name: lang.label }).click(); } +export const clickInEditorShareButton = async (page: Page) => { + await page + .getByTestId('floating-bar') + .getByRole('button', { name: 'Share' }) + .click(); +}; + export const clickInEditorMenu = async (page: Page, textButton: string) => { - await page.getByRole('button', { name: 'Open the document options' }).click(); + await page + .getByTestId('floating-bar') + .getByRole('button', { name: 'Open the document options' }) + .click(); await page.getByRole('menuitem', { name: textButton }).click(); }; diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/shared.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/shared.svg index 6d7c9f17a6..7097f5b671 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/shared.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/shared.svg @@ -1,6 +1,20 @@ - - - - - + + + + + diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx deleted file mode 100644 index 9f86e08afb..0000000000 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { Button } from '@gouvfr-lasuite/cunningham-react'; -import { useTreeContext } from '@gouvfr-lasuite/ui-kit'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { css } from 'styled-components'; - -import { Box, Icon } from '@/components'; -import { Doc } from '@/docs/doc-management'; -import { useFocusStore } from '@/stores'; - -interface BoutonShareProps { - displayNbAccess: boolean; - doc: Doc; - isDisabled?: boolean; - isHidden?: boolean; - open: () => void; -} - -export const BoutonShare = ({ - displayNbAccess, - doc, - isDisabled, - isHidden, - open, -}: BoutonShareProps) => { - const { t } = useTranslation(); - const addLastFocus = useFocusStore((state) => state.addLastFocus); - const treeContext = useTreeContext(); - - /** - * Following the change where there is no default owner when adding a sub-page, - * we need to handle both the case where the doc is the root and the case of sub-pages. - */ - const hasAccesses = useMemo(() => { - if (treeContext?.root?.id === doc.id) { - return doc.nb_accesses_direct > 1 && displayNbAccess; - } - - return doc.nb_accesses_direct >= 1 && displayNbAccess; - }, [doc.id, treeContext?.root, doc.nb_accesses_direct, displayNbAccess]); - - if (isHidden) { - return null; - } - - if (hasAccesses) { - return ( - - - } - onClick={(e) => { - addLastFocus(e.currentTarget); - open(); - }} - size="medium" - disabled={isDisabled} - > - {doc.nb_accesses_direct} - - - ); - } - - return ( - - ); -}; diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx index 85430234c0..9b8ac210e0 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx @@ -13,7 +13,6 @@ import { useResponsiveStore } from '@/stores'; import { AlertNetwork } from './AlertNetwork'; import { AlertPublic } from './AlertPublic'; import { AlertRestore } from './AlertRestore'; -import { BoutonShare } from './BoutonShare'; import { DocHeaderInfo } from './DocHeaderInfo'; import { DocTitle } from './DocTitle'; import { DocToolBox } from './DocToolBox'; @@ -66,14 +65,6 @@ export const DocHeader = ({ doc }: DocHeaderProps) => { {!isDeletedDoc && } - {isDeletedDoc && ( - {}} - displayNbAccess={true} - isDisabled - /> - )} diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx index 19973d6c28..7d2f749e02 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx @@ -12,7 +12,6 @@ import DeleteSVG from '@/assets/icons/ui-kit/delete.svg'; import DownloadSVG from '@/assets/icons/ui-kit/download.svg'; import RemoveEmojiSVG from '@/assets/icons/ui-kit/face-remove.svg'; import AddEmojiSVG from '@/assets/icons/ui-kit/face.svg'; -import GroupSVG from '@/assets/icons/ui-kit/group.svg'; import HistorySVG from '@/assets/icons/ui-kit/history.svg'; import KeepSVG from '@/assets/icons/ui-kit/keep.svg'; import KeepOffSVG from '@/assets/icons/ui-kit/keep_off.svg'; @@ -42,16 +41,6 @@ import { useFocusStore, useResponsiveStore } from '@/stores'; import { useCopyCurrentEditorToClipboard } from '../hooks/useCopyCurrentEditorToClipboard'; -import { BoutonShare } from './BoutonShare'; - -const DocShareModal = dynamic( - () => - import('@/docs/doc-share/components/DocShareModal').then((mod) => ({ - default: mod.DocShareModal, - })), - { ssr: false }, -); - const ModalRemoveDoc = dynamic( () => import('@/docs/doc-management/components/ModalRemoveDoc').then((mod) => ({ @@ -94,7 +83,6 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false); const [isModalExportOpen, setIsModalExportOpen] = useState(false); const selectHistoryModal = useModal(); - const modalShare = useModal(); const { addLastFocus, restoreFocus } = useFocusStore(); const { isSmallMobile, isMobile } = useResponsiveStore(); @@ -116,12 +104,6 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { const { updateDocEmoji } = useDocTitleUpdate(); const options: DropdownMenuOption[] = [ - { - label: t('Share'), - icon: , - callback: modalShare.open, - show: isSmallMobile, - }, { label: t('Export'), icon: , @@ -229,13 +211,6 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { $margin={{ left: 'auto' }} $gap={spacingsTokens['2xs']} > - - {!isSmallMobile && ModalExport && ( + + ), + }; +}); + +vi.mock('../hooks/useCopyCurrentEditorToClipboard', () => ({ + useCopyCurrentEditorToClipboard: () => vi.fn(), +})); + const doc = { nb_accesses: 1, abilities: { @@ -39,9 +63,7 @@ describe('DocToolBox - Licence', () => { wrapper: AppWrapper, }); - expect( - await screen.findByLabelText('Export the document'), - ).toBeInTheDocument(); + expect(await screen.findByText('Download')).toBeInTheDocument(); }, 15000); test('The export button is not rendered when MIT version is activated', async () => { @@ -53,12 +75,6 @@ describe('DocToolBox - Licence', () => { wrapper: AppWrapper, }); - expect( - screen.getByLabelText('Open the document options'), - ).toBeInTheDocument(); - - expect( - screen.queryByLabelText('Export the document'), - ).not.toBeInTheDocument(); + expect(screen.queryByText('Download')).not.toBeInTheDocument(); }, 15000); }); diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx index 43c4a7eab9..2a71202ed8 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeader.tsx @@ -1,62 +1,90 @@ +import { Button } from '@gouvfr-lasuite/cunningham-react'; import { useTranslation } from 'react-i18next'; +import RemoveEmojiSVG from '@/assets/icons/ui-kit/face-remove.svg'; +import AddEmojiSVG from '@/assets/icons/ui-kit/face.svg'; import { Box, HorizontalSeparator } from '@/components'; -import { useCunninghamTheme } from '@/cunningham'; -import { Doc, useIsCollaborativeEditable } from '@/docs/doc-management'; -import { useResponsiveStore } from '@/stores'; +import { + Doc, + getEmojiAndTitle, + useDocTitleUpdate, + useDocUtils, + useIsCollaborativeEditable, +} from '@/docs/doc-management'; import { AlertNetwork } from './AlertNetwork'; import { AlertRestore } from './AlertRestore'; import { DocHeaderInfo } from './DocHeaderInfo'; import { DocTitle } from './DocTitle'; -import { DocToolBox } from './DocToolBox'; interface DocHeaderProps { doc: Doc; } export const DocHeader = ({ doc }: DocHeaderProps) => { - const { spacingsTokens } = useCunninghamTheme(); - const { isDesktop } = useResponsiveStore(); const { t } = useTranslation(); const { isEditable } = useIsCollaborativeEditable(doc); const isDeletedDoc = !!doc.deleted_at; + // Emoji Management + const { emoji } = getEmojiAndTitle(doc.title ?? ''); + const { updateDocEmoji } = useDocTitleUpdate(); + const { isTopRoot } = useDocUtils(doc); + const displayEmojiButton = doc.abilities.partial_update && !isTopRoot; return ( <> - {isDeletedDoc && } - {!isEditable && } - - - - - - - - {!isDeletedDoc && } + {isDeletedDoc && } + {!isEditable && } + + + + {displayEmojiButton && ( + + )} + + - + ); diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx index 273c15c892..8de22bd4a4 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx @@ -2,7 +2,7 @@ import { t } from 'i18next'; import PublicSVG from '@/assets/icons/ui-kit/public.svg'; import ProtedtedSVG from '@/assets/icons/ui-kit/vpn_lock.svg'; -import { Text } from '@/components'; +import { Box, Text } from '@/components'; import { useConfig } from '@/core'; import { Doc, @@ -40,7 +40,7 @@ export const DocHeaderInfo = ({ doc }: DocHeaderInfoProps) => { } return ( - <> + { {dateToDisplay} - + ); }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx index 7a3ce2ea26..7c87ac5422 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx @@ -42,11 +42,7 @@ export const DocTitleText = () => { return ( - + {currentDoc?.title || untitledDocument} @@ -110,7 +106,7 @@ const DocTitleEmojiPicker = ({ doc }: DocTitleProps) => { }; const DocTitleInput = ({ doc }: DocTitleProps) => { - const { isLargeScreen } = useResponsiveStore(); + const { isSmallMobile } = useResponsiveStore(); const { t } = useTranslation(); const { isTopRoot } = useDocUtils(doc); const { untitledDocument } = useTrans(); @@ -200,7 +196,6 @@ const DocTitleInput = ({ doc }: DocTitleProps) => { $minHeight="40px" > {!isTopRoot && } - { } onPasteCapture={handlePaste} onDropCapture={handleDrop} - $padding={{ right: 'big' }} $css={css` &[contenteditable='true']:empty:not(:focus):before { content: '${untitledDocument}'; @@ -227,11 +221,12 @@ const DocTitleInput = ({ doc }: DocTitleProps) => { pointer-events: none; font-style: italic; } - font-size: ${isLargeScreen - ? 'var(--c--globals--font--sizes--h2)' - : 'var(--c--globals--font--sizes--sm)'}; + font-size: ${isSmallMobile + ? 'var(--c--globals--font--sizes--h4)' + : 'var(--c--globals--font--sizes--h2)'}; font-weight: 700; outline: none; + width: 100%; `} > {titleDisplay} diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx index 7d2f749e02..78380ca3df 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx @@ -1,42 +1,36 @@ import { Button, useModal } from '@gouvfr-lasuite/cunningham-react'; -import { useTreeContext } from '@gouvfr-lasuite/ui-kit'; +import { + DropdownMenu, + DropdownMenuOption, + useTreeContext, +} from '@gouvfr-lasuite/ui-kit'; import dynamic from 'next/dynamic'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { css } from 'styled-components'; import AddLinkSVG from '@/assets/icons/ui-kit/add_link.svg'; import ContentCopySVG from '@/assets/icons/ui-kit/content_copy.svg'; import DeleteSVG from '@/assets/icons/ui-kit/delete.svg'; import DownloadSVG from '@/assets/icons/ui-kit/download.svg'; -import RemoveEmojiSVG from '@/assets/icons/ui-kit/face-remove.svg'; -import AddEmojiSVG from '@/assets/icons/ui-kit/face.svg'; +import SharedSVG from '@/assets/icons/ui-kit/group.svg'; import HistorySVG from '@/assets/icons/ui-kit/history.svg'; import KeepSVG from '@/assets/icons/ui-kit/keep.svg'; import KeepOffSVG from '@/assets/icons/ui-kit/keep_off.svg'; import MarkdownCopySVG from '@/assets/icons/ui-kit/markdown_copy.svg'; -import { - Box, - DropdownMenu, - DropdownMenuOption, - Icon, - IconOptions, -} from '@/components'; -import { useCunninghamTheme } from '@/cunningham'; +import MoreSVG from '@/assets/icons/ui-kit/more_horiz.svg'; import { Doc, KEY_DOC, KEY_LIST_DOC, KEY_LIST_FAVORITE_DOC, - getEmojiAndTitle, useCopyDocLink, useCreateFavoriteDoc, useDeleteFavoriteDoc, - useDocTitleUpdate, useDocUtils, useDuplicateDoc, } from '@/docs/doc-management'; +import { useAuth } from '@/features/auth'; import { useFocusStore, useResponsiveStore } from '@/stores'; import { useCopyCurrentEditorToClipboard } from '../hooks/useCopyCurrentEditorToClipboard'; @@ -57,6 +51,14 @@ const ModalSelectVersion = dynamic( { ssr: false }, ); +const DocShareModal = dynamic( + () => + import('@/docs/doc-share/components/DocShareModal').then((mod) => ({ + default: mod.DocShareModal, + })), + { ssr: false }, +); + const ModalExport = process.env.NEXT_PUBLIC_PUBLISH_AS_MIT === 'false' ? dynamic( @@ -76,16 +78,18 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { const { t } = useTranslation(); const treeContext = useTreeContext(); const router = useRouter(); - const { isChild, isTopRoot } = useDocUtils(doc); - - const { spacingsTokens, colorsTokens } = useCunninghamTheme(); + const { isTopRoot } = useDocUtils(doc); + const { authenticated } = useAuth(); + const copyCurrentEditorToClipboard = useCopyCurrentEditorToClipboard(); + const [openDropdown, setOpenDropdown] = useState(false); const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false); const [isModalExportOpen, setIsModalExportOpen] = useState(false); + const shareModal = useModal(); const selectHistoryModal = useModal(); - const { addLastFocus, restoreFocus } = useFocusStore(); - const { isSmallMobile, isMobile } = useResponsiveStore(); + const { restoreFocus } = useFocusStore(); + const { isMobile } = useResponsiveStore(); const copyDocLink = useCopyDocLink(doc.id); const { mutate: duplicateDoc } = useDuplicateDoc({ onSuccess: (data) => { @@ -99,19 +103,7 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { listInvalidQueries: [KEY_LIST_DOC, KEY_DOC, KEY_LIST_FAVORITE_DOC], }); - // Emoji Management - const { emoji } = getEmojiAndTitle(doc.title ?? ''); - const { updateDocEmoji } = useDocTitleUpdate(); - const options: DropdownMenuOption[] = [ - { - label: t('Export'), - icon: