@evoke-platform/ui-components 1.6.0-dev.3 → 1.6.0-dev.30
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/core/SwipeableDrawer/SwipeableDrawer.d.ts +4 -0
- package/dist/published/components/core/SwipeableDrawer/SwipeableDrawer.js +8 -0
- package/dist/published/components/core/SwipeableDrawer/index.d.ts +3 -0
- package/dist/published/components/core/SwipeableDrawer/index.js +3 -0
- package/dist/published/components/core/index.d.ts +1 -0
- package/dist/published/components/core/index.js +1 -0
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +1 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +45 -5
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js +8 -1
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/Image.js +2 -2
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +87 -57
- package/dist/published/components/custom/Form/tests/Form.test.js +1 -1
- package/dist/published/components/custom/Form/utils.js +6 -0
- package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +1 -1
- package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.js +3 -3
- package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.js +7 -1
- package/dist/published/components/custom/FormField/DateTimePickerSelect/DateTimePickerSelect.js +7 -1
- package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.js +6 -3
- package/dist/published/components/custom/FormField/Select/Select.js +17 -5
- package/dist/published/components/custom/FormField/TimePickerSelect/TimePickerSelect.js +13 -3
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +19 -0
- package/dist/published/components/custom/FormV2/FormRenderer.js +183 -0
- package/dist/published/components/custom/FormV2/components/AccordionSections.d.ts +4 -0
- package/dist/published/components/custom/FormV2/components/AccordionSections.js +131 -0
- package/dist/published/components/custom/FormV2/components/ActionButtons.d.ts +19 -0
- package/dist/published/components/custom/FormV2/components/ActionButtons.js +106 -0
- package/dist/published/components/custom/FormV2/components/FieldWrapper.d.ts +24 -0
- package/dist/published/components/custom/FormV2/components/FieldWrapper.js +100 -0
- package/dist/published/components/custom/FormV2/components/FormContext.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormContext.js +8 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/AddressFields.d.ts +17 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/AddressFields.js +50 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +14 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.js +88 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DocumentViewerCell.d.ts +13 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DocumentViewerCell.js +140 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableField.d.ts +17 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableField.js +233 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.d.ts +40 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.js +95 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +526 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.js +93 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +16 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +113 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +13 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +179 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +108 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/UserProperty.d.ts +16 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/UserProperty.js +129 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.d.ts +15 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +226 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/ObjectPropertyInput.d.ts +4 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/ObjectPropertyInput.js +439 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.d.ts +29 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.js +74 -0
- package/dist/published/components/custom/FormV2/components/FormSections.d.ts +4 -0
- package/dist/published/components/custom/FormV2/components/FormSections.js +104 -0
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.d.ts +2 -0
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +209 -0
- package/dist/published/components/custom/FormV2/components/TabNav.d.ts +10 -0
- package/dist/published/components/custom/FormV2/components/TabNav.js +23 -0
- package/dist/published/components/custom/FormV2/components/ValidationFiles/Validation.d.ts +3 -0
- package/dist/published/components/custom/FormV2/components/ValidationFiles/Validation.js +176 -0
- package/dist/published/components/custom/FormV2/components/ValidationFiles/ValidationErrorDisplay.d.ts +10 -0
- package/dist/published/components/custom/FormV2/components/ValidationFiles/ValidationErrorDisplay.js +45 -0
- package/dist/published/components/custom/FormV2/components/types.d.ts +122 -0
- package/dist/published/components/custom/FormV2/components/types.js +1 -0
- package/dist/published/components/custom/FormV2/components/utils.d.ts +47 -0
- package/dist/published/components/custom/FormV2/components/utils.js +434 -0
- package/dist/published/components/custom/FormV2/index.d.ts +1 -0
- package/dist/published/components/custom/FormV2/index.js +1 -0
- package/dist/published/components/custom/HistoryLog/HistoryData.d.ts +1 -0
- package/dist/published/components/custom/HistoryLog/HistoryData.js +14 -6
- package/dist/published/components/custom/HistoryLog/HistoryLoading.d.ts +4 -1
- package/dist/published/components/custom/HistoryLog/HistoryLoading.js +14 -8
- package/dist/published/components/custom/HistoryLog/index.d.ts +2 -0
- package/dist/published/components/custom/HistoryLog/index.js +4 -4
- package/dist/published/components/custom/ResponsiveOverflow/ResponsiveOverflow.d.ts +33 -0
- package/dist/published/components/custom/ResponsiveOverflow/ResponsiveOverflow.js +140 -0
- package/dist/published/components/custom/ResponsiveOverflow/ResponsiveOverflow.test.d.ts +1 -0
- package/dist/published/components/custom/ResponsiveOverflow/ResponsiveOverflow.test.js +100 -0
- package/dist/published/components/custom/ResponsiveOverflow/index.d.ts +4 -0
- package/dist/published/components/custom/ResponsiveOverflow/index.js +3 -0
- package/dist/published/components/custom/index.d.ts +2 -0
- package/dist/published/components/custom/index.js +2 -0
- package/dist/published/components/custom/util.d.ts +1 -0
- package/dist/published/components/custom/util.js +28 -0
- package/dist/published/index.d.ts +1 -1
- package/dist/published/index.js +1 -1
- package/dist/published/stories/ResponsiveOverflow.stories.d.ts +8 -0
- package/dist/published/stories/ResponsiveOverflow.stories.js +91 -0
- package/dist/published/theme/hooks.d.ts +7 -0
- package/dist/published/theme/hooks.js +9 -0
- package/package.json +6 -2
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { useApiServices, useAuthenticationContext, } from '@evoke-platform/context';
|
|
2
|
+
import { WarningRounded } from '@mui/icons-material';
|
|
3
|
+
import { cloneDeep } from 'lodash';
|
|
4
|
+
import React, { useEffect, useMemo } from 'react';
|
|
5
|
+
import { useResponsive } from '../../../../theme';
|
|
6
|
+
import { useFormContext } from '../../../../theme/hooks';
|
|
7
|
+
import { TextField, Typography } from '../../../core';
|
|
8
|
+
import { Box } from '../../../layout';
|
|
9
|
+
import FormField from '../../FormField';
|
|
10
|
+
import AccordionSections from './AccordionSections';
|
|
11
|
+
import FieldWrapper from './FieldWrapper';
|
|
12
|
+
import AddressFields from './FormFieldTypes/AddressFields';
|
|
13
|
+
import DropdownRepeatableField from './FormFieldTypes/CollectionFiles/DropdownRepeatableField';
|
|
14
|
+
import RepeatableField from './FormFieldTypes/CollectionFiles/RepeatableField';
|
|
15
|
+
import Criteria from './FormFieldTypes/Criteria';
|
|
16
|
+
import { Document } from './FormFieldTypes/DocumentFiles/Document';
|
|
17
|
+
import { Image } from './FormFieldTypes/Image';
|
|
18
|
+
import ObjectPropertyInput from './FormFieldTypes/relatedObjectFiles/ObjectPropertyInput';
|
|
19
|
+
import UserProperty from './FormFieldTypes/UserProperty';
|
|
20
|
+
import FormSections from './FormSections';
|
|
21
|
+
import { entryIsVisible, fetchCollectionData, getEntryId, isAddressProperty, isOptionEqualToValue, updateCriteriaInputs, } from './utils';
|
|
22
|
+
function getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors, validation) {
|
|
23
|
+
return {
|
|
24
|
+
inputId: entryId,
|
|
25
|
+
inputType: fieldDefinition.type,
|
|
26
|
+
label: display?.label || fieldDefinition.name || 'default',
|
|
27
|
+
description: display?.description,
|
|
28
|
+
tooltip: display?.tooltip,
|
|
29
|
+
value: fieldValue,
|
|
30
|
+
maxLength: validation && 'maxLength' in validation ? validation.maxLength : 0,
|
|
31
|
+
required: entry.display?.required || false,
|
|
32
|
+
showCharCount: display?.charCount,
|
|
33
|
+
prefix: display?.prefix,
|
|
34
|
+
suffix: display?.suffix,
|
|
35
|
+
viewOnly: entry.type === 'readonlyField',
|
|
36
|
+
fieldHeight,
|
|
37
|
+
errorMessage: errors?.[entryId]?.message,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function RecursiveEntryRenderer(props) {
|
|
41
|
+
const { handleChange, errors, showSubmitError, fieldHeight, instance, richTextEditor, expandedSections, setExpandedSections, expandAll, setExpandAll, parameters, entry, triggerFieldReset, } = props;
|
|
42
|
+
const { fetchedOptions, setFetchedOptions, object, getValues } = useFormContext();
|
|
43
|
+
// If the entry is hidden, clear its value and any nested values, and skip rendering
|
|
44
|
+
if (!entryIsVisible(entry, getValues(), instance)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const apiServices = useApiServices();
|
|
48
|
+
const userAccount = useAuthenticationContext()?.account;
|
|
49
|
+
const { smallerThan, isXs } = useResponsive();
|
|
50
|
+
const entryId = getEntryId(entry) || 'defaultId';
|
|
51
|
+
const display = 'display' in entry ? entry.display : undefined;
|
|
52
|
+
const fieldValue = entry.type === 'readonlyField' ? instance?.[entryId] : getValues(entryId);
|
|
53
|
+
const initialMiddleObjectInstances = fetchedOptions[`${entryId}InitialMiddleObjectInstances`];
|
|
54
|
+
const middleObject = fetchedOptions[`${entryId}MiddleObject`];
|
|
55
|
+
const fieldDefinition = useMemo(() => {
|
|
56
|
+
let def;
|
|
57
|
+
if (entry.type === 'input') {
|
|
58
|
+
def = parameters?.find((param) => param.id === entry.parameterId);
|
|
59
|
+
}
|
|
60
|
+
else if (entry.type === 'readonlyField') {
|
|
61
|
+
def = isAddressProperty(entry.propertyId)
|
|
62
|
+
? object?.properties?.find((prop) => prop.id === entry.propertyId.split('.')[0])
|
|
63
|
+
: object?.properties?.find((prop) => prop.id === entry.propertyId);
|
|
64
|
+
}
|
|
65
|
+
else if (entry.type === 'inputField') {
|
|
66
|
+
def = entry.input;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
if (def?.enum && def.type === 'string') {
|
|
72
|
+
const cloned = cloneDeep(def);
|
|
73
|
+
// single select must be made to be type choices for label and error handling
|
|
74
|
+
cloned.type = 'choices';
|
|
75
|
+
return cloned;
|
|
76
|
+
}
|
|
77
|
+
return def;
|
|
78
|
+
}, [entry, parameters, object]);
|
|
79
|
+
const validation = fieldDefinition?.validation || {};
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (fieldDefinition?.type === 'collection' && fieldDefinition?.manyToManyPropertyId && instance) {
|
|
82
|
+
fetchCollectionData(apiServices, fieldDefinition, setFetchedOptions, instance.id, fetchedOptions, initialMiddleObjectInstances);
|
|
83
|
+
}
|
|
84
|
+
}, [fieldDefinition, instance]);
|
|
85
|
+
if (entry.type === 'content') {
|
|
86
|
+
return (React.createElement(Box, { dangerouslySetInnerHTML: { __html: entry.html }, sx: {
|
|
87
|
+
fontFamily: 'Roboto, Helvetica, Arial, sans-serif',
|
|
88
|
+
} }));
|
|
89
|
+
}
|
|
90
|
+
else if ((entry.type === 'input' || entry.type === 'readonlyField' || entry.type === 'inputField') &&
|
|
91
|
+
fieldDefinition) {
|
|
92
|
+
if (isAddressProperty(entryId)) {
|
|
93
|
+
return (React.createElement(AddressFields, { entry: entry, errors: errors, handleChange: handleChange, fieldHeight: fieldHeight, parameters: parameters, instance: instance, entryId: entryId, fieldDefinition: fieldDefinition }));
|
|
94
|
+
}
|
|
95
|
+
else if (fieldDefinition.type === 'image') {
|
|
96
|
+
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
97
|
+
React.createElement(Image, { id: entryId, handleChange: handleChange, canUpdateProperty: entry.type !== 'readonlyField', error: !!errors[entryId], value: fieldValue, hasDescription: !!display?.description })));
|
|
98
|
+
}
|
|
99
|
+
else if (fieldDefinition.type === 'object') {
|
|
100
|
+
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
101
|
+
React.createElement(ObjectPropertyInput, { instance: instance, fieldDefinition: fieldDefinition, id: entryId, handleChangeObjectProperty: handleChange, mode: display?.mode || 'default', error: !!errors[entryId], displayOption: display?.relatedObjectDisplay || 'dialogBox', initialValue: fieldValue, parameters: parameters, readOnly: entry.type === 'readonlyField', filter: validation?.criteria
|
|
102
|
+
? updateCriteriaInputs(validation.criteria, getValues(), userAccount)
|
|
103
|
+
: undefined, sortBy: typeof display?.defaultValue === 'object' && 'sortBy' in display.defaultValue
|
|
104
|
+
? display?.defaultValue.sortBy
|
|
105
|
+
: undefined, orderBy: typeof display?.defaultValue === 'object' && 'orderBy' in display.defaultValue
|
|
106
|
+
? display?.defaultValue.orderBy
|
|
107
|
+
: undefined, fieldHeight: fieldHeight, richTextEditor: richTextEditor, defaultValueCriteria: typeof display?.defaultValue === 'object' && 'criteria' in display.defaultValue
|
|
108
|
+
? display?.defaultValue?.criteria
|
|
109
|
+
: undefined, viewLayout: display?.viewLayout, hasDescription: !!display?.description })));
|
|
110
|
+
}
|
|
111
|
+
else if (fieldDefinition.type === 'user') {
|
|
112
|
+
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
113
|
+
React.createElement(UserProperty, { id: entryId, value: fieldValue, handleChange: handleChange, error: !!errors[entryId], readOnly: entry.type === 'readonlyField', fieldHeight: fieldHeight, hasDescription: !!display?.description })));
|
|
114
|
+
}
|
|
115
|
+
else if (fieldDefinition.type === 'collection') {
|
|
116
|
+
return fieldDefinition?.manyToManyPropertyId ? (middleObject && initialMiddleObjectInstances && (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
117
|
+
React.createElement(DropdownRepeatableField, { initialMiddleObjectInstances: fetchedOptions[`${entryId}MiddleObjectInstances`] || initialMiddleObjectInstances, fieldDefinition: fieldDefinition, id: entryId, middleObject: middleObject, instance: instance, readOnly: entry.type === 'readonlyField', fieldHeight: fieldHeight, criteria: validation?.criteria, hasDescription: !!display?.description })))) : (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
118
|
+
React.createElement(RepeatableField, { fieldDefinition: fieldDefinition, canUpdateProperty: entry.type !== 'readonlyField', criteria: validation?.criteria, viewLayout: display?.viewLayout, instance: instance })));
|
|
119
|
+
}
|
|
120
|
+
else if (fieldDefinition.type === 'richText') {
|
|
121
|
+
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) }, richTextEditor ? (React.createElement(richTextEditor, {
|
|
122
|
+
id: entryId,
|
|
123
|
+
value: fieldValue,
|
|
124
|
+
handleUpdate: (value) => handleChange(entryId, value),
|
|
125
|
+
format: 'rtf',
|
|
126
|
+
disabled: entry.type === 'readonlyField',
|
|
127
|
+
rows: display?.rowCount,
|
|
128
|
+
hasError: !!errors[entryId],
|
|
129
|
+
})) : (React.createElement(FormField, { id: entryId, property: fieldDefinition, defaultValue: fieldValue || getValues(entryId), onChange: handleChange, readOnly: entry.type === 'readonlyField', placeholder: display?.placeholder, error: !!errors[entryId], errorMessage: errors[entryId]?.message, isMultiLineText: !!display?.rowCount, rows: display?.rowCount, size: fieldHeight }))));
|
|
130
|
+
}
|
|
131
|
+
else if (fieldDefinition.type === 'document') {
|
|
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 })));
|
|
134
|
+
}
|
|
135
|
+
else if (fieldDefinition.type === 'criteria') {
|
|
136
|
+
return (React.createElement(FieldWrapper, { ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors) },
|
|
137
|
+
React.createElement(Criteria, { key: triggerFieldReset ? `${entryId}-reset-true` : `${entryId}-reset-false`, fieldDefinition: fieldDefinition, value: fieldValue, handleChange: handleChange, canUpdateProperty: !(entry.type === 'readonlyField'), error: !!errors[entryId] })));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// Add `aria-describedby` to ensure screen readers read the description
|
|
141
|
+
// when the input is tabbed into.
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
+
const additionalProps = {};
|
|
144
|
+
if (fieldDefinition.enum && display?.description) {
|
|
145
|
+
additionalProps.renderInput = (params) => (React.createElement(TextField, { ...params, inputProps: {
|
|
146
|
+
...params.inputProps,
|
|
147
|
+
'aria-describedby': `${entryId}-description`,
|
|
148
|
+
} }));
|
|
149
|
+
}
|
|
150
|
+
else if (display?.description) {
|
|
151
|
+
additionalProps.inputProps = {
|
|
152
|
+
'aria-describedby': `${entryId}-description`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return (React.createElement(FieldWrapper
|
|
156
|
+
/*
|
|
157
|
+
* Key remounts the field if a value is changed.
|
|
158
|
+
* Needed to clear certain fields on discard changes.
|
|
159
|
+
*/
|
|
160
|
+
, {
|
|
161
|
+
/*
|
|
162
|
+
* Key remounts the field if a value is changed.
|
|
163
|
+
* Needed to clear certain fields on discard changes.
|
|
164
|
+
*/
|
|
165
|
+
key: (fieldDefinition.type === 'choices' ||
|
|
166
|
+
fieldDefinition?.type === 'time' ||
|
|
167
|
+
fieldDefinition?.type === 'boolean') &&
|
|
168
|
+
triggerFieldReset
|
|
169
|
+
? `${entryId}-reset-true`
|
|
170
|
+
: `${entryId}-reset-false`, ...getFieldWrapperProps(fieldDefinition, entry, entryId, fieldValue, display, fieldHeight, errors), errorMessage: undefined },
|
|
171
|
+
React.createElement(FormField, { id: entryId,
|
|
172
|
+
// TODO: Ideally the FormField prop should be called parameter but can't change the name for backwards compatibility reasons
|
|
173
|
+
property: fieldDefinition, defaultValue: fieldValue || getValues(entryId), onChange: handleChange, readOnly: entry.type === 'readonlyField', placeholder: display?.placeholder, mask: validation?.mask, isOptionEqualToValue: isOptionEqualToValue, error: !!errors[entryId], errorMessage: errors[entryId]?.message, isMultiLineText: !!display?.rowCount, rows: display?.rowCount, required: entry.display?.required || false, getOptionLabel: (option) => {
|
|
174
|
+
if (typeof option === 'string') {
|
|
175
|
+
return (entry?.enumWithLabels?.find((e) => e.value === option)
|
|
176
|
+
?.label ?? option);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return (entry?.enumWithLabels?.find((e) => e.value === option.value)?.label ?? String(option.value));
|
|
180
|
+
}
|
|
181
|
+
}, size: fieldHeight, sortBy: display?.choicesDisplay?.sortBy && display.choicesDisplay.sortBy, displayOption: fieldDefinition.type === 'boolean'
|
|
182
|
+
? display?.booleanDisplay
|
|
183
|
+
: display?.choicesDisplay?.type && display.choicesDisplay.type, label: display?.label, description: display?.description, tooltip: display?.tooltip, selectOptions: entry?.enumWithLabels &&
|
|
184
|
+
entry.enumWithLabels, additionalProps: additionalProps, isCombobox: fieldDefinition.nonStrictEnum, strictlyTrue: fieldDefinition.strictlyTrue })));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (entry.type === 'columns') {
|
|
188
|
+
return (React.createElement(Box, { sx: { display: 'flex', alignItems: 'flex-start', gap: '30px', flexDirection: isXs ? 'column' : 'row' } }, entry.columns.map((column, colIndex) => (
|
|
189
|
+
// calculating the width like this rather than flex={column.width} to prevent collections from being too wide
|
|
190
|
+
React.createElement(Box, { key: colIndex, sx: { width: isXs ? '100%' : `calc(${(column.width / 12) * 100}% - 15px)` } }, column.entries?.map((columnEntry, entryIndex) => {
|
|
191
|
+
return (React.createElement(RecursiveEntryRenderer, { key: entryIndex + (columnEntry?.parameterId ?? ''), entry: columnEntry, handleChange: handleChange, errors: errors, fieldHeight: fieldHeight, richTextEditor: richTextEditor, instance: instance, expandedSections: expandedSections, setExpandedSections: setExpandedSections, expandAll: expandAll, setExpandAll: setExpandAll, parameters: parameters, triggerFieldReset: triggerFieldReset }));
|
|
192
|
+
}))))));
|
|
193
|
+
}
|
|
194
|
+
else if (entry.type === 'sections') {
|
|
195
|
+
return smallerThan('md') ? (React.createElement(AccordionSections, { entry: entry, handleChange: handleChange, fieldHeight: fieldHeight, richTextEditor: richTextEditor, instance: instance, expandedSections: expandedSections, setExpandedSections: setExpandedSections, expandAll: expandAll, setExpandAll: setExpandAll, errors: errors, parameters: parameters, triggerFieldReset: triggerFieldReset })) : (React.createElement(FormSections, { entry: entry, errors: errors, handleChange: handleChange, showSubmitError: showSubmitError, fieldHeight: fieldHeight, richTextEditor: richTextEditor, instance: instance, expandedSections: expandedSections, setExpandedSections: setExpandedSections, expandAll: expandAll, setExpandAll: setExpandAll, parameters: parameters }));
|
|
196
|
+
}
|
|
197
|
+
else if (!fieldDefinition) {
|
|
198
|
+
return (React.createElement(Box, { sx: {
|
|
199
|
+
display: 'flex',
|
|
200
|
+
backgroundColor: '#ffc1073b',
|
|
201
|
+
borderRadius: '8px',
|
|
202
|
+
padding: '16.5px 14px',
|
|
203
|
+
marginTop: '6px',
|
|
204
|
+
} },
|
|
205
|
+
React.createElement(WarningRounded, { sx: { paddingRight: '8px' }, color: "warning" }),
|
|
206
|
+
React.createElement(Typography, { variant: "body2", color: "textSecondary" }, "This field was not configured correctly")));
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type TabNavProps = {
|
|
3
|
+
numberOfTabs: number;
|
|
4
|
+
tabValue: number;
|
|
5
|
+
handleTabChange: (type: 'tabNav' | 'buttonNav', newValue: number) => void;
|
|
6
|
+
prevTabLabel?: string;
|
|
7
|
+
nextTabLabel?: string;
|
|
8
|
+
};
|
|
9
|
+
declare function TabNav(props: TabNavProps): React.JSX.Element;
|
|
10
|
+
export default TabNav;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
|
2
|
+
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Button } from '../../../core';
|
|
5
|
+
import { Box } from '../../../layout';
|
|
6
|
+
function TabNav(props) {
|
|
7
|
+
const { numberOfTabs, tabValue, handleTabChange, prevTabLabel, nextTabLabel } = props;
|
|
8
|
+
const isFirstTab = tabValue === 0;
|
|
9
|
+
const isLastTab = tabValue === numberOfTabs - 1;
|
|
10
|
+
return (React.createElement(Box, { sx: {
|
|
11
|
+
display: 'flex',
|
|
12
|
+
justifyContent: isFirstTab ? 'flex-end' : 'space-between',
|
|
13
|
+
paddingTop: '10px',
|
|
14
|
+
paddingBottom: '20px',
|
|
15
|
+
} },
|
|
16
|
+
!isFirstTab && (React.createElement(Button, { onClick: () => handleTabChange('buttonNav', tabValue - 1), sx: { color: 'black', backgroundColor: '#dfe3e8', '&:hover': { backgroundColor: '#d0d4d9' } }, "aria-label": `Navigate to previous tab ${prevTabLabel}` },
|
|
17
|
+
React.createElement(ArrowBackIosNewIcon, { sx: { fontSize: 'medium', marginRight: 1 } }),
|
|
18
|
+
prevTabLabel ?? 'Previous tab')),
|
|
19
|
+
!isLastTab && (React.createElement(Button, { onClick: () => handleTabChange('buttonNav', tabValue + 1), sx: { color: 'black', backgroundColor: '#dfe3e8', '&:hover': { backgroundColor: '#d0d4d9' } }, "aria-label": `Navigate to next tab ${nextTabLabel}` },
|
|
20
|
+
nextTabLabel ?? 'Next tab',
|
|
21
|
+
React.createElement(ArrowForwardIosIcon, { sx: { fontSize: 'medium', marginLeft: 1 } })))));
|
|
22
|
+
}
|
|
23
|
+
export default TabNav;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { FormEntry, InputParameter } from '@evoke-platform/context';
|
|
2
|
+
import { FieldValues, UseFormRegister } from 'react-hook-form';
|
|
3
|
+
export declare const handleValidation: (entries: FormEntry[], register: UseFormRegister<FieldValues>, formValues: FieldValues, parameters?: InputParameter[], instance?: FieldValues) => void;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { isArray } from 'lodash';
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
3
|
+
import Handlebars from 'no-eval-handlebars';
|
|
4
|
+
function isNumericValidation(validation) {
|
|
5
|
+
return 'minimum' in validation || 'maximum' in validation;
|
|
6
|
+
}
|
|
7
|
+
function isCalendarValidation(validation) {
|
|
8
|
+
return 'to' in validation || 'from' in validation;
|
|
9
|
+
}
|
|
10
|
+
function isStringValidation(validation) {
|
|
11
|
+
return 'operator' in validation;
|
|
12
|
+
}
|
|
13
|
+
function isDocumentValidation(validation) {
|
|
14
|
+
const documentValidationKeys = ['minDocuments', 'maxDocuments', 'errorMessage'];
|
|
15
|
+
return !validation || Object.keys(validation).every((key) => documentValidationKeys.includes(key));
|
|
16
|
+
}
|
|
17
|
+
export const handleValidation = (entries, register, formValues, parameters, instance) => {
|
|
18
|
+
entries?.forEach((entry) => {
|
|
19
|
+
if (entry.type === 'sections' || entry.type === 'columns') {
|
|
20
|
+
const subEntries = entry.type === 'sections' ? entry.sections : entry.columns;
|
|
21
|
+
subEntries.forEach((subEntry) => {
|
|
22
|
+
if (subEntry.entries) {
|
|
23
|
+
handleValidation(subEntry.entries, register, formValues, parameters, instance);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
else if (entry.type !== 'input' && entry.type !== 'inputField') {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const display = entry?.display;
|
|
32
|
+
const parameter = entry.type === 'input'
|
|
33
|
+
? parameters?.find((param) => param.id === entry.parameterId)
|
|
34
|
+
: entry.type === 'inputField'
|
|
35
|
+
? entry.input
|
|
36
|
+
: undefined;
|
|
37
|
+
const validation = parameter?.validation || {};
|
|
38
|
+
const fieldName = display?.label;
|
|
39
|
+
const errorMsg = validation?.errorMessage;
|
|
40
|
+
const validationRules = {};
|
|
41
|
+
// Required fields
|
|
42
|
+
if (display?.required) {
|
|
43
|
+
validationRules.required = `${fieldName} is required`;
|
|
44
|
+
}
|
|
45
|
+
if (parameter?.type === 'boolean' && parameter?.strictlyTrue) {
|
|
46
|
+
validationRules.required = {
|
|
47
|
+
value: true,
|
|
48
|
+
message: display?.booleanDisplay === 'switch'
|
|
49
|
+
? `${fieldName} must be toggled on`
|
|
50
|
+
: `${fieldName} must be checked`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Min/max char string fields
|
|
54
|
+
if (typeof validation.minLength === 'number') {
|
|
55
|
+
validationRules.minLength = {
|
|
56
|
+
value: validation.minLength,
|
|
57
|
+
message: `${fieldName} must have at least ${validation.minLength} characters`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (typeof validation.maxLength === 'number') {
|
|
61
|
+
validationRules.maxLength = {
|
|
62
|
+
value: validation.maxLength,
|
|
63
|
+
message: `${fieldName} must have no more than ${validation.maxLength} characters`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Min/max number fields
|
|
67
|
+
if (isNumericValidation(validation) && validation.maximum) {
|
|
68
|
+
validationRules.max = {
|
|
69
|
+
value: validation.maximum,
|
|
70
|
+
message: errorMsg || `${fieldName} must have a value under ${validation.maximum}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (isNumericValidation(validation) && validation.minimum) {
|
|
74
|
+
validationRules.min = {
|
|
75
|
+
value: validation.minimum,
|
|
76
|
+
message: errorMsg || `${fieldName} must have a value over ${validation.minimum}`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
validationRules.validate = (value) => {
|
|
80
|
+
if (!value)
|
|
81
|
+
return true;
|
|
82
|
+
// Document validation
|
|
83
|
+
if (isDocumentValidation(validation)) {
|
|
84
|
+
const amountOfDocuments = isArray(value) ? value.length : 0;
|
|
85
|
+
const min = validation?.minDocuments;
|
|
86
|
+
const max = validation?.maxDocuments;
|
|
87
|
+
if (max && min && (amountOfDocuments > max || amountOfDocuments < min)) {
|
|
88
|
+
return errorMsg || `Please select between ${min} and ${max} document${max > 1 ? 's' : ''}`;
|
|
89
|
+
}
|
|
90
|
+
else if (min && amountOfDocuments < min) {
|
|
91
|
+
return errorMsg || `Please select at least ${min} document${min > 1 ? 's' : ''}`;
|
|
92
|
+
}
|
|
93
|
+
else if (max && amountOfDocuments > max) {
|
|
94
|
+
return errorMsg || `Please select no more than ${max} document${max > 1 ? 's' : ''}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Date and Time validation
|
|
98
|
+
if (isCalendarValidation(validation)) {
|
|
99
|
+
const data = {
|
|
100
|
+
__today__: DateTime.now().toISODate(),
|
|
101
|
+
input: formValues,
|
|
102
|
+
};
|
|
103
|
+
if (validation.from) {
|
|
104
|
+
let earliestAllowed = validation.from;
|
|
105
|
+
if (/{{[\w.]+(?:\s+[\w.]+)*(?:\s+\d+)?}}/.test(earliestAllowed)) {
|
|
106
|
+
earliestAllowed = Handlebars.compileAST(earliestAllowed)(data);
|
|
107
|
+
}
|
|
108
|
+
if (earliestAllowed && value < earliestAllowed) {
|
|
109
|
+
return (errorMsg ||
|
|
110
|
+
`${fieldName} must be ${parameter?.type === 'time' ? 'at' : 'on'} or later than ${earliestAllowed || 'a field with no value'}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (validation.to) {
|
|
114
|
+
let latestAllowed = validation.to;
|
|
115
|
+
if (/{{[\w.]+(?:\s+[\w.]+)*(?:\s+\d+)?}}/.test(latestAllowed)) {
|
|
116
|
+
latestAllowed = Handlebars.compileAST(latestAllowed)(data);
|
|
117
|
+
}
|
|
118
|
+
if (latestAllowed && value > latestAllowed) {
|
|
119
|
+
return (errorMsg ||
|
|
120
|
+
`${fieldName} must be ${parameter?.type === 'time' ? 'at' : 'on'} or before ${latestAllowed || 'a field with no value'}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Regex validation
|
|
125
|
+
if (isStringValidation(validation) && validation.rules) {
|
|
126
|
+
const rules = validation.rules;
|
|
127
|
+
const failedRules = rules.filter((rule) => {
|
|
128
|
+
const regex = new RegExp(rule.regex);
|
|
129
|
+
return !regex.test(value);
|
|
130
|
+
});
|
|
131
|
+
const operator = validation.operator;
|
|
132
|
+
if (failedRules.length > 0) {
|
|
133
|
+
if (operator === 'all') {
|
|
134
|
+
const messages = failedRules
|
|
135
|
+
.map((rule) => rule.errorMessage || 'Property is not in a valid format')
|
|
136
|
+
.join(' and ');
|
|
137
|
+
return `${fieldName}: ${messages}`;
|
|
138
|
+
}
|
|
139
|
+
if (operator === 'any' && failedRules.length < rules.length) {
|
|
140
|
+
return true; // passes if at least one rule passed
|
|
141
|
+
}
|
|
142
|
+
const messages = failedRules
|
|
143
|
+
.map((rule) => rule.errorMessage || 'Property is not in a valid format')
|
|
144
|
+
.join(' or ');
|
|
145
|
+
return `${fieldName}: ${messages}`;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Integer check
|
|
149
|
+
if (parameter?.type === 'integer') {
|
|
150
|
+
if (value && !Number.isInteger(value)) {
|
|
151
|
+
return `${fieldName} must be an integer`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Invalid date check
|
|
155
|
+
if (value?.invalid && value?.dateText) {
|
|
156
|
+
return `Invalid Date`;
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
};
|
|
160
|
+
register(entry.parameterId || entry.input?.id, validationRules);
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
Handlebars.registerHelper('addDays', function (addend1, addend2) {
|
|
164
|
+
const dateAddend1 = DateTime.fromISO(addend1);
|
|
165
|
+
if (dateAddend1.isValid) {
|
|
166
|
+
return dateAddend1.plus({ days: addend2 }).toISODate();
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
});
|
|
170
|
+
Handlebars.registerHelper('subDays', function (minuend, subtrahend) {
|
|
171
|
+
const dateMinuend = DateTime.fromISO(minuend);
|
|
172
|
+
if (dateMinuend.isValid) {
|
|
173
|
+
return dateMinuend.minus({ days: subtrahend }).toISODate();
|
|
174
|
+
}
|
|
175
|
+
return undefined;
|
|
176
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FieldErrors } from 'react-hook-form';
|
|
3
|
+
export type ValidationErrorDisplayProps = {
|
|
4
|
+
errors: FieldErrors;
|
|
5
|
+
show: boolean;
|
|
6
|
+
formId: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
};
|
|
9
|
+
declare function ValidationErrorDisplay(props: ValidationErrorDisplayProps): React.JSX.Element | null;
|
|
10
|
+
export default ValidationErrorDisplay;
|
package/dist/published/components/custom/FormV2/components/ValidationFiles/ValidationErrorDisplay.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useResponsive } from '../../../../../theme';
|
|
3
|
+
import { List, ListItem, Typography } from '../../../../core';
|
|
4
|
+
import { Box } from '../../../../layout';
|
|
5
|
+
function ValidationErrorDisplay(props) {
|
|
6
|
+
const { errors, show, formId, title } = props;
|
|
7
|
+
const { isSm, isXs } = useResponsive();
|
|
8
|
+
function extractErrorMessages(errors) {
|
|
9
|
+
const messages = [];
|
|
10
|
+
for (const key in errors) {
|
|
11
|
+
const error = errors[key];
|
|
12
|
+
if (error?.message) {
|
|
13
|
+
messages.push(error.message);
|
|
14
|
+
}
|
|
15
|
+
else if (error) {
|
|
16
|
+
for (const nestedKey in error) {
|
|
17
|
+
const nestedError = error[nestedKey];
|
|
18
|
+
if (nestedError?.message) {
|
|
19
|
+
messages.push(nestedError.message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return messages;
|
|
25
|
+
}
|
|
26
|
+
const errorMessages = extractErrorMessages(errors);
|
|
27
|
+
return show && errorMessages.length > 0 ? (React.createElement(Box, { id: `validation-error-display-${formId}`, sx: {
|
|
28
|
+
backgroundColor: '#f8d7da',
|
|
29
|
+
borderColor: '#f5c6cb',
|
|
30
|
+
color: '#721c24',
|
|
31
|
+
border: '1px solid #721c24',
|
|
32
|
+
padding: '8px 24px',
|
|
33
|
+
borderRadius: '4px',
|
|
34
|
+
marginBottom: isSm || isXs ? 2 : 3,
|
|
35
|
+
marginTop: !title ? (isSm || isXs ? -2 : -3) : undefined,
|
|
36
|
+
} },
|
|
37
|
+
React.createElement(Typography, { sx: { color: '#721c24', mt: '16px', mb: '8px' } }, "Please fix the following errors before submitting:"),
|
|
38
|
+
React.createElement(List, { sx: {
|
|
39
|
+
listStyleType: 'disc',
|
|
40
|
+
paddingLeft: '40px',
|
|
41
|
+
mb: '8px',
|
|
42
|
+
fontFamily: 'Arial, Helvetica, sans-serif',
|
|
43
|
+
} }, errorMessages.map((msg, index) => (React.createElement(ListItem, { key: index, sx: { display: 'list-item', p: 0 } }, msg)))))) : null;
|
|
44
|
+
}
|
|
45
|
+
export default ValidationErrorDisplay;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { FormEntry, InputParameter, ObjectInstance, Property, Section, Sections, ViewLayoutEntityReference } from '@evoke-platform/context';
|
|
2
|
+
import { GridSize } from '@mui/material';
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
|
+
import { FieldErrors, FieldValues } from 'react-hook-form';
|
|
5
|
+
export type FieldAddress = {
|
|
6
|
+
line1?: string;
|
|
7
|
+
line2?: string;
|
|
8
|
+
city?: string;
|
|
9
|
+
county?: string;
|
|
10
|
+
state?: string;
|
|
11
|
+
zipCode?: string;
|
|
12
|
+
};
|
|
13
|
+
export type AccessCheck = {
|
|
14
|
+
result: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type SavedDocumentReference = {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
export type Document = {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
contentType: string;
|
|
24
|
+
size: number;
|
|
25
|
+
uploadedDate: string;
|
|
26
|
+
metadata: {
|
|
27
|
+
[field: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
versionId?: string;
|
|
30
|
+
};
|
|
31
|
+
export type SimpleEditorProps = {
|
|
32
|
+
id: string;
|
|
33
|
+
value: string;
|
|
34
|
+
handleUpdate?: (value: string) => void;
|
|
35
|
+
format: 'rtf' | 'plain' | 'openxml';
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
rows?: number;
|
|
38
|
+
hasError?: boolean;
|
|
39
|
+
viewHistory?: boolean;
|
|
40
|
+
};
|
|
41
|
+
export type ObjectPropertyInputProps = {
|
|
42
|
+
id: string;
|
|
43
|
+
instance?: FieldValues;
|
|
44
|
+
fieldDefinition: InputParameter;
|
|
45
|
+
handleChangeObjectProperty: (propertyId: string, instance?: ObjectInstance | null) => void;
|
|
46
|
+
mode: 'default' | 'existingOnly' | 'newOnly';
|
|
47
|
+
nestedFieldsView?: boolean;
|
|
48
|
+
readOnly?: boolean;
|
|
49
|
+
error?: boolean;
|
|
50
|
+
displayOption?: 'dropdown' | 'dialogBox';
|
|
51
|
+
filter?: Record<string, unknown>;
|
|
52
|
+
defaultValueCriteria?: Record<string, unknown>;
|
|
53
|
+
sortBy?: string;
|
|
54
|
+
orderBy?: string;
|
|
55
|
+
isModal?: boolean;
|
|
56
|
+
label?: string;
|
|
57
|
+
initialValue?: ObjectInstance | null;
|
|
58
|
+
fieldHeight?: 'small' | 'medium';
|
|
59
|
+
richTextEditor?: ComponentType<SimpleEditorProps>;
|
|
60
|
+
viewLayout?: ViewLayoutEntityReference;
|
|
61
|
+
hasDescription?: boolean;
|
|
62
|
+
parameters?: InputParameter[];
|
|
63
|
+
};
|
|
64
|
+
export type Page = {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
slug?: string;
|
|
68
|
+
pk?: string;
|
|
69
|
+
appId?: string;
|
|
70
|
+
pathParameters?: {
|
|
71
|
+
id: string;
|
|
72
|
+
}[];
|
|
73
|
+
children?: unknown[];
|
|
74
|
+
};
|
|
75
|
+
export type SearchFieldProps = {
|
|
76
|
+
searchableColumns: Property[];
|
|
77
|
+
filter: Record<string, unknown> | undefined;
|
|
78
|
+
setFilter: (filter: Record<string, unknown> | undefined) => void;
|
|
79
|
+
searchString: string;
|
|
80
|
+
setSearchString: (searchString: string) => void;
|
|
81
|
+
};
|
|
82
|
+
export type BaseProps = {
|
|
83
|
+
colspan?: GridSize;
|
|
84
|
+
baseUrl?: string;
|
|
85
|
+
getWidgetState?: () => any;
|
|
86
|
+
saveWidgetState?: (widgetState: unknown) => void;
|
|
87
|
+
};
|
|
88
|
+
export type ExpandedSection = Section & {
|
|
89
|
+
id: string;
|
|
90
|
+
expanded?: boolean;
|
|
91
|
+
};
|
|
92
|
+
export type EntryRendererProps = BaseProps & {
|
|
93
|
+
entry: FormEntry;
|
|
94
|
+
errors: FieldErrors;
|
|
95
|
+
handleChange: (name: string, value: unknown) => void;
|
|
96
|
+
showSubmitError?: boolean;
|
|
97
|
+
fieldHeight?: 'small' | 'medium';
|
|
98
|
+
instance?: FieldValues;
|
|
99
|
+
richTextEditor?: ComponentType<SimpleEditorProps>;
|
|
100
|
+
expandedSections: ExpandedSection[];
|
|
101
|
+
setExpandedSections: React.Dispatch<React.SetStateAction<ExpandedSection[]>>;
|
|
102
|
+
expandAll?: boolean | undefined | null;
|
|
103
|
+
setExpandAll: React.Dispatch<React.SetStateAction<boolean | undefined | null>>;
|
|
104
|
+
parameters?: InputParameter[];
|
|
105
|
+
readOnly?: boolean;
|
|
106
|
+
triggerFieldReset?: boolean;
|
|
107
|
+
};
|
|
108
|
+
export type SectionsProps = {
|
|
109
|
+
entry: Sections;
|
|
110
|
+
handleChange: (propertyId: string, value: unknown) => void;
|
|
111
|
+
fieldHeight?: 'small' | 'medium';
|
|
112
|
+
richTextEditor?: ComponentType<SimpleEditorProps>;
|
|
113
|
+
instance?: FieldValues;
|
|
114
|
+
expandAll?: boolean | undefined | null;
|
|
115
|
+
expandedSections: ExpandedSection[];
|
|
116
|
+
setExpandedSections: React.Dispatch<React.SetStateAction<ExpandedSection[]>>;
|
|
117
|
+
setExpandAll: React.Dispatch<React.SetStateAction<boolean | undefined | null>>;
|
|
118
|
+
errors: FieldErrors;
|
|
119
|
+
parameters?: InputParameter[];
|
|
120
|
+
triggerFieldReset?: boolean;
|
|
121
|
+
showSubmitError?: boolean;
|
|
122
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ApiServices, Column, Columns, FormEntry, InputParameter, Obj, ObjectInstance, Property, Section, Sections, UserAccount } from '@evoke-platform/context';
|
|
2
|
+
import { LocalDateTime } from '@js-joda/core';
|
|
3
|
+
import { FieldErrors, FieldValues } from 'react-hook-form';
|
|
4
|
+
import { AutocompleteOption } from '../../../core';
|
|
5
|
+
import { Document } from './types';
|
|
6
|
+
export declare const scrollIntoViewWithOffset: (el: HTMLElement, offset: number, container?: HTMLElement) => void;
|
|
7
|
+
export declare const normalizeDateTime: (dateTime: LocalDateTime) => string;
|
|
8
|
+
export declare function isAddressProperty(key: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Determine if a form entry is visible or not.
|
|
11
|
+
*/
|
|
12
|
+
export declare const entryIsVisible: (entry: FormEntry, formValues: FieldValues, instance?: FieldValues) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Recursively retrieves all parameter IDs from a given entry of type Sections or Columns.
|
|
15
|
+
*
|
|
16
|
+
* @param {Sections | Columns} entry - The entry object, which can be of type Sections or Columns.
|
|
17
|
+
* @returns {string[]} - An array of parameter IDs found within the entry.
|
|
18
|
+
*/
|
|
19
|
+
export declare const getNestedParameterIds: (entry: Sections | Columns) => string[];
|
|
20
|
+
export declare const getEntryId: (entry: FormEntry) => string | undefined;
|
|
21
|
+
export declare function getPrefixedUrl(url: string): string;
|
|
22
|
+
export declare const isOptionEqualToValue: (option: AutocompleteOption | string, value: unknown) => boolean;
|
|
23
|
+
export declare function addressProperties(addressProperty: Property): Property[];
|
|
24
|
+
export declare const normalizeDates: (instance: ObjectInstance, evokeObject?: Obj) => ObjectInstance;
|
|
25
|
+
export declare const transformToWhere: (mongoQuery: Record<string, unknown>) => Record<string, unknown>;
|
|
26
|
+
export declare const getMiddleObject: (fieldDefinition: InputParameter | Property, endObjectId: string, endObjectName: string, instance?: FieldValues) => {
|
|
27
|
+
[x: string]: {
|
|
28
|
+
id: any;
|
|
29
|
+
name: any;
|
|
30
|
+
};
|
|
31
|
+
} | undefined;
|
|
32
|
+
export declare const getMiddleObjectFilter: (fieldDefinition: InputParameter | Property, instanceId: string) => {
|
|
33
|
+
where: {
|
|
34
|
+
[x: string]: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export declare const encodePageSlug: (slug: string) => string;
|
|
38
|
+
export declare function getDefaultPages(parameters: InputParameter[], defaultPages: Record<string, string> | undefined, findDefaultPageSlugFor: (objectId: string) => Promise<string | undefined>): Promise<{
|
|
39
|
+
[x: string]: string;
|
|
40
|
+
}>;
|
|
41
|
+
export declare function updateCriteriaInputs(criteria: Record<string, unknown>, data: Record<string, unknown>, user?: UserAccount): Record<string, unknown>;
|
|
42
|
+
export declare function fetchCollectionData(apiServices: ApiServices, fieldDefinition: InputParameter | Property, setFetchedOptions: (newData: FieldValues) => void, instanceId?: string, fetchedOptions?: Record<string, unknown>, initialMiddleObjectInstances?: ObjectInstance[]): Promise<void>;
|
|
43
|
+
export declare const getErrorCountForSection: (section: Section | Column, errors: FieldErrors) => number;
|
|
44
|
+
export declare const convertDocToParameters: (obj: Document) => InputParameter[];
|
|
45
|
+
export declare const propertyToParameter: (property: Property) => InputParameter;
|
|
46
|
+
export declare const propertyValidationToParameterValidation: (property: Property) => InputParameter['validation'];
|
|
47
|
+
export declare const convertPropertiesToParams: (object: Obj) => InputParameter[] | undefined;
|