👔(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:
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user