diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e40099d..08587812 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ and this project adheres to
- ✨Add image attachments with access control
- ✨(frontend) Upload image to a document #211
+- ✨(frontend) Versions #217
## Changed
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
index 94a44e0c..6c68dbfc 100644
--- a/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts
+++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts
@@ -133,4 +133,62 @@ test.describe('Doc Version', () => {
await expect(page.getByText('Hello')).toBeVisible();
await expect(page.getByText('World')).toBeHidden();
});
+
+ test('it restores the doc version from button title', 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 page
+ .getByRole('button', {
+ name: 'Restore this version',
+ })
+ .click();
+
+ await expect(page.getByText('Restore this version?')).toBeVisible();
+
+ await page
+ .getByRole('button', {
+ name: 'Restore',
+ })
+ .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 48b8a96e..4988ea54 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
@@ -35,7 +35,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
return (
<>
-
+
{!doc.abilities.partial_update && (
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 68582013..90622191 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,4 +1,5 @@
-import React, { Fragment } from 'react';
+import { Button } from '@openfun/cunningham-react';
+import React, { Fragment, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Box, Card, StyledLink, Text } from '@/components';
@@ -9,96 +10,124 @@ import {
currentDocRole,
useTransRole,
} from '@/features/docs/doc-management';
+import { ModalVersion, Versions } from '@/features/docs/doc-versioning';
import { useDate } from '@/hook';
import { DocToolBox } from './DocToolBox';
interface DocHeaderProps {
doc: Doc;
+ versionId?: Versions['version_id'];
}
-export const DocHeader = ({ doc }: DocHeaderProps) => {
+export const DocHeader = ({ doc, versionId }: DocHeaderProps) => {
const { colorsTokens } = useCunninghamTheme();
const { t } = useTranslation();
const { formatDate } = useDate();
const transRole = useTransRole();
+ const [isModalVersionOpen, setIsModalVersionOpen] = useState(false);
return (
-
-
-
-
- home
-
-
-
-
- {doc.title}
-
-
-
-
+
-
- {doc.is_public && (
+
+
- {t('Public')}
+ home
- )}
+
+
+
+
+ {doc.title}
+
+ {versionId && (
+
+ )}
+
+
+
+
+
+ {doc.is_public && (
+
+ {t('Public')}
+
+ )}
+
+ {t('Created at')} {formatDate(doc.created_at)}
+
+
+ {t('Owners:')}{' '}
+
+ {doc.accesses
+ .filter(
+ (access) => access.role === Role.OWNER && access.user.email,
+ )
+ .map((access, index, accesses) => (
+
+ {access.user.email}{' '}
+ {index < accesses.length - 1 ? ' / ' : ''}
+
+ ))}
+
+
+
- {t('Created at')} {formatDate(doc.created_at)}
-
-
- {t('Owners:')}{' '}
-
- {doc.accesses
- .filter(
- (access) => access.role === Role.OWNER && access.user.email,
- )
- .map((access, index, accesses) => (
-
- {access.user.email}{' '}
- {index < accesses.length - 1 ? ' / ' : ''}
-
- ))}
-
+ {t('Your role:')}{' '}
+ {transRole(currentDocRole(doc.abilities))}
-
- {t('Your role:')}{' '}
- {transRole(currentDocRole(doc.abilities))}
-
-
-
+
+ {isModalVersionOpen && versionId && (
+ setIsModalVersionOpen(false)}
+ docId={doc.id}
+ versionId={versionId}
+ />
+ )}
+ >
);
};
diff --git a/src/frontend/apps/impress/src/features/docs/doc-versioning/components/index.ts b/src/frontend/apps/impress/src/features/docs/doc-versioning/components/index.ts
index 8960d84f..950b2de7 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-versioning/components/index.ts
+++ b/src/frontend/apps/impress/src/features/docs/doc-versioning/components/index.ts
@@ -1 +1,2 @@
+export * from './ModalVersion';
export * from './Panel';