@oneblink/apps-react 8.7.0-beta.12 → 8.7.0-beta.13

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.
@@ -9,11 +9,11 @@ const useAttachments = (element, onChange, setIsDirty) => {
9
9
  return;
10
10
  const newAttachments = await Promise.all(files.map(async (file) => {
11
11
  if (!file.size) {
12
- return generateErrorAttachment(file, file.name, element, 'You cannot upload an empty file.');
12
+ return generateErrorAttachment(file, file.name, element, 'You cannot upload an empty file.', 'EMPTY_FILE');
13
13
  }
14
14
  const fileSizeInMB = file.size / 1024 / 1024;
15
15
  if (element.maxFileSize && fileSizeInMB > element.maxFileSize) {
16
- return generateErrorAttachment(file, file.name, element, `File size ${fileSizeInMB.toFixed(2)}MB exceeds the allowed maximum of ${element.maxFileSize}MB.`);
16
+ return generateErrorAttachment(file, file.name, element, `File size ${fileSizeInMB.toFixed(2)}MB exceeds the allowed maximum of ${element.maxFileSize}MB.`, 'EXCEEDS_MAX_SIZE');
17
17
  }
18
18
  const result = await correctFileOrientation(file);
19
19
  if (result instanceof Blob) {
@@ -1 +1 @@
1
- {"version":3,"file":"useAttachments.js","sourceRoot":"","sources":["../../../src/hooks/attachments/useAttachments.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport {\n prepareNewAttachment,\n generateErrorAttachment,\n correctFileOrientation,\n} from '../../services/attachments'\nimport { attachmentsService } from '@oneblink/apps'\nimport { canvasToBlob } from '../../services/blob-utils'\nimport useIsMounted from '../useIsMounted'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../../types/form'\n\nconst useAttachments = (\n element: FormTypes.FilesElement,\n onChange: FormElementValueChangeHandler<attachmentsService.Attachment[]>,\n setIsDirty: IsDirtyProps['setIsDirty'],\n) => {\n const isMounted = useIsMounted()\n\n const addAttachments = React.useCallback(\n async (files: File[]): Promise<void> => {\n if (!files.length) return\n const newAttachments: Array<\n attachmentsService.AttachmentNew | attachmentsService.AttachmentError\n > = await Promise.all(\n files.map(async (file) => {\n if (!file.size) {\n return generateErrorAttachment(\n file,\n file.name,\n element,\n 'You cannot upload an empty file.',\n )\n }\n const fileSizeInMB = file.size / 1024 / 1024\n if (element.maxFileSize && fileSizeInMB > element.maxFileSize) {\n return generateErrorAttachment(\n file,\n file.name,\n element,\n `File size ${fileSizeInMB.toFixed(2)}MB exceeds the allowed maximum of ${element.maxFileSize}MB.`,\n )\n }\n const result = await correctFileOrientation(file)\n if (result instanceof Blob) {\n return prepareNewAttachment(result, file.name, element)\n }\n\n const blob = await canvasToBlob(result)\n return prepareNewAttachment(blob, file.name, element)\n }),\n )\n\n onChange(element, {\n value: (currentAttachments) => {\n if (!currentAttachments) return newAttachments\n return [...currentAttachments, ...newAttachments]\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n const removeAttachment = React.useCallback(\n (id: string) => {\n onChange(element, {\n value: (currentAttachments) => {\n const newAttachments = currentAttachments?.filter((att) => {\n // Return items that are not the removed id\n if (!att.type) {\n return att.id !== id\n }\n return att._id !== id\n })\n if (newAttachments?.length) {\n return newAttachments\n }\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n const changeAttachment = React.useCallback(\n (id: string, attachment: attachmentsService.Attachment) => {\n onChange(element, {\n value: (currentAttachments) => {\n if (!currentAttachments) return\n return currentAttachments.map((att) => {\n // Can only change attachments that are not uploaded (have a type)\n if (att.type && att._id === id) {\n return attachment\n }\n return att\n })\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n return {\n addAttachments,\n removeAttachment,\n changeAttachment,\n }\n}\n\nexport default useAttachments\n"]}
1
+ {"version":3,"file":"useAttachments.js","sourceRoot":"","sources":["../../../src/hooks/attachments/useAttachments.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport {\n prepareNewAttachment,\n generateErrorAttachment,\n correctFileOrientation,\n} from '../../services/attachments'\nimport { attachmentsService } from '@oneblink/apps'\nimport { canvasToBlob } from '../../services/blob-utils'\nimport useIsMounted from '../useIsMounted'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../../types/form'\n\nconst useAttachments = (\n element: FormTypes.FilesElement,\n onChange: FormElementValueChangeHandler<attachmentsService.Attachment[]>,\n setIsDirty: IsDirtyProps['setIsDirty'],\n) => {\n const isMounted = useIsMounted()\n\n const addAttachments = React.useCallback(\n async (files: File[]): Promise<void> => {\n if (!files.length) return\n const newAttachments: Array<\n attachmentsService.AttachmentNew | attachmentsService.AttachmentError\n > = await Promise.all(\n files.map(async (file) => {\n if (!file.size) {\n return generateErrorAttachment(\n file,\n file.name,\n element,\n 'You cannot upload an empty file.',\n 'EMPTY_FILE',\n )\n }\n const fileSizeInMB = file.size / 1024 / 1024\n if (element.maxFileSize && fileSizeInMB > element.maxFileSize) {\n return generateErrorAttachment(\n file,\n file.name,\n element,\n `File size ${fileSizeInMB.toFixed(2)}MB exceeds the allowed maximum of ${element.maxFileSize}MB.`,\n 'EXCEEDS_MAX_SIZE',\n )\n }\n const result = await correctFileOrientation(file)\n if (result instanceof Blob) {\n return prepareNewAttachment(result, file.name, element)\n }\n\n const blob = await canvasToBlob(result)\n return prepareNewAttachment(blob, file.name, element)\n }),\n )\n\n onChange(element, {\n value: (currentAttachments) => {\n if (!currentAttachments) return newAttachments\n return [...currentAttachments, ...newAttachments]\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n const removeAttachment = React.useCallback(\n (id: string) => {\n onChange(element, {\n value: (currentAttachments) => {\n const newAttachments = currentAttachments?.filter((att) => {\n // Return items that are not the removed id\n if (!att.type) {\n return att.id !== id\n }\n return att._id !== id\n })\n if (newAttachments?.length) {\n return newAttachments\n }\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n const changeAttachment = React.useCallback(\n (id: string, attachment: attachmentsService.Attachment) => {\n onChange(element, {\n value: (currentAttachments) => {\n if (!currentAttachments) return\n return currentAttachments.map((att) => {\n // Can only change attachments that are not uploaded (have a type)\n if (att.type && att._id === id) {\n return attachment\n }\n return att\n })\n },\n })\n if (isMounted.current) {\n setIsDirty()\n }\n },\n [element, isMounted, onChange, setIsDirty],\n )\n\n return {\n addAttachments,\n removeAttachment,\n changeAttachment,\n }\n}\n\nexport default useAttachments\n"]}
@@ -1,6 +1,6 @@
1
1
  import { FormTypes } from '@oneblink/types';
2
2
  import { attachmentsService } from '@oneblink/apps';
3
- export declare function generateErrorAttachment(blob: Blob, fileName: string, element: FormTypes.FormElementBinaryStorage, errorMessage: string): attachmentsService.AttachmentError;
3
+ export declare function generateErrorAttachment(blob: Blob, fileName: string, element: FormTypes.FormElementBinaryStorage, errorMessage: string, errorType?: attachmentsService.AttachmentError['errorType']): attachmentsService.AttachmentError;
4
4
  export declare function prepareNewAttachment(blob: Blob, fileName: string, element: FormTypes.FormElementBinaryStorage): attachmentsService.AttachmentNew;
5
5
  export declare function checkIfContentTypeIsImage(contentType: string): boolean;
6
6
  export declare function parseFilesAsAttachmentsLegacy(files: File[], onAnnotateCanvas?: (file: File, canvas: HTMLCanvasElement) => void): Promise<Array<{
@@ -1,7 +1,7 @@
1
1
  import { Sentry } from '@oneblink/apps';
2
2
  import { v4 as uuid } from 'uuid';
3
3
  import { blobToCanvas, getBlobOrientation } from './blob-utils';
4
- export function generateErrorAttachment(blob, fileName, element, errorMessage) {
4
+ export function generateErrorAttachment(blob, fileName, element, errorMessage, errorType) {
5
5
  return {
6
6
  _id: uuid(),
7
7
  data: blob,
@@ -9,6 +9,7 @@ export function generateErrorAttachment(blob, fileName, element, errorMessage) {
9
9
  isPrivate: element.storageType !== 'public',
10
10
  type: 'ERROR',
11
11
  errorMessage,
12
+ errorType,
12
13
  };
13
14
  }
14
15
  export function prepareNewAttachment(blob, fileName, element) {
@@ -1 +1 @@
1
- {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/services/attachments.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { Sentry, attachmentsService } from '@oneblink/apps'\nimport { v4 as uuid } from 'uuid'\nimport { blobToCanvas, getBlobOrientation } from './blob-utils'\n\nexport function generateErrorAttachment(\n blob: Blob,\n fileName: string,\n element: FormTypes.FormElementBinaryStorage,\n errorMessage: string,\n): attachmentsService.AttachmentError {\n return {\n _id: uuid(),\n data: blob,\n fileName,\n isPrivate: element.storageType !== 'public',\n type: 'ERROR',\n errorMessage,\n }\n}\n\nexport function prepareNewAttachment(\n blob: Blob,\n fileName: string,\n element: FormTypes.FormElementBinaryStorage,\n): attachmentsService.AttachmentNew {\n return {\n _id: uuid(),\n data: blob,\n fileName,\n isPrivate: element.storageType !== 'public',\n type: 'NEW',\n }\n}\n\nexport function checkIfContentTypeIsImage(contentType: string) {\n return contentType.indexOf('image/') === 0\n}\n\nexport async function parseFilesAsAttachmentsLegacy(\n files: File[],\n onAnnotateCanvas?: (file: File, canvas: HTMLCanvasElement) => void,\n): Promise<Array<{ data: string; fileName: string; contentType: string }>> {\n const attachments: Array<{\n data: string\n fileName: string\n contentType: string\n }> = []\n\n for (const file of files) {\n const result = await correctFileOrientation(file, onAnnotateCanvas)\n\n if (result instanceof Blob) {\n console.log('Attempting to parse File as attachment', file)\n\n const base64data = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = function () {\n resolve(reader.result as string)\n }\n reader.onerror = function () {\n reject(new Error('Could not read file from data url'))\n }\n reader.readAsDataURL(file)\n })\n\n attachments.push({\n fileName: file.name,\n contentType: file.type,\n data: base64data,\n })\n } else {\n attachments.push({\n fileName: file.name,\n contentType: file.type,\n data: result.toDataURL(),\n })\n }\n }\n\n return attachments\n}\n\nexport async function correctFileOrientation(\n file: File,\n onAnnotateCanvas?: (file: File, canvas: HTMLCanvasElement) => void,\n): Promise<Blob | HTMLCanvasElement> {\n try {\n if (!checkIfContentTypeIsImage(file.type)) {\n return file\n }\n\n console.log('Attempting to parse File as image attachment', file)\n\n const orientation = await getBlobOrientation(file)\n if (\n (typeof orientation !== 'number' || orientation === 1) &&\n !onAnnotateCanvas\n ) {\n console.log('Skipping orientation correction for image')\n return file\n }\n\n console.log(\n 'Loading image onto canvas to correct orientation using image meta data',\n { orientation },\n )\n const canvas = await blobToCanvas(file, orientation)\n if (onAnnotateCanvas) {\n onAnnotateCanvas(file, canvas)\n }\n return canvas\n } catch (err) {\n console.warn('Failed to rotate the orientation of a file:', err)\n Sentry.captureException(err)\n return file\n }\n}\n"]}
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/services/attachments.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { Sentry, attachmentsService } from '@oneblink/apps'\nimport { v4 as uuid } from 'uuid'\nimport { blobToCanvas, getBlobOrientation } from './blob-utils'\n\nexport function generateErrorAttachment(\n blob: Blob,\n fileName: string,\n element: FormTypes.FormElementBinaryStorage,\n errorMessage: string,\n errorType?: attachmentsService.AttachmentError['errorType'],\n): attachmentsService.AttachmentError {\n return {\n _id: uuid(),\n data: blob,\n fileName,\n isPrivate: element.storageType !== 'public',\n type: 'ERROR',\n errorMessage,\n errorType,\n }\n}\n\nexport function prepareNewAttachment(\n blob: Blob,\n fileName: string,\n element: FormTypes.FormElementBinaryStorage,\n): attachmentsService.AttachmentNew {\n return {\n _id: uuid(),\n data: blob,\n fileName,\n isPrivate: element.storageType !== 'public',\n type: 'NEW',\n }\n}\n\nexport function checkIfContentTypeIsImage(contentType: string) {\n return contentType.indexOf('image/') === 0\n}\n\nexport async function parseFilesAsAttachmentsLegacy(\n files: File[],\n onAnnotateCanvas?: (file: File, canvas: HTMLCanvasElement) => void,\n): Promise<Array<{ data: string; fileName: string; contentType: string }>> {\n const attachments: Array<{\n data: string\n fileName: string\n contentType: string\n }> = []\n\n for (const file of files) {\n const result = await correctFileOrientation(file, onAnnotateCanvas)\n\n if (result instanceof Blob) {\n console.log('Attempting to parse File as attachment', file)\n\n const base64data = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = function () {\n resolve(reader.result as string)\n }\n reader.onerror = function () {\n reject(new Error('Could not read file from data url'))\n }\n reader.readAsDataURL(file)\n })\n\n attachments.push({\n fileName: file.name,\n contentType: file.type,\n data: base64data,\n })\n } else {\n attachments.push({\n fileName: file.name,\n contentType: file.type,\n data: result.toDataURL(),\n })\n }\n }\n\n return attachments\n}\n\nexport async function correctFileOrientation(\n file: File,\n onAnnotateCanvas?: (file: File, canvas: HTMLCanvasElement) => void,\n): Promise<Blob | HTMLCanvasElement> {\n try {\n if (!checkIfContentTypeIsImage(file.type)) {\n return file\n }\n\n console.log('Attempting to parse File as image attachment', file)\n\n const orientation = await getBlobOrientation(file)\n if (\n (typeof orientation !== 'number' || orientation === 1) &&\n !onAnnotateCanvas\n ) {\n console.log('Skipping orientation correction for image')\n return file\n }\n\n console.log(\n 'Loading image onto canvas to correct orientation using image meta data',\n { orientation },\n )\n const canvas = await blobToCanvas(file, orientation)\n if (onAnnotateCanvas) {\n onAnnotateCanvas(file, canvas)\n }\n return canvas\n } catch (err) {\n console.warn('Failed to rotate the orientation of a file:', err)\n Sentry.captureException(err)\n return file\n }\n}\n"]}
@@ -49,16 +49,46 @@ export function getInvalidAttachment(value) {
49
49
  }
50
50
  }
51
51
  export function validateAttachments(value) {
52
- const invalidAttachmentNames = value === null || value === void 0 ? void 0 : value.reduce((invalidAttachmentNames, att) => {
53
- var _a;
54
- const attachmentName = (_a = getInvalidAttachment(att)) === null || _a === void 0 ? void 0 : _a.fileName;
55
- if (attachmentName) {
56
- invalidAttachmentNames.push(attachmentName);
52
+ const exceedsMaximumSize = value === null || value === void 0 ? void 0 : value.some((att) => {
53
+ const invalidAttachment = getInvalidAttachment(att);
54
+ if ((invalidAttachment === null || invalidAttachment === void 0 ? void 0 : invalidAttachment.fileName) &&
55
+ (invalidAttachment === null || invalidAttachment === void 0 ? void 0 : invalidAttachment.errorType) === 'EXCEEDS_MAX_SIZE') {
56
+ return true;
57
57
  }
58
- return invalidAttachmentNames;
59
- }, []);
60
- if (invalidAttachmentNames === null || invalidAttachmentNames === void 0 ? void 0 : invalidAttachmentNames.length) {
61
- return [`${invalidAttachmentNames.join(', ')} could not be uploaded.`];
58
+ });
59
+ const emptyFiles = value === null || value === void 0 ? void 0 : value.some((att) => {
60
+ const invalidAttachment = getInvalidAttachment(att);
61
+ if ((invalidAttachment === null || invalidAttachment === void 0 ? void 0 : invalidAttachment.fileName) &&
62
+ (invalidAttachment === null || invalidAttachment === void 0 ? void 0 : invalidAttachment.errorType) === 'EMPTY_FILE') {
63
+ return true;
64
+ }
65
+ });
66
+ if (!exceedsMaximumSize && !emptyFiles) {
67
+ const invalidAttachmentNames = value === null || value === void 0 ? void 0 : value.reduce((invalidAttachmentNames, att) => {
68
+ var _a;
69
+ const attachmentName = (_a = getInvalidAttachment(att)) === null || _a === void 0 ? void 0 : _a.fileName;
70
+ if (attachmentName) {
71
+ invalidAttachmentNames.push(attachmentName);
72
+ }
73
+ return invalidAttachmentNames;
74
+ }, []);
75
+ if (invalidAttachmentNames === null || invalidAttachmentNames === void 0 ? void 0 : invalidAttachmentNames.length) {
76
+ return [`${invalidAttachmentNames.join(', ')} could not be uploaded.`];
77
+ }
78
+ return [];
79
+ }
80
+ let errorMessage;
81
+ if (exceedsMaximumSize) {
82
+ errorMessage = 'One or more of the files exceed the maximum size allowed.';
83
+ }
84
+ if (emptyFiles) {
85
+ const emptyMessage = 'One or more of the files are empty.';
86
+ errorMessage = errorMessage
87
+ ? `${errorMessage} ${emptyMessage}`
88
+ : emptyMessage;
89
+ }
90
+ if (errorMessage) {
91
+ return [errorMessage];
62
92
  }
63
93
  return [];
64
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/services/form-validation/validators.ts"],"names":[],"mappings":"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","sourcesContent":["import { EnvironmentTypes, FormTypes, SubmissionTypes } from '@oneblink/types'\nimport getDateRangeConfiguration, {\n DateRangeConfigurationOptions,\n} from '../getDateRangeConfiguration'\nimport {\n FormElementsConditionallyShown,\n FormElementsValidation,\n} from '../../types/form'\nimport cleanFormSubmissionModel from '../cleanFormSubmissionModel'\nimport getRepeatableSetEntriesConfiguration from '../getRepeatableSetEntriesConfiguration'\nimport { attachmentsService } from '@oneblink/apps'\nimport { FormElementBinaryStorageValue } from '../../types/attachments'\n\nexport function getCleanDateRangeConfiguration(\n options: DateRangeConfigurationOptions,\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): ReturnType<typeof getDateRangeConfiguration> {\n if (options.referenceFormElementId && submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getDateRangeConfiguration(options, elements, model)\n }\n return [options.date, options.daysOffset]\n}\n\nexport function getCleanRepeatableSetConfiguration(\n setEntries: FormTypes.RepeatableSetElement['minSetEntries'],\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n) {\n if (submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getRepeatableSetEntriesConfiguration(setEntries, elements, model)\n }\n}\n\nexport function checkFileNameIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n const extension = fileName.split('.').pop()\n return (\n !formElement.restrictedFileTypes ||\n formElement.restrictedFileTypes.some(\n (fileType) => fileType.toLowerCase() === extension?.toLowerCase(),\n )\n )\n}\n\nexport function checkFileNameExtensionIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n return (\n formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2\n )\n}\n\nexport function checkSectionValidity(\n element: FormTypes.PageElement | FormTypes.SectionElement,\n formElementsValidation: FormElementsValidation | undefined,\n): boolean {\n // If everything is valid, no need to check elements\n if (!formElementsValidation) {\n return false\n }\n\n // If there is no elements on the page that are invalid, we will treat as valid\n return element.elements.some((formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return checkSectionValidity(formElement, formElementsValidation)\n }\n default: {\n return formElementsValidation[formElement.name]\n }\n }\n })\n}\n\nexport function getInvalidAttachment(\n value: unknown,\n): attachmentsService.AttachmentError | undefined {\n if (\n value &&\n typeof value === 'object' &&\n 'type' in value &&\n value.type === 'ERROR'\n ) {\n return value as attachmentsService.AttachmentError\n }\n}\n\nexport function validateAttachments(\n value: FormElementBinaryStorageValue[] | undefined,\n): string[] {\n const invalidAttachmentNames = value?.reduce(\n (invalidAttachmentNames: string[], att) => {\n const attachmentName = getInvalidAttachment(att)?.fileName\n if (attachmentName) {\n invalidAttachmentNames.push(attachmentName)\n }\n return invalidAttachmentNames\n },\n [],\n )\n if (invalidAttachmentNames?.length) {\n return [`${invalidAttachmentNames.join(', ')} could not be uploaded.`]\n }\n return []\n}\n\nexport const generateLookupValidationMessage = (\n lookupButtonConfig?: EnvironmentTypes.ButtonConfiguration,\n) => {\n return lookupButtonConfig && lookupButtonConfig.label\n ? `${lookupButtonConfig.label} is required`\n : 'Lookup is required'\n}\n"]}
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/services/form-validation/validators.ts"],"names":[],"mappings":"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","sourcesContent":["import { EnvironmentTypes, FormTypes, SubmissionTypes } from '@oneblink/types'\nimport getDateRangeConfiguration, {\n DateRangeConfigurationOptions,\n} from '../getDateRangeConfiguration'\nimport {\n FormElementsConditionallyShown,\n FormElementsValidation,\n} from '../../types/form'\nimport cleanFormSubmissionModel from '../cleanFormSubmissionModel'\nimport getRepeatableSetEntriesConfiguration from '../getRepeatableSetEntriesConfiguration'\nimport { attachmentsService } from '@oneblink/apps'\nimport { FormElementBinaryStorageValue } from '../../types/attachments'\n\nexport function getCleanDateRangeConfiguration(\n options: DateRangeConfigurationOptions,\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): ReturnType<typeof getDateRangeConfiguration> {\n if (options.referenceFormElementId && submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getDateRangeConfiguration(options, elements, model)\n }\n return [options.date, options.daysOffset]\n}\n\nexport function getCleanRepeatableSetConfiguration(\n setEntries: FormTypes.RepeatableSetElement['minSetEntries'],\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n) {\n if (submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getRepeatableSetEntriesConfiguration(setEntries, elements, model)\n }\n}\n\nexport function checkFileNameIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n const extension = fileName.split('.').pop()\n return (\n !formElement.restrictedFileTypes ||\n formElement.restrictedFileTypes.some(\n (fileType) => fileType.toLowerCase() === extension?.toLowerCase(),\n )\n )\n}\n\nexport function checkFileNameExtensionIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n return (\n formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2\n )\n}\n\nexport function checkSectionValidity(\n element: FormTypes.PageElement | FormTypes.SectionElement,\n formElementsValidation: FormElementsValidation | undefined,\n): boolean {\n // If everything is valid, no need to check elements\n if (!formElementsValidation) {\n return false\n }\n\n // If there is no elements on the page that are invalid, we will treat as valid\n return element.elements.some((formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return checkSectionValidity(formElement, formElementsValidation)\n }\n default: {\n return formElementsValidation[formElement.name]\n }\n }\n })\n}\n\nexport function getInvalidAttachment(\n value: unknown,\n): attachmentsService.AttachmentError | undefined {\n if (\n value &&\n typeof value === 'object' &&\n 'type' in value &&\n value.type === 'ERROR'\n ) {\n return value as attachmentsService.AttachmentError\n }\n}\n\nexport function validateAttachments(\n value: FormElementBinaryStorageValue[] | undefined,\n): string[] {\n const exceedsMaximumSize = value?.some((att) => {\n const invalidAttachment = getInvalidAttachment(att)\n if (\n invalidAttachment?.fileName &&\n invalidAttachment?.errorType === 'EXCEEDS_MAX_SIZE'\n ) {\n return true\n }\n })\n const emptyFiles = value?.some((att) => {\n const invalidAttachment = getInvalidAttachment(att)\n if (\n invalidAttachment?.fileName &&\n invalidAttachment?.errorType === 'EMPTY_FILE'\n ) {\n return true\n }\n })\n if (!exceedsMaximumSize && !emptyFiles) {\n const invalidAttachmentNames = value?.reduce(\n (invalidAttachmentNames: string[], att) => {\n const attachmentName = getInvalidAttachment(att)?.fileName\n if (attachmentName) {\n invalidAttachmentNames.push(attachmentName)\n }\n return invalidAttachmentNames\n },\n [],\n )\n if (invalidAttachmentNames?.length) {\n return [`${invalidAttachmentNames.join(', ')} could not be uploaded.`]\n }\n return []\n }\n let errorMessage\n if (exceedsMaximumSize) {\n errorMessage = 'One or more of the files exceed the maximum size allowed.'\n }\n if (emptyFiles) {\n const emptyMessage = 'One or more of the files are empty.'\n errorMessage = errorMessage\n ? `${errorMessage} ${emptyMessage}`\n : emptyMessage\n }\n if (errorMessage) {\n return [errorMessage]\n }\n\n return []\n}\n\nexport const generateLookupValidationMessage = (\n lookupButtonConfig?: EnvironmentTypes.ButtonConfiguration,\n) => {\n return lookupButtonConfig && lookupButtonConfig.label\n ? `${lookupButtonConfig.label} is required`\n : 'Lookup is required'\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/apps-react",
3
3
  "description": "Helper functions for OneBlink apps in ReactJS.",
4
- "version": "8.7.0-beta.12",
4
+ "version": "8.7.0-beta.13",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/apps-react/issues"
@@ -47,7 +47,7 @@
47
47
  "@mui/lab": "^5.0.0-alpha.152",
48
48
  "@mui/material": "^5.15.6",
49
49
  "@mui/x-date-pickers": "^6.20.2",
50
- "@oneblink/apps": "^23.1.0-beta.8",
50
+ "@oneblink/apps": "^23.1.0-beta.9",
51
51
  "@oneblink/release-cli": "^3.4.0-beta.1",
52
52
  "@oneblink/types": "github:oneblink/types",
53
53
  "@types/blueimp-load-image": "^5.16.6",