From 5d6ae870fac081b3fe8413b461e2aa0cece8e7ac Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 17 Apr 2024 15:14:53 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(app-impress)=20select=20template=20on?= =?UTF-8?q?=20pad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We add a template select component to the pad toolbox. This component is a dropdown that allows the user to select a template for the pad to add in a PDF. --- .../__tests__/app-impress/pad-editor.spec.ts | 87 +++++++++++++------ .../pads/pad-tools/components/PadToolBox.tsx | 53 ++++++++++- .../pad-tools/components/PrintToPDFButton.tsx | 6 +- 3 files changed, 113 insertions(+), 33 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts index fa3d31e8..0fee2b18 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/pad-editor.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import cs from 'convert-stream'; import pdf from 'pdf-parse'; -import { createPad, keyCloakSignIn } from './common'; +import { createPad, createTemplate, keyCloakSignIn } from './common'; test.beforeEach(async ({ page, browserName }) => { await page.goto('/'); @@ -51,33 +51,6 @@ test.describe('Pad Editor', () => { expect(typeCases.includes(payload.type)).toBeTruthy(); }); - test('it converts the pad to pdf with a template integrated', async ({ - page, - browserName, - }) => { - const downloadPromise = page.waitForEvent('download', (download) => { - return download.suggestedFilename().includes('impress-document.pdf'); - }); - - const randomPad = await createPad(page, 'pad-editor', browserName, 1); - await expect(page.locator('h2').getByText(randomPad[0])).toBeVisible(); - - await page.locator('.ProseMirror.bn-editor').click(); - await page.locator('.ProseMirror.bn-editor').fill('Hello World'); - - await page.getByText('Print the pad').first().click(); - - const download = await downloadPromise; - expect(download.suggestedFilename()).toBe('impress-document.pdf'); - - const pdfBuffer = await cs.toBuffer(await download.createReadStream()); - const pdfText = (await pdf(pdfBuffer)).text; - - expect(pdfText).toContain('Monsieur le Premier Ministre'); // This is the template text - expect(pdfText).toContain('La directrice'); // This is the template text - expect(pdfText).toContain('Hello World'); // This is the pad text - }); - test('markdown button converts from markdown to the editor syntax json', async ({ page, browserName, @@ -103,4 +76,62 @@ test.describe('Pad Editor', () => { }), ).toHaveAttribute('href', 'http://test-markdown.html'); }); + + test('it converts the pad to pdf with a template created', async ({ + page, + browserName, + }) => { + // eslint-disable-next-line playwright/no-skipped-test + test.skip( + browserName !== 'chromium', + 'This test failed with safary because of the dragNdrop', + ); + + const downloadPromise = page.waitForEvent('download', (download) => { + return download.suggestedFilename().includes('impress-document.pdf'); + }); + + const templates = await createTemplate( + page, + 'template-pad', + browserName, + 1, + ); + + const iframe = page.frameLocator('iFrame.gjs-frame'); + await page.getByTitle('Open Blocks').click(); + await page + .locator('.gjs-editor .gjs-block[title="Text"]') + .dragTo(iframe.locator('body.gjs-dashed')); + + await iframe + .getByText('Insert your text here') + .fill('My template ! {{body}}'); + await iframe.locator('body.gjs-dashed').click(); + + await page.getByText('Save template').click(); + + const menu = page.locator('menu').first(); + await menu.getByLabel(`Search button`).click(); + + const randomPad = await createPad(page, 'pad-editor', browserName, 1); + await expect(page.locator('h2').getByText(randomPad[0])).toBeVisible(); + + await page.locator('.ProseMirror.bn-editor').click(); + await page.locator('.ProseMirror.bn-editor').fill('And my pad !'); + + await page.getByRole('combobox', { name: 'Template' }).click(); + await page.getByRole('option', { name: templates[0] }).click(); + + await page.getByText('Generate PDF').first().click(); + + const download = await downloadPromise; + expect(download.suggestedFilename()).toBe('impress-document.pdf'); + + const pdfBuffer = await cs.toBuffer(await download.createReadStream()); + const pdfText = (await pdf(pdfBuffer)).text; + + expect(pdfText).toContain('My template !'); + expect(pdfText).toContain('And my pad !'); + }); }); diff --git a/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx b/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx index 7ade8c66..eee318c7 100644 --- a/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx +++ b/src/frontend/apps/impress/src/features/pads/pad-tools/components/PadToolBox.tsx @@ -1,7 +1,10 @@ -import React from 'react'; +import { Select } from '@openfun/cunningham-react'; +import React, { useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { Box } from '@/components'; import { Pad } from '@/features/pads/pad'; +import { TemplatesOrdering, useTemplates } from '@/features/templates'; import PrintToPDFButton from './PrintToPDFButton'; @@ -10,9 +13,53 @@ interface PadToolBoxProps { } export const PadToolBox = ({ pad }: PadToolBoxProps) => { + const { t } = useTranslation(); + const { data: templates } = useTemplates({ + ordering: TemplatesOrdering.BY_CREATED_ON_DESC, + }); + const [templateIdSelected, setTemplateIdSelected] = useState(); + + const templateOptions = useMemo(() => { + if (!templates?.pages) { + return []; + } + + const templateOptions = templates.pages + .map((page) => + page.results.map((template) => ({ + label: template.title, + value: template.id, + })), + ) + .flat(); + + if (templateOptions.length) { + setTemplateIdSelected(templateOptions[0].value); + } + + return templateOptions; + }, [templates?.pages]); + return ( - - + +