@arquimedes.co/eureka-forms 3.0.70 → 3.0.71
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/FormSteps/AYFStepMapper.js +2 -24
- package/dist/FormSteps/SmartSelectStep/MaterialSmartSelectStep/MaterialSmartSelectStep.js +11 -1
- package/dist/FormSteps/SmartSelectStep/SmartSelectStep.staleOptions.test.d.ts +1 -0
- package/dist/FormSteps/SmartSelectStep/SmartSelectStep.staleOptions.test.js +100 -0
- package/dist/FormSteps/ciudadesICAQuery.d.ts +8 -0
- package/dist/FormSteps/ciudadesICAQuery.js +31 -0
- package/dist/FormSteps/ciudadesICAQuery.test.d.ts +1 -0
- package/dist/FormSteps/ciudadesICAQuery.test.js +39 -0
- package/dist/Shared/ErkSmartSelect/ErkSmartSelect.js +4 -14
- package/dist/Shared/ErkSmartSelect/ErkSmartSelect.test.js +21 -1
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ import axios from 'axios';
|
|
|
7
7
|
import CalendarIcon from '../Icons/CalendarIcon';
|
|
8
8
|
import LocationIcon from '../Icons/LocationIcon';
|
|
9
9
|
import FileIcon from '../Icons/FileIcon';
|
|
10
|
+
import { ciudadesICAQuery } from './ciudadesICAQuery';
|
|
10
11
|
const baseUrl = `https://api.integrations.${import.meta.env.VITE_REACT_APP_DOMAIN}/sinco/ayf/`;
|
|
11
12
|
function AYFStepMapper(props) {
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
@@ -29,30 +30,7 @@ function AYFStepMapper(props) {
|
|
|
29
30
|
const getCiudadesOptions = async (step, dependencyStore, { idOrganization }) => {
|
|
30
31
|
if (!idOrganization)
|
|
31
32
|
return null;
|
|
32
|
-
const
|
|
33
|
-
const params = new URLSearchParams({
|
|
34
|
-
idOrganization,
|
|
35
|
-
idCompany: nit,
|
|
36
|
-
nit: 'true',
|
|
37
|
-
});
|
|
38
|
-
for (const dep of step.dependencies ?? []) {
|
|
39
|
-
const value = dependencyStore[dep]?.value;
|
|
40
|
-
if (value && dep.startsWith('AYF')) {
|
|
41
|
-
switch (dep.split('-')?.[0]) {
|
|
42
|
-
case AYFFormStepTypes.AYF_START_MONTH:
|
|
43
|
-
params.set('startMonth', value.id);
|
|
44
|
-
break;
|
|
45
|
-
case AYFFormStepTypes.AYF_END_MONTH:
|
|
46
|
-
params.set('endMonth', value.id);
|
|
47
|
-
break;
|
|
48
|
-
case AYFFormStepTypes.AYF_YEAR:
|
|
49
|
-
params.set('year', value);
|
|
50
|
-
break;
|
|
51
|
-
default:
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
33
|
+
const params = ciudadesICAQuery(step, dependencyStore, idOrganization);
|
|
56
34
|
try {
|
|
57
35
|
return (await axios.get(baseUrl + 'CiudadesICA?' + params.toString())).data;
|
|
58
36
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
import ErkSmartSelect from '../../../Shared/ErkSmartSelect/ErkSmartSelect';
|
|
4
|
-
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import FormContext from '../../../Contexts/FormContext';
|
|
7
7
|
import { useAppDispatch, useAppSelector } from '../../../hooks';
|
|
@@ -28,6 +28,11 @@ function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValu
|
|
|
28
28
|
const [loading, setLoading] = useState(false);
|
|
29
29
|
const [firstTime, setFirstTime] = useState(true);
|
|
30
30
|
const [touched, setTouched] = useState(false);
|
|
31
|
+
/**
|
|
32
|
+
* Every dependency change (each keystroke of a NIT, say) starts a new request without cancelling the
|
|
33
|
+
* ones in flight, and they can resolve in any order. Only the latest request may touch the options.
|
|
34
|
+
*/
|
|
35
|
+
const lastRequest = useRef(0);
|
|
31
36
|
const dispatch = useAppDispatch();
|
|
32
37
|
const allDeps = useMemo(() => [...(step.dependencies ?? []), ...getOptionalDependencies(step)], [getOptionalDependencies, step]);
|
|
33
38
|
const idDependencies = useMemo(() => getOptionsConditionsIdSteps(step), [getOptionsConditionsIdSteps, step]);
|
|
@@ -52,6 +57,7 @@ function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValu
|
|
|
52
57
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
58
|
}, [allDepsValues]);
|
|
54
59
|
const calcOptions = async (firstTime) => {
|
|
60
|
+
const request = ++lastRequest.current;
|
|
55
61
|
if (!firstTime)
|
|
56
62
|
setOptions(undefined);
|
|
57
63
|
if (value && !firstTime)
|
|
@@ -61,6 +67,8 @@ function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValu
|
|
|
61
67
|
idOrganization,
|
|
62
68
|
idCurrentAgent: postview ? undefined : idCurrentAgent,
|
|
63
69
|
});
|
|
70
|
+
if (request !== lastRequest.current)
|
|
71
|
+
return;
|
|
64
72
|
if (value) {
|
|
65
73
|
/** If the value is still valid select it */
|
|
66
74
|
if (resp && getValueString(value) !== undefined) {
|
|
@@ -82,6 +90,8 @@ function SmartSelectStep({ step, editable, getOptions, calcDepError, defaultValu
|
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
catch (error) {
|
|
93
|
+
if (request !== lastRequest.current)
|
|
94
|
+
return;
|
|
85
95
|
console.error(error);
|
|
86
96
|
setOptions(null);
|
|
87
97
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { act, render } from '@testing-library/react';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import '@testing-library/jest-dom';
|
|
5
|
+
import { Provider } from 'react-redux';
|
|
6
|
+
import { FormProvider, useForm } from 'react-hook-form';
|
|
7
|
+
import { configureStore } from '@reduxjs/toolkit';
|
|
8
|
+
import { EurekaFormsReducer, defaultRootState } from '../../Utils/store';
|
|
9
|
+
import { RootApi } from '../../Utils/_api';
|
|
10
|
+
import FormStepTypes from '../../constants/FormStepTypes';
|
|
11
|
+
import { StoreContext } from '../../Utils/StoreContext';
|
|
12
|
+
import FormContext, { IdFormContext } from '../../Contexts/FormContext';
|
|
13
|
+
import SectionContext from '../../Contexts/SectionContext';
|
|
14
|
+
import MaterialProviders from '../../Utils/MaterialProviders';
|
|
15
|
+
import InternalFormStyle from '../../constants/InternalFormStyle';
|
|
16
|
+
import { setStepDependency } from '../../States/SiteSlice';
|
|
17
|
+
import SmartSelectStep from './SmartSelectStep';
|
|
18
|
+
const ID_FORM = 'STALE_OPTIONS_FORM';
|
|
19
|
+
const nitStep = {
|
|
20
|
+
id: 'nit-step',
|
|
21
|
+
idSection: 'SECTION_1',
|
|
22
|
+
stepPath: ['nit-step'],
|
|
23
|
+
type: FormStepTypes.TEXTINPUT,
|
|
24
|
+
label: 'NIT',
|
|
25
|
+
description: '',
|
|
26
|
+
required: true,
|
|
27
|
+
size: 1,
|
|
28
|
+
maxLength: 20,
|
|
29
|
+
};
|
|
30
|
+
/** A city-like selector whose options come from the NIT the user is still typing. */
|
|
31
|
+
const cityStep = {
|
|
32
|
+
id: 'city-step',
|
|
33
|
+
idSection: 'SECTION_1',
|
|
34
|
+
stepPath: ['city-step'],
|
|
35
|
+
type: 'AYF_ICA_CITY',
|
|
36
|
+
label: 'Ciudad',
|
|
37
|
+
description: '',
|
|
38
|
+
showIcon: false,
|
|
39
|
+
required: false,
|
|
40
|
+
searchable: false,
|
|
41
|
+
size: 1,
|
|
42
|
+
dependencies: ['nit-step'],
|
|
43
|
+
};
|
|
44
|
+
const form = {
|
|
45
|
+
firstSection: 'SECTION_1',
|
|
46
|
+
sections: {
|
|
47
|
+
SECTION_1: { id: 'SECTION_1', name: 'Sección 1', steps: ['nit-step', 'city-step'], nextSection: null },
|
|
48
|
+
},
|
|
49
|
+
steps: { 'nit-step': nitStep, 'city-step': cityStep },
|
|
50
|
+
confirmationMessage: { blocks: [], entityMap: {} },
|
|
51
|
+
showLink: false,
|
|
52
|
+
size: { blockSize: 200, blockNum: 4, spacingSize: 10 },
|
|
53
|
+
};
|
|
54
|
+
const dependencies = {
|
|
55
|
+
'nit-step': { idOriginal: 'nit-step', dependents: [cityStep], value: '', type: FormStepTypes.TEXTINPUT },
|
|
56
|
+
};
|
|
57
|
+
function makeStore() {
|
|
58
|
+
return configureStore({
|
|
59
|
+
reducer: { forms: EurekaFormsReducer, [RootApi.reducerPath]: RootApi.reducer },
|
|
60
|
+
preloadedState: {
|
|
61
|
+
forms: { [ID_FORM]: { ...defaultRootState, site: { ...defaultRootState.site, dependencies } } },
|
|
62
|
+
},
|
|
63
|
+
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(RootApi.middleware),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function Harness({ store, requests }) {
|
|
67
|
+
const methods = useForm({ mode: 'onTouched' });
|
|
68
|
+
return (_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(Provider, { store: store, context: StoreContext, children: _jsx(IdFormContext.Provider, { value: ID_FORM, children: _jsx(FormContext.Provider, { value: form, children: _jsx(SectionContext.Provider, { value: "SECTION_1", children: _jsx(FormProvider, { ...methods, children: _jsx(SmartSelectStep, { step: cityStep, editable: true, getOptions: (_step, deps) => new Promise((resolve) => {
|
|
69
|
+
requests.push({ nit: deps['nit-step']?.value, resolve });
|
|
70
|
+
}), getOptionSelected: (option, value) => option === value, getValueString: (value) => value }) }) }) }) }) }) }));
|
|
71
|
+
}
|
|
72
|
+
const optionTexts = () => Array.from(document.querySelectorAll('[role=option]')).map((option) => option.textContent ?? '');
|
|
73
|
+
describe('SmartSelectStep when a dependency changes faster than its options load', () => {
|
|
74
|
+
it('keeps the options of the latest dependency value when an older request resolves last', async () => {
|
|
75
|
+
const store = makeStore();
|
|
76
|
+
const requests = [];
|
|
77
|
+
render(_jsx(Harness, { store: store, requests: requests }));
|
|
78
|
+
const typeNit = (value) => {
|
|
79
|
+
act(() => {
|
|
80
|
+
store.dispatch({ ...setStepDependency({ step: nitStep, value }), meta: { idForm: ID_FORM } });
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
typeNit('9');
|
|
84
|
+
typeNit('901379420');
|
|
85
|
+
const byNit = (nit) => requests.find((request) => request.nit === nit);
|
|
86
|
+
expect(byNit('9')).toBeDefined();
|
|
87
|
+
expect(byNit('901379420')).toBeDefined();
|
|
88
|
+
// The full NIT answers first with cities; the partial NIT straggles in afterwards with nothing.
|
|
89
|
+
const settle = (pending, options) => act(async () => {
|
|
90
|
+
pending.resolve(options);
|
|
91
|
+
await Promise.resolve();
|
|
92
|
+
});
|
|
93
|
+
await settle(byNit('901379420'), ['BELLO', 'MEDELLIN']);
|
|
94
|
+
await settle(byNit('9'), []);
|
|
95
|
+
act(() => {
|
|
96
|
+
document.querySelector('[role=combobox]').dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
|
|
97
|
+
});
|
|
98
|
+
expect(optionTexts()).toEqual(expect.arrayContaining(['BELLO', 'MEDELLIN']));
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { GSmartSelect } from '../@Types/GenericFormSteps';
|
|
2
|
+
import { DependencyStore } from '../Form/Form';
|
|
3
|
+
/**
|
|
4
|
+
* Query for `CiudadesICA`. The NIT dependency is `null` until the user types it; it must be left out of the
|
|
5
|
+
* query rather than serialised as the text "null", which the integrations API would take as a real NIT (and
|
|
6
|
+
* SINCO answers that with no cities instead of the organisation's main city).
|
|
7
|
+
*/
|
|
8
|
+
export declare function ciudadesICAQuery(step: GSmartSelect, dependencyStore: DependencyStore, idOrganization: string): URLSearchParams;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import AYFFormStepTypes from '../constants/AYFFormStepTypes';
|
|
2
|
+
/**
|
|
3
|
+
* Query for `CiudadesICA`. The NIT dependency is `null` until the user types it; it must be left out of the
|
|
4
|
+
* query rather than serialised as the text "null", which the integrations API would take as a real NIT (and
|
|
5
|
+
* SINCO answers that with no cities instead of the organisation's main city).
|
|
6
|
+
*/
|
|
7
|
+
export function ciudadesICAQuery(step, dependencyStore, idOrganization) {
|
|
8
|
+
const params = new URLSearchParams({ idOrganization, nit: 'true' });
|
|
9
|
+
const nit = dependencyStore[step.idNitStep]?.value;
|
|
10
|
+
if (nit)
|
|
11
|
+
params.set('idCompany', nit);
|
|
12
|
+
for (const dep of step.dependencies ?? []) {
|
|
13
|
+
const value = dependencyStore[dep]?.value;
|
|
14
|
+
if (value && dep.startsWith('AYF')) {
|
|
15
|
+
switch (dep.split('-')?.[0]) {
|
|
16
|
+
case AYFFormStepTypes.AYF_START_MONTH:
|
|
17
|
+
params.set('startMonth', value.id);
|
|
18
|
+
break;
|
|
19
|
+
case AYFFormStepTypes.AYF_END_MONTH:
|
|
20
|
+
params.set('endMonth', value.id);
|
|
21
|
+
break;
|
|
22
|
+
case AYFFormStepTypes.AYF_YEAR:
|
|
23
|
+
params.set('year', value);
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return params;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import AYFFormStepTypes from '../constants/AYFFormStepTypes';
|
|
3
|
+
import FormStepTypes from '../constants/FormStepTypes';
|
|
4
|
+
import { ciudadesICAQuery } from './ciudadesICAQuery';
|
|
5
|
+
const cityStep = {
|
|
6
|
+
id: 'AYF_ICA_CITY-1',
|
|
7
|
+
idSection: 'SECTION_1',
|
|
8
|
+
stepPath: ['AYF_ICA_CITY-1'],
|
|
9
|
+
type: AYFFormStepTypes.AYF_ICA_CITY,
|
|
10
|
+
label: 'Ciudad',
|
|
11
|
+
description: '',
|
|
12
|
+
showIcon: false,
|
|
13
|
+
required: false,
|
|
14
|
+
size: 1,
|
|
15
|
+
idNitStep: 'TEXTINPUT-nit',
|
|
16
|
+
dependencies: ['TEXTINPUT-nit', 'AYF_YEAR-1'],
|
|
17
|
+
};
|
|
18
|
+
const storeWithNit = (value) => ({
|
|
19
|
+
'TEXTINPUT-nit': { idOriginal: 'TEXTINPUT-nit', dependents: [], value, type: FormStepTypes.TEXTINPUT },
|
|
20
|
+
'AYF_YEAR-1': { idOriginal: 'AYF_YEAR-1', dependents: [], value: '2026', type: AYFFormStepTypes.AYF_YEAR },
|
|
21
|
+
});
|
|
22
|
+
describe('ciudadesICAQuery', () => {
|
|
23
|
+
it('sends the NIT as idCompany once the user has typed it', () => {
|
|
24
|
+
const params = ciudadesICAQuery(cityStep, storeWithNit('901379420'), 'casa');
|
|
25
|
+
expect(params.get('idCompany')).toBe('901379420');
|
|
26
|
+
expect(params.get('nit')).toBe('true');
|
|
27
|
+
expect(params.get('year')).toBe('2026');
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* The NIT dependency is `null` until the user types something. Serialising that as the text "null"
|
|
31
|
+
* makes the integrations API query SINCO for a provider literally called "null", which answers with no
|
|
32
|
+
* cities instead of the organisation's main city.
|
|
33
|
+
*/
|
|
34
|
+
it.each([null, undefined, ''])('omits idCompany while the NIT is %s', (nit) => {
|
|
35
|
+
const params = ciudadesICAQuery(cityStep, storeWithNit(nit), 'casa');
|
|
36
|
+
expect(params.has('idCompany')).toBe(false);
|
|
37
|
+
expect(params.get('idOrganization')).toBe('casa');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -5,6 +5,8 @@ import { StyledTextField } from '../ErkTextField/ErkTextField';
|
|
|
5
5
|
import ErkMenuItem from '../ErkMenuItem';
|
|
6
6
|
import ErkAutocompleteOption from '../ErkAutocompleteOption';
|
|
7
7
|
const filter = createFilterOptions();
|
|
8
|
+
/** Options are either `{ label }` objects or plain strings that are their own label (e.g. the ICA cities). */
|
|
9
|
+
const calcOptionLabel = (option) => (typeof option === 'string' ? option : (option?.label ?? ''));
|
|
8
10
|
const StyledAutoComplete = styled(MuiAutocomplete)(({ theme, readOnly, ...props }) => ({
|
|
9
11
|
'& .Erk-MuiInputBase-root': {
|
|
10
12
|
cursor: props.disabled || readOnly ? 'default' : 'text',
|
|
@@ -35,21 +37,9 @@ export default function ErkSmartSelect({ options, value = '', onChange, label, g
|
|
|
35
37
|
else {
|
|
36
38
|
return filter(options, params);
|
|
37
39
|
}
|
|
38
|
-
}, renderOption: ({ key, ...props }, option, state) => (_jsx(ErkAutocompleteOption, { ...props, selected: state.selected, children: option
|
|
39
|
-
// Value selected with enter, right from the input
|
|
40
|
-
if (typeof option === 'string') {
|
|
41
|
-
return option;
|
|
42
|
-
}
|
|
43
|
-
else if (option?.inputValue) {
|
|
44
|
-
return option.inputValue ?? '';
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
// Regular option
|
|
48
|
-
return option?.label ?? '';
|
|
49
|
-
}
|
|
50
|
-
}, slotProps: { popper: { sx: { zIndex: 1305 } } }, renderInput: (params) => (_jsx(StyledTextField, { ...params, size: size, label: label, labelMargin: 0, name: others.name, readOnly: readOnly, disabled: disabled, inputRef: inputRef, error: others.error, onBlur: others.onBlur, required: others.required, helperText: others.helperText })) }));
|
|
40
|
+
}, renderOption: ({ key, ...props }, option, state) => (_jsx(ErkAutocompleteOption, { ...props, selected: state.selected, children: calcOptionLabel(option) }, key)), getOptionKey: (option) => getValueString(option), getOptionLabel: (option) => option?.inputValue ?? calcOptionLabel(option), slotProps: { popper: { sx: { zIndex: 1305 } } }, renderInput: (params) => (_jsx(StyledTextField, { ...params, size: size, label: label, labelMargin: 0, name: others.name, readOnly: readOnly, disabled: disabled, inputRef: inputRef, error: others.error, onBlur: others.onBlur, required: others.required, helperText: others.helperText })) }));
|
|
51
41
|
}
|
|
52
42
|
else {
|
|
53
|
-
return (_jsxs(ErkSelect, { ...others, labelMargin: 0, disabled: disabled, readOnly: readOnly, inputRef: inputRef, onChange: (value) => onChange?.(options?.find((option) => getValueString(option) === value)), value: loading ? '' : getValueString(value), label: label, IconComponent: loading ? () => _jsx(CircularProgress, { size: 22 }) : IconComponent, children: [options?.map((option) => (_jsx(ErkMenuItem, { value: getValueString(option), "data-testid": 'smart-select-' + getValueString(option), children: option
|
|
43
|
+
return (_jsxs(ErkSelect, { ...others, labelMargin: 0, disabled: disabled, readOnly: readOnly, inputRef: inputRef, onChange: (value) => onChange?.(options?.find((option) => getValueString(option) === value)), value: loading ? '' : getValueString(value), label: label, IconComponent: loading ? () => _jsx(CircularProgress, { size: 22 }) : IconComponent, children: [options?.map((option) => (_jsx(ErkMenuItem, { value: getValueString(option), "data-testid": 'smart-select-' + getValueString(option), children: calcOptionLabel(option) }, getValueString(option)))), options === undefined && value && !loading && (_jsx(ErkMenuItem, { value: getValueString(value), children: calcOptionLabel(value) }, getValueString(value)))] }));
|
|
54
44
|
}
|
|
55
45
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
import { describe, expect, it, vi } from 'vitest';
|
|
5
5
|
import '@testing-library/jest-dom';
|
|
@@ -31,3 +31,23 @@ describe('ErkSmartSelect (searchable)', () => {
|
|
|
31
31
|
expect(await screen.findByRole('option', { name: 'Uno' })).toHaveAttribute('aria-selected', 'true');
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
/** Steps such as the ICA city selector feed plain strings; the string is both the value and the label. */
|
|
35
|
+
const cities = ['BELLO', 'MEDELLIN'];
|
|
36
|
+
const cityString = (value) => value;
|
|
37
|
+
describe('ErkSmartSelect with plain-string options', () => {
|
|
38
|
+
it('searchable: shows each string as the option text', async () => {
|
|
39
|
+
const user = userEvent.setup();
|
|
40
|
+
render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkSmartSelect, { searchable: true, label: "Ciudad", options: cities, value: "", onChange: () => { }, getValueString: cityString }) }));
|
|
41
|
+
await user.click(screen.getByRole('combobox'));
|
|
42
|
+
expect(await screen.findByRole('option', { name: 'BELLO' })).toBeInTheDocument();
|
|
43
|
+
expect(screen.getByRole('option', { name: 'MEDELLIN' })).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
it('non-searchable: shows each string as the option text', () => {
|
|
46
|
+
render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkSmartSelect, { searchable: false, label: "Ciudad", options: cities, value: "", onChange: () => { }, getValueString: cityString }) }));
|
|
47
|
+
// The inline (disablePortal) menu marks the rest of the tree aria-hidden while open, so the
|
|
48
|
+
// options are read from the raw DOM instead of through role queries.
|
|
49
|
+
fireEvent.mouseDown(document.querySelector('[role=combobox]'));
|
|
50
|
+
expect(document.querySelector('[role=option][data-value=BELLO]')).toHaveTextContent('BELLO');
|
|
51
|
+
expect(document.querySelector('[role=option][data-value=MEDELLIN]')).toHaveTextContent('MEDELLIN');
|
|
52
|
+
});
|
|
53
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arquimedes.co/eureka-forms",
|
|
3
3
|
"repository": "git://github.com/Arquimede5/Eureka-Forms.git",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.71",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"watch": "node node_modules/@typescript/native/bin/tsc --noEmit --watch --project tsconfig.app.json",
|
|
7
7
|
"start": "vite",
|