@pdfme/ui 4.5.2 → 5.0.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -11
- package/dist/index.es.js +534 -530
- package/dist/index.umd.js +14 -14
- package/dist/types/Form.d.ts +1 -1
- package/dist/types/class.d.ts +5 -2
- package/dist/types/components/Preview.d.ts +1 -1
- package/dist/types/helper.d.ts +4 -4
- package/package.json +2 -1
- package/src/Form.tsx +7 -7
- package/src/components/Designer/LeftSidebar.tsx +1 -1
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +6 -6
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +2 -2
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +3 -3
- package/src/components/Designer/RightSidebar/ListView/index.tsx +2 -2
- package/src/components/Designer/index.tsx +8 -8
- package/src/components/Preview.tsx +15 -11
- package/src/components/Renderer.tsx +1 -2
- package/src/helper.ts +56 -70
- package/src/hooks.ts +4 -4
- package/tsconfig.json +1 -1
package/dist/types/Form.d.ts
CHANGED
package/dist/types/class.d.ts
CHANGED
@@ -19,7 +19,8 @@ export declare abstract class BaseUIClass {
|
|
19
19
|
protected getPluginsRegistry(): Plugins;
|
20
20
|
protected getOptions(): {};
|
21
21
|
getTemplate(): import("zod").objectOutputType<{
|
22
|
-
schemas: import("zod").ZodArray<import("zod").
|
22
|
+
schemas: import("zod").ZodArray<import("zod").ZodArray<import("zod").ZodObject<{
|
23
|
+
name: import("zod").ZodString;
|
23
24
|
type: import("zod").ZodString;
|
24
25
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
25
26
|
position: import("zod").ZodObject<{
|
@@ -50,6 +51,7 @@ export declare abstract class BaseUIClass {
|
|
50
51
|
}>>;
|
51
52
|
__isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
52
53
|
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
54
|
+
name: import("zod").ZodString;
|
53
55
|
type: import("zod").ZodString;
|
54
56
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
55
57
|
position: import("zod").ZodObject<{
|
@@ -80,6 +82,7 @@ export declare abstract class BaseUIClass {
|
|
80
82
|
}>>;
|
81
83
|
__isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
82
84
|
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
85
|
+
name: import("zod").ZodString;
|
83
86
|
type: import("zod").ZodString;
|
84
87
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
85
88
|
position: import("zod").ZodObject<{
|
@@ -109,7 +112,7 @@ export declare abstract class BaseUIClass {
|
|
109
112
|
end?: number | undefined;
|
110
113
|
}>>;
|
111
114
|
__isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
112
|
-
}, import("zod").ZodTypeAny, "passthrough"
|
115
|
+
}, import("zod").ZodTypeAny, "passthrough">>, "many">, "many">;
|
113
116
|
basePdf: import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodType<ArrayBuffer, import("zod").ZodTypeDef, ArrayBuffer>, import("zod").ZodType<Uint8Array, import("zod").ZodTypeDef, Uint8Array>]>, import("zod").ZodObject<{
|
114
117
|
width: import("zod").ZodNumber;
|
115
118
|
height: import("zod").ZodNumber;
|
package/dist/types/helper.d.ts
CHANGED
@@ -27,12 +27,12 @@ export declare const template2SchemasList: (_template: Template) => Promise<{
|
|
27
27
|
width: number;
|
28
28
|
height: number;
|
29
29
|
type: string;
|
30
|
+
name: string;
|
30
31
|
position: {
|
31
32
|
x: number;
|
32
33
|
y: number;
|
33
34
|
};
|
34
35
|
id: string;
|
35
|
-
key: string;
|
36
36
|
opacity?: number | undefined;
|
37
37
|
rotate?: number | undefined;
|
38
38
|
required?: boolean | undefined;
|
@@ -45,10 +45,10 @@ export declare const template2SchemasList: (_template: Template) => Promise<{
|
|
45
45
|
__isSplit?: boolean | undefined;
|
46
46
|
}[][]>;
|
47
47
|
export declare const schemasList2template: (schemasList: SchemaForUI[][], basePdf: BasePdf) => Template;
|
48
|
-
export declare const
|
49
|
-
|
48
|
+
export declare const getUniqueSchemaName: (arg: {
|
49
|
+
copiedSchemaName: string;
|
50
50
|
schema: SchemaForUI[];
|
51
|
-
|
51
|
+
stackUniqueSchemaNames: string[];
|
52
52
|
}) => string;
|
53
53
|
export declare const moveCommandToChangeSchemasArg: (props: {
|
54
54
|
command: 'up' | 'down' | 'left' | 'right';
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@pdfme/ui",
|
3
|
-
"version": "
|
3
|
+
"version": "5.0.0-dev.1",
|
4
4
|
"sideEffects": false,
|
5
5
|
"author": "hand-dot",
|
6
6
|
"license": "MIT",
|
@@ -81,6 +81,7 @@
|
|
81
81
|
],
|
82
82
|
"moduleNameMapper": {
|
83
83
|
"\\.(png|css)$": "<rootDir>/__mocks__/assetsTransformer.js",
|
84
|
+
"^@pdfme/schemas/utils$": "<rootDir>/../schemas/src/utils.ts",
|
84
85
|
"^antd/es/": "antd/lib/",
|
85
86
|
"^form-render/es/": "form-render/lib/",
|
86
87
|
"^rc-picker/es/": "rc-picker/lib/",
|
package/src/Form.tsx
CHANGED
@@ -7,13 +7,13 @@ import AppContextProvider from './components/AppContextProvider';
|
|
7
7
|
import Preview from './components/Preview';
|
8
8
|
|
9
9
|
class Form extends PreviewUI {
|
10
|
-
private onChangeInputCallback?: (arg: { index: number; value: string;
|
10
|
+
private onChangeInputCallback?: (arg: { index: number; value: string; name: string }) => void;
|
11
11
|
|
12
12
|
constructor(props: PreviewProps) {
|
13
13
|
super(props);
|
14
14
|
}
|
15
15
|
|
16
|
-
public onChangeInput(cb: (arg: { index: number; value: string;
|
16
|
+
public onChangeInput(cb: (arg: { index: number; value: string; name: string }) => void) {
|
17
17
|
this.onChangeInputCallback = cb;
|
18
18
|
}
|
19
19
|
|
@@ -30,14 +30,14 @@ class Form extends PreviewUI {
|
|
30
30
|
template={this.template}
|
31
31
|
size={this.size}
|
32
32
|
inputs={this.inputs}
|
33
|
-
onChangeInput={(arg: { index: number; value: string;
|
34
|
-
const { index, value,
|
33
|
+
onChangeInput={(arg: { index: number; value: string; name: string }) => {
|
34
|
+
const { index, value, name } = arg;
|
35
35
|
if (this.onChangeInputCallback) {
|
36
|
-
this.onChangeInputCallback({ index, value,
|
36
|
+
this.onChangeInputCallback({ index, value, name });
|
37
37
|
}
|
38
38
|
if (this.inputs && this.inputs[index]) {
|
39
|
-
if (this.inputs[index][
|
40
|
-
this.inputs[index][
|
39
|
+
if (this.inputs[index][name] !== value) {
|
40
|
+
this.inputs[index][name] = value;
|
41
41
|
this.render();
|
42
42
|
}
|
43
43
|
}
|
@@ -25,7 +25,7 @@ const Draggable = (props: { plugin: Plugin<any>, scale: number, basePdf: BasePdf
|
|
25
25
|
<div style={{ transform: `scale(${scale})` }}>
|
26
26
|
<Renderer
|
27
27
|
key={defaultSchema.type}
|
28
|
-
schema={{ ...defaultSchema, id: defaultSchema.type
|
28
|
+
schema={{ ...defaultSchema, id: defaultSchema.type }}
|
29
29
|
basePdf={basePdf}
|
30
30
|
value={defaultSchema.content || ''}
|
31
31
|
onChangeHoveringSchemaId={() => { void 0 }}
|
@@ -68,10 +68,10 @@ const DetailView = (props: DetailViewProps) => {
|
|
68
68
|
useEffect(() => form.resetFields(), [activeSchema.id])
|
69
69
|
|
70
70
|
useEffect(() => {
|
71
|
-
|
71
|
+
uniqueSchemaName.current = (value: string): boolean => {
|
72
72
|
for (const page of schemasList) {
|
73
73
|
for (const s of Object.values(page)) {
|
74
|
-
if (s.
|
74
|
+
if (s.name === value && s.id !== activeSchema.id) {
|
75
75
|
return false;
|
76
76
|
}
|
77
77
|
}
|
@@ -80,9 +80,9 @@ const DetailView = (props: DetailViewProps) => {
|
|
80
80
|
};
|
81
81
|
}, [schemasList, activeSchema]);
|
82
82
|
|
83
|
-
const
|
83
|
+
const uniqueSchemaName = useRef((value: string): boolean => true);
|
84
84
|
|
85
|
-
const
|
85
|
+
const validateUniqueSchemaName = (_: any, value: string): boolean => uniqueSchemaName.current(value)
|
86
86
|
|
87
87
|
const handleWatch = debounce((formSchema: any) => {
|
88
88
|
const formAndSchemaValuesDiffer = (formValue: any, schemaValue: any): boolean => {
|
@@ -163,13 +163,13 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
163
163
|
required: true,
|
164
164
|
span: 12,
|
165
165
|
},
|
166
|
-
|
166
|
+
name: {
|
167
167
|
title: i18n('fieldName'),
|
168
168
|
type: 'string',
|
169
169
|
required: true,
|
170
170
|
span: 12,
|
171
171
|
rules: [{
|
172
|
-
validator:
|
172
|
+
validator: validateUniqueSchemaName,
|
173
173
|
message: i18n('validation.uniqueName'),
|
174
174
|
}],
|
175
175
|
props: { autoComplete: "off" }
|
@@ -159,7 +159,7 @@ const SelectableSortableContainer = (
|
|
159
159
|
<ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
|
160
160
|
<Item
|
161
161
|
icon={getPluginIcon(activeId)}
|
162
|
-
value={activeSchema.
|
162
|
+
value={activeSchema.name}
|
163
163
|
required={activeSchema.required}
|
164
164
|
readOnly={activeSchema.readOnly}
|
165
165
|
style={{ background: token.colorPrimary }}
|
@@ -173,7 +173,7 @@ const SelectableSortableContainer = (
|
|
173
173
|
<Item
|
174
174
|
icon={getPluginIcon(item)}
|
175
175
|
key={item.id}
|
176
|
-
value={item.
|
176
|
+
value={item.name}
|
177
177
|
required={item.required}
|
178
178
|
readOnly={item.readOnly}
|
179
179
|
style={{ background: token.colorPrimary }}
|
@@ -49,9 +49,9 @@ const SelectableSortableItem = ({
|
|
49
49
|
const iconStyles = { width: 20, marginRight: '0.5rem' };
|
50
50
|
|
51
51
|
let status: undefined | 'is-warning' | 'is-danger';
|
52
|
-
if (!schema.
|
52
|
+
if (!schema.name) {
|
53
53
|
status = 'is-warning';
|
54
|
-
} else if (schemas.find((s) => schema.
|
54
|
+
} else if (schemas.find((s) => schema.name && s.name === schema.name && s.id !== schema.id)) {
|
55
55
|
status = 'is-danger';
|
56
56
|
}
|
57
57
|
|
@@ -73,7 +73,7 @@ const SelectableSortableItem = ({
|
|
73
73
|
onMouseLeave={onMouseLeave}
|
74
74
|
onClick={() => onEdit(schema.id)}
|
75
75
|
icon={thisPlugin && <PluginIcon plugin={thisPlugin} label={pluginLabel} size={20} styles={iconStyles}/>}
|
76
|
-
value={schema.
|
76
|
+
value={schema.name}
|
77
77
|
status={status}
|
78
78
|
title={title}
|
79
79
|
required={schema.required}
|
@@ -45,7 +45,7 @@ const ListView = (
|
|
45
45
|
} else {
|
46
46
|
changeSchemas(
|
47
47
|
names.map((value, index) => ({
|
48
|
-
key: '
|
48
|
+
key: 'name',
|
49
49
|
value,
|
50
50
|
schemaId: schemas[index].id,
|
51
51
|
}))
|
@@ -55,7 +55,7 @@ const ListView = (
|
|
55
55
|
};
|
56
56
|
|
57
57
|
const startBulk = () => {
|
58
|
-
setFieldNamesValue(schemas.map((s) => s.
|
58
|
+
setFieldNamesValue(schemas.map((s) => s.name).join('\n'));
|
59
59
|
setIsBulkUpdateFieldNamesMode(true);
|
60
60
|
};
|
61
61
|
|
@@ -162,21 +162,21 @@ const TemplateEditor = ({
|
|
162
162
|
const [paddingTop, paddingRight, paddingBottom, paddingLeft] = isBlankPdf(template.basePdf) ? template.basePdf.padding : [0, 0, 0, 0];
|
163
163
|
const pageSize = pageSizes[pageCursor];
|
164
164
|
|
165
|
-
const
|
166
|
-
let
|
167
|
-
let
|
168
|
-
while (schemasList.some(page => page.find((s) => s.
|
169
|
-
|
170
|
-
|
165
|
+
const newSchemaName = (prefix: string) => {
|
166
|
+
let index = schemasList.reduce((acc, page) => acc + page.length, 1);
|
167
|
+
let newName = prefix + index;
|
168
|
+
while (schemasList.some(page => page.find((s) => s.name === newName))) {
|
169
|
+
index++;
|
170
|
+
newName = prefix + index;
|
171
171
|
}
|
172
|
-
return
|
172
|
+
return newName;
|
173
173
|
};
|
174
174
|
const ensureMiddleValue = (min: number, value: number, max: number) => Math.min(Math.max(min, value), max)
|
175
175
|
|
176
176
|
const s = {
|
177
177
|
id: uuid(),
|
178
|
-
key: newSchemaKey(i18n('field')),
|
179
178
|
...defaultSchema,
|
179
|
+
name: newSchemaName(i18n('field')),
|
180
180
|
position: {
|
181
181
|
x: ensureMiddleValue(paddingLeft, defaultSchema.position.x, pageSize.width - paddingRight - defaultSchema.width),
|
182
182
|
y: ensureMiddleValue(paddingTop, defaultSchema.position.y, pageSize.height - paddingBottom - defaultSchema.height),
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React, { useRef, useState, useEffect, useContext } from 'react';
|
2
2
|
import { Template, SchemaForUI, PreviewProps, Size, getDynamicTemplate } from '@pdfme/common';
|
3
|
-
import { getDynamicHeightsForTable } from '@pdfme/schemas';
|
3
|
+
import { getDynamicHeightsForTable } from '@pdfme/schemas/utils';
|
4
4
|
import UnitPager from './UnitPager';
|
5
5
|
import Root from './Root';
|
6
6
|
import ErrorScreen from './ErrorScreen';
|
@@ -20,7 +20,7 @@ const Preview = ({
|
|
20
20
|
size,
|
21
21
|
onChangeInput,
|
22
22
|
}: Omit<PreviewProps, 'domContainer'> & {
|
23
|
-
onChangeInput?: (args: { index: number; value: string;
|
23
|
+
onChangeInput?: (args: { index: number; value: string; name: string }) => void;
|
24
24
|
size: Size;
|
25
25
|
}) => {
|
26
26
|
const { token } = theme.useToken();
|
@@ -50,9 +50,13 @@ const Preview = ({
|
|
50
50
|
options,
|
51
51
|
_cache,
|
52
52
|
getDynamicHeights: (value, args) => {
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
switch (args.schema.type) {
|
54
|
+
case 'table':
|
55
|
+
return getDynamicHeightsForTable(value, args);
|
56
|
+
default:
|
57
|
+
return Promise.resolve([args.schema.height]);
|
58
|
+
}
|
59
|
+
},
|
56
60
|
})
|
57
61
|
.then(async (dynamicTemplate) => {
|
58
62
|
const sl = await template2SchemasList(dynamicTemplate);
|
@@ -78,8 +82,8 @@ const Preview = ({
|
|
78
82
|
onChangePageCursor: setPageCursor,
|
79
83
|
});
|
80
84
|
|
81
|
-
const handleChangeInput = ({
|
82
|
-
onChangeInput && onChangeInput({ index: unitCursor,
|
85
|
+
const handleChangeInput = ({ name, value }: { name: string; value: string }) =>
|
86
|
+
onChangeInput && onChangeInput({ index: unitCursor, name, value });
|
83
87
|
|
84
88
|
if (error) {
|
85
89
|
return <ErrorScreen size={size} error={error} />;
|
@@ -114,8 +118,8 @@ const Preview = ({
|
|
114
118
|
pageSizes={pageSizes}
|
115
119
|
backgrounds={backgrounds}
|
116
120
|
renderSchema={({ schema, index }) => {
|
117
|
-
const {
|
118
|
-
const content = readOnly ? String(schema.content) || '' : String(input && input[
|
121
|
+
const { name, readOnly } = schema;
|
122
|
+
const content = readOnly ? String(schema.content) || '' : String(input && input[name] || '');
|
119
123
|
return (
|
120
124
|
<Renderer
|
121
125
|
key={schema.id}
|
@@ -131,9 +135,9 @@ const Preview = ({
|
|
131
135
|
args.forEach(({ key: _key, value }) => {
|
132
136
|
if (_key === 'content') {
|
133
137
|
const newValue = value as string;
|
134
|
-
const oldValue = (input?.[
|
138
|
+
const oldValue = (input?.[name] as string) || '';
|
135
139
|
if (newValue === oldValue) return;
|
136
|
-
handleChangeInput({
|
140
|
+
handleChangeInput({ name, value: newValue });
|
137
141
|
// TODO Improve this to allow schema types to determine whether the execution of getDynamicTemplate is required.
|
138
142
|
if (schema.type === 'table') isNeedInit = true;
|
139
143
|
} else {
|
@@ -45,7 +45,7 @@ const Wrapper = ({
|
|
45
45
|
schema,
|
46
46
|
}: RendererProps & { children: ReactNode }) => (
|
47
47
|
<div
|
48
|
-
title={schema.
|
48
|
+
title={schema.name}
|
49
49
|
onMouseEnter={() => onChangeHoveringSchemaId && onChangeHoveringSchemaId(schema.id)}
|
50
50
|
onMouseLeave={() => onChangeHoveringSchemaId && onChangeHoveringSchemaId(null)}
|
51
51
|
className={SELECTABLE_CLASSNAME}
|
@@ -105,7 +105,6 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
105
105
|
const render = plugin.ui;
|
106
106
|
|
107
107
|
void render({
|
108
|
-
key: schema.key,
|
109
108
|
value,
|
110
109
|
schema,
|
111
110
|
basePdf,
|
package/src/helper.ts
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
// @ts-ignore
|
3
3
|
import PDFJSWorker from 'pdfjs-dist/legacy/build/pdf.worker.entry.js';
|
4
4
|
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist/legacy/build/pdf.js';
|
5
|
-
GlobalWorkerOptions.workerSrc = PDFJSWorker;
|
6
|
-
|
7
5
|
import hotkeys from 'hotkeys-js';
|
8
6
|
import {
|
9
7
|
cloneDeep,
|
@@ -14,13 +12,14 @@ import {
|
|
14
12
|
Template,
|
15
13
|
BasePdf,
|
16
14
|
SchemaForUI,
|
17
|
-
Schema,
|
18
15
|
Size,
|
19
16
|
isBlankPdf,
|
20
17
|
Plugins,
|
21
18
|
} from '@pdfme/common';
|
22
19
|
import { RULER_HEIGHT } from './constants.js';
|
23
20
|
|
21
|
+
GlobalWorkerOptions.workerSrc = PDFJSWorker;
|
22
|
+
|
24
23
|
export const uuid = () =>
|
25
24
|
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
26
25
|
const r = (Math.random() * 16) | 0;
|
@@ -201,13 +200,11 @@ export const getPdfPageSizes = async (pdfBlob: Blob) => {
|
|
201
200
|
|
202
201
|
const promises = Promise.all(
|
203
202
|
new Array(pdfDoc.numPages).fill('').map(async (_, i) => {
|
204
|
-
|
205
|
-
const { height, width } = page.getViewport({ scale: 1 });
|
203
|
+
return await pdfDoc.getPage(i + 1).then((page) => {
|
204
|
+
const { height, width } = page.getViewport({ scale: 1, rotation: 0 });
|
206
205
|
|
207
206
|
return { height: pt2mm(height), width: pt2mm(width) };
|
208
207
|
});
|
209
|
-
|
210
|
-
return pageSize;
|
211
208
|
})
|
212
209
|
);
|
213
210
|
|
@@ -222,20 +219,18 @@ const pdf2Images = async (pdfBlob: Blob, width: number, imageType: 'png' | 'jpeg
|
|
222
219
|
|
223
220
|
const promises = Promise.all(
|
224
221
|
new Array(pdfDoc.numPages).fill('').map(async (_, i) => {
|
225
|
-
|
222
|
+
return await pdfDoc.getPage(i + 1).then((page) => {
|
226
223
|
const canvas = document.createElement('canvas');
|
227
224
|
canvas.width = width * 2;
|
228
225
|
const canvasContext = canvas.getContext('2d')!;
|
229
|
-
const scaleRequired = canvas.width / page.getViewport({ scale: 1 }).width;
|
230
|
-
const viewport = page.getViewport({ scale: scaleRequired });
|
226
|
+
const scaleRequired = canvas.width / page.getViewport({ scale: 1, rotation: 0 }).width;
|
227
|
+
const viewport = page.getViewport({ scale: scaleRequired, rotation: 0 });
|
231
228
|
canvas.height = viewport.height;
|
232
229
|
|
233
230
|
return page
|
234
231
|
.render({ canvasContext, viewport })
|
235
232
|
.promise.then(() => canvas.toDataURL(`image/${imageType}`));
|
236
233
|
});
|
237
|
-
|
238
|
-
return image;
|
239
234
|
})
|
240
235
|
);
|
241
236
|
URL.revokeObjectURL(url);
|
@@ -246,31 +241,27 @@ const pdf2Images = async (pdfBlob: Blob, width: number, imageType: 'png' | 'jpeg
|
|
246
241
|
export const pdf2Pngs = (pdfBlob: Blob, width: number) => pdf2Images(pdfBlob, width, 'png');
|
247
242
|
|
248
243
|
export const b64toBlob = (base64: string) => {
|
249
|
-
const
|
244
|
+
const uint8Array = b64toUint8Array(base64);
|
250
245
|
const [, , mimeType] = base64.match(/(:)([a-z/]+)(;)/)!;
|
251
246
|
|
252
|
-
return new Blob([
|
247
|
+
return new Blob([uint8Array.buffer], { type: mimeType });
|
253
248
|
};
|
254
249
|
|
255
|
-
const
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
)
|
265
|
-
: []
|
266
|
-
);
|
267
|
-
return acc;
|
268
|
-
}, [] as SchemaForUI[][]);
|
250
|
+
const convertSchemasForUI = (template: Template): SchemaForUI[][] => {
|
251
|
+
template.schemas.forEach((page, i) => {
|
252
|
+
page.forEach((schema) => {
|
253
|
+
schema.id = uuid();
|
254
|
+
schema.content = schema.content || '';
|
255
|
+
});
|
256
|
+
});
|
257
|
+
|
258
|
+
return template.schemas as SchemaForUI[][];
|
269
259
|
};
|
260
|
+
|
270
261
|
export const template2SchemasList = async (_template: Template) => {
|
271
262
|
const template = cloneDeep(_template);
|
272
263
|
const { basePdf, schemas } = template;
|
273
|
-
const
|
264
|
+
const schemasForUI = convertSchemasForUI(template);
|
274
265
|
|
275
266
|
let pageSizes: Size[] = [];
|
276
267
|
if (isBlankPdf(basePdf)) {
|
@@ -284,12 +275,13 @@ export const template2SchemasList = async (_template: Template) => {
|
|
284
275
|
pageSizes = await getPdfPageSizes(pdfBlob);
|
285
276
|
}
|
286
277
|
|
287
|
-
const ssl =
|
278
|
+
const ssl = schemasForUI.length;
|
288
279
|
const psl = pageSizes.length;
|
289
|
-
|
280
|
+
|
281
|
+
return (
|
290
282
|
ssl < psl
|
291
|
-
?
|
292
|
-
:
|
283
|
+
? schemasForUI.concat(new Array(psl - ssl).fill(cloneDeep([])))
|
284
|
+
: schemasForUI.slice(0, pageSizes.length)
|
293
285
|
).map((schema, i) => {
|
294
286
|
Object.values(schema).forEach((value) => {
|
295
287
|
const { width, height } = pageSizes[i];
|
@@ -307,60 +299,54 @@ export const template2SchemasList = async (_template: Template) => {
|
|
307
299
|
|
308
300
|
return schema;
|
309
301
|
});
|
310
|
-
return schemasList;
|
311
302
|
};
|
312
303
|
|
313
304
|
export const schemasList2template = (schemasList: SchemaForUI[][], basePdf: BasePdf): Template => ({
|
314
|
-
schemas: cloneDeep(schemasList).map((
|
315
|
-
|
316
|
-
const k = cur.key;
|
305
|
+
schemas: cloneDeep(schemasList).map((page) =>
|
306
|
+
page.map((schema) => {
|
317
307
|
// @ts-ignore
|
318
|
-
delete
|
319
|
-
|
320
|
-
|
321
|
-
acc[k] = cur;
|
322
|
-
|
323
|
-
return acc;
|
324
|
-
}, {} as { [key: string]: Schema })
|
308
|
+
delete schema.id;
|
309
|
+
return schema;
|
310
|
+
})
|
325
311
|
),
|
326
312
|
basePdf,
|
327
313
|
});
|
328
314
|
|
329
|
-
export const
|
330
|
-
|
315
|
+
export const getUniqueSchemaName = (arg: {
|
316
|
+
copiedSchemaName: string;
|
331
317
|
schema: SchemaForUI[];
|
332
|
-
|
318
|
+
stackUniqueSchemaNames: string[];
|
333
319
|
}) => {
|
334
|
-
const {
|
335
|
-
const
|
336
|
-
const tmp: { [
|
337
|
-
(acc, cur) => Object.assign(acc, {
|
320
|
+
const { copiedSchemaName, schema, stackUniqueSchemaNames } = arg;
|
321
|
+
const schemaNames = schema.map((s) => s.name).concat(stackUniqueSchemaNames);
|
322
|
+
const tmp: { [originalName: string]: number } = schemaNames.reduce(
|
323
|
+
(acc, cur) => Object.assign(acc, { originalName: cur, copiedNum: 0 }),
|
338
324
|
{}
|
339
325
|
);
|
340
|
-
const
|
341
|
-
|
342
|
-
.filter((
|
343
|
-
.forEach((
|
344
|
-
const
|
345
|
-
const match =
|
326
|
+
const extractOriginalName = (name: string) => name.replace(/ copy$| copy [0-9]*$/, '');
|
327
|
+
schemaNames
|
328
|
+
.filter((name) => / copy$| copy [0-9]*$/.test(name))
|
329
|
+
.forEach((name) => {
|
330
|
+
const originalName = extractOriginalName(name);
|
331
|
+
const match = name.match(/[0-9]*$/);
|
346
332
|
const copiedNum = match && match[0] ? Number(match[0]) : 1;
|
347
|
-
if ((tmp[
|
348
|
-
tmp[
|
333
|
+
if ((tmp[originalName] ?? 0) < copiedNum) {
|
334
|
+
tmp[originalName] = copiedNum;
|
349
335
|
}
|
350
336
|
});
|
351
337
|
|
352
|
-
const
|
353
|
-
if (tmp[
|
354
|
-
const copiedNum = tmp[
|
355
|
-
const
|
356
|
-
|
338
|
+
const originalName = extractOriginalName(copiedSchemaName);
|
339
|
+
if (tmp[originalName]) {
|
340
|
+
const copiedNum = tmp[originalName];
|
341
|
+
const uniqueName = `${originalName} copy ${copiedNum + 1}`;
|
342
|
+
stackUniqueSchemaNames.push(uniqueName);
|
357
343
|
|
358
|
-
return
|
344
|
+
return uniqueName;
|
359
345
|
}
|
360
|
-
const
|
361
|
-
|
346
|
+
const uniqueName = `${copiedSchemaName} copy`;
|
347
|
+
stackUniqueSchemaNames.push(uniqueName);
|
362
348
|
|
363
|
-
return
|
349
|
+
return uniqueName;
|
364
350
|
};
|
365
351
|
|
366
352
|
export const moveCommandToChangeSchemasArg = (props: {
|
@@ -447,7 +433,7 @@ const handleTypeChange = (
|
|
447
433
|
pluginsRegistry: Plugins
|
448
434
|
) => {
|
449
435
|
if (key !== 'type') return;
|
450
|
-
const keysToKeep = ['id', '
|
436
|
+
const keysToKeep = ['id', 'name', 'type', 'position', 'required'];
|
451
437
|
Object.keys(schema).forEach((key) => {
|
452
438
|
if (!keysToKeep.includes(key)) {
|
453
439
|
delete schema[key as keyof typeof schema];
|
@@ -491,4 +477,4 @@ export const changeSchemas = (args: {
|
|
491
477
|
return acc;
|
492
478
|
}, cloneDeep(schemas));
|
493
479
|
commitSchemas(newSchemas);
|
494
|
-
};
|
480
|
+
};
|
package/src/hooks.ts
CHANGED
@@ -13,7 +13,7 @@ import {
|
|
13
13
|
import {
|
14
14
|
schemasList2template,
|
15
15
|
uuid,
|
16
|
-
|
16
|
+
getUniqueSchemaName,
|
17
17
|
moveCommandToChangeSchemasArg,
|
18
18
|
pdf2Pngs,
|
19
19
|
getPdfPageSizes,
|
@@ -227,10 +227,10 @@ export const useInitEvents = ({
|
|
227
227
|
paste: () => {
|
228
228
|
if (!copiedSchemas.current || copiedSchemas.current.length === 0) return;
|
229
229
|
const schema = schemasList[pageCursor];
|
230
|
-
const
|
230
|
+
const stackUniqueSchemaNames: string[] = [];
|
231
231
|
const pasteSchemas = copiedSchemas.current.map((cs) => {
|
232
232
|
const id = uuid();
|
233
|
-
const
|
233
|
+
const name = getUniqueSchemaName({ copiedSchemaName: cs.name, schema, stackUniqueSchemaNames });
|
234
234
|
const { height, width, position: p } = cs;
|
235
235
|
const ps = pageSizes[pageCursor];
|
236
236
|
const position = {
|
@@ -238,7 +238,7 @@ export const useInitEvents = ({
|
|
238
238
|
y: p.y + 10 > ps.height - height ? ps.height - height : p.y + 10,
|
239
239
|
};
|
240
240
|
|
241
|
-
return Object.assign(cloneDeep(cs), { id,
|
241
|
+
return Object.assign(cloneDeep(cs), { id, name, position });
|
242
242
|
});
|
243
243
|
commitSchemas(schemasList[pageCursor].concat(pasteSchemas));
|
244
244
|
onEdit(pasteSchemas.map((s) => document.getElementById(s.id)!));
|