🔥(frontend) remove all code related to template
The template feature is removed from the frontend applications. It was used mainly for document export with predefined templates.
This commit is contained in:
@@ -35,9 +35,6 @@ test.describe('Doc Export', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByText(/Download your document in a \.docx, \.odt.*format\./i),
|
page.getByText(/Download your document in a \.docx, \.odt.*format\./i),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
await expect(
|
|
||||||
page.getByRole('combobox', { name: 'Template' }),
|
|
||||||
).toBeVisible();
|
|
||||||
await expect(page.getByRole('combobox', { name: 'Format' })).toBeVisible();
|
await expect(page.getByRole('combobox', { name: 'Format' })).toBeVisible();
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', {
|
page.getByRole('button', {
|
||||||
@@ -236,20 +233,6 @@ test.describe('Doc Export', () => {
|
|||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
await page
|
|
||||||
.getByRole('combobox', {
|
|
||||||
name: 'Template',
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await page
|
|
||||||
.getByRole('option', {
|
|
||||||
name: 'Demo Template',
|
|
||||||
})
|
|
||||||
.click({
|
|
||||||
delay: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
|
await expect(page.getByTestId('doc-export-download-button')).toBeVisible();
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import { useMutation } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { APIError, errorCauses, fetchAPI } from '@/api';
|
|
||||||
|
|
||||||
interface CreateExportParams {
|
|
||||||
templateId: string;
|
|
||||||
body: string;
|
|
||||||
body_type: 'html' | 'markdown';
|
|
||||||
format: 'pdf' | 'docx';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createExport = async ({
|
|
||||||
templateId,
|
|
||||||
body,
|
|
||||||
body_type,
|
|
||||||
format,
|
|
||||||
}: CreateExportParams): Promise<Blob> => {
|
|
||||||
const response = await fetchAPI(
|
|
||||||
`templates/${templateId}/generate-document/`,
|
|
||||||
{
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
body,
|
|
||||||
body_type,
|
|
||||||
format,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new APIError(
|
|
||||||
'Failed to export the document',
|
|
||||||
await errorCauses(response),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await response.blob();
|
|
||||||
};
|
|
||||||
|
|
||||||
export function useExport() {
|
|
||||||
return useMutation<Blob, APIError, CreateExportParams>({
|
|
||||||
mutationFn: createExport,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
import {
|
|
||||||
DefinedInitialDataInfiniteOptions,
|
|
||||||
InfiniteData,
|
|
||||||
QueryKey,
|
|
||||||
useInfiniteQuery,
|
|
||||||
} from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { APIError, APIList, errorCauses, fetchAPI } from '@/api';
|
|
||||||
|
|
||||||
import { Template } from '../types';
|
|
||||||
|
|
||||||
export enum TemplatesOrdering {
|
|
||||||
BY_CREATED_ON = 'created_at',
|
|
||||||
BY_CREATED_ON_DESC = '-created_at',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TemplatesParams = {
|
|
||||||
ordering: TemplatesOrdering;
|
|
||||||
};
|
|
||||||
type TemplatesAPIParams = TemplatesParams & {
|
|
||||||
page: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TemplatesResponse = APIList<Template>;
|
|
||||||
|
|
||||||
export const getTemplates = async ({
|
|
||||||
ordering,
|
|
||||||
page,
|
|
||||||
}: TemplatesAPIParams): Promise<TemplatesResponse> => {
|
|
||||||
const orderingQuery = ordering ? `&ordering=${ordering}` : '';
|
|
||||||
const response = await fetchAPI(`templates/?page=${page}${orderingQuery}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new APIError(
|
|
||||||
'Failed to get the templates',
|
|
||||||
await errorCauses(response),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json() as Promise<TemplatesResponse>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const KEY_LIST_TEMPLATE = 'templates';
|
|
||||||
|
|
||||||
export function useTemplates(
|
|
||||||
param: TemplatesParams,
|
|
||||||
queryConfig?: DefinedInitialDataInfiniteOptions<
|
|
||||||
TemplatesResponse,
|
|
||||||
APIError,
|
|
||||||
InfiniteData<TemplatesResponse>,
|
|
||||||
QueryKey,
|
|
||||||
number
|
|
||||||
>,
|
|
||||||
) {
|
|
||||||
return useInfiniteQuery<
|
|
||||||
TemplatesResponse,
|
|
||||||
APIError,
|
|
||||||
InfiniteData<TemplatesResponse>,
|
|
||||||
QueryKey,
|
|
||||||
number
|
|
||||||
>({
|
|
||||||
initialPageParam: 1,
|
|
||||||
queryKey: [KEY_LIST_TEMPLATE, param],
|
|
||||||
queryFn: ({ pageParam }) =>
|
|
||||||
getTemplates({
|
|
||||||
...param,
|
|
||||||
page: pageParam,
|
|
||||||
}),
|
|
||||||
getNextPageParam(lastPage, allPages) {
|
|
||||||
return lastPage.next ? allPages.length + 1 : undefined;
|
|
||||||
},
|
|
||||||
...queryConfig,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,7 @@ import { DocumentProps, pdf } from '@react-pdf/renderer';
|
|||||||
import jsonemoji from 'emoji-datasource-apple' assert { type: 'json' };
|
import jsonemoji from 'emoji-datasource-apple' assert { type: 'json' };
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import { cloneElement, isValidElement, useMemo, useState } from 'react';
|
import { cloneElement, isValidElement, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { css } from 'styled-components';
|
import { css } from 'styled-components';
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@ import { Doc, useTrans } from '@/docs/doc-management';
|
|||||||
import { fallbackLng } from '@/i18n/config';
|
import { fallbackLng } from '@/i18n/config';
|
||||||
|
|
||||||
import { exportCorsResolveFileUrl } from '../api/exportResolveFileUrl';
|
import { exportCorsResolveFileUrl } from '../api/exportResolveFileUrl';
|
||||||
import { TemplatesOrdering, useTemplates } from '../api/useTemplates';
|
|
||||||
import { docxDocsSchemaMappings } from '../mappingDocx';
|
import { docxDocsSchemaMappings } from '../mappingDocx';
|
||||||
import { odtDocsSchemaMappings } from '../mappingODT';
|
import { odtDocsSchemaMappings } from '../mappingODT';
|
||||||
import { pdfDocsSchemaMappings } from '../mappingPDF';
|
import { pdfDocsSchemaMappings } from '../mappingPDF';
|
||||||
@@ -50,12 +49,8 @@ interface ModalExportProps {
|
|||||||
|
|
||||||
export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
|
export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { data: templates } = useTemplates({
|
|
||||||
ordering: TemplatesOrdering.BY_CREATED_ON_DESC,
|
|
||||||
});
|
|
||||||
const { toast } = useToastProvider();
|
const { toast } = useToastProvider();
|
||||||
const { editor } = useEditorStore();
|
const { editor } = useEditorStore();
|
||||||
const [templateSelected, setTemplateSelected] = useState<string>('');
|
|
||||||
const [isExporting, setIsExporting] = useState(false);
|
const [isExporting, setIsExporting] = useState(false);
|
||||||
const [format, setFormat] = useState<DocDownloadFormat>(
|
const [format, setFormat] = useState<DocDownloadFormat>(
|
||||||
DocDownloadFormat.PDF,
|
DocDownloadFormat.PDF,
|
||||||
@@ -63,24 +58,6 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
|
|||||||
const { untitledDocument } = useTrans();
|
const { untitledDocument } = useTrans();
|
||||||
const mediaUrl = useMediaUrl();
|
const mediaUrl = useMediaUrl();
|
||||||
|
|
||||||
const templateOptions = useMemo(() => {
|
|
||||||
const templateOptions = (templates?.pages || [])
|
|
||||||
.map((page) =>
|
|
||||||
page.results.map((template) => ({
|
|
||||||
label: template.title,
|
|
||||||
value: template.code,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.flat();
|
|
||||||
|
|
||||||
templateOptions.unshift({
|
|
||||||
label: t('Empty template'),
|
|
||||||
value: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
return templateOptions;
|
|
||||||
}, [t, templates?.pages]);
|
|
||||||
|
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
toast(t('The export failed'), VariantType.ERROR);
|
toast(t('The export failed'), VariantType.ERROR);
|
||||||
@@ -97,13 +74,7 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
|
|||||||
|
|
||||||
const documentTitle = doc.title || untitledDocument;
|
const documentTitle = doc.title || untitledDocument;
|
||||||
|
|
||||||
const html = templateSelected;
|
const exportDocument = editor.document;
|
||||||
let exportDocument = editor.document;
|
|
||||||
if (html) {
|
|
||||||
const blockTemplate = await editor.tryParseHTMLToBlocks(html);
|
|
||||||
exportDocument = [...blockTemplate, ...editor.document];
|
|
||||||
}
|
|
||||||
|
|
||||||
let blobExport: Blob;
|
let blobExport: Blob;
|
||||||
if (format === DocDownloadFormat.PDF) {
|
if (format === DocDownloadFormat.PDF) {
|
||||||
const exporter = new PDFExporter(editor.schema, pdfDocsSchemaMappings, {
|
const exporter = new PDFExporter(editor.schema, pdfDocsSchemaMappings, {
|
||||||
@@ -290,17 +261,6 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
|
|||||||
setFormat(options.target.value as DocDownloadFormat)
|
setFormat(options.target.value as DocDownloadFormat)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Select
|
|
||||||
clearable={false}
|
|
||||||
fullWidth
|
|
||||||
label={t('Template')}
|
|
||||||
options={templateOptions}
|
|
||||||
value={templateSelected}
|
|
||||||
disabled={format === DocDownloadFormat.HTML}
|
|
||||||
onChange={(options) =>
|
|
||||||
setTemplateSelected(options.target.value as string)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isExporting && (
|
{isExporting && (
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
@@ -13,24 +13,6 @@ import {
|
|||||||
DocsInlineContentSchema,
|
DocsInlineContentSchema,
|
||||||
DocsStyleSchema,
|
DocsStyleSchema,
|
||||||
} from '../doc-editor';
|
} from '../doc-editor';
|
||||||
import { Access } from '../doc-management';
|
|
||||||
|
|
||||||
export interface Template {
|
|
||||||
id: string;
|
|
||||||
abilities: {
|
|
||||||
destroy: boolean;
|
|
||||||
generate_document: boolean;
|
|
||||||
accesses_manage: boolean;
|
|
||||||
retrieve: boolean;
|
|
||||||
update: boolean;
|
|
||||||
partial_update: boolean;
|
|
||||||
};
|
|
||||||
accesses: Access[];
|
|
||||||
title: string;
|
|
||||||
is_public: boolean;
|
|
||||||
css: string;
|
|
||||||
code: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DocsExporterPDF = Exporter<
|
export type DocsExporterPDF = Exporter<
|
||||||
NoInfer<DocsBlockSchema>,
|
NoInfer<DocsBlockSchema>,
|
||||||
|
|||||||
Reference in New Issue
Block a user