@evoke-platform/ui-components 1.10.0-dev.10 → 1.10.0-dev.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +1 -1
- package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.js +14 -1
- package/dist/published/components/custom/FormField/DateTimePickerSelect/DateTimePickerSelect.js +14 -1
- package/dist/published/components/custom/FormField/TimePickerSelect/TimePickerSelect.js +14 -1
- package/dist/published/components/custom/FormV2/components/Header.js +2 -2
- package/dist/published/components/custom/FormV2/tests/FormRendererContainer.test.js +9 -18
- package/package.json +1 -1
|
@@ -430,7 +430,7 @@ const RepeatableField = (props) => {
|
|
|
430
430
|
hasCreateAction && (React.createElement(Button, { variant: "contained", sx: styles.addButton, onClick: addRow }, "Add"))),
|
|
431
431
|
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,
|
|
432
432
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
433
|
-
objectInputCommonProps: { apiServices }, action: relatedObject?.actions?.find((a) => a.id ===
|
|
433
|
+
objectInputCommonProps: { apiServices, setSnackbarError }, action: relatedObject?.actions?.find((a) => a.id ===
|
|
434
434
|
(dialogType === 'create' ? '_create' : dialogType === 'update' ? '_update' : '_delete')), instanceId: selectedRow, queryAddresses: queryAddresses, user: user, associatedObject: instance.id && property.relatedPropertyId
|
|
435
435
|
? { instanceId: instance.id, propertyId: property.relatedPropertyId }
|
|
436
436
|
: undefined, richTextEditor: richTextEditor })),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DateTimeFormatter } from '@js-joda/core';
|
|
2
2
|
import { omit } from 'lodash';
|
|
3
3
|
import React, { useEffect, useState } from 'react';
|
|
4
|
+
import { useFormContext } from '../../../../theme/hooks';
|
|
4
5
|
import { InvalidDate, LocalDate, nativeJs } from '../../../../util';
|
|
5
6
|
import { DatePicker, LocalizationProvider, TextField } from '../../../core';
|
|
6
7
|
import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
|
|
@@ -29,6 +30,7 @@ const asMonthDayYearFormat = (date) => {
|
|
|
29
30
|
const DatePickerSelect = (props) => {
|
|
30
31
|
const { id, property, defaultValue, error, errorMessage, readOnly, required, size, onBlur, onChange, additionalProps, } = props;
|
|
31
32
|
const [value, setValue] = useState(asCalendarDate(defaultValue));
|
|
33
|
+
const { onAutosave } = useFormContext();
|
|
32
34
|
useEffect(() => {
|
|
33
35
|
setValue(asCalendarDate(defaultValue));
|
|
34
36
|
}, [defaultValue]);
|
|
@@ -36,8 +38,19 @@ const DatePickerSelect = (props) => {
|
|
|
36
38
|
setValue(date);
|
|
37
39
|
onChange && onChange(property.id, date, property);
|
|
38
40
|
};
|
|
41
|
+
const handleAccept = async () => {
|
|
42
|
+
// Trigger autosave when date is accepted (picker closes after selection)
|
|
43
|
+
if (onAutosave) {
|
|
44
|
+
try {
|
|
45
|
+
await onAutosave(id);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('Autosave failed:', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
39
52
|
return readOnly ? (React.createElement(InputFieldComponent, { ...{ ...props, defaultValue: asMonthDayYearFormat(value) } })) : (React.createElement(LocalizationProvider, null,
|
|
40
|
-
React.createElement(DatePicker, { value: value, onChange: handleChange, inputFormat: "MM/dd/yyyy", renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium',
|
|
53
|
+
React.createElement(DatePicker, { value: value, onChange: handleChange, onAccept: handleAccept, inputFormat: "MM/dd/yyyy", renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium',
|
|
41
54
|
// merges MUI inputProps with additionalProps.inputProps in a way that still shows the value
|
|
42
55
|
inputProps: {
|
|
43
56
|
...params.inputProps,
|
package/dist/published/components/custom/FormField/DateTimePickerSelect/DateTimePickerSelect.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LocalDate, LocalDateTime, LocalTime, nativeJs } from '@js-joda/core';
|
|
2
2
|
import { omit } from 'lodash';
|
|
3
3
|
import React, { useEffect, useState } from 'react';
|
|
4
|
+
import { useFormContext } from '../../../../theme/hooks';
|
|
4
5
|
import { InvalidDate } from '../../../../util';
|
|
5
6
|
import { DateTimePicker, LocalizationProvider, TextField } from '../../../core';
|
|
6
7
|
import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
|
|
@@ -30,6 +31,7 @@ const formatDateTime = (date) => {
|
|
|
30
31
|
const DateTimePickerSelect = (props) => {
|
|
31
32
|
const { id, property, defaultValue, error, errorMessage, readOnly, required, size, onBlur, additionalProps } = props;
|
|
32
33
|
const [value, setValue] = useState(asCalendarDate(defaultValue));
|
|
34
|
+
const { onAutosave } = useFormContext();
|
|
33
35
|
useEffect(() => {
|
|
34
36
|
setValue(asCalendarDate(defaultValue));
|
|
35
37
|
}, [defaultValue]);
|
|
@@ -43,8 +45,19 @@ const DateTimePickerSelect = (props) => {
|
|
|
43
45
|
setValue(date);
|
|
44
46
|
props.onChange && props.onChange(property.id, date, property);
|
|
45
47
|
};
|
|
48
|
+
const handleAccept = async () => {
|
|
49
|
+
// Trigger autosave when date/time is accepted (picker closes after selection)
|
|
50
|
+
if (onAutosave) {
|
|
51
|
+
try {
|
|
52
|
+
await onAutosave(id);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error('Autosave failed:', error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
46
59
|
return readOnly ? (React.createElement(InputFieldComponent, { ...{ ...props, defaultValue: formatDateTime(value) } })) : (React.createElement(LocalizationProvider, null,
|
|
47
|
-
React.createElement(DateTimePicker, { value: value, onChange: handleChange, renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium',
|
|
60
|
+
React.createElement(DateTimePicker, { value: value, onChange: handleChange, onAccept: handleAccept, renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium',
|
|
48
61
|
// merges MUI inputProps with additionalProps.inputProps in a way that still shows the value
|
|
49
62
|
inputProps: {
|
|
50
63
|
...params.inputProps,
|
|
@@ -3,11 +3,13 @@ import { TimePicker } from '@mui/x-date-pickers';
|
|
|
3
3
|
import { isUndefined, omit, padStart } from 'lodash';
|
|
4
4
|
import { DateTime } from 'luxon';
|
|
5
5
|
import React, { useEffect, useState } from 'react';
|
|
6
|
+
import { useFormContext } from '../../../../theme/hooks';
|
|
6
7
|
import { InvalidDate } from '../../../../util';
|
|
7
8
|
import { LocalizationProvider, TextField } from '../../../core';
|
|
8
9
|
import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
|
|
9
10
|
const TimePickerSelect = (props) => {
|
|
10
11
|
const { id, property, defaultValue, error, errorMessage, readOnly, required, size, onBlur, placeholder, additionalProps, } = props;
|
|
12
|
+
const { onAutosave } = useFormContext();
|
|
11
13
|
const values = defaultValue ? defaultValue.split(':') : undefined;
|
|
12
14
|
const hour = values ? parseInt(values[0]) : undefined;
|
|
13
15
|
const minute = values ? parseInt(values[1]) : undefined;
|
|
@@ -41,11 +43,22 @@ const TimePickerSelect = (props) => {
|
|
|
41
43
|
props.onChange && props.onChange(property.id, date, property);
|
|
42
44
|
}
|
|
43
45
|
};
|
|
46
|
+
const handleAccept = async () => {
|
|
47
|
+
// Trigger autosave when time is accepted (picker closes after selection)
|
|
48
|
+
if (onAutosave) {
|
|
49
|
+
try {
|
|
50
|
+
await onAutosave(id);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Autosave failed:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
44
57
|
return readOnly ? (React.createElement(InputFieldComponent, { ...{
|
|
45
58
|
...props,
|
|
46
59
|
defaultValue: value instanceof LocalDateTime ? DateTime.fromISO(value.toString()).toFormat('hh:mm a') : '',
|
|
47
60
|
} })) : (React.createElement(LocalizationProvider, null,
|
|
48
|
-
React.createElement(TimePicker, { value: value, onChange: handleChange, renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium', placeholder: placeholder,
|
|
61
|
+
React.createElement(TimePicker, { value: value, onChange: handleChange, onAccept: handleAccept, renderInput: (params) => (React.createElement(TextField, { ...params, id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size ?? 'medium', placeholder: placeholder,
|
|
49
62
|
// merges MUI inputProps with additionalProps.inputProps in a way that still shows the value
|
|
50
63
|
inputProps: {
|
|
51
64
|
...params.inputProps,
|
|
@@ -26,10 +26,10 @@ const Header = (props) => {
|
|
|
26
26
|
// when rendering the default delete action, we don't want a border
|
|
27
27
|
borderBottom: !form.id ? undefined : '1px solid #e9ecef',
|
|
28
28
|
gap: isSm || isXs ? 2 : 3,
|
|
29
|
-
...sx,
|
|
30
29
|
'.evoke-form-renderer-header': {
|
|
31
|
-
flex: 1,
|
|
30
|
+
flex: '1 1 100%',
|
|
32
31
|
},
|
|
32
|
+
...sx,
|
|
33
33
|
} },
|
|
34
34
|
title && (React.createElement(Box, { sx: { flex: '1 1 auto', minWidth: 0, display: 'flex', alignItems: 'center', gap: 1 } },
|
|
35
35
|
React.createElement(Title, { ...props }),
|
|
@@ -123,8 +123,7 @@ describe('FormRendererContainer', () => {
|
|
|
123
123
|
license: null,
|
|
124
124
|
});
|
|
125
125
|
}));
|
|
126
|
-
render(React.createElement(
|
|
127
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
126
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
128
127
|
await waitFor(() => {
|
|
129
128
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
130
129
|
});
|
|
@@ -174,8 +173,7 @@ describe('FormRendererContainer', () => {
|
|
|
174
173
|
license: null,
|
|
175
174
|
});
|
|
176
175
|
}));
|
|
177
|
-
render(React.createElement(
|
|
178
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
176
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
179
177
|
await waitFor(() => {
|
|
180
178
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
181
179
|
});
|
|
@@ -222,8 +220,7 @@ describe('FormRendererContainer', () => {
|
|
|
222
220
|
autosaveActionSpy();
|
|
223
221
|
return HttpResponse.json({ error: 'Save failed' }, { status: 500 });
|
|
224
222
|
}));
|
|
225
|
-
render(React.createElement(
|
|
226
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
223
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
227
224
|
await waitFor(() => {
|
|
228
225
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
229
226
|
});
|
|
@@ -267,8 +264,7 @@ describe('FormRendererContainer', () => {
|
|
|
267
264
|
license: null,
|
|
268
265
|
});
|
|
269
266
|
}));
|
|
270
|
-
render(React.createElement(
|
|
271
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
267
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
272
268
|
await waitFor(() => {
|
|
273
269
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
274
270
|
});
|
|
@@ -321,8 +317,7 @@ describe('FormRendererContainer', () => {
|
|
|
321
317
|
},
|
|
322
318
|
});
|
|
323
319
|
}));
|
|
324
|
-
render(React.createElement(
|
|
325
|
-
React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' })));
|
|
320
|
+
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
326
321
|
await waitFor(() => {
|
|
327
322
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
328
323
|
});
|
|
@@ -382,8 +377,7 @@ describe('FormRendererContainer', () => {
|
|
|
382
377
|
address: body.input.address,
|
|
383
378
|
});
|
|
384
379
|
}));
|
|
385
|
-
render(React.createElement(
|
|
386
|
-
React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' })));
|
|
380
|
+
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
387
381
|
await waitFor(() => {
|
|
388
382
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
389
383
|
});
|
|
@@ -444,8 +438,7 @@ describe('FormRendererContainer', () => {
|
|
|
444
438
|
address: body.input.address,
|
|
445
439
|
});
|
|
446
440
|
}));
|
|
447
|
-
render(React.createElement(
|
|
448
|
-
React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' })));
|
|
441
|
+
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
449
442
|
await waitFor(() => {
|
|
450
443
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
451
444
|
});
|
|
@@ -492,8 +485,7 @@ describe('FormRendererContainer', () => {
|
|
|
492
485
|
autosaveActionId: '_autosave',
|
|
493
486
|
});
|
|
494
487
|
}));
|
|
495
|
-
render(React.createElement(
|
|
496
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
488
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
497
489
|
await waitFor(() => {
|
|
498
490
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
499
491
|
});
|
|
@@ -526,8 +518,7 @@ describe('FormRendererContainer', () => {
|
|
|
526
518
|
});
|
|
527
519
|
}));
|
|
528
520
|
const user = userEvent.setup();
|
|
529
|
-
render(React.createElement(
|
|
530
|
-
React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' })));
|
|
521
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
531
522
|
await waitFor(() => {
|
|
532
523
|
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
533
524
|
});
|