👔(app-impress) button to save html and css of the template

We created a button to save the template's html and css.
With the template saved we will be able to use it
in the near future with our pads.
This commit is contained in:
Anthony LC
2024-04-17 10:22:19 +02:00
committed by Anthony LC
parent faeb8d137b
commit a8248f10d2
3 changed files with 78 additions and 8 deletions

View File

@@ -59,4 +59,31 @@ test.describe('Template Editor', () => {
timeout: 5000,
});
});
test('it saves the html generated by the template', async ({
page,
browserName,
}) => {
const randomTemplate = await createTemplate(
page,
'template-html',
browserName,
1,
);
await expect(page.locator('h2').getByText(randomTemplate[0])).toBeVisible();
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('Hello World');
await iframe.locator('body.gjs-dashed').click();
await page.getByText('Save template').click();
await expect(page.getByText('Template save successfully')).toBeVisible();
});
});

View File

@@ -7,16 +7,25 @@ import { Template } from '../types';
import { KEY_TEMPLATE } from './useTemplate';
type UpdateTemplateProps = Pick<Template, 'title' | 'id'>;
type UpdateTemplateProps = {
id: Template['id'];
css?: string;
html?: string;
title?: Template['title'];
};
export const updateTemplate = async ({
title,
id,
title,
css,
html,
}: UpdateTemplateProps): Promise<Template> => {
const response = await fetchAPI(`templates/${id}/`, {
method: 'PATCH',
body: JSON.stringify({
title,
css,
code: html,
}),
});

View File

@@ -1,11 +1,18 @@
import GjsEditor from '@grapesjs/react';
import {
Button,
VariantType,
useToastProvider,
} from '@openfun/cunningham-react';
import grapesjs, { Editor, ProjectData } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
import pluginBlocksBasic from 'grapesjs-blocks-basic';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Card, Text } from '@/components';
import { Box, Text } from '@/components';
import { useUpdateTemplate } from '../api/useUpdateTemplate';
import { useUpdateTemplateCodeEditor } from '../api/useUpdateTemplateCodeEditor';
import { Template } from '../types';
@@ -14,7 +21,14 @@ interface TemplateEditorProps {
}
export const TemplateEditor = ({ template }: TemplateEditorProps) => {
const { t } = useTranslation();
const { toast } = useToastProvider();
const { mutate: updateCodeEditor } = useUpdateTemplateCodeEditor();
const { mutate: updateTemplate } = useUpdateTemplate({
onSuccess: () => {
toast(t('Template save successfully'), VariantType.SUCCESS);
},
});
const [editor, setEditor] = useState<Editor>();
useEffect(() => {
@@ -55,10 +69,30 @@ export const TemplateEditor = ({ template }: TemplateEditorProps) => {
return (
<>
<Text as="h2" $align="center">
{template.title}
</Text>
<Card className="m-b p-b" $css="margin-top:0;flex:1;" $overflow="auto">
<Box
className="m-b mb-t mt-t"
$direction="row"
$align="center"
$justify="space-between"
>
<Text as="h2" $align="center">
{template.title}
</Text>
<Button
onClick={() => {
if (editor) {
updateTemplate({
id: template.id,
css: editor.getCss(),
html: editor.getHtml(),
});
}
}}
>
{t('Save template')}
</Button>
</Box>
<Box className="m-b" $css="margin-top:0;flex:1;" $overflow="auto">
<GjsEditor
grapesjs={grapesjs}
options={{
@@ -69,7 +103,7 @@ export const TemplateEditor = ({ template }: TemplateEditorProps) => {
plugins={[(editor) => pluginBlocksBasic(editor, {})]}
onEditor={onEditor}
/>
</Card>
</Box>
</>
);
};