@evoke-platform/ui-components 1.6.0-testing.17 → 1.6.0-testing.18
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/published/components/custom/Form/FormComponents/DocumentComponent/Document.d.ts +0 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +5 -45
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.d.ts +0 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js +1 -8
- package/dist/published/components/custom/Form/utils.js +0 -6
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +6 -46
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +1 -1
- package/dist/published/components/custom/util.d.ts +0 -1
- package/dist/published/components/custom/util.js +0 -28
- package/package.json +2 -4
package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ type DocumentProps = {
|
|
|
12
12
|
objectId?: string;
|
|
13
13
|
validate?: DocumentValidation;
|
|
14
14
|
value: (File | SavedDocumentReference)[] | undefined;
|
|
15
|
-
onFileRejections: (fileRejectionsErrors: string[]) => void;
|
|
16
15
|
};
|
|
17
16
|
export declare const Document: (props: DocumentProps) => React.JSX.Element;
|
|
18
17
|
export {};
|
|
@@ -1,32 +1,16 @@
|
|
|
1
1
|
import { isNil } from 'lodash';
|
|
2
|
-
import prettyBytes from 'pretty-bytes';
|
|
3
2
|
import React, { useEffect, useState } from 'react';
|
|
4
3
|
import { useDropzone } from 'react-dropzone';
|
|
5
4
|
import { UploadCloud } from '../../../../../icons';
|
|
6
5
|
import { Skeleton, Snackbar, Typography } from '../../../../core';
|
|
7
6
|
import { Box, Grid } from '../../../../layout';
|
|
8
|
-
import { createAcceptObject } from '../../../util';
|
|
9
7
|
import { getPrefixedUrl } from '../../utils';
|
|
10
8
|
import { DocumentList } from './DocumentList';
|
|
11
9
|
export const Document = (props) => {
|
|
12
|
-
const { id, handleChange, property, instance, canUpdateProperty, apiServices, error, objectId, value, validate
|
|
10
|
+
const { id, handleChange, property, instance, canUpdateProperty, apiServices, error, objectId, value, validate } = props;
|
|
13
11
|
const [documents, setDocuments] = useState();
|
|
14
12
|
const [hasUpdatePermission, setHasUpdatePermission] = useState();
|
|
15
13
|
const [snackbarError, setSnackbarError] = useState();
|
|
16
|
-
let allowedTypesMessage = '';
|
|
17
|
-
if (validate?.allowedFileExtensions?.length) {
|
|
18
|
-
if (validate.allowedFileExtensions.length === 1) {
|
|
19
|
-
allowedTypesMessage = validate.allowedFileExtensions[0];
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
allowedTypesMessage = `${validate.allowedFileExtensions.slice(0, -1).join(', ')} or ${validate.allowedFileExtensions.slice(-1)[0]}`;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const maxSizeInBytes = Number.isFinite(validate?.maxSizeInKB)
|
|
26
|
-
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
27
|
-
validate.maxSizeInKB * 1000 // convert to bytes
|
|
28
|
-
: undefined;
|
|
29
|
-
const formattedMaxSize = maxSizeInBytes !== undefined ? prettyBytes(maxSizeInBytes) : '';
|
|
30
14
|
useEffect(() => {
|
|
31
15
|
setDocuments(value);
|
|
32
16
|
}, [value]);
|
|
@@ -52,27 +36,15 @@ export const Document = (props) => {
|
|
|
52
36
|
handleChange(property.id, newDocuments);
|
|
53
37
|
};
|
|
54
38
|
const uploadDisabled = !!validate?.maxDocuments && (documents?.length ?? 0) >= validate.maxDocuments;
|
|
55
|
-
const { getRootProps, getInputProps, open
|
|
39
|
+
const { getRootProps, getInputProps, open } = useDropzone({
|
|
56
40
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
41
|
onDrop: (files) => handleUpload(files),
|
|
58
42
|
disabled: uploadDisabled,
|
|
59
|
-
accept: validate?.allowedFileExtensions ? createAcceptObject(validate.allowedFileExtensions) : undefined,
|
|
60
|
-
maxSize: maxSizeInBytes,
|
|
61
43
|
});
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const errors = [];
|
|
64
|
-
if (fileRejections.some((fileRejection) => fileRejection.errors.some((error) => error.code === 'file-invalid-type'))) {
|
|
65
|
-
errors.push(`Invalid file extension. Allowed extensions are: ${allowedTypesMessage}`);
|
|
66
|
-
}
|
|
67
|
-
if (fileRejections.some((fileRejection) => fileRejection.errors.some((error) => error.code === 'file-too-large'))) {
|
|
68
|
-
errors.push(`File size exceeds the max limit of ${formattedMaxSize}`);
|
|
69
|
-
}
|
|
70
|
-
onFileRejections(errors);
|
|
71
|
-
}, [fileRejections, onFileRejections]);
|
|
72
44
|
return (React.createElement(React.Fragment, null,
|
|
73
45
|
canUpdateProperty && hasUpdatePermission && (React.createElement(Box, { sx: {
|
|
74
46
|
margin: '5px 0',
|
|
75
|
-
height:
|
|
47
|
+
height: '115px',
|
|
76
48
|
borderRadius: '8px',
|
|
77
49
|
display: 'flex',
|
|
78
50
|
justifyContent: 'center',
|
|
@@ -91,20 +63,8 @@ export const Document = (props) => {
|
|
|
91
63
|
' ',
|
|
92
64
|
React.createElement(Typography, { component: 'span', sx: { color: uploadDisabled ? '#919EAB' : '#0075A7', fontSize: '14px' } }, "select file"),
|
|
93
65
|
' ',
|
|
94
|
-
"to upload"),
|
|
95
|
-
|
|
96
|
-
color: '#637381',
|
|
97
|
-
textAlign: 'center',
|
|
98
|
-
fontSize: '12px',
|
|
99
|
-
} }, `${allowedTypesMessage}.`)),
|
|
100
|
-
formattedMaxSize && (React.createElement(Typography, { sx: {
|
|
101
|
-
color: '#637381',
|
|
102
|
-
textAlign: 'center',
|
|
103
|
-
fontSize: '12px',
|
|
104
|
-
} }, validate?.maxDocuments === 1
|
|
105
|
-
? `Max size of ${formattedMaxSize}.`
|
|
106
|
-
: `The max size of each document is ${formattedMaxSize}.`)))))),
|
|
107
|
-
canUpdateProperty && isNil(hasUpdatePermission) && (React.createElement(Skeleton, { variant: "rectangular", height: formattedMaxSize || allowedTypesMessage ? '136px' : '115px', sx: { margin: '5px 0', borderRadius: '8px' } })),
|
|
66
|
+
"to upload"))))),
|
|
67
|
+
canUpdateProperty && isNil(hasUpdatePermission) && (React.createElement(Skeleton, { variant: "rectangular", height: "115px", sx: { margin: '5px 0', borderRadius: '8px' } })),
|
|
108
68
|
React.createElement(DocumentList, { property: property, instance: instance, objectId: objectId, handleChange: handleChange, value: value, apiServices: apiServices, setSnackbarError: (type, message) => setSnackbarError({ message, type }), canUpdateProperty: canUpdateProperty && !!hasUpdatePermission }),
|
|
109
69
|
React.createElement(Snackbar, { open: !!snackbarError?.message, handleClose: () => setSnackbarError(null), message: snackbarError?.message, error: snackbarError?.type === 'error' })));
|
|
110
70
|
};
|
|
@@ -16,7 +16,6 @@ export declare class DocumentComponent extends ReactComponent {
|
|
|
16
16
|
*/
|
|
17
17
|
manageFormErrors(): void;
|
|
18
18
|
handleChange: (key: string, value?: (File | SavedDocumentReference)[] | null) => void;
|
|
19
|
-
handleFileRejections(fileRejectionsErrors: string[]): void;
|
|
20
19
|
handleValidation(value?: (File | SavedDocumentReference)[] | null): void;
|
|
21
20
|
beforeSubmit(): Promise<void>;
|
|
22
21
|
attachReact(element: Element): void;
|
package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js
CHANGED
|
@@ -26,7 +26,6 @@ export class DocumentComponent extends ReactComponent {
|
|
|
26
26
|
};
|
|
27
27
|
this.errorDetails = {};
|
|
28
28
|
this.handleChange = this.handleChange.bind(this);
|
|
29
|
-
this.handleFileRejections = this.handleFileRejections.bind(this);
|
|
30
29
|
}
|
|
31
30
|
init() {
|
|
32
31
|
this.on(`api-error`, (details) => {
|
|
@@ -88,12 +87,6 @@ export class DocumentComponent extends ReactComponent {
|
|
|
88
87
|
}
|
|
89
88
|
});
|
|
90
89
|
}
|
|
91
|
-
handleFileRejections(fileRejectionsErrors) {
|
|
92
|
-
delete this.errorDetails['file-rejections'];
|
|
93
|
-
if (fileRejectionsErrors.length > 0) {
|
|
94
|
-
this.errorDetails['file-rejections'] = `${fileRejectionsErrors.join('; ')}.`;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
90
|
handleValidation(value) {
|
|
98
91
|
const validate = this.component.validate;
|
|
99
92
|
const amountOfDocuments = value?.length ?? 0;
|
|
@@ -138,6 +131,6 @@ export class DocumentComponent extends ReactComponent {
|
|
|
138
131
|
const inputId = `${this.component.id}-input`;
|
|
139
132
|
return ReactDOM.render(React.createElement("div", null,
|
|
140
133
|
React.createElement(FormComponentWrapper, { ...this.component, inputId: inputId, viewOnly: !this.component.canUpdateProperty, errorMessage: this.errorMessages() },
|
|
141
|
-
React.createElement(Document, { ...this.component, id: inputId, handleChange: this.handleChange, error: this.hasErrors(), value: this.dataValue
|
|
134
|
+
React.createElement(Document, { ...this.component, id: inputId, handleChange: this.handleChange, error: this.hasErrors(), value: this.dataValue }))), root);
|
|
142
135
|
}
|
|
143
136
|
}
|
|
@@ -233,12 +233,6 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
|
233
233
|
maxDocuments: parameter.type === 'document'
|
|
234
234
|
? parameter.validation?.maxDocuments
|
|
235
235
|
: undefined,
|
|
236
|
-
allowedFileExtensions: parameter.type === 'document'
|
|
237
|
-
? parameter.validation?.allowedFileExtensions
|
|
238
|
-
: undefined,
|
|
239
|
-
maxSizeInKB: parameter.type === 'document'
|
|
240
|
-
? parameter.validation?.maxSizeInKB
|
|
241
|
-
: undefined,
|
|
242
236
|
customMessage: ['integer', 'number', 'date', 'time', 'document'].includes(parameter.type ?? '')
|
|
243
237
|
? parameter.validation
|
|
244
238
|
?.errorMessage
|
package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { useApiServices } from '@evoke-platform/context';
|
|
2
2
|
import { isNil } from 'lodash';
|
|
3
|
-
import prettyBytes from 'pretty-bytes';
|
|
4
3
|
import React, { useEffect, useState } from 'react';
|
|
5
4
|
import { useDropzone } from 'react-dropzone';
|
|
6
|
-
import {
|
|
5
|
+
import { UploadCloud } from '../../../../../../icons';
|
|
7
6
|
import { useFormContext } from '../../../../../../theme/hooks';
|
|
8
7
|
import { Skeleton, Snackbar, Typography } from '../../../../../core';
|
|
9
8
|
import { Box, Grid } from '../../../../../layout';
|
|
10
|
-
import { createAcceptObject } from '../../../../util';
|
|
11
9
|
import { getPrefixedUrl } from '../../utils';
|
|
12
10
|
import { DocumentList } from './DocumentList';
|
|
13
11
|
export const Document = (props) => {
|
|
@@ -17,20 +15,6 @@ export const Document = (props) => {
|
|
|
17
15
|
const [snackbarError, setSnackbarError] = useState();
|
|
18
16
|
const [documents, setDocuments] = useState();
|
|
19
17
|
const [hasUpdatePermission, setHasUpdatePermission] = useState(fetchedOptions[`${id}UpdatePermission`]);
|
|
20
|
-
let allowedTypesMessage = '';
|
|
21
|
-
if (validate?.allowedFileExtensions?.length) {
|
|
22
|
-
if (validate.allowedFileExtensions.length === 1) {
|
|
23
|
-
allowedTypesMessage = validate.allowedFileExtensions[0];
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
allowedTypesMessage = `${validate.allowedFileExtensions.slice(0, -1).join(', ')} or ${validate.allowedFileExtensions.slice(-1)[0]}`;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const maxSizeInBytes = Number.isFinite(validate?.maxSizeInKB)
|
|
30
|
-
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
31
|
-
validate.maxSizeInKB * 1000 // convert to bytes
|
|
32
|
-
: undefined;
|
|
33
|
-
const formattedMaxSize = maxSizeInBytes !== undefined ? prettyBytes(maxSizeInBytes) : '';
|
|
34
18
|
useEffect(() => {
|
|
35
19
|
setDocuments(value);
|
|
36
20
|
}, [value]);
|
|
@@ -55,24 +39,15 @@ export const Document = (props) => {
|
|
|
55
39
|
handleChange(id, newDocuments);
|
|
56
40
|
};
|
|
57
41
|
const uploadDisabled = !!validate?.maxDocuments && (documents?.length ?? 0) >= validate.maxDocuments;
|
|
58
|
-
const { getRootProps, getInputProps, open
|
|
42
|
+
const { getRootProps, getInputProps, open } = useDropzone({
|
|
59
43
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
44
|
onDrop: (files) => handleUpload(files),
|
|
61
45
|
disabled: uploadDisabled,
|
|
62
|
-
accept: validate?.allowedFileExtensions ? createAcceptObject(validate.allowedFileExtensions) : undefined,
|
|
63
|
-
maxSize: maxSizeInBytes,
|
|
64
46
|
});
|
|
65
|
-
const errors = [];
|
|
66
|
-
if (fileRejections.some((fileRejection) => fileRejection.errors.some((error) => error.code === 'file-invalid-type'))) {
|
|
67
|
-
errors.push(`Invalid file extension. Allowed extensions are: ${allowedTypesMessage}`);
|
|
68
|
-
}
|
|
69
|
-
if (fileRejections.some((fileRejection) => fileRejection.errors.some((error) => error.code === 'file-too-large'))) {
|
|
70
|
-
errors.push(`File size exceeds the max limit of ${formattedMaxSize}`);
|
|
71
|
-
}
|
|
72
47
|
return (React.createElement(React.Fragment, null,
|
|
73
48
|
canUpdateProperty && hasUpdatePermission && (React.createElement(Box, { sx: {
|
|
74
49
|
margin: '5px 0',
|
|
75
|
-
height:
|
|
50
|
+
height: '115px',
|
|
76
51
|
borderRadius: '8px',
|
|
77
52
|
display: 'flex',
|
|
78
53
|
justifyContent: 'center',
|
|
@@ -91,23 +66,8 @@ export const Document = (props) => {
|
|
|
91
66
|
' ',
|
|
92
67
|
React.createElement(Typography, { component: 'span', color: uploadDisabled ? '#919EAB' : 'primary', sx: { fontSize: '14px' } }, "select file"),
|
|
93
68
|
' ',
|
|
94
|
-
"to upload"),
|
|
95
|
-
|
|
96
|
-
color: '#637381',
|
|
97
|
-
textAlign: 'center',
|
|
98
|
-
fontSize: '12px',
|
|
99
|
-
} }, `${allowedTypesMessage}.`)),
|
|
100
|
-
formattedMaxSize && (React.createElement(Typography, { sx: {
|
|
101
|
-
color: '#637381',
|
|
102
|
-
textAlign: 'center',
|
|
103
|
-
fontSize: '12px',
|
|
104
|
-
} }, validate?.maxDocuments === 1
|
|
105
|
-
? `Max size of ${formattedMaxSize}.`
|
|
106
|
-
: `The max size of each document is ${formattedMaxSize}.`)))))),
|
|
107
|
-
canUpdateProperty && isNil(hasUpdatePermission) && (React.createElement(Skeleton, { variant: "rectangular", height: formattedMaxSize || allowedTypesMessage ? '136px' : '115px', sx: { margin: '5px 0', borderRadius: '8px' } })),
|
|
69
|
+
"to upload"))))),
|
|
70
|
+
canUpdateProperty && isNil(hasUpdatePermission) && (React.createElement(Skeleton, { variant: "rectangular", height: "115px", sx: { margin: '5px 0', borderRadius: '8px' } })),
|
|
108
71
|
React.createElement(DocumentList, { id: id, instance: instance, handleChange: handleChange, value: value, setSnackbarError: (type, message) => setSnackbarError({ message, type }), canUpdateProperty: canUpdateProperty && !!hasUpdatePermission }),
|
|
109
|
-
React.createElement(Snackbar, { open: !!snackbarError?.message, handleClose: () => setSnackbarError(null), message: snackbarError?.message, error: snackbarError?.type === 'error' })
|
|
110
|
-
errors.length > 0 && (React.createElement(Box, { display: 'flex', alignItems: 'center' },
|
|
111
|
-
React.createElement(InfoRounded, { color: 'error', sx: { fontSize: '.75rem', marginRight: '3px' } }),
|
|
112
|
-
React.createElement(Typography, { fontSize: '12px', color: 'error', sx: { lineHeight: '18px' } }, errors.join('; ') + '.')))));
|
|
72
|
+
React.createElement(Snackbar, { open: !!snackbarError?.message, handleClose: () => setSnackbarError(null), message: snackbarError?.message, error: snackbarError?.type === 'error' })));
|
|
113
73
|
};
|
|
@@ -130,7 +130,7 @@ export function RecursiveEntryRenderer(props) {
|
|
|
130
130
|
}
|
|
131
131
|
else if (fieldDefinition.type === 'document') {
|
|
132
132
|
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
133
|
-
React.createElement(Document, { id: entryId, handleChange: handleChange, error: !!errors[entryId], value: fieldValue, instance: instance, canUpdateProperty: !(entry.type === 'readonlyField'), hasDescription: !!display?.description
|
|
133
|
+
React.createElement(Document, { id: entryId, handleChange: handleChange, error: !!errors[entryId], value: fieldValue, instance: instance, canUpdateProperty: !(entry.type === 'readonlyField'), hasDescription: !!display?.description })));
|
|
134
134
|
}
|
|
135
135
|
else if (fieldDefinition.type === 'criteria') {
|
|
136
136
|
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isEqual, isObject, transform } from 'lodash';
|
|
2
|
-
import mime from 'mime-types';
|
|
3
2
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
export function difference(object, base) {
|
|
5
4
|
if (!object) {
|
|
@@ -15,30 +14,3 @@ export function difference(object, base) {
|
|
|
15
14
|
}
|
|
16
15
|
});
|
|
17
16
|
}
|
|
18
|
-
// Helper function to convert file extensions array to dropzone accept format
|
|
19
|
-
export const createAcceptObject = (allowedTypes) => {
|
|
20
|
-
if (!allowedTypes.length)
|
|
21
|
-
return undefined;
|
|
22
|
-
const acceptObject = {};
|
|
23
|
-
const customExtensions = [];
|
|
24
|
-
// First pass: collect custom extensions from allowedTypes that don't map to standard MIME types
|
|
25
|
-
allowedTypes.forEach((extension) => {
|
|
26
|
-
const mimeType = mime.lookup(extension);
|
|
27
|
-
// It's a custom extension
|
|
28
|
-
if (!mimeType) {
|
|
29
|
-
customExtensions.push(extension.startsWith('.') ? extension : `.${extension}`);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// If it is mapped to a value, add it to the accept object
|
|
33
|
-
if (!acceptObject[mimeType]) {
|
|
34
|
-
acceptObject[mimeType] = [];
|
|
35
|
-
}
|
|
36
|
-
acceptObject[mimeType].push(extension.startsWith('.') ? extension : `.${extension}`);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
if (customExtensions.length) {
|
|
40
|
-
// Add custom files extensions to the accept object
|
|
41
|
-
acceptObject['file/custom'] = customExtensions;
|
|
42
|
-
}
|
|
43
|
-
return acceptObject;
|
|
44
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evoke-platform/ui-components",
|
|
3
|
-
"version": "1.6.0-testing.
|
|
3
|
+
"version": "1.6.0-testing.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/published/index.js",
|
|
6
6
|
"module": "dist/published/index.js",
|
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
"@types/jest": "^28.1.4",
|
|
57
57
|
"@types/json-logic-js": "^2.0.8",
|
|
58
58
|
"@types/luxon": "^3.4.2",
|
|
59
|
-
"@types/mime-types": "^3.0.1",
|
|
60
59
|
"@types/nanoid-dictionary": "^4.2.3",
|
|
61
60
|
"@types/node": "^18.0.0",
|
|
62
61
|
"@types/react": "^18.0.17",
|
|
@@ -88,7 +87,7 @@
|
|
|
88
87
|
"yalc": "^1.0.0-pre.53"
|
|
89
88
|
},
|
|
90
89
|
"peerDependencies": {
|
|
91
|
-
"@evoke-platform/context": "^1.3.0-
|
|
90
|
+
"@evoke-platform/context": "^1.3.0-dev.6",
|
|
92
91
|
"react": "^18.1.0",
|
|
93
92
|
"react-dom": "^18.1.0"
|
|
94
93
|
},
|
|
@@ -120,7 +119,6 @@
|
|
|
120
119
|
"formiojs": "^4.15.0-rc.23",
|
|
121
120
|
"html-react-parser": "^5.1.18",
|
|
122
121
|
"luxon": "^2.5.2",
|
|
123
|
-
"mime-type": "^5.0.3",
|
|
124
122
|
"msw": "^2.7.3",
|
|
125
123
|
"nanoid": "^5.0.8",
|
|
126
124
|
"nanoid-dictionary": "^4.3.0",
|