@inseefr/lunatic 3.13.6-rc-fix-multimode.2 → 3.14.0-rc-delay-sequence-cleaning.0
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/components/Duration/getDurationFromValue.d.ts +2 -2
- package/components/Duration/getDurationFromValue.js +7 -6
- package/components/Duration/getDurationFromValue.js.map +1 -1
- package/components/Suggester/SuggesterType.d.ts +3 -1
- package/components/shared/Combobox/ComboboxType.d.ts +2 -0
- package/esm/components/Duration/getDurationFromValue.d.ts +2 -2
- package/esm/components/Duration/getDurationFromValue.js +7 -6
- package/esm/components/Duration/getDurationFromValue.js.map +1 -1
- package/esm/components/Suggester/SuggesterType.d.ts +3 -1
- package/esm/components/shared/Combobox/ComboboxType.d.ts +2 -0
- package/esm/use-lunatic/commons/compile-controls.d.ts +5 -0
- package/esm/use-lunatic/commons/compile-controls.js +6 -1
- package/esm/use-lunatic/commons/compile-controls.js.map +1 -1
- package/esm/use-lunatic/commons/compile-controls.spec.d.ts +1 -0
- package/esm/use-lunatic/commons/compile-controls.spec.js +121 -0
- package/esm/use-lunatic/commons/compile-controls.spec.js.map +1 -0
- package/esm/use-lunatic/reducer/reducerInitializer.js +1 -1
- package/esm/use-lunatic/reducer/reducerInitializer.js.map +1 -1
- package/esm/utils/search/SearchInterface.d.ts +9 -1
- package/esm/utils/search/melauto.d.ts +4 -1
- package/esm/utils/search/melauto.js +17 -17
- package/esm/utils/search/melauto.js.map +1 -1
- package/esm/utils/search/melauto.spec.js +9 -13
- package/esm/utils/search/melauto.spec.js.map +1 -1
- package/package.json +13 -1
- package/src/components/Duration/getDurationFromValue.ts +10 -6
- package/src/components/Suggester/SuggesterType.ts +3 -1
- package/src/components/shared/Combobox/ComboboxType.ts +2 -0
- package/src/stories/behaviour/cleaning/cleaning.stories.tsx +7 -0
- package/src/stories/behaviour/cleaning/source-sequence.json +444 -0
- package/src/stories/behaviour/search/search.stories.tsx +258 -0
- package/src/stories/questionnaires/SRCV/data.json +116 -0
- package/src/stories/questionnaires/SRCV/source.json +69256 -0
- package/src/stories/questionnaires/SRCV/srcv.stories.tsx +23 -0
- package/src/use-lunatic/commons/compile-controls.spec.ts +136 -0
- package/src/use-lunatic/commons/compile-controls.ts +7 -1
- package/src/use-lunatic/reducer/reducerInitializer.tsx +1 -1
- package/src/use-lunatic/use-lunatic.test.ts +6 -2
- package/src/utils/search/SearchInterface.ts +10 -1
- package/src/utils/search/melauto.spec.ts +10 -13
- package/src/utils/search/melauto.ts +20 -13
- package/tsconfig.build.tsbuildinfo +1 -1
- package/use-lunatic/commons/compile-controls.d.ts +5 -0
- package/use-lunatic/commons/compile-controls.js +6 -0
- package/use-lunatic/commons/compile-controls.js.map +1 -1
- package/use-lunatic/commons/compile-controls.spec.d.ts +1 -0
- package/use-lunatic/commons/compile-controls.spec.js +123 -0
- package/use-lunatic/commons/compile-controls.spec.js.map +1 -0
- package/use-lunatic/reducer/reducerInitializer.js +1 -1
- package/use-lunatic/reducer/reducerInitializer.js.map +1 -1
- package/utils/search/SearchInterface.d.ts +9 -1
- package/utils/search/melauto.d.ts +4 -1
- package/utils/search/melauto.js +11 -14
- package/utils/search/melauto.js.map +1 -1
- package/utils/search/melauto.spec.js +9 -13
- package/utils/search/melauto.spec.js.map +1 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import {
|
|
3
|
+
Orchestrator,
|
|
4
|
+
OrchestratorMeta,
|
|
5
|
+
type OrchestratorStory,
|
|
6
|
+
} from '../../utils/Orchestrator';
|
|
7
|
+
import D from '../../../i18n';
|
|
8
|
+
|
|
9
|
+
import { ComboboxOptionType } from '../../../components/shared/Combobox/ComboboxType';
|
|
10
|
+
|
|
11
|
+
import { Meta } from '@storybook/react';
|
|
12
|
+
import {
|
|
13
|
+
type ComponentProps,
|
|
14
|
+
type FormEventHandler,
|
|
15
|
+
useCallback,
|
|
16
|
+
useMemo,
|
|
17
|
+
useState,
|
|
18
|
+
} from 'react';
|
|
19
|
+
import { LunaticSource } from '../../../type.source';
|
|
20
|
+
import { useLocalStorage } from '../../../hooks/useLocalStorage';
|
|
21
|
+
|
|
22
|
+
type Props = {
|
|
23
|
+
option: ComboboxOptionType;
|
|
24
|
+
shouldDisplayOptionId?: boolean;
|
|
25
|
+
selected?: boolean;
|
|
26
|
+
};
|
|
27
|
+
const CustomComboboxOption = ({
|
|
28
|
+
option,
|
|
29
|
+
shouldDisplayOptionId = true,
|
|
30
|
+
selected,
|
|
31
|
+
}: Props) => {
|
|
32
|
+
const { id, value, label, score, melautoScore } = option;
|
|
33
|
+
|
|
34
|
+
const scoreValues = (
|
|
35
|
+
<span>{` [ Score: ${score} | MelautoScore: ${melautoScore} ] `}</span>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (value === 'OTHER') {
|
|
39
|
+
return (
|
|
40
|
+
<div className={classNames('lunatic-combo-box-option', { selected })}>
|
|
41
|
+
<span className="label">
|
|
42
|
+
{`${D.SUGGESTER_NO_RESULT} : ${D.SUGGESTER_ARBITRARY} "${label}"`}
|
|
43
|
+
</span>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
if (label) {
|
|
48
|
+
return (
|
|
49
|
+
<div className={classNames('lunatic-combo-box-option', { selected })}>
|
|
50
|
+
{shouldDisplayOptionId && (
|
|
51
|
+
<>
|
|
52
|
+
<span className="id">{id || value}</span>
|
|
53
|
+
<span> - </span>
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
<span className="label">{label}</span>
|
|
57
|
+
{scoreValues}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return (
|
|
62
|
+
<div className={classNames('lunatic-combo-box-option', { selected })}>
|
|
63
|
+
<span className="id">{id || value}</span>
|
|
64
|
+
{scoreValues}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const meta: Meta<typeof Orchestrator> = {
|
|
70
|
+
title: 'Behaviour/SearchScore',
|
|
71
|
+
...OrchestratorMeta,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default meta;
|
|
75
|
+
|
|
76
|
+
export const Default: OrchestratorStory = {
|
|
77
|
+
args: {
|
|
78
|
+
slots: {
|
|
79
|
+
ComboboxOption: CustomComboboxOption,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
render(args) {
|
|
83
|
+
return <PasteOrchestrator {...args} />;
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type Nomenclature = { name: string; uri: string };
|
|
88
|
+
|
|
89
|
+
type GetReferentiel = NonNullable<
|
|
90
|
+
ComponentProps<typeof Orchestrator>['getReferentiel']
|
|
91
|
+
>;
|
|
92
|
+
|
|
93
|
+
function PasteOrchestrator(
|
|
94
|
+
props: Readonly<ComponentProps<typeof Orchestrator>>
|
|
95
|
+
) {
|
|
96
|
+
const [source, setSource, sourceAsString] =
|
|
97
|
+
useLocalStorage<LunaticSource | null>('story-source-search');
|
|
98
|
+
const [nomenclatures, setNomenclatures] = useLocalStorage<
|
|
99
|
+
Nomenclature[] | null
|
|
100
|
+
>('story-nomenclatures-search');
|
|
101
|
+
|
|
102
|
+
const getReferentiel = useCallback<GetReferentiel>(
|
|
103
|
+
async (name: string) => {
|
|
104
|
+
const nomenclature = (nomenclatures ?? []).find((n) => n.name === name);
|
|
105
|
+
if (!nomenclature) {
|
|
106
|
+
throw new Error(`Nomenclature "${name}" introuvable`);
|
|
107
|
+
}
|
|
108
|
+
const response = await fetch(nomenclature.uri);
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Impossible de charger "${name}" (${response.status} ${response.statusText})`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
return response.json();
|
|
115
|
+
},
|
|
116
|
+
[nomenclatures]
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const extraTabs = useMemo(() => {
|
|
120
|
+
return [
|
|
121
|
+
{
|
|
122
|
+
label: 'Source & nomenclatures',
|
|
123
|
+
children: (
|
|
124
|
+
<FormForSourceAndNomenclatures
|
|
125
|
+
source={sourceAsString}
|
|
126
|
+
nomenclatures={nomenclatures ?? []}
|
|
127
|
+
onChange={(source: string, nomenclatures: Nomenclature[]) => {
|
|
128
|
+
setNomenclatures(JSON.stringify(nomenclatures));
|
|
129
|
+
setSource(source);
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
),
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
}, [sourceAsString, nomenclatures, setSource, setNomenclatures]);
|
|
136
|
+
|
|
137
|
+
if (!source) {
|
|
138
|
+
return <>{extraTabs[0].children}</>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const key = `${sourceAsString}-${JSON.stringify(nomenclatures)}`;
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<div key={key}>
|
|
145
|
+
<Orchestrator
|
|
146
|
+
{...props}
|
|
147
|
+
slots={{
|
|
148
|
+
ComboboxOption: CustomComboboxOption,
|
|
149
|
+
}}
|
|
150
|
+
source={source}
|
|
151
|
+
getReferentiel={getReferentiel}
|
|
152
|
+
extraTabs={extraTabs}
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function FormForSourceAndNomenclatures(
|
|
159
|
+
props: Readonly<{
|
|
160
|
+
source: string;
|
|
161
|
+
nomenclatures: Nomenclature[];
|
|
162
|
+
onChange: (source: string, nomenclatures: Nomenclature[]) => void;
|
|
163
|
+
}>
|
|
164
|
+
) {
|
|
165
|
+
const [items, setItems] = useState<Nomenclature[]>(props.nomenclatures);
|
|
166
|
+
|
|
167
|
+
const add = () => setItems((prev) => [...prev, { name: '', uri: '' }]);
|
|
168
|
+
|
|
169
|
+
const remove = (index: number) =>
|
|
170
|
+
setItems((prev) => prev.filter((_, i) => i !== index));
|
|
171
|
+
|
|
172
|
+
const update = (index: number, field: keyof Nomenclature, value: string) =>
|
|
173
|
+
setItems((prev) =>
|
|
174
|
+
prev.map((item, i) => (i === index ? { ...item, [field]: value } : item))
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const onSubmit: FormEventHandler<HTMLFormElement> = (e) => {
|
|
178
|
+
e.preventDefault();
|
|
179
|
+
const data = new FormData(e.currentTarget);
|
|
180
|
+
if (data.has('source')) {
|
|
181
|
+
props.onChange(
|
|
182
|
+
data.get('source') as string,
|
|
183
|
+
items.filter((item) => item.name.trim() && item.uri.trim())
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<form onSubmit={onSubmit}>
|
|
190
|
+
<fieldset className="fieldset">
|
|
191
|
+
<legend className="fieldset-legend">Paste the source.json</legend>
|
|
192
|
+
<textarea
|
|
193
|
+
required
|
|
194
|
+
name="source"
|
|
195
|
+
defaultValue={props.source}
|
|
196
|
+
className="textarea w-full h-24"
|
|
197
|
+
placeholder="source.json content"
|
|
198
|
+
/>
|
|
199
|
+
<div className="label">
|
|
200
|
+
The content of this textarea will be saved in your local storage to
|
|
201
|
+
persist between refreshes
|
|
202
|
+
</div>
|
|
203
|
+
</fieldset>
|
|
204
|
+
<fieldset className="fieldset">
|
|
205
|
+
<legend className="fieldset-legend">Nomenclatures</legend>
|
|
206
|
+
<div className="label">
|
|
207
|
+
Associate the nomenclature name (the one used in the source) with the
|
|
208
|
+
URL that returns a JSON array. The list is saved in local storage.
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<ul className="flex flex-col gap-2 mt-2">
|
|
212
|
+
{items.map((item, index) => (
|
|
213
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: liste éditable sans id stable
|
|
214
|
+
<li key={index} className="flex flex-row items-end gap-2">
|
|
215
|
+
<label className="flex flex-col flex-1">
|
|
216
|
+
<span className="label">Name</span>
|
|
217
|
+
<input
|
|
218
|
+
required
|
|
219
|
+
type="text"
|
|
220
|
+
className="input w-full"
|
|
221
|
+
placeholder="ex: L_COMMUNES"
|
|
222
|
+
value={item.name}
|
|
223
|
+
onChange={(e) => update(index, 'name', e.target.value)}
|
|
224
|
+
/>
|
|
225
|
+
</label>
|
|
226
|
+
<label className="flex flex-col flex-[2]">
|
|
227
|
+
<span className="label">URI</span>
|
|
228
|
+
<input
|
|
229
|
+
required
|
|
230
|
+
type="url"
|
|
231
|
+
className="input w-full"
|
|
232
|
+
placeholder="https://.../nomenclature.json"
|
|
233
|
+
value={item.uri}
|
|
234
|
+
onChange={(e) => update(index, 'uri', e.target.value)}
|
|
235
|
+
/>
|
|
236
|
+
</label>
|
|
237
|
+
<button
|
|
238
|
+
type="button"
|
|
239
|
+
className="btn btn-ghost"
|
|
240
|
+
title="Delete this nomenclature"
|
|
241
|
+
onClick={() => remove(index)}
|
|
242
|
+
>
|
|
243
|
+
✕
|
|
244
|
+
</button>
|
|
245
|
+
</li>
|
|
246
|
+
))}
|
|
247
|
+
</ul>
|
|
248
|
+
|
|
249
|
+
<button type="button" className="btn btn-secondary w-fit" onClick={add}>
|
|
250
|
+
Add a nomenclature
|
|
251
|
+
</button>
|
|
252
|
+
</fieldset>
|
|
253
|
+
<button className="btn btn-primary mt-2" type="submit">
|
|
254
|
+
Load
|
|
255
|
+
</button>
|
|
256
|
+
</form>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "5a90586e-a2a3-4853-aa3a-f8ebd0f6e86b",
|
|
3
|
+
"questionnaireId": "4552-CAPI",
|
|
4
|
+
"personalization": [],
|
|
5
|
+
"data": {
|
|
6
|
+
"EXTERNAL": {
|
|
7
|
+
"ADR": "1 RUE DU GRAND CHENE 79200 PARTHENAY",
|
|
8
|
+
"TROPIQUE": "1"
|
|
9
|
+
},
|
|
10
|
+
"COLLECTED": {
|
|
11
|
+
"RESIND": [],
|
|
12
|
+
"LIENS": {
|
|
13
|
+
"COLLECTED": [
|
|
14
|
+
[
|
|
15
|
+
null,
|
|
16
|
+
"17",
|
|
17
|
+
"17"
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
"17",
|
|
21
|
+
null,
|
|
22
|
+
"17"
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"17",
|
|
26
|
+
"17"
|
|
27
|
+
]
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"T_NHAB": {
|
|
31
|
+
"COLLECTED": 3
|
|
32
|
+
},
|
|
33
|
+
"T_SEXE": {
|
|
34
|
+
"COLLECTED": [
|
|
35
|
+
"1",
|
|
36
|
+
"1",
|
|
37
|
+
"1"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"T_STOC": {
|
|
41
|
+
"COLLECTED": "3"
|
|
42
|
+
},
|
|
43
|
+
"T_STOL": {
|
|
44
|
+
"COLLECTED": "2"
|
|
45
|
+
},
|
|
46
|
+
"T_LNAIS": {
|
|
47
|
+
"COLLECTED": [
|
|
48
|
+
"1",
|
|
49
|
+
"1",
|
|
50
|
+
"1"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"T_UNLOG": {
|
|
54
|
+
"COLLECTED": [
|
|
55
|
+
"2",
|
|
56
|
+
"2",
|
|
57
|
+
"2"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"DATE_ITW": {
|
|
61
|
+
"COLLECTED": "2027-03-01"
|
|
62
|
+
},
|
|
63
|
+
"T_PRENOM": {
|
|
64
|
+
"COLLECTED": [
|
|
65
|
+
"Lucas",
|
|
66
|
+
"Mathieu",
|
|
67
|
+
"Antoine"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"T_TYPLOG": {
|
|
71
|
+
"COLLECTED": "1"
|
|
72
|
+
},
|
|
73
|
+
"T_DEPNAIS": {
|
|
74
|
+
"COLLECTED": [
|
|
75
|
+
"Seine-Saint-Denis",
|
|
76
|
+
"Seine-et-Marne",
|
|
77
|
+
"Seine-Maritime"
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"T_NATION1": {
|
|
81
|
+
"COLLECTED": [
|
|
82
|
+
true,
|
|
83
|
+
true,
|
|
84
|
+
true
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"T_NPIECES": {
|
|
88
|
+
"COLLECTED": 5
|
|
89
|
+
},
|
|
90
|
+
"T_SURFACE": {
|
|
91
|
+
"COLLECTED": 98
|
|
92
|
+
},
|
|
93
|
+
"T_TYPMAIS": {
|
|
94
|
+
"COLLECTED": "2"
|
|
95
|
+
},
|
|
96
|
+
"T_DATENAIS": {
|
|
97
|
+
"COLLECTED": [
|
|
98
|
+
"1998-02-19",
|
|
99
|
+
"1997-06-03",
|
|
100
|
+
"1999-06-14"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"T_EMMENAGE": {
|
|
104
|
+
"COLLECTED": "2023"
|
|
105
|
+
},
|
|
106
|
+
"T_LOGPROPRI": {
|
|
107
|
+
"COLLECTED": "6"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"stateData": {
|
|
112
|
+
"state": "INIT",
|
|
113
|
+
"date": 1790865361892,
|
|
114
|
+
"currentPage": "1"
|
|
115
|
+
}
|
|
116
|
+
}
|