@evoke-platform/ui-components 1.4.0-testing.4 → 1.4.0-testing.6
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/Alert/Alert.js +1 -1
- package/dist/published/components/core/Autocomplete/Autocomplete.js +3 -3
- package/dist/published/components/core/Chip/Chip.d.ts +2 -5
- package/dist/published/components/core/Chip/Chip.js +3 -6
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +0 -1
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +1 -2
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +2 -2
- package/dist/published/components/custom/Form/Common/Form.js +19 -7
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js +3 -2
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +1 -1
- package/dist/published/components/custom/Form/tests/Form.test.js +46 -0
- package/dist/published/components/custom/Form/tests/test-data.js +99 -0
- package/dist/published/components/custom/Form/utils.js +73 -38
- package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +1 -1
- package/dist/published/stories/Chip.stories.d.ts +3 -4
- package/dist/published/stories/Chip.stories.js +2 -4
- package/package.json +2 -2
@@ -31,7 +31,7 @@ const colorMap = {
|
|
31
31
|
const Alert = (props) => {
|
32
32
|
const { children, action, severity, onClose, color } = props;
|
33
33
|
const getIcon = () => {
|
34
|
-
const iconColor = color ? colorMap[color] ?? color : severity ? colorMap[severity] : colorMap['success'];
|
34
|
+
const iconColor = color ? (colorMap[color] ?? color) : severity ? colorMap[severity] : colorMap['success'];
|
35
35
|
switch (severity) {
|
36
36
|
case 'error':
|
37
37
|
return React.createElement(ErrorRounded, { sx: { ...styles.icon, color: iconColor } });
|
@@ -14,7 +14,7 @@ const Autocomplete = (props) => {
|
|
14
14
|
? option
|
15
15
|
: typeof option?.label === 'boolean'
|
16
16
|
? new Boolean(option?.label).toString()
|
17
|
-
: option?.label ?? '',
|
17
|
+
: (option?.label ?? ''),
|
18
18
|
value: option?.value ?? option,
|
19
19
|
};
|
20
20
|
})
|
@@ -62,7 +62,7 @@ const Autocomplete = (props) => {
|
|
62
62
|
marginTop: '3px',
|
63
63
|
borderRadius: '8px',
|
64
64
|
...props.sx,
|
65
|
-
}, options: sortedOptions, popupIcon:
|
65
|
+
}, options: sortedOptions, popupIcon: props.popupIcon ? props.popupIcon : props.readOnly || props.disabled ? null : React.createElement(ExpandMore, null) }),
|
66
66
|
props.error && React.createElement(FieldError, { required: props.required, label: props.errorMessage })));
|
67
67
|
}
|
68
68
|
else {
|
@@ -78,7 +78,7 @@ const Autocomplete = (props) => {
|
|
78
78
|
backgroundColor: props.readOnly ? '#f4f6f8' : 'auto',
|
79
79
|
borderRadius: '8px',
|
80
80
|
...props.sx,
|
81
|
-
}, options: sortedOptions, popupIcon:
|
81
|
+
}, options: sortedOptions, popupIcon: props.popupIcon ? props.popupIcon : props.readOnly || props.disabled ? null : React.createElement(ExpandMore, null) }),
|
82
82
|
props.error && React.createElement(FieldError, { required: props.required, label: props.errorMessage })));
|
83
83
|
}
|
84
84
|
};
|
@@ -1,7 +1,4 @@
|
|
1
|
-
import { ChipProps
|
1
|
+
import { ChipProps } from '@mui/material';
|
2
2
|
import React from 'react';
|
3
|
-
|
4
|
-
tooltip?: string;
|
5
|
-
}
|
6
|
-
declare const Chip: ({ tooltip, ...props }: ChipProps) => React.JSX.Element;
|
3
|
+
declare const Chip: (props: ChipProps) => React.JSX.Element;
|
7
4
|
export default Chip;
|
@@ -1,11 +1,8 @@
|
|
1
1
|
import { Chip as MUIChip } from '@mui/material';
|
2
2
|
import React from 'react';
|
3
|
-
import
|
4
|
-
const Chip = (
|
5
|
-
|
6
|
-
return React.createElement(MUIChip, { ...props });
|
7
|
-
}
|
8
|
-
return (React.createElement(Tooltip, { title: tooltip },
|
3
|
+
import UIThemeProvider from '../../../theme';
|
4
|
+
const Chip = (props) => {
|
5
|
+
return (React.createElement(UIThemeProvider, null,
|
9
6
|
React.createElement(MUIChip, { ...props })));
|
10
7
|
};
|
11
8
|
export default Chip;
|
@@ -26,7 +26,6 @@ export type CriteriaInputProps = {
|
|
26
26
|
fetchObject?: (objectId: string) => Promise<EvokeObject | undefined>;
|
27
27
|
object: TreeViewObject;
|
28
28
|
};
|
29
|
-
rootObject?: EvokeObject;
|
30
29
|
/**
|
31
30
|
* String matching operators ('contains', 'beginsWith', 'endsWith') use regex patterns.
|
32
31
|
* Special characters like .*+?^${}()|[] are escaped (\\) by default.
|
@@ -265,7 +265,7 @@ export const valueEditor = (props) => {
|
|
265
265
|
return ValueEditor(props);
|
266
266
|
};
|
267
267
|
const CriteriaBuilder = (props) => {
|
268
|
-
const { properties, criteria, setCriteria, originalCriteria, enablePresetValues, presetValues, operators, disabled, disabledCriteria, hideBorder, presetGroupLabel, customValueEditor, treeViewOpts, disableRegexEscapeChars,
|
268
|
+
const { properties, criteria, setCriteria, originalCriteria, enablePresetValues, presetValues, operators, disabled, disabledCriteria, hideBorder, presetGroupLabel, customValueEditor, treeViewOpts, disableRegexEscapeChars, } = props;
|
269
269
|
const [query, setQuery] = useState(undefined);
|
270
270
|
const [propertyTreeMap, setPropertyTreeMap] = useState();
|
271
271
|
useEffect(() => {
|
@@ -483,7 +483,6 @@ const CriteriaBuilder = (props) => {
|
|
483
483
|
valueEditor: customValueEditor ? customValueEditor.component : valueEditor,
|
484
484
|
}, context: {
|
485
485
|
...(customValueEditor?.props ?? {}),
|
486
|
-
rootObject,
|
487
486
|
presetValues,
|
488
487
|
enablePresetValues,
|
489
488
|
presetGroupLabel,
|
@@ -123,8 +123,8 @@ const PropertyTree = ({ fetchObject, handleTreePropertySelect, rootObject, value
|
|
123
123
|
}, getOptionLabel: (option) => {
|
124
124
|
// Retrieve the full name path from the map
|
125
125
|
const namePath = typeof option === 'string'
|
126
|
-
? objectPropertyNamePathMap[option] ?? ''
|
127
|
-
: objectPropertyNamePathMap[option.value] ?? '';
|
126
|
+
? (objectPropertyNamePathMap[option] ?? '')
|
127
|
+
: (objectPropertyNamePathMap[option.value] ?? '');
|
128
128
|
return truncateNamePath(namePath, NAME_PATH_LIMIT);
|
129
129
|
}, renderInput: (params) => {
|
130
130
|
const fullDisplayName = value && objectPropertyNamePathMap[value];
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { useApp, useAuthenticationContext, } from '@evoke-platform/context';
|
2
2
|
import { Components, Form as FormIO, Utils } from '@formio/react';
|
3
3
|
import { flatten } from 'flat';
|
4
|
-
import { isEmpty, isEqual, isObject, pick, toPairs } from 'lodash';
|
4
|
+
import { isEmpty, isEqual, isObject, omit, pick, toPairs } from 'lodash';
|
5
5
|
import React, { useEffect, useRef, useState } from 'react';
|
6
6
|
import '../../../../styles/form-component.css';
|
7
7
|
import { Skeleton, Snackbar } from '../../../core';
|
@@ -126,7 +126,7 @@ export function Form(props) {
|
|
126
126
|
const allDefaultPages = { ...defaultPages, ...foundDefaultPages };
|
127
127
|
// visibleObjectProperties
|
128
128
|
if (input && object?.properties) {
|
129
|
-
const allCriteriaInputs = getAllCriteriaInputs(action?.inputProperties ? flattenFormComponents(action.inputProperties) : action?.parameters ?? []);
|
129
|
+
const allCriteriaInputs = getAllCriteriaInputs(action?.inputProperties ? flattenFormComponents(action.inputProperties) : (action?.parameters ?? []));
|
130
130
|
if (input.length || action?.type !== 'delete') {
|
131
131
|
// formIO builder-configured input properties exist
|
132
132
|
const newComponentProps = await addObjectPropertiesToComponentProps(object.properties, input, allCriteriaInputs, instance, {
|
@@ -139,6 +139,18 @@ export function Form(props) {
|
|
139
139
|
if (!hideButtons && !isReadOnly) {
|
140
140
|
newComponentProps.push(BottomButtons);
|
141
141
|
}
|
142
|
+
if (action?.type !== 'create') {
|
143
|
+
// Add an additional, hidden _instance property on update/delete actions
|
144
|
+
// so that instance data is accessible in conditional display logic.
|
145
|
+
const hiddenComponent = {
|
146
|
+
key: '_instance',
|
147
|
+
type: 'hidden',
|
148
|
+
input: true,
|
149
|
+
tableView: false,
|
150
|
+
defaultValue: instance,
|
151
|
+
};
|
152
|
+
newComponentProps.push(hiddenComponent);
|
153
|
+
}
|
142
154
|
setComponentProps(newComponentProps);
|
143
155
|
}
|
144
156
|
else {
|
@@ -313,8 +325,8 @@ export function Form(props) {
|
|
313
325
|
const savedValue = submittedFields[docProperty.id];
|
314
326
|
const originalValue = instance?.[docProperty.id];
|
315
327
|
const documentsToRemove = requestSuccess
|
316
|
-
? originalValue?.filter((file) => !savedValue?.some((f) => f.id === file.id)) ?? []
|
317
|
-
: savedValue?.filter((file) => !originalValue?.some((f) => f.id === file.id)) ?? [];
|
328
|
+
? (originalValue?.filter((file) => !savedValue?.some((f) => f.id === file.id)) ?? [])
|
329
|
+
: (savedValue?.filter((file) => !originalValue?.some((f) => f.id === file.id)) ?? []);
|
318
330
|
for (const doc of documentsToRemove) {
|
319
331
|
try {
|
320
332
|
await apiServices?.delete(getPrefixedUrl(`/objects/${object?.id}/instances/${instance?.id}/documents/${doc.id}`));
|
@@ -416,7 +428,7 @@ export function Form(props) {
|
|
416
428
|
key: 'save-draft',
|
417
429
|
variant: 'outlined',
|
418
430
|
isModal: !!closeModal,
|
419
|
-
onClick: async (data, setError, setSubmitting) => await saveHandler(data, 'draft', setError, setSubmitting),
|
431
|
+
onClick: async (data, setError, setSubmitting) => await saveHandler(omit(data, '_instance'), 'draft', setError, setSubmitting),
|
420
432
|
style: { lineHeight: '2.75', margin: '5px', padding: '0 10px' },
|
421
433
|
}
|
422
434
|
: undefined,
|
@@ -437,7 +449,7 @@ export function Form(props) {
|
|
437
449
|
variant: 'contained',
|
438
450
|
isModal: !!closeModal,
|
439
451
|
onClick: (data, setError, setSubmitting) => {
|
440
|
-
saveHandler(data, 'submit', setError, setSubmitting);
|
452
|
+
saveHandler(omit(data, '_instance'), 'submit', setError, setSubmitting);
|
441
453
|
},
|
442
454
|
},
|
443
455
|
],
|
@@ -447,7 +459,7 @@ export function Form(props) {
|
|
447
459
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
448
460
|
, {
|
449
461
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
450
|
-
onChange: (e) => !isEqual(e.data, formData) && setFormData(e.data), key: closeModal ? undefined : formKey, form: {
|
462
|
+
onChange: (e) => !isEqual(omit(e.data, '_instance'), formData) && setFormData(omit(e.data, '_instance')), key: closeModal ? undefined : formKey, form: {
|
451
463
|
display: 'form',
|
452
464
|
components: componentProps,
|
453
465
|
}, formReady: handleFormReady })) : (React.createElement(Box, null,
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js
CHANGED
@@ -227,7 +227,7 @@ export const ObjectPropertyInput = (props) => {
|
|
227
227
|
return option.value === value?.value;
|
228
228
|
}, options: options.map((o) => ({ label: o.name, value: o.id })), getOptionLabel: (option) => {
|
229
229
|
return typeof option === 'string'
|
230
|
-
? options.find((o) => o.id === option)?.name ?? ''
|
230
|
+
? (options.find((o) => o.id === option)?.name ?? '')
|
231
231
|
: option.label;
|
232
232
|
}, onKeyDownCapture: (e) => {
|
233
233
|
if (instance?.[property.id]?.id || selectedInstance?.id) {
|
@@ -292,7 +292,8 @@ export const ObjectPropertyInput = (props) => {
|
|
292
292
|
}
|
293
293
|
: {}),
|
294
294
|
} })), readOnly: !loadingOptions && !canUpdateProperty, error: error, sortBy: "NONE" }))) : (React.createElement(Box, { sx: {
|
295
|
-
padding: (instance?.[property.id]?.name ??
|
295
|
+
padding: (instance?.[property.id]?.name ??
|
296
|
+
selectedInstance?.name)
|
296
297
|
? '16.5px 14px'
|
297
298
|
: '10.5px 0',
|
298
299
|
} },
|
@@ -402,7 +402,7 @@ const RepeatableField = (props) => {
|
|
402
402
|
React.createElement(Tooltip, { title: "Delete" },
|
403
403
|
React.createElement(TrashCan, { sx: { ':hover': { color: '#A12723' } } })))))))))))),
|
404
404
|
hasCreateAction && (React.createElement(Button, { variant: "contained", sx: styles.addButton, onClick: addRow }, "Add"))),
|
405
|
-
relatedObject && openDialog && (React.createElement(ActionDialog, { object: relatedObject, open: openDialog, apiServices: apiServices, onClose: () => setOpenDialog(false), instanceInput: dialogType === 'update' ? relatedInstances.find((i) => i.id === selectedRow) ?? {} : {}, handleSubmit: save,
|
405
|
+
relatedObject && openDialog && (React.createElement(ActionDialog, { object: relatedObject, open: openDialog, apiServices: apiServices, onClose: () => setOpenDialog(false), instanceInput: dialogType === 'update' ? (relatedInstances.find((i) => i.id === selectedRow) ?? {}) : {}, handleSubmit: save,
|
406
406
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
407
407
|
objectInputCommonProps: { apiServices }, action: relatedObject?.actions?.find((a) => a.id ===
|
408
408
|
(dialogType === 'create' ? '_create' : dialogType === 'update' ? '_update' : '_delete')), instanceId: selectedRow, queryAddresses: queryAddresses, user: user, associatedObject: instance.id && property.relatedPropertyId
|
@@ -109,4 +109,50 @@ describe('Form component', () => {
|
|
109
109
|
await waitFor(() => expect(within(openAutocomplete).queryByRole('option', { name: 'NP Specialty Type #2' })).to.be.null);
|
110
110
|
});
|
111
111
|
});
|
112
|
+
describe('visibility configuration', () => {
|
113
|
+
it('shows fields based on instance data using JsonLogic', async () => {
|
114
|
+
server.use(http.get('/data/objects/license/instances/rnLicense', () => HttpResponse.json(rnLicense)));
|
115
|
+
render(React.createElement(Form, { actionId: 'jsonLogicDisplayTest', actionType: 'update', object: specialtyObject, apiServices: apiServices, instance: {
|
116
|
+
id: '123',
|
117
|
+
objectId: 'specialty',
|
118
|
+
name: 'Test Specialty Object Instance',
|
119
|
+
} }));
|
120
|
+
// Validate that specialty type dropdown renders
|
121
|
+
await screen.findByRole('combobox', { name: 'Specialty Type' });
|
122
|
+
});
|
123
|
+
it('hides fields based on instance data using JsonLogic', async () => {
|
124
|
+
server.use(http.get('/data/objects/license/instances/rnLicense', () => HttpResponse.json(rnLicense)));
|
125
|
+
render(React.createElement(Form, { actionId: 'jsonLogicDisplayTest', actionType: 'update', object: specialtyObject, apiServices: apiServices, instance: {
|
126
|
+
id: '123',
|
127
|
+
objectId: 'specialty',
|
128
|
+
name: 'Test Specialty Object Instance -- hidden',
|
129
|
+
} }));
|
130
|
+
// Validate that license dropdown renders
|
131
|
+
await screen.findByRole('combobox', { name: 'License' });
|
132
|
+
// Validate that specialty type dropdown does not render
|
133
|
+
expect(screen.queryByRole('combobox', { name: 'Specialty Type' })).to.be.null;
|
134
|
+
});
|
135
|
+
it('shows fields based on instance data using simple conditions', async () => {
|
136
|
+
server.use(http.get('/data/objects/license/instances/rnLicense', () => HttpResponse.json(rnLicense)));
|
137
|
+
render(React.createElement(Form, { actionId: 'simpleConditionDisplayTest', actionType: 'update', object: specialtyObject, apiServices: apiServices, instance: {
|
138
|
+
id: '123',
|
139
|
+
objectId: 'specialty',
|
140
|
+
name: 'Test Specialty Object Instance',
|
141
|
+
} }));
|
142
|
+
// Validate that specialty type dropdown renders
|
143
|
+
await screen.findByRole('combobox', { name: 'Specialty Type' });
|
144
|
+
});
|
145
|
+
it('hides fields based on instance data using simple conditions', async () => {
|
146
|
+
server.use(http.get('/data/objects/license/instances/rnLicense', () => HttpResponse.json(rnLicense)));
|
147
|
+
render(React.createElement(Form, { actionId: 'simpleConditionDisplayTest', actionType: 'update', object: specialtyObject, apiServices: apiServices, instance: {
|
148
|
+
id: '123',
|
149
|
+
objectId: 'specialty',
|
150
|
+
name: 'Test Specialty Object Instance -- hidden',
|
151
|
+
} }));
|
152
|
+
// Validate that license dropdown renders
|
153
|
+
await screen.findByRole('combobox', { name: 'License' });
|
154
|
+
// Validate that specialty type dropdown does not render
|
155
|
+
expect(screen.queryByRole('combobox', { name: 'Specialty Type' })).to.be.null;
|
156
|
+
});
|
157
|
+
});
|
112
158
|
});
|
@@ -170,6 +170,105 @@ export const specialtyObject = {
|
|
170
170
|
],
|
171
171
|
},
|
172
172
|
},
|
173
|
+
{
|
174
|
+
id: 'jsonLogicDisplayTest',
|
175
|
+
name: 'JsonLogic Display Test',
|
176
|
+
type: 'update',
|
177
|
+
outputEvent: 'Specialty Updated',
|
178
|
+
parameters: [
|
179
|
+
{
|
180
|
+
id: 'specialtyType',
|
181
|
+
name: 'Specialty Type',
|
182
|
+
type: 'object',
|
183
|
+
objectId: 'specialtyType',
|
184
|
+
},
|
185
|
+
{
|
186
|
+
id: 'license',
|
187
|
+
name: 'License',
|
188
|
+
type: 'object',
|
189
|
+
objectId: 'license',
|
190
|
+
},
|
191
|
+
],
|
192
|
+
form: {
|
193
|
+
entries: [
|
194
|
+
{
|
195
|
+
parameterId: 'specialtyType',
|
196
|
+
type: 'input',
|
197
|
+
display: {
|
198
|
+
label: 'Specialty Type',
|
199
|
+
relatedObjectDisplay: 'dropdown',
|
200
|
+
visibility: {
|
201
|
+
'===': [
|
202
|
+
{
|
203
|
+
var: 'instance.name',
|
204
|
+
},
|
205
|
+
'Test Specialty Object Instance',
|
206
|
+
],
|
207
|
+
},
|
208
|
+
},
|
209
|
+
},
|
210
|
+
{
|
211
|
+
parameterId: 'license',
|
212
|
+
type: 'input',
|
213
|
+
display: {
|
214
|
+
label: 'License',
|
215
|
+
relatedObjectDisplay: 'dropdown',
|
216
|
+
},
|
217
|
+
},
|
218
|
+
],
|
219
|
+
},
|
220
|
+
},
|
221
|
+
{
|
222
|
+
id: 'simpleConditionDisplayTest',
|
223
|
+
name: 'Simple Condition Display Test',
|
224
|
+
type: 'update',
|
225
|
+
outputEvent: 'Specialty Updated',
|
226
|
+
parameters: [
|
227
|
+
{
|
228
|
+
id: 'specialtyType',
|
229
|
+
name: 'Specialty Type',
|
230
|
+
type: 'object',
|
231
|
+
objectId: 'specialtyType',
|
232
|
+
},
|
233
|
+
{
|
234
|
+
id: 'license',
|
235
|
+
name: 'License',
|
236
|
+
type: 'object',
|
237
|
+
objectId: 'license',
|
238
|
+
},
|
239
|
+
],
|
240
|
+
form: {
|
241
|
+
entries: [
|
242
|
+
{
|
243
|
+
parameterId: 'specialtyType',
|
244
|
+
type: 'input',
|
245
|
+
display: {
|
246
|
+
label: 'Specialty Type',
|
247
|
+
relatedObjectDisplay: 'dropdown',
|
248
|
+
visibility: {
|
249
|
+
operator: 'all',
|
250
|
+
conditions: [
|
251
|
+
{
|
252
|
+
property: 'name',
|
253
|
+
operator: 'eq',
|
254
|
+
value: 'Test Specialty Object Instance',
|
255
|
+
isInstanceProperty: true,
|
256
|
+
},
|
257
|
+
],
|
258
|
+
},
|
259
|
+
},
|
260
|
+
},
|
261
|
+
{
|
262
|
+
parameterId: 'license',
|
263
|
+
type: 'input',
|
264
|
+
display: {
|
265
|
+
label: 'License',
|
266
|
+
relatedObjectDisplay: 'dropdown',
|
267
|
+
},
|
268
|
+
},
|
269
|
+
],
|
270
|
+
},
|
271
|
+
},
|
173
272
|
],
|
174
273
|
};
|
175
274
|
export const specialtyTypeObject = {
|
@@ -100,15 +100,7 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
100
100
|
? convertFormToComponents(section.entries, parameters, object)
|
101
101
|
: [],
|
102
102
|
})),
|
103
|
-
conditional:
|
104
|
-
? {
|
105
|
-
show: entry.visibility.conditions[0].operator === 'eq',
|
106
|
-
when: entry.visibility.conditions[0].property,
|
107
|
-
eq: entry.visibility.conditions[0].value,
|
108
|
-
}
|
109
|
-
: {
|
110
|
-
json: entry.visibility,
|
111
|
-
},
|
103
|
+
conditional: convertVisibilityToConditional(entry.visibility),
|
112
104
|
};
|
113
105
|
}
|
114
106
|
else if (entry.type === 'columns') {
|
@@ -124,15 +116,7 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
124
116
|
? convertFormToComponents(column.entries, parameters, object)
|
125
117
|
: [],
|
126
118
|
})),
|
127
|
-
conditional:
|
128
|
-
? {
|
129
|
-
show: entry.visibility.conditions[0].operator === 'eq',
|
130
|
-
when: entry.visibility.conditions[0].property,
|
131
|
-
eq: entry.visibility.conditions[0].value,
|
132
|
-
}
|
133
|
-
: {
|
134
|
-
json: entry.visibility,
|
135
|
-
},
|
119
|
+
conditional: convertVisibilityToConditional(entry.visibility),
|
136
120
|
};
|
137
121
|
}
|
138
122
|
else if (entry.type === 'content') {
|
@@ -140,15 +124,7 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
140
124
|
type: 'Content',
|
141
125
|
key: nanoid(),
|
142
126
|
html: entry.html,
|
143
|
-
conditional:
|
144
|
-
? {
|
145
|
-
show: entry.visibility.conditions[0].operator === 'eq',
|
146
|
-
when: entry.visibility.conditions[0].property,
|
147
|
-
eq: entry.visibility.conditions[0].value,
|
148
|
-
}
|
149
|
-
: {
|
150
|
-
json: entry.visibility,
|
151
|
-
},
|
127
|
+
conditional: convertVisibilityToConditional(entry.visibility),
|
152
128
|
};
|
153
129
|
}
|
154
130
|
else {
|
@@ -266,17 +242,7 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
266
242
|
widget: (parameter.type === 'string' && parameter.enum) || parameter.type === 'array'
|
267
243
|
? 'choicejs'
|
268
244
|
: undefined,
|
269
|
-
conditional: displayOptions?.visibility
|
270
|
-
typeof displayOptions?.visibility !== 'string' &&
|
271
|
-
displayOptions.visibility.conditions?.length
|
272
|
-
? {
|
273
|
-
show: displayOptions?.visibility.conditions[0].operator === 'eq',
|
274
|
-
when: displayOptions?.visibility.conditions[0].property,
|
275
|
-
eq: displayOptions?.visibility.conditions[0].value,
|
276
|
-
}
|
277
|
-
: {
|
278
|
-
json: displayOptions?.visibility,
|
279
|
-
},
|
245
|
+
conditional: convertVisibilityToConditional(displayOptions?.visibility),
|
280
246
|
viewLayout: displayOptions?.viewLayout,
|
281
247
|
};
|
282
248
|
}
|
@@ -1313,3 +1279,72 @@ export function normalizeDates(instances, object) {
|
|
1313
1279
|
});
|
1314
1280
|
});
|
1315
1281
|
}
|
1282
|
+
/**
|
1283
|
+
* Given an object entry in a JsonLogic object, map it to the correct value.
|
1284
|
+
* @param entry An entry in a JsonLogic object.
|
1285
|
+
* @returns entry with all values starting with "instance" replaced with "data._instance"
|
1286
|
+
*/
|
1287
|
+
function processJsonLogicEntry(entry) {
|
1288
|
+
if (entry !== Object(entry)) {
|
1289
|
+
// entry is a primitive
|
1290
|
+
return typeof entry === 'string' ? entry.replace(/^instance/, 'data._instance') : entry;
|
1291
|
+
}
|
1292
|
+
else if (isArray(entry)) {
|
1293
|
+
return entry.map((element) => processJsonLogicEntry(element));
|
1294
|
+
}
|
1295
|
+
else if (typeof entry === 'object' && entry !== null) {
|
1296
|
+
let result = {};
|
1297
|
+
const entries = Object.entries(entry);
|
1298
|
+
for (const [key, val] of entries) {
|
1299
|
+
result = {
|
1300
|
+
...result,
|
1301
|
+
[key]: processJsonLogicEntry(val),
|
1302
|
+
};
|
1303
|
+
}
|
1304
|
+
return result;
|
1305
|
+
}
|
1306
|
+
return entry;
|
1307
|
+
}
|
1308
|
+
/**
|
1309
|
+
* Given a JsonLogic, replace all keys (if any) starting with "instance" with
|
1310
|
+
* "data._instance".
|
1311
|
+
*
|
1312
|
+
* @param jsonLogic A JsonLogic instance.
|
1313
|
+
* @returns jsonLogic, with all keys starting with "instance" replaced with "data._instance".
|
1314
|
+
*/
|
1315
|
+
function normalizeInstanceDataInJsonLogic(jsonLogic) {
|
1316
|
+
if (typeof jsonLogic === 'object' && jsonLogic !== null) {
|
1317
|
+
// jsonLogic is a Record<string, unknown>
|
1318
|
+
let result = {};
|
1319
|
+
const entries = Object.entries(jsonLogic);
|
1320
|
+
for (const [key, entry] of entries) {
|
1321
|
+
result = {
|
1322
|
+
...result,
|
1323
|
+
[key]: processJsonLogicEntry(entry),
|
1324
|
+
};
|
1325
|
+
}
|
1326
|
+
return result;
|
1327
|
+
}
|
1328
|
+
// jsonLogic is a primitive
|
1329
|
+
return jsonLogic;
|
1330
|
+
}
|
1331
|
+
/**
|
1332
|
+
*
|
1333
|
+
* @param visibility A form's visibility entry.
|
1334
|
+
* @returns The form's visibility entry, converted to formio-readable form.
|
1335
|
+
*/
|
1336
|
+
function convertVisibilityToConditional(visibility) {
|
1337
|
+
if (isObject(visibility) && 'conditions' in visibility && isArray(visibility.conditions)) {
|
1338
|
+
const [condition] = visibility.conditions;
|
1339
|
+
return {
|
1340
|
+
show: condition.operator === 'eq',
|
1341
|
+
when: condition.isInstanceProperty ? `_instance.${condition.property}` : condition.property,
|
1342
|
+
eq: condition.value,
|
1343
|
+
};
|
1344
|
+
}
|
1345
|
+
return visibility
|
1346
|
+
? {
|
1347
|
+
json: normalizeInstanceDataInJsonLogic(visibility),
|
1348
|
+
}
|
1349
|
+
: undefined;
|
1350
|
+
}
|
package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js
CHANGED
@@ -58,7 +58,7 @@ const AddressFieldComponent = (props) => {
|
|
58
58
|
backgroundColor: '#f4f6f8',
|
59
59
|
},
|
60
60
|
}
|
61
|
-
: undefined, required: required, error: error, errorMessage: errorMessage, InputProps: { readOnly: readOnly }, fullWidth: true, size: size ?? 'medium', type: 'text', multiline: property.type === 'string' && !readOnly && isMultiLineText, rows: isMultiLineText ? rows ?? 3 : undefined, value: value, ...(additionalProps ?? {}) })
|
61
|
+
: undefined, required: required, error: error, errorMessage: errorMessage, InputProps: { readOnly: readOnly }, fullWidth: true, size: size ?? 'medium', type: 'text', multiline: property.type === 'string' && !readOnly && isMultiLineText, rows: isMultiLineText ? (rows ?? 3) : undefined, value: value, ...(additionalProps ?? {}) })
|
62
62
|
// Casting to `React.ReactNode` is necessary to resolve TypeScript errors
|
63
63
|
// due to compatibility issues with the outdated `react-input-mask` version
|
64
64
|
// and the newer `@types/react` package.
|
@@ -1,7 +1,6 @@
|
|
1
|
+
import { ChipProps } from '@mui/material';
|
1
2
|
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
2
3
|
import React from 'react';
|
3
|
-
|
4
|
-
declare const _default: ComponentMeta<({ tooltip, ...props }: ChipProps) => React.JSX.Element>;
|
4
|
+
declare const _default: ComponentMeta<(props: ChipProps<"div", {}>) => React.JSX.Element>;
|
5
5
|
export default _default;
|
6
|
-
export declare const
|
7
|
-
export declare const Chip: ComponentStory<({ tooltip, ...props }: ChipProps) => React.JSX.Element>;
|
6
|
+
export declare const Chip: ComponentStory<(props: ChipProps<"div", {}>) => React.JSX.Element>;
|
@@ -1,10 +1,8 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Chip as CustomChip } from '../index';
|
3
3
|
export default {
|
4
|
-
|
4
|
+
title: 'Data Display/Chip',
|
5
5
|
component: CustomChip,
|
6
6
|
};
|
7
|
-
const ChipTemplate = (args) =>
|
8
|
-
const ChipWithToolipTemplate = (args) => (React.createElement(CustomChip, { tooltip: "Here is a tooltip", label: "Chip with Tooltip", ...args }));
|
9
|
-
export const ChipWithTooltip = ChipWithToolipTemplate.bind({});
|
7
|
+
const ChipTemplate = (args) => React.createElement(CustomChip, { ...args });
|
10
8
|
export const Chip = ChipTemplate.bind({});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@evoke-platform/ui-components",
|
3
|
-
"version": "1.4.0-testing.
|
3
|
+
"version": "1.4.0-testing.6",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/published/index.js",
|
6
6
|
"module": "dist/published/index.js",
|
@@ -94,7 +94,7 @@
|
|
94
94
|
"@dnd-kit/sortable": "^7.0.1",
|
95
95
|
"@emotion/react": "^11.13.5",
|
96
96
|
"@emotion/styled": "^11.8.1",
|
97
|
-
"@evoke-platform/context": "^1.1.0-testing.
|
97
|
+
"@evoke-platform/context": "^1.1.0-testing.4",
|
98
98
|
"@formio/react": "^5.2.4-rc.1",
|
99
99
|
"@js-joda/core": "^3.2.0",
|
100
100
|
"@js-joda/locale_en-us": "^3.2.2",
|