@evoke-platform/ui-components 1.6.0-dev.30 → 1.6.0-dev.31

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.
@@ -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, onFileRejections, } = props;
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, fileRejections } = useDropzone({
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: formattedMaxSize || allowedTypesMessage ? '136px' : '115px',
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
- allowedTypesMessage && (React.createElement(Typography, { sx: {
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;
@@ -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, onFileRejections: this.handleFileRejections }))), root);
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
@@ -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 { InfoRounded, UploadCloud } from '../../../../../../icons';
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, fileRejections } = useDropzone({
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: formattedMaxSize || allowedTypesMessage ? '136px' : '115px',
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
- allowedTypesMessage && (React.createElement(Typography, { sx: {
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, validate: validation })));
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,2 +1 @@
1
1
  export declare function difference(object?: any, base?: any): any;
2
- export declare const createAcceptObject: (allowedTypes: string[]) => Record<string, string[]> | undefined;
@@ -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-dev.30",
3
+ "version": "1.6.0-dev.31",
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-testing.9",
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",