diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts new file mode 100644 index 00000000..330c989c --- /dev/null +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts @@ -0,0 +1,128 @@ +import { expect, test } from '@playwright/test'; + +import { createDoc, goToGridDoc, mockedDocument } from './common'; + +test.beforeEach(async ({ page }) => { + await page.goto('/'); +}); + +test.describe('Doc Version', () => { + test('it displays the doc versions', async ({ page, browserName }) => { + const [randomDoc] = await createDoc(page, 'doc-version', browserName, 1); + + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); + + await page.getByLabel('Open the document options').click(); + await page + .getByRole('button', { + name: 'Version history', + }) + .click(); + + const panel = page.getByLabel('Document version panel'); + + await expect(panel.getByText('Current version')).toBeVisible(); + expect(await panel.locator('li').count()).toBe(1); + + await page.locator('.ProseMirror.bn-editor').click(); + await page.locator('.ProseMirror.bn-editor').last().fill('Hello World'); + + await goToGridDoc(page, { + title: randomDoc, + }); + + await expect(page.getByText('Hello World')).toBeVisible(); + + await page + .locator('.ProseMirror .bn-block') + .getByText('Hello World') + .fill('It will create a version'); + + await goToGridDoc(page, { + title: randomDoc, + }); + + await expect(page.getByText('Hello World')).toBeHidden(); + await expect(page.getByText('It will create a version')).toBeVisible(); + + await expect(panel.getByText('Current version')).toBeVisible(); + expect(await panel.locator('li').count()).toBe(2); + + await panel.locator('li').nth(1).click(); + await expect( + page.getByText('Read only, you cannot edit document versions.'), + ).toBeVisible(); + await expect(page.getByText('Hello World')).toBeVisible(); + await expect(page.getByText('It will create a version')).toBeHidden(); + + await panel.getByText('Current version').click(); + await expect(page.getByText('Hello World')).toBeHidden(); + await expect(page.getByText('It will create a version')).toBeVisible(); + }); + + test('it does not display the doc versions if not allowed', async ({ + page, + }) => { + await mockedDocument(page, { + abilities: { + versions_list: false, + partial_update: true, + }, + }); + + await goToGridDoc(page); + + await expect(page.locator('h2').getByText('Mocked document')).toBeVisible(); + + await page.getByLabel('Open the document options').click(); + await expect( + page.getByRole('button', { name: 'Version history' }), + ).toBeHidden(); + + await expect(page.getByLabel('Document version panel')).toBeHidden(); + }); + + test('it restores the doc version', async ({ page, browserName }) => { + const [randomDoc] = await createDoc(page, 'doc-version', browserName, 1); + + await expect(page.locator('h2').getByText(randomDoc)).toBeVisible(); + + await page.locator('.bn-block-outer').last().click(); + await page.locator('.bn-block-outer').last().fill('Hello'); + + await goToGridDoc(page, { + title: randomDoc, + }); + + await expect(page.getByText('Hello')).toBeVisible(); + await page.locator('.bn-block-outer').last().click(); + await page.keyboard.press('Enter'); + await page.locator('.bn-block-outer').last().fill('World'); + + await goToGridDoc(page, { + title: randomDoc, + }); + + await expect(page.getByText('World')).toBeVisible(); + + await page.getByLabel('Open the document options').click(); + await page + .getByRole('button', { + name: 'Version history', + }) + .click(); + + const panel = page.getByLabel('Document version panel'); + await panel.locator('li').nth(1).click(); + await expect(page.getByText('World')).toBeHidden(); + + await panel.getByLabel('Open the version options').click(); + await page.getByText('Restore the version').click(); + + await expect(panel.locator('li')).toHaveCount(3); + + await panel.getByText('Current version').click(); + await expect(page.getByText('Hello')).toBeVisible(); + await expect(page.getByText('World')).toBeHidden(); + }); +}); 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 1d8d2428..48b8a96e 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 @@ -8,7 +8,12 @@ import { Box, Card, Text, TextErrors } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { DocHeader } from '@/features/docs/doc-header'; import { Doc } from '@/features/docs/doc-management'; -import { Versions, useDocVersion } from '@/features/docs/doc-versioning/'; +import { + Panel, + Versions, + useDocVersion, + useDocVersionStore, +} from '@/features/docs/doc-versioning/'; import { BlockNoteEditor } from './BlockNoteEditor'; @@ -20,6 +25,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => { const { query: { versionId }, } = useRouter(); + const { isPanelOpen } = useDocVersionStore(); const { t } = useTranslation(); @@ -58,6 +64,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => { )} + {doc.abilities.versions_list && isPanelOpen && } ); 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 9ea72241..359564aa 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 @@ -9,6 +9,7 @@ import { ModalShare, ModalUpdateDoc, } from '@/features/docs/doc-management'; +import { useDocVersionStore } from '@/features/docs/doc-versioning'; import { ModalPDF } from './ModalExport'; @@ -23,6 +24,7 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false); const [isModalPDFOpen, setIsModalPDFOpen] = useState(false); const [isDropOpen, setIsDropOpen] = useState(false); + const { setIsPanelOpen } = useDocVersionStore(); return ( { {t('Delete document')} )} + {doc.abilities.versions_list && ( + + )}