@servicetitan/dte-pdf-editor 1.2.0 → 1.3.0
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/dist/components/field-config-panel.d.ts.map +1 -1
- package/dist/components/field-config-panel.js +4 -2
- package/dist/components/field-config-panel.js.map +1 -1
- package/dist/components/fillable-field-type-list.d.ts.map +1 -1
- package/dist/components/fillable-field-type-list.js +4 -1
- package/dist/components/fillable-field-type-list.js.map +1 -1
- package/dist/components/pdf-editor.d.ts.map +1 -1
- package/dist/components/pdf-editor.js +9 -3
- package/dist/components/pdf-editor.js.map +1 -1
- package/dist/components/pdf-field-overlay.d.ts +10 -0
- package/dist/components/pdf-field-overlay.d.ts.map +1 -1
- package/dist/components/pdf-field-overlay.js +46 -18
- package/dist/components/pdf-field-overlay.js.map +1 -1
- package/dist/components/pdf-view-fields.d.ts +17 -0
- package/dist/components/pdf-view-fields.d.ts.map +1 -0
- package/dist/components/pdf-view-fields.js +53 -0
- package/dist/components/pdf-view-fields.js.map +1 -0
- package/dist/components/pdf-view.d.ts +19 -0
- package/dist/components/pdf-view.d.ts.map +1 -0
- package/dist/components/pdf-view.js +32 -0
- package/dist/components/pdf-view.js.map +1 -0
- package/dist/components/resize-handle.d.ts +7 -0
- package/dist/components/resize-handle.d.ts.map +1 -0
- package/dist/components/resize-handle.js +5 -0
- package/dist/components/resize-handle.js.map +1 -0
- package/dist/constants/field.constants.d.ts +7 -3
- package/dist/constants/field.constants.d.ts.map +1 -1
- package/dist/constants/field.constants.js +10 -3
- package/dist/constants/field.constants.js.map +1 -1
- package/dist/hooks/useFieldResize.d.ts +1 -1
- package/dist/hooks/useFieldResize.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interface/pdf-editor.d.ts +1 -1
- package/dist/interface/pdf-editor.d.ts.map +1 -1
- package/dist/utils/generate-fillable-path.d.ts +2 -0
- package/dist/utils/generate-fillable-path.d.ts.map +1 -0
- package/dist/utils/generate-fillable-path.js +4 -0
- package/dist/utils/generate-fillable-path.js.map +1 -0
- package/dist/utils/get-field-background-color.d.ts +2 -0
- package/dist/utils/get-field-background-color.d.ts.map +1 -0
- package/dist/utils/get-field-background-color.js +4 -0
- package/dist/utils/get-field-background-color.js.map +1 -0
- package/dist/utils/get-field-placeholder-text.d.ts +3 -0
- package/dist/utils/get-field-placeholder-text.d.ts.map +1 -0
- package/dist/utils/get-field-placeholder-text.js +7 -0
- package/dist/utils/get-field-placeholder-text.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/parse-fillable-path.d.ts +2 -0
- package/dist/utils/parse-fillable-path.d.ts.map +1 -0
- package/dist/utils/parse-fillable-path.js +9 -0
- package/dist/utils/parse-fillable-path.js.map +1 -0
- package/dist/utils/resolve-pdf-data-values.d.ts +2 -0
- package/dist/utils/resolve-pdf-data-values.d.ts.map +1 -0
- package/dist/utils/resolve-pdf-data-values.js +27 -0
- package/dist/utils/resolve-pdf-data-values.js.map +1 -0
- package/package.json +1 -1
- package/src/components/field-config-panel.tsx +13 -1
- package/src/components/fillable-field-type-list.tsx +6 -1
- package/src/components/pdf-editor.tsx +8 -1
- package/src/components/pdf-field-overlay.tsx +147 -48
- package/src/components/pdf-view-fields.tsx +138 -0
- package/src/components/pdf-view.tsx +99 -0
- package/src/components/resize-handle.tsx +8 -0
- package/src/constants/field.constants.ts +16 -3
- package/src/hooks/useFieldResize.ts +1 -1
- package/src/index.ts +1 -0
- package/src/interface/pdf-editor.ts +1 -1
- package/src/styles/pdf-field-overlay.css +34 -9
- package/src/utils/generate-fillable-path.ts +3 -0
- package/src/utils/get-field-background-color.ts +6 -0
- package/src/utils/get-field-placeholder-text.ts +8 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/parse-fillable-path.ts +8 -0
- package/src/utils/resolve-pdf-data-values.ts +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-fillable-path.d.ts","sourceRoot":"","sources":["../../src/utils/generate-fillable-path.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,GAAI,WAAW,MAAM,EAAE,MAAM,MAAM,KAAG,MAEtE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-fillable-path.js","sourceRoot":"","sources":["../../src/utils/generate-fillable-path.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAiB,EAAE,IAAY,EAAU,EAAE;IAC5E,OAAO,YAAY,SAAS,IAAI,IAAI,EAAE,CAAC;AAC3C,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-field-background-color.d.ts","sourceRoot":"","sources":["../../src/utils/get-field-background-color.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,GAChC,WAAW,MAAM,GAAG,SAAS,EAC7B,kBAAkB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACzC,MAEF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-field-background-color.js","sourceRoot":"","sources":["../../src/utils/get-field-background-color.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACnC,SAA6B,EAC7B,gBAAwC,EAClC,EAAE;IACR,OAAO,SAAS,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3F,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-field-placeholder-text.d.ts","sourceRoot":"","sources":["../../src/utils/get-field-placeholder-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,eAAO,MAAM,uBAAuB,GAAI,OAAO,QAAQ,EAAE,SAAS,MAAM,KAAG,MAK1E,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const getFieldPlaceholderText = (field, prefix) => {
|
|
2
|
+
const requiredIndicator = field.required ? '*' : '';
|
|
3
|
+
const label = field.label || '';
|
|
4
|
+
const parts = [prefix, label, requiredIndicator].filter(Boolean);
|
|
5
|
+
return parts.join(' ');
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=get-field-placeholder-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-field-placeholder-text.js","sourceRoot":"","sources":["../../src/utils/get-field-placeholder-text.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAe,EAAE,MAAe,EAAU,EAAE;IAChF,MAAM,iBAAiB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -10,4 +10,9 @@ export * from './is-drag-over-canvas.utils';
|
|
|
10
10
|
export * from './map-colors-to-recipients';
|
|
11
11
|
export * from './pdfjs-init';
|
|
12
12
|
export * from './generate-e-sign-path';
|
|
13
|
+
export * from './resolve-pdf-data-values';
|
|
14
|
+
export * from './generate-fillable-path';
|
|
15
|
+
export * from './get-field-background-color';
|
|
16
|
+
export * from './get-field-placeholder-text';
|
|
17
|
+
export * from './parse-fillable-path';
|
|
13
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -10,4 +10,9 @@ export * from './is-drag-over-canvas.utils';
|
|
|
10
10
|
export * from './map-colors-to-recipients';
|
|
11
11
|
export * from './pdfjs-init';
|
|
12
12
|
export * from './generate-e-sign-path';
|
|
13
|
+
export * from './resolve-pdf-data-values';
|
|
14
|
+
export * from './generate-fillable-path';
|
|
15
|
+
export * from './get-field-background-color';
|
|
16
|
+
export * from './get-field-placeholder-text';
|
|
17
|
+
export * from './parse-fillable-path';
|
|
13
18
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-fillable-path.d.ts","sourceRoot":"","sources":["../../src/utils/parse-fillable-path.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,GAAG,SAAS,KAAG,MAOhE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-fillable-path.js","sourceRoot":"","sources":["../../src/utils/parse-fillable-path.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAwB,EAAU,EAAE;IACtE,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,2CAA2C;IAC3C,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-pdf-data-values.d.ts","sourceRoot":"","sources":["../../src/utils/resolve-pdf-data-values.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,GAC7B,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,EACrC,MAAM,MAAM,GAAG,SAAS,KACzB,MA8BF,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const resolvePdfDataValues = (data, path) => {
|
|
2
|
+
if (!data || !path) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
const keys = path.split('.');
|
|
6
|
+
let value = data;
|
|
7
|
+
for (const key of keys) {
|
|
8
|
+
if (value === null || value === undefined || typeof value !== 'object') {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
value = value[key];
|
|
12
|
+
}
|
|
13
|
+
if (value === null || value === undefined) {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'object') {
|
|
17
|
+
if ('Amount' in value && 'Currency' in value) {
|
|
18
|
+
return `${value.Currency} ${value.Amount}`;
|
|
19
|
+
}
|
|
20
|
+
if ('Value' in value) {
|
|
21
|
+
return String(value.Value);
|
|
22
|
+
}
|
|
23
|
+
return JSON.stringify(value);
|
|
24
|
+
}
|
|
25
|
+
return String(value);
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=resolve-pdf-data-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-pdf-data-values.js","sourceRoot":"","sources":["../../src/utils/resolve-pdf-data-values.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAChC,IAAqC,EACrC,IAAwB,EAClB,EAAE;IACR,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,GAAQ,IAAI,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrE,OAAO,EAAE,CAAC;QACd,CAAC;QACD,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,QAAQ,IAAI,KAAK,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YAC3C,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import { Button, Checkbox, Combobox, Flex, TextField } from '@servicetitan/anvil
|
|
|
2
2
|
import { FC, useMemo } from 'react';
|
|
3
3
|
import { E_SIGN_FIELD_TYPE_OPTIONS } from '../constants';
|
|
4
4
|
import { ESignFieldType, FieldTypeEnum, PdfField } from '../interface/pdf-editor';
|
|
5
|
-
import { generateESignPath } from '../utils';
|
|
5
|
+
import { generateESignPath, generateFillablePath, parseFillablePathName } from '../utils';
|
|
6
6
|
import { RecipientInfo } from './pdf-editor';
|
|
7
7
|
|
|
8
8
|
interface FieldConfigPanelProps {
|
|
@@ -123,6 +123,17 @@ export const FieldConfigPanel: FC<FieldConfigPanelProps> = ({
|
|
|
123
123
|
{field.type === FieldTypeEnum.dataModel && field.path && (
|
|
124
124
|
<TextField label="Data Path" value={field.path} disabled />
|
|
125
125
|
)}
|
|
126
|
+
{field.type === FieldTypeEnum.fillable && (
|
|
127
|
+
<TextField
|
|
128
|
+
label="Input Name"
|
|
129
|
+
value={parseFillablePathName(field.path)}
|
|
130
|
+
onChange={e =>
|
|
131
|
+
onFieldConfigChange({
|
|
132
|
+
path: generateFillablePath(field.recipient!, e.target.value),
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
/>
|
|
136
|
+
)}
|
|
126
137
|
{field.type === FieldTypeEnum.fillable && (
|
|
127
138
|
<Checkbox
|
|
128
139
|
label="Required"
|
|
@@ -134,6 +145,7 @@ export const FieldConfigPanel: FC<FieldConfigPanelProps> = ({
|
|
|
134
145
|
}
|
|
135
146
|
/>
|
|
136
147
|
)}
|
|
148
|
+
|
|
137
149
|
<Button className="full-width" onClick={onDeleteField}>
|
|
138
150
|
Delete Field
|
|
139
151
|
</Button>
|
|
@@ -33,7 +33,12 @@ export const FillableFieldTypeList: FC<FillableFieldTypeListProps> = ({
|
|
|
33
33
|
key={fieldOption.subType}
|
|
34
34
|
label={fieldOption.label}
|
|
35
35
|
onDragEnd={onDragEnd}
|
|
36
|
-
onDragStart={() =>
|
|
36
|
+
onDragStart={() =>
|
|
37
|
+
onDragStart({
|
|
38
|
+
...fieldOption,
|
|
39
|
+
label: '',
|
|
40
|
+
})
|
|
41
|
+
}
|
|
37
42
|
/>
|
|
38
43
|
);
|
|
39
44
|
})}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Flex } from '@servicetitan/anvil2';
|
|
2
2
|
import { DragEvent, FC, MouseEvent, ReactNode, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
-
import { FIELD_CONSTANTS } from '../constants';
|
|
4
|
+
import { FIELD_CONSTANTS, FILLABLE_FIELD_DEFAULT_SIZES } from '../constants';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
ESignFieldType,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
calculateDropCoordinates,
|
|
16
16
|
extractGroupedFieldsFromDataModel,
|
|
17
17
|
generateESignPath,
|
|
18
|
+
generateFillablePath,
|
|
18
19
|
initializePdfJsWorker,
|
|
19
20
|
isDragOverCanvas,
|
|
20
21
|
mapColorsToRecipients,
|
|
@@ -104,8 +105,14 @@ export const PdfEditor: FC<PdfEditorProps> = ({
|
|
|
104
105
|
);
|
|
105
106
|
}
|
|
106
107
|
if (draggedFieldOption.type === FieldTypeEnum.fillable) {
|
|
108
|
+
const defaultFieldSizes = FILLABLE_FIELD_DEFAULT_SIZES[newField.subType!];
|
|
107
109
|
newField.recipient = recipients[0]?.name ?? '';
|
|
108
110
|
newField.required = false;
|
|
111
|
+
newField.path = generateFillablePath(recipients[0]?.name ?? '', uuidv4());
|
|
112
|
+
if (defaultFieldSizes) {
|
|
113
|
+
newField.width = defaultFieldSizes.width;
|
|
114
|
+
newField.height = defaultFieldSizes.height;
|
|
115
|
+
}
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
onFieldsChange([...fields, newField]);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { FC, MouseEvent, RefObject } from 'react';
|
|
2
|
-
import { useFieldDrag, useFieldResize } from '../hooks';
|
|
1
|
+
import { FC, Fragment, MouseEvent, RefObject, useMemo } from 'react';
|
|
2
|
+
import { useFieldDrag, useFieldResize, UseFieldResizeReturn } from '../hooks';
|
|
3
3
|
import { FieldTypeEnum, PdfField } from '../interface/pdf-editor';
|
|
4
|
-
import { getPagePosition } from '../utils';
|
|
4
|
+
import { getFieldBackgroundColor, getFieldPlaceholderText, getPagePosition } from '../utils';
|
|
5
|
+
import { ResizeHandle } from './resize-handle';
|
|
5
6
|
|
|
6
7
|
interface PdfFieldOverlayProps {
|
|
7
8
|
fields: PdfField[];
|
|
@@ -21,63 +22,161 @@ export const PdfFieldOverlay: FC<PdfFieldOverlayProps> = ({
|
|
|
21
22
|
pdfWrapperRef,
|
|
22
23
|
recipientsColors,
|
|
23
24
|
selectedField,
|
|
25
|
+
}) => {
|
|
26
|
+
return (
|
|
27
|
+
<div className="dte-pdf-field-overlay skeleton-item">
|
|
28
|
+
{fields.map(field => (
|
|
29
|
+
<PdfFieldOverlayField
|
|
30
|
+
key={field.id}
|
|
31
|
+
field={field}
|
|
32
|
+
onFieldMove={onFieldMove}
|
|
33
|
+
onFieldClick={onFieldClick}
|
|
34
|
+
pdfWrapperRef={pdfWrapperRef}
|
|
35
|
+
onFieldResize={onFieldResize}
|
|
36
|
+
isSelected={selectedField === field.id}
|
|
37
|
+
recipientsColors={recipientsColors}
|
|
38
|
+
/>
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
interface PdfFieldOverlayFieldProps {
|
|
45
|
+
field: PdfField;
|
|
46
|
+
isSelected: boolean;
|
|
47
|
+
recipientsColors: Record<string, string>;
|
|
48
|
+
pdfWrapperRef: RefObject<HTMLDivElement>;
|
|
49
|
+
onFieldClick(fieldId: string, e: MouseEvent): void;
|
|
50
|
+
onFieldMove(fieldId: string, newX: number, newY: number, pageNumber: number): void;
|
|
51
|
+
onFieldResize(fieldId: string, newWidth: number, newHeight: number, pageNumber: number): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const PdfFieldOverlayField: FC<PdfFieldOverlayFieldProps> = ({
|
|
55
|
+
field,
|
|
56
|
+
isSelected,
|
|
57
|
+
onFieldClick,
|
|
58
|
+
onFieldMove,
|
|
59
|
+
onFieldResize,
|
|
60
|
+
pdfWrapperRef,
|
|
61
|
+
recipientsColors,
|
|
24
62
|
}) => {
|
|
25
63
|
const { draggingFieldIdRef, handleDrag, handleDragEnd, handleDragStart } = useFieldDrag({
|
|
26
64
|
pdfWrapperRef,
|
|
27
65
|
onFieldMove,
|
|
28
66
|
});
|
|
67
|
+
const isDragging = draggingFieldIdRef.current === field.id;
|
|
29
68
|
|
|
30
69
|
const { handleResizeStart } = useFieldResize({
|
|
31
70
|
pdfWrapperRef,
|
|
32
71
|
onFieldResize,
|
|
33
72
|
});
|
|
34
73
|
|
|
74
|
+
const pagePos = useMemo(() => {
|
|
75
|
+
return getPagePosition(field.page, pdfWrapperRef);
|
|
76
|
+
}, [field.page, pdfWrapperRef]);
|
|
77
|
+
|
|
78
|
+
const style = useMemo(() => {
|
|
79
|
+
const bgColor = getFieldBackgroundColor(field.recipient, recipientsColors);
|
|
80
|
+
return {
|
|
81
|
+
left: pagePos.left + field.x,
|
|
82
|
+
top: pagePos.top + field.y,
|
|
83
|
+
width: field.width,
|
|
84
|
+
height: field.height,
|
|
85
|
+
backgroundColor: bgColor,
|
|
86
|
+
};
|
|
87
|
+
}, [
|
|
88
|
+
field.recipient,
|
|
89
|
+
field.x,
|
|
90
|
+
field.y,
|
|
91
|
+
field.width,
|
|
92
|
+
field.height,
|
|
93
|
+
recipientsColors,
|
|
94
|
+
pagePos.left,
|
|
95
|
+
pagePos.top,
|
|
96
|
+
]);
|
|
97
|
+
|
|
35
98
|
return (
|
|
36
|
-
<div
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
className={`dte-pdf-field ${isSelected ? 'dte-pdf-field-selected' : 'dte-pdf-field-unselected'} ${isDragging ? 'dte-pdf-field-dragging' : ''}`}
|
|
55
|
-
style={{
|
|
56
|
-
left: `${pagePos.left + field.x}px`,
|
|
57
|
-
top: `${pagePos.top + field.y}px`,
|
|
58
|
-
width: `${field.width}px`,
|
|
59
|
-
height: `${field.height}px`,
|
|
60
|
-
backgroundColor: bgColor,
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
-
<span>
|
|
64
|
-
{(field.type === FieldTypeEnum.eSign ||
|
|
65
|
-
field.type === FieldTypeEnum.fillable) &&
|
|
66
|
-
`${field.label} ${field.required ? '*' : ''}`}
|
|
67
|
-
|
|
68
|
-
{field.path && (
|
|
69
|
-
<div className="dte-pdf-field-path">{`{{${field.path}}}`}</div>
|
|
70
|
-
)}
|
|
71
|
-
</span>
|
|
72
|
-
{isSelected && (
|
|
73
|
-
<div
|
|
74
|
-
className="dte-pdf-field-resize-handle"
|
|
75
|
-
onMouseDown={e => handleResizeStart(e, field)}
|
|
76
|
-
/>
|
|
77
|
-
)}
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
})}
|
|
99
|
+
<div
|
|
100
|
+
onClick={e => onFieldClick(field.id, e)}
|
|
101
|
+
draggable
|
|
102
|
+
onDragStart={e => handleDragStart(e, field)}
|
|
103
|
+
onDrag={e => handleDrag(e, field)}
|
|
104
|
+
onDragEnd={handleDragEnd}
|
|
105
|
+
className={`dte-pdf-field ${isSelected ? 'dte-pdf-field-selected' : 'dte-pdf-field-unselected'} ${isDragging ? 'dte-pdf-field-dragging' : ''}`}
|
|
106
|
+
style={style}
|
|
107
|
+
>
|
|
108
|
+
{field.type === FieldTypeEnum.eSign && <FieldEsign field={field} />}
|
|
109
|
+
{field.type === FieldTypeEnum.dataModel && <FieldDataModel field={field} />}
|
|
110
|
+
{field.type === FieldTypeEnum.fillable && (
|
|
111
|
+
<FieldFillable
|
|
112
|
+
field={field}
|
|
113
|
+
handleResizeStart={handleResizeStart}
|
|
114
|
+
isSelected={isSelected}
|
|
115
|
+
/>
|
|
116
|
+
)}
|
|
81
117
|
</div>
|
|
82
118
|
);
|
|
83
119
|
};
|
|
120
|
+
|
|
121
|
+
interface FieldProps {
|
|
122
|
+
field: PdfField;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const FieldEsign: FC<FieldProps> = ({ field }) => {
|
|
126
|
+
return (
|
|
127
|
+
<span>
|
|
128
|
+
{field.label} {field.required ? '*' : ''}
|
|
129
|
+
<div className="dte-pdf-field-value">{field.path}</div>
|
|
130
|
+
</span>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const FieldDataModel: FC<FieldProps> = ({ field }) => {
|
|
135
|
+
return (
|
|
136
|
+
<span>
|
|
137
|
+
{field.label ? field.label : field.path}
|
|
138
|
+
{field.required ? '*' : ''}
|
|
139
|
+
</span>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
interface FieldFillableProps extends FieldProps {
|
|
144
|
+
isSelected: boolean;
|
|
145
|
+
handleResizeStart: UseFieldResizeReturn['handleResizeStart'];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const FieldFillable: FC<FieldFillableProps> = ({ field, handleResizeStart, isSelected }) => {
|
|
149
|
+
const placeholderText = getFieldPlaceholderText(field);
|
|
150
|
+
|
|
151
|
+
if (field.subType === 'checkbox' || field.subType === 'radio') {
|
|
152
|
+
return <input type={field.subType} readOnly className="dte-pdf-field-fillable" />;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (field.subType === 'date') {
|
|
156
|
+
return (
|
|
157
|
+
<Fragment>
|
|
158
|
+
<input
|
|
159
|
+
type="date"
|
|
160
|
+
readOnly
|
|
161
|
+
className="dte-pdf-field-fillable"
|
|
162
|
+
placeholder={placeholderText}
|
|
163
|
+
/>
|
|
164
|
+
{isSelected && (
|
|
165
|
+
<ResizeHandle handleResizeStart={e => handleResizeStart(e, field)} />
|
|
166
|
+
)}
|
|
167
|
+
</Fragment>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<Fragment>
|
|
173
|
+
<input
|
|
174
|
+
type="text"
|
|
175
|
+
readOnly
|
|
176
|
+
placeholder={placeholderText}
|
|
177
|
+
className="dte-pdf-field-fillable"
|
|
178
|
+
/>
|
|
179
|
+
{isSelected && <ResizeHandle handleResizeStart={e => handleResizeStart(e, field)} />}
|
|
180
|
+
</Fragment>
|
|
181
|
+
);
|
|
182
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { PdfField } from '../interface/pdf-editor';
|
|
3
|
+
import { getFieldPlaceholderText, resolvePdfDataValues } from '../utils';
|
|
4
|
+
|
|
5
|
+
interface BaseFieldViewProps {
|
|
6
|
+
field: PdfField;
|
|
7
|
+
data?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ViewDataModel: FC<BaseFieldViewProps> = ({ data, field }) => {
|
|
11
|
+
const resolvedValue = field.path ? resolvePdfDataValues(data, field.path) : '';
|
|
12
|
+
return <div className="dte-pdf-field-value">{resolvedValue ?? ''}</div>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const ViewEsign: FC<BaseFieldViewProps> = ({ data, field }) => {
|
|
16
|
+
const resolvedValue = field.path ? resolvePdfDataValues(data, field.path) : '';
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<span>
|
|
20
|
+
{field.label} {field.required ? '*' : ''}
|
|
21
|
+
<div className="dte-pdf-field-value">{resolvedValue}</div>
|
|
22
|
+
</span>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
interface FillableFieldViewProps extends BaseFieldViewProps {
|
|
27
|
+
fillingBy?: string[];
|
|
28
|
+
onDataChange?(changedData: { [path: string]: string | boolean }): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const FillableFieldView: FC<FillableFieldViewProps> = ({
|
|
32
|
+
data,
|
|
33
|
+
field,
|
|
34
|
+
fillingBy,
|
|
35
|
+
onDataChange,
|
|
36
|
+
}) => {
|
|
37
|
+
const resolvedValue = data?.[field.path!];
|
|
38
|
+
const isViewByCurrentRecipient = fillingBy?.includes(field.recipient!);
|
|
39
|
+
if (field.subType === 'checkbox') {
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
style={{
|
|
43
|
+
display: 'flex',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
background: 'inherit',
|
|
46
|
+
width: 'inherit',
|
|
47
|
+
height: 'inherit',
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<input
|
|
51
|
+
style={{ width: 'inherit', height: 'inherit', margin: 0 }}
|
|
52
|
+
type="checkbox"
|
|
53
|
+
checked={resolvedValue ?? false}
|
|
54
|
+
disabled={!isViewByCurrentRecipient}
|
|
55
|
+
name={field.path}
|
|
56
|
+
onChange={e =>
|
|
57
|
+
onDataChange?.({
|
|
58
|
+
[field.path!]: e!.target.checked,
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
/>
|
|
62
|
+
{field.label}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (field.subType === 'radio') {
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
style={{
|
|
71
|
+
display: 'flex',
|
|
72
|
+
alignItems: 'center',
|
|
73
|
+
background: 'inherit',
|
|
74
|
+
width: 'inherit',
|
|
75
|
+
height: 'inherit',
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<input
|
|
79
|
+
style={{ width: 'inherit', height: 'inherit', margin: 0 }}
|
|
80
|
+
type="radio"
|
|
81
|
+
checked={resolvedValue ?? false}
|
|
82
|
+
disabled={!isViewByCurrentRecipient}
|
|
83
|
+
name={field.path}
|
|
84
|
+
onChange={e =>
|
|
85
|
+
onDataChange?.({
|
|
86
|
+
[field.path!]: e!.target.value,
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
/>
|
|
90
|
+
{field.label}
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (field.subType === 'date') {
|
|
96
|
+
return (
|
|
97
|
+
<input
|
|
98
|
+
type="date"
|
|
99
|
+
style={{
|
|
100
|
+
background: 'inherit',
|
|
101
|
+
width: 'inherit',
|
|
102
|
+
height: 'inherit',
|
|
103
|
+
}}
|
|
104
|
+
disabled={!isViewByCurrentRecipient}
|
|
105
|
+
id={field.path}
|
|
106
|
+
name={field.path}
|
|
107
|
+
value={resolvedValue ?? ''}
|
|
108
|
+
onChange={e =>
|
|
109
|
+
onDataChange?.({
|
|
110
|
+
[field.path!]: e.target.value,
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
placeholder={getFieldPlaceholderText(field, 'mm/dd/yyyy')}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<input
|
|
120
|
+
type="text"
|
|
121
|
+
style={{
|
|
122
|
+
background: 'inherit',
|
|
123
|
+
width: 'inherit',
|
|
124
|
+
height: 'inherit',
|
|
125
|
+
}}
|
|
126
|
+
disabled={!isViewByCurrentRecipient}
|
|
127
|
+
id={field.path}
|
|
128
|
+
name={field.path}
|
|
129
|
+
value={resolvedValue ?? ''}
|
|
130
|
+
onChange={e =>
|
|
131
|
+
onDataChange?.({
|
|
132
|
+
[field.path!]: e.target.value,
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
placeholder={getFieldPlaceholderText(field)}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
};
|