@rsuci/shared-form-components 1.0.128 → 1.0.130
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/components/form-renderer/FormRenderer.d.ts.map +1 -1
- package/dist/components/form-renderer/FormRenderer.js +14 -1
- package/dist/components/inputs/ExtraitInput.d.ts +2 -2
- package/dist/components/inputs/ExtraitInput.d.ts.map +1 -1
- package/dist/components/inputs/SearchableSelect.d.ts +3 -0
- package/dist/components/inputs/SearchableSelect.d.ts.map +1 -1
- package/dist/components/inputs/SearchableSelect.js +15 -5
- package/dist/components/selectors/EnqueteInput.d.ts +2 -2
- package/dist/components/selectors/EnqueteInput.d.ts.map +1 -1
- package/dist/components/selectors/EnqueteInput.js +42 -24
- package/dist/components/selectors/MenageInput.d.ts +2 -2
- package/dist/components/selectors/MenageInput.d.ts.map +1 -1
- package/dist/components/selectors/MenageInput.js +42 -24
- package/dist/lib/utils/groupeInstanceManager.d.ts.map +1 -1
- package/dist/lib/utils/groupeInstanceManager.js +42 -30
- package/dist/types/services.d.ts +7 -2
- package/dist/types/services.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAuBlF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iCAAiC;IACjC,SAAS,EAAE,qBAAqB,CAAC;IACjC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAuBlF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iCAAiC;IACjC,SAAS,EAAE,qBAAqB,CAAC;IACjC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAilCD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgBpD,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -253,6 +253,16 @@ const FormRendererInner = () => {
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
|
+
// Variables appartenant à un groupe multiple dans le formulaire CIBLE
|
|
257
|
+
// Permet de détecter le cas source-simple → cible-multiple
|
|
258
|
+
const multipleGroupVarCodes = new Set();
|
|
259
|
+
for (const groupe of (formulaire.groupes || [])) {
|
|
260
|
+
if (groupe.estMultiple) {
|
|
261
|
+
for (const v of (groupe.variables || [])) {
|
|
262
|
+
multipleGroupVarCodes.add(v.code);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
256
266
|
const allVariables = formulaire.variables ||
|
|
257
267
|
formulaire.groupes?.flatMap((g) => g.variables || []) || [];
|
|
258
268
|
for (const reponse of enqueteData.reponses) {
|
|
@@ -260,7 +270,10 @@ const FormRendererInner = () => {
|
|
|
260
270
|
continue;
|
|
261
271
|
const variable = allVariables.find((v) => v.code === reponse.variableCode);
|
|
262
272
|
if (variable) {
|
|
263
|
-
|
|
273
|
+
// Si la source n'a pas de numeroMembre mais la cible est dans un groupe multiple,
|
|
274
|
+
// appliquer uniquement au premier membre pour éviter la propagation sur tous les membres
|
|
275
|
+
const numeroMembre = reponse.numeroMembre ?? (multipleGroupVarCodes.has(variable.code) ? 1 : undefined);
|
|
276
|
+
updateResponse(variable.code, reponse.valeur, variable, numeroMembre);
|
|
264
277
|
}
|
|
265
278
|
}
|
|
266
279
|
}, [formulaire.variables, formulaire.groupes, updateResponse]);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Composant ExtraitInput - Saisie d'Extrait de Naissance
|
|
3
3
|
* RSU v2 - Moteur de Rendu des Formulaires d'Enquête
|
|
4
4
|
*
|
|
5
|
-
* Format composé : numéro (
|
|
6
|
-
* Exemple affiché : "
|
|
5
|
+
* Format composé : numéro (1 à 4 chiffres) + date d'établissement + année registre (4 chiffres)
|
|
6
|
+
* Exemple affiché : "1000 du 12/12/2020 du registre 2020"
|
|
7
7
|
* Stockage : JSON { numero, dateEtablissement, anneeRegistre }
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtraitInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/ExtraitInput.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC;IACvD,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAgED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ExtraitInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/ExtraitInput.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,kBAAkB,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC;IACvD,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAgED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8I7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -22,6 +22,9 @@ interface SearchableSelectProps {
|
|
|
22
22
|
className?: string;
|
|
23
23
|
noOptionsMessage?: string;
|
|
24
24
|
formatOptionLabel?: (option: SelectOption) => string;
|
|
25
|
+
onSearchChange?: (term: string) => void;
|
|
26
|
+
onScrollEnd?: () => void;
|
|
27
|
+
loadingMore?: boolean;
|
|
25
28
|
}
|
|
26
29
|
export declare const SearchableSelect: React.FC<SearchableSelectProps>;
|
|
27
30
|
export default SearchableSelect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/SearchableSelect.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/SearchableSelect.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IACrD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA2N5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Inspiré du design de production avec champ de filtre
|
|
5
5
|
*/
|
|
6
6
|
import { useState, useRef, useEffect } from 'react';
|
|
7
|
-
export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sélectionner...', searchPlaceholder = 'Rechercher...', disabled = false, required = false, loading = false, error, className = '', noOptionsMessage = 'Aucune option disponible', formatOptionLabel }) => {
|
|
7
|
+
export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sélectionner...', searchPlaceholder = 'Rechercher...', disabled = false, required = false, loading = false, error, className = '', noOptionsMessage = 'Aucune option disponible', formatOptionLabel, onSearchChange, onScrollEnd, loadingMore = false, }) => {
|
|
8
8
|
const [isOpen, setIsOpen] = useState(false);
|
|
9
9
|
const [searchTerm, setSearchTerm] = useState('');
|
|
10
10
|
const dropdownRef = useRef(null);
|
|
@@ -71,9 +71,19 @@ export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sél
|
|
|
71
71
|
};
|
|
72
72
|
return (_jsxs("div", { className: `relative w-full ${className}`, ref: dropdownRef, children: [_jsx("button", { type: "button", onClick: toggleDropdown, disabled: disabled || loading, className: `w-full px-3 py-2 text-left border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors ${error ? 'border-red-300 bg-red-50' : 'border-gray-300'} ${disabled || loading
|
|
73
73
|
? 'bg-gray-100 cursor-not-allowed text-gray-500'
|
|
74
|
-
: 'bg-white text-gray-900 hover:border-gray-400'} ${isOpen ? 'ring-2 ring-blue-500 border-transparent' : ''}`, children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: value ? 'text-gray-900' : 'text-gray-500', children: loading ? 'Chargement...' : getSelectedLabel() }), _jsx("svg", { className: `w-5 h-5 text-gray-400 transition-transform ${isOpen ? 'transform rotate-180' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && !disabled && !loading && (_jsxs("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg", children: [_jsx("div", { className: "p-2 border-b border-gray-200 bg-gray-50", children: _jsxs("div", { className: "relative", children: [_jsx("svg", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx("input", { ref: searchInputRef, type: "text", value: searchTerm, onChange: (e) =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
: 'bg-white text-gray-900 hover:border-gray-400'} ${isOpen ? 'ring-2 ring-blue-500 border-transparent' : ''}`, children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: value ? 'text-gray-900' : 'text-gray-500', children: loading ? 'Chargement...' : getSelectedLabel() }), _jsx("svg", { className: `w-5 h-5 text-gray-400 transition-transform ${isOpen ? 'transform rotate-180' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && !disabled && !loading && (_jsxs("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg", children: [_jsx("div", { className: "p-2 border-b border-gray-200 bg-gray-50", children: _jsxs("div", { className: "relative", children: [_jsx("svg", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx("input", { ref: searchInputRef, type: "text", value: searchTerm, onChange: (e) => {
|
|
75
|
+
setSearchTerm(e.target.value);
|
|
76
|
+
onSearchChange?.(e.target.value);
|
|
77
|
+
}, placeholder: searchPlaceholder, className: "w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" })] }) }), _jsxs("div", { className: "overflow-y-auto", style: { maxHeight: '240px' }, onScroll: (e) => {
|
|
78
|
+
if (!onScrollEnd)
|
|
79
|
+
return;
|
|
80
|
+
const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
|
|
81
|
+
if (scrollHeight - scrollTop - clientHeight < 30) {
|
|
82
|
+
onScrollEnd();
|
|
83
|
+
}
|
|
84
|
+
}, children: [filteredOptions.length === 0 ? (_jsx("div", { className: "px-4 py-3 text-sm text-gray-500 text-center", children: searchTerm ? `Aucun résultat pour "${searchTerm}"` : noOptionsMessage })) : (_jsx("ul", { className: "py-1", children: filteredOptions.map((option) => {
|
|
85
|
+
const isSelected = value?.id === option.id;
|
|
86
|
+
return (_jsx("li", { children: _jsx("button", { type: "button", onMouseDown: (e) => handleSelect(option, e), className: `w-full px-4 py-2 text-left text-sm hover:bg-blue-50 transition-colors ${isSelected ? 'bg-blue-100 text-blue-900 font-medium' : 'text-gray-900'}`, children: getOptionLabel(option) }) }, option.id));
|
|
87
|
+
}) })), loadingMore && (_jsx("div", { className: "px-4 py-2 text-sm text-gray-400 text-center", children: "Chargement..." }))] })] })), error && (_jsxs("p", { className: "mt-1 text-sm text-red-600 flex items-center", children: [_jsx("svg", { className: "w-4 h-4 mr-1", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", clipRule: "evenodd" }) }), error] })), required && !value && (_jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Ce champ est obligatoire" }))] }));
|
|
78
88
|
};
|
|
79
89
|
export default SearchableSelect;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { EnqueteCompletDto } from '../../types/services';
|
|
2
|
+
import { EnqueteCompletDto, FetchFilter } from '../../types/services';
|
|
3
3
|
export interface EnqueteInputProps {
|
|
4
4
|
variable: {
|
|
5
5
|
typeCode: string;
|
|
@@ -21,7 +21,7 @@ export interface EnqueteInputProps {
|
|
|
21
21
|
onFillFormFromEnquete?: (enqueteData: any) => void;
|
|
22
22
|
formulaireVariables?: any[];
|
|
23
23
|
services?: {
|
|
24
|
-
fetchEnquetes?: (filter?:
|
|
24
|
+
fetchEnquetes?: (filter?: FetchFilter) => Promise<EnqueteCompletDto[]>;
|
|
25
25
|
fetchEnqueteDonnees?: (enqueteId: number) => Promise<any>;
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnqueteInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/EnqueteInput.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"EnqueteInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/EnqueteInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvE,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KAC3D,CAAC;CACH;AAID,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsH7C,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,eAAe,YAAY,CAAC"}
|
|
@@ -1,36 +1,61 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import SearchableSelect from '../inputs/SearchableSelect';
|
|
5
|
+
const PAGE_SIZE = 50;
|
|
5
6
|
const EnqueteInput = ({ variable, value, onChange, error, disabled, onFillFormFromEnquete, services }) => {
|
|
6
7
|
const [enquetes, setEnquetes] = useState([]);
|
|
8
|
+
const [page, setPage] = useState(1);
|
|
9
|
+
const [hasMore, setHasMore] = useState(true);
|
|
7
10
|
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
|
8
12
|
const [loadingData, setLoadingData] = useState(false);
|
|
9
13
|
const [loadError, setLoadError] = useState(null);
|
|
10
|
-
|
|
14
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
15
|
+
// Chargement initial + reset sur changement de recherche (debounce 300ms)
|
|
11
16
|
useEffect(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
if (!services?.fetchEnquetes) {
|
|
18
|
+
setLoadError('Service de chargement des enquêtes non disponible');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const timer = setTimeout(async () => {
|
|
17
22
|
setLoading(true);
|
|
18
23
|
setLoadError(null);
|
|
24
|
+
setEnquetes([]);
|
|
25
|
+
setPage(1);
|
|
26
|
+
setHasMore(true);
|
|
19
27
|
try {
|
|
20
|
-
const data = await services.fetchEnquetes();
|
|
28
|
+
const data = await services.fetchEnquetes({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
|
|
21
29
|
setEnquetes(data);
|
|
30
|
+
setHasMore(data.length === PAGE_SIZE);
|
|
22
31
|
}
|
|
23
|
-
catch
|
|
24
|
-
console.error('Erreur lors du chargement des enquêtes:', err);
|
|
32
|
+
catch {
|
|
25
33
|
setLoadError('Erreur lors du chargement des enquêtes');
|
|
26
34
|
}
|
|
27
35
|
finally {
|
|
28
36
|
setLoading(false);
|
|
29
37
|
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
}, [services]);
|
|
33
|
-
|
|
38
|
+
}, searchTerm ? 300 : 0);
|
|
39
|
+
return () => clearTimeout(timer);
|
|
40
|
+
}, [searchTerm, services]);
|
|
41
|
+
const handleScrollEnd = useCallback(async () => {
|
|
42
|
+
if (!hasMore || loadingMore || loading || !services?.fetchEnquetes)
|
|
43
|
+
return;
|
|
44
|
+
setLoadingMore(true);
|
|
45
|
+
const nextPage = page + 1;
|
|
46
|
+
try {
|
|
47
|
+
const data = await services.fetchEnquetes({ searchText: searchTerm || undefined, page: nextPage, pageSize: PAGE_SIZE });
|
|
48
|
+
setEnquetes(prev => [...prev, ...data]);
|
|
49
|
+
setPage(nextPage);
|
|
50
|
+
setHasMore(data.length === PAGE_SIZE);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Silencieux — les données existantes restent affichées
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
setLoadingMore(false);
|
|
57
|
+
}
|
|
58
|
+
}, [hasMore, loadingMore, loading, page, searchTerm, services]);
|
|
34
59
|
const options = enquetes.map(enquete => {
|
|
35
60
|
const code = enquete.numeroEnquete || enquete.id.toString();
|
|
36
61
|
const name = [enquete.chefMenageNom, enquete.chefMenagePrenoms].filter(Boolean).join(' ');
|
|
@@ -41,33 +66,26 @@ const EnqueteInput = ({ variable, value, onChange, error, disabled, onFillFormFr
|
|
|
41
66
|
designation: name ? `${code} - ${name}${surnom}` : code,
|
|
42
67
|
};
|
|
43
68
|
});
|
|
44
|
-
// Trouver l'enquête sélectionnée
|
|
45
69
|
const enqueteId = value ? parseInt(value) : null;
|
|
46
70
|
const selectedOption = enqueteId ? options.find(opt => opt.id === enqueteId) : null;
|
|
47
|
-
// Gérer le changement de sélection
|
|
48
71
|
const handleChange = async (option) => {
|
|
49
72
|
const newEnqueteId = option?.id;
|
|
50
73
|
onChange(newEnqueteId?.toString() || null);
|
|
51
|
-
// Charger les données complètes de l'enquête sélectionnée et remplir le formulaire
|
|
52
74
|
if (newEnqueteId && services?.fetchEnqueteDonnees && onFillFormFromEnquete) {
|
|
53
75
|
try {
|
|
54
76
|
setLoadingData(true);
|
|
55
77
|
const enqueteData = await services.fetchEnqueteDonnees(newEnqueteId);
|
|
56
78
|
onFillFormFromEnquete(enqueteData);
|
|
57
79
|
}
|
|
58
|
-
catch
|
|
59
|
-
|
|
80
|
+
catch {
|
|
81
|
+
// Silencieux
|
|
60
82
|
}
|
|
61
83
|
finally {
|
|
62
84
|
setLoadingData(false);
|
|
63
85
|
}
|
|
64
86
|
}
|
|
65
87
|
};
|
|
66
|
-
|
|
67
|
-
const formatOptionLabel = (option) => {
|
|
68
|
-
return option.designation;
|
|
69
|
-
};
|
|
70
|
-
return (_jsxs("div", { children: [_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une enqu\u00EAte...", searchPlaceholder: "Rechercher une enqu\u00EAte...", disabled: disabled || loadingData, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: formatOptionLabel, noOptionsMessage: loading ? "Chargement..." : "Aucune enquête trouvée" }), loadingData && (_jsx("p", { className: "text-sm text-blue-600 mt-1", children: "Chargement des donn\u00E9es de l'enqu\u00EAte..." }))] }));
|
|
88
|
+
return (_jsxs("div", { children: [_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une enqu\u00EAte...", searchPlaceholder: "Rechercher une enqu\u00EAte...", disabled: disabled || loadingData, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune enquête trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }), loadingData && (_jsx("p", { className: "text-sm text-blue-600 mt-1", children: "Chargement des donn\u00E9es de l'enqu\u00EAte..." }))] }));
|
|
71
89
|
};
|
|
72
90
|
export { EnqueteInput };
|
|
73
91
|
export default EnqueteInput;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { MenageCompletDto } from '../../types/services';
|
|
2
|
+
import { MenageCompletDto, FetchFilter } from '../../types/services';
|
|
3
3
|
export interface MenageInputProps {
|
|
4
4
|
variable: {
|
|
5
5
|
typeCode: string;
|
|
@@ -21,7 +21,7 @@ export interface MenageInputProps {
|
|
|
21
21
|
onFillFormFromMenage?: (menageData: MenageCompletDto) => void;
|
|
22
22
|
formulaireVariables?: any[];
|
|
23
23
|
services?: {
|
|
24
|
-
fetchMenages?: () => Promise<MenageCompletDto[]>;
|
|
24
|
+
fetchMenages?: (filter?: FetchFilter) => Promise<MenageCompletDto[]>;
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
declare const MenageInput: React.FC<MenageInputProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenageInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/MenageInput.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"MenageInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/MenageInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9D,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;KACtE,CAAC;CACH;AAID,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuG3C,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,eAAe,WAAW,CAAC"}
|
|
@@ -1,35 +1,60 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import SearchableSelect from '../inputs/SearchableSelect';
|
|
5
|
+
const PAGE_SIZE = 50;
|
|
5
6
|
const MenageInput = ({ variable, value, onChange, error, disabled, onFillFormFromMenage, services }) => {
|
|
6
7
|
const [menages, setMenages] = useState([]);
|
|
8
|
+
const [page, setPage] = useState(1);
|
|
9
|
+
const [hasMore, setHasMore] = useState(true);
|
|
7
10
|
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
|
8
12
|
const [loadError, setLoadError] = useState(null);
|
|
9
|
-
|
|
13
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
14
|
+
// Chargement initial + reset sur changement de recherche (debounce 300ms)
|
|
10
15
|
useEffect(() => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
if (!services?.fetchMenages) {
|
|
17
|
+
setLoadError('Service de chargement des ménages non disponible');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const timer = setTimeout(async () => {
|
|
16
21
|
setLoading(true);
|
|
17
22
|
setLoadError(null);
|
|
23
|
+
setMenages([]);
|
|
24
|
+
setPage(1);
|
|
25
|
+
setHasMore(true);
|
|
18
26
|
try {
|
|
19
|
-
const data = await services.fetchMenages();
|
|
27
|
+
const data = await services.fetchMenages({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
|
|
20
28
|
setMenages(data);
|
|
29
|
+
setHasMore(data.length === PAGE_SIZE);
|
|
21
30
|
}
|
|
22
|
-
catch
|
|
23
|
-
console.error('Erreur lors du chargement des ménages:', err);
|
|
31
|
+
catch {
|
|
24
32
|
setLoadError('Erreur lors du chargement des ménages');
|
|
25
33
|
}
|
|
26
34
|
finally {
|
|
27
35
|
setLoading(false);
|
|
28
36
|
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
}, [services]);
|
|
32
|
-
|
|
37
|
+
}, searchTerm ? 300 : 0);
|
|
38
|
+
return () => clearTimeout(timer);
|
|
39
|
+
}, [searchTerm, services]);
|
|
40
|
+
const handleScrollEnd = useCallback(async () => {
|
|
41
|
+
if (!hasMore || loadingMore || loading || !services?.fetchMenages)
|
|
42
|
+
return;
|
|
43
|
+
setLoadingMore(true);
|
|
44
|
+
const nextPage = page + 1;
|
|
45
|
+
try {
|
|
46
|
+
const data = await services.fetchMenages({ searchText: searchTerm || undefined, page: nextPage, pageSize: PAGE_SIZE });
|
|
47
|
+
setMenages(prev => [...prev, ...data]);
|
|
48
|
+
setPage(nextPage);
|
|
49
|
+
setHasMore(data.length === PAGE_SIZE);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Silencieux — les données existantes restent affichées
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
setLoadingMore(false);
|
|
56
|
+
}
|
|
57
|
+
}, [hasMore, loadingMore, loading, page, searchTerm, services]);
|
|
33
58
|
const options = menages.map(menage => {
|
|
34
59
|
const code = menage.numeroMenage || menage.id.toString();
|
|
35
60
|
const name = [menage.nomChefMenage, menage.prenomChefMenage].filter(Boolean).join(' ');
|
|
@@ -40,22 +65,15 @@ const MenageInput = ({ variable, value, onChange, error, disabled, onFillFormFro
|
|
|
40
65
|
designation: name ? `${code} - ${name}${surnom}` : code,
|
|
41
66
|
};
|
|
42
67
|
});
|
|
43
|
-
// Trouver le ménage sélectionné
|
|
44
68
|
const menageId = value ? parseInt(value) : null;
|
|
45
69
|
const selectedOption = menageId ? options.find(opt => opt.id === menageId) : null;
|
|
46
|
-
// Gérer le changement de sélection
|
|
47
70
|
const handleChange = (option) => {
|
|
48
71
|
const newMenageId = option?.id;
|
|
49
72
|
onChange(newMenageId?.toString() || null);
|
|
50
|
-
// NOTE: onFillFormFromMenage n'est
|
|
51
|
-
// pour éviter les re-renders
|
|
52
|
-
// Il doit être appelé manuellement si nécessaire (bouton séparé).
|
|
53
|
-
};
|
|
54
|
-
// Format d'affichage: Designation uniquement
|
|
55
|
-
const formatOptionLabel = (option) => {
|
|
56
|
-
return option.designation;
|
|
73
|
+
// NOTE: onFillFormFromMenage n'est pas appelé automatiquement ici
|
|
74
|
+
// pour éviter les re-renders lors de la création d'une nouvelle enquête.
|
|
57
75
|
};
|
|
58
|
-
return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner un m\u00E9nage...", searchPlaceholder: "Rechercher un m\u00E9nage...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel:
|
|
76
|
+
return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner un m\u00E9nage...", searchPlaceholder: "Rechercher un m\u00E9nage...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucun ménage trouvé', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }));
|
|
59
77
|
};
|
|
60
78
|
export { MenageInput };
|
|
61
79
|
export default MenageInput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupeInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/groupeInstanceManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,cAAc,EAEd,0BAA0B,EAE3B,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,qBAAqB;IAEhC;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACxC,MAAM;IAsCT;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IASxD;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CACtB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACxC,MAAM;IAuBT;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,MAAM,EAAE,gBAAgB,EACxB,cAAc,EAAE,MAAM,GACrB,cAAc;IAWjB;;OAEG;IACH,MAAM,CAAC,mBAAmB,CACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACxC,cAAc,EAAE;
|
|
1
|
+
{"version":3,"file":"groupeInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/groupeInstanceManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -107,20 +107,19 @@ export class GroupeInstanceManager {
|
|
|
107
107
|
// Note: le parsing de clé par format "CODE_NUMERO" a été supprimé car il
|
|
108
108
|
// produisait des faux positifs pour les codes variables contenant des chiffres (ex: S1_01)
|
|
109
109
|
const maxInstances = this.getMaxInstances(groupe, responses);
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
110
|
+
// Borne supérieure : au moins maxInstances (variable de contrôle), au moins le
|
|
111
|
+
// numéro le plus élevé trouvé dans les réponses (protège contre la perte de données
|
|
112
|
+
// si des réponses existent au-delà de la variable de contrôle, ex: membre 2 vide
|
|
113
|
+
// dans un groupe lié où le numéro max existant est 3).
|
|
114
|
+
const highestExistingMembre = instanceNumbers.size > 0
|
|
115
|
+
? Math.max(...Array.from(instanceNumbers))
|
|
116
|
+
: 0;
|
|
117
|
+
const upperBound = Math.max(maxInstances, highestExistingMembre, 1);
|
|
119
118
|
const instances = [];
|
|
120
119
|
// Séparer les réponses avec et sans numeroMembre
|
|
121
120
|
const responsesWithMember = groupResponses.filter(r => r.numeroMembre);
|
|
122
121
|
const responsesWithoutMember = groupResponses.filter(r => !r.numeroMembre);
|
|
123
|
-
for (let i = 1; i <=
|
|
122
|
+
for (let i = 1; i <= upperBound; i++) {
|
|
124
123
|
const instance = this.createInstance(groupe, i);
|
|
125
124
|
// Remplir les réponses existantes pour cette instance
|
|
126
125
|
groupe.variables.forEach(variable => {
|
|
@@ -287,7 +286,10 @@ export class GroupeInstanceManager {
|
|
|
287
286
|
};
|
|
288
287
|
}
|
|
289
288
|
const currentInstances = groupe.instances || [];
|
|
290
|
-
const
|
|
289
|
+
const maxExisting = currentInstances.length > 0
|
|
290
|
+
? Math.max(...currentInstances.map(i => i.numeroInstance))
|
|
291
|
+
: 0;
|
|
292
|
+
const newInstanceNumber = maxExisting + 1;
|
|
291
293
|
const newInstance = this.createInstance(groupe, newInstanceNumber);
|
|
292
294
|
// Construire un nouveau groupe avec l'instance ajoutée (sans muter l'original)
|
|
293
295
|
const updatedInstances = [...currentInstances, newInstance];
|
|
@@ -621,32 +623,42 @@ export class GroupeInstanceManager {
|
|
|
621
623
|
groupsByControlVar.set(g.codeVariable, existing);
|
|
622
624
|
}
|
|
623
625
|
}
|
|
624
|
-
// Pour chaque ensemble de groupes liés, synchroniser
|
|
626
|
+
// Pour chaque ensemble de groupes liés, synchroniser les instances manquantes
|
|
625
627
|
const updatedGroupes = [...allGroupes];
|
|
626
628
|
for (const [, linkedGroups] of groupsByControlVar) {
|
|
627
629
|
if (linkedGroups.length <= 1)
|
|
628
630
|
continue;
|
|
629
|
-
//
|
|
630
|
-
const
|
|
631
|
-
|
|
631
|
+
// Union de tous les numéros d'instances réels à travers les groupes liés
|
|
632
|
+
const allInstanceNumbers = new Set();
|
|
633
|
+
for (const g of linkedGroups) {
|
|
634
|
+
for (const inst of g.instances || []) {
|
|
635
|
+
allInstanceNumbers.add(inst.numeroInstance);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (allInstanceNumbers.size === 0)
|
|
632
639
|
continue;
|
|
633
|
-
//
|
|
640
|
+
// Pour chaque groupe, créer uniquement les instances dont le numéro est absent
|
|
641
|
+
// (comparaison par ensemble, pas par longueur — évite les doublons)
|
|
634
642
|
for (const g of linkedGroups) {
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
instancesCount: instances.length
|
|
648
|
-
};
|
|
643
|
+
const existingNumbers = new Set((g.instances || []).map(i => i.numeroInstance));
|
|
644
|
+
const missingNumbers = [...allInstanceNumbers]
|
|
645
|
+
.filter(n => !existingNumbers.has(n))
|
|
646
|
+
.sort((a, b) => a - b);
|
|
647
|
+
if (missingNumbers.length === 0)
|
|
648
|
+
continue;
|
|
649
|
+
const idx = updatedGroupes.findIndex(ug => ug.code === g.code);
|
|
650
|
+
if (idx === -1)
|
|
651
|
+
continue;
|
|
652
|
+
const instances = [...(updatedGroupes[idx].instances || [])];
|
|
653
|
+
for (const num of missingNumbers) {
|
|
654
|
+
instances.push(this.createInstance(g, num));
|
|
649
655
|
}
|
|
656
|
+
instances.sort((a, b) => a.numeroInstance - b.numeroInstance);
|
|
657
|
+
updatedGroupes[idx] = {
|
|
658
|
+
...updatedGroupes[idx],
|
|
659
|
+
instances,
|
|
660
|
+
instancesCount: instances.length
|
|
661
|
+
};
|
|
650
662
|
}
|
|
651
663
|
}
|
|
652
664
|
return updatedGroupes;
|
package/dist/types/services.d.ts
CHANGED
|
@@ -24,9 +24,14 @@ export interface CurrentUserDto {
|
|
|
24
24
|
email?: string;
|
|
25
25
|
telephone?: string;
|
|
26
26
|
}
|
|
27
|
+
export interface FetchFilter {
|
|
28
|
+
searchText?: string;
|
|
29
|
+
page?: number;
|
|
30
|
+
pageSize?: number;
|
|
31
|
+
}
|
|
27
32
|
export interface FormRendererServices {
|
|
28
|
-
fetchMenages?: () => Promise<MenageCompletDto[]>;
|
|
29
|
-
fetchEnquetes?: (filter?:
|
|
33
|
+
fetchMenages?: (filter?: FetchFilter) => Promise<MenageCompletDto[]>;
|
|
34
|
+
fetchEnquetes?: (filter?: FetchFilter) => Promise<EnqueteCompletDto[]>;
|
|
30
35
|
fetchEnqueteDonnees?: (enqueteId: number) => Promise<any>;
|
|
31
36
|
fetchStructures?: () => Promise<StructureDto[]>;
|
|
32
37
|
fetchGeographicData?: (level: string, parentId?: number) => Promise<GeographicItem[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/types/services.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,oBAAoB;IAEnC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/types/services.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED