@rsuci/shared-form-components 1.0.131 → 1.0.133

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.
@@ -1,13 +1,5 @@
1
- /**
2
- * Composant unifié pour la sélection géographique en cascade
3
- * S'adapte automatiquement selon le type de variable (DISTRICT, REGION, DEPARTEMENT, etc.)
4
- * Gère la cascade via le champ variable.valeur (ex: "${G_01}")
5
- * Utilise SearchableSelect pour une meilleure UX avec recherche intégrée
6
- */
7
1
  import React from 'react';
8
- /**
9
- * Format de données retourné par les APIs backend
10
- */
2
+ import { GeographicItem, FetchFilter } from '../../types/services';
11
3
  interface SelectDto {
12
4
  id: number;
13
5
  code: string;
@@ -22,6 +14,9 @@ interface GeographicCascadeInputProps {
22
14
  required?: boolean;
23
15
  className?: string;
24
16
  isConsultationMode?: boolean;
17
+ services?: {
18
+ fetchGeographicData?: (entityType: string, parentId?: number, filter?: FetchFilter) => Promise<GeographicItem[]>;
19
+ };
25
20
  }
26
21
  export declare const GeographicCascadeInput: React.FC<GeographicCascadeInputProps>;
27
22
  export default GeographicCascadeInput;
@@ -1 +1 @@
1
- {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAWjF;;GAEG;AACH,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAwPxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnE,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE;QACT,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;KAClH,CAAC;CACH;AAID,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CA2OxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -1,128 +1,106 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Composant unifié pour la sélection géographique en cascade
4
- * S'adapte automatiquement selon le type de variable (DISTRICT, REGION, DEPARTEMENT, etc.)
5
- * Gère la cascade via le champ variable.valeur (ex: "${G_01}")
6
- * Utilise SearchableSelect pour une meilleure UX avec recherche intégrée
7
- */
8
2
  import { useEffect, useState, useCallback, useRef, useMemo } from 'react';
9
3
  import SearchableSelect from './SearchableSelect';
10
- import { extractVariableCode, resolveParentValue, getApiEndpoint, getParentLabel, requiresParent } from '../../utils/variableDependencyResolver';
4
+ import { extractVariableCode, resolveParentValue, getParentLabel, requiresParent } from '../../utils/variableDependencyResolver';
11
5
  import { isComponentReadonly } from '../../utils/componentStateUtils';
12
- export const GeographicCascadeInput = ({ variable, value, onChange, reponses, disabled = false, required = false, className = '', isConsultationMode = false }) => {
6
+ const PAGE_SIZE = 50;
7
+ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, disabled = false, required = false, className = '', isConsultationMode = false, services }) => {
13
8
  const [items, setItems] = useState([]);
14
9
  const [loading, setLoading] = useState(false);
10
+ const [loadingMore, setLoadingMore] = useState(false);
15
11
  const [error, setError] = useState(null);
16
- // 1. Déterminer si ce type nécessite un parent
12
+ const [page, setPage] = useState(1);
13
+ const [hasMore, setHasMore] = useState(true);
14
+ const [searchTerm, setSearchTerm] = useState('');
17
15
  const needsParent = requiresParent(variable.typeCode);
18
- // 1b. Vérifier si un parent est CONFIGURÉ dans la variable (valeur non vide)
19
16
  const hasParentConfigured = !!extractVariableCode(variable);
20
- // Le champ a besoin d'un parent SEULEMENT si le type le requiert ET qu'un parent est configuré
21
17
  const effectiveNeedsParent = needsParent && hasParentConfigured;
22
- // 2. Résoudre la valeur du parent depuis les réponses
23
18
  const parentValue = resolveParentValue(variable, reponses);
24
- // Debug temporaire - À SUPPRIMER après validation
25
- console.log('[GeographicCascade] Debug:', {
26
- variableCode: variable.code,
27
- variableType: variable.typeCode,
28
- valueProp: value,
29
- valueType: typeof value,
30
- variableValeurDefaut: variable.valeurDefaut,
31
- needsParent,
32
- parentCode: extractVariableCode(variable),
33
- parentValue,
34
- reponsesKeys: Object.keys(reponses || {})
35
- });
36
- // 3. Pour DISTRICT, déterminer le code pays (depuis variable.valeur ou défaut 'CIV')
37
- const countryCode = variable.typeCode === 'DISTRICT'
38
- ? (variable.valeur || 'CIV')
39
- : undefined;
40
- // 4. Déterminer l'endpoint API à appeler
41
- const apiEndpoint = getApiEndpoint(variable.typeCode, parentValue, countryCode, hasParentConfigured);
42
- // 4. Fonction pour charger les données
43
- const fetchData = useCallback(async () => {
44
- // Si un parent est requis (configuré) mais absent, ne rien charger
45
- if (effectiveNeedsParent && !parentValue) {
46
- setItems([]);
47
- setLoading(false);
48
- setError(null);
19
+ const entityType = variable.typeCode;
20
+ useEffect(() => {
21
+ if (!services?.fetchGeographicData) {
22
+ setError('Service de chargement géographique non disponible');
49
23
  return;
50
24
  }
51
- // Si pas d'endpoint valide, ne rien charger
52
- if (!apiEndpoint) {
25
+ if (effectiveNeedsParent && !parentValue) {
53
26
  setItems([]);
54
27
  setLoading(false);
55
28
  setError(null);
29
+ setPage(1);
30
+ setHasMore(true);
56
31
  return;
57
32
  }
58
- try {
33
+ const timer = setTimeout(async () => {
59
34
  setLoading(true);
60
35
  setError(null);
61
- const response = await fetch(apiEndpoint);
62
- if (!response.ok) {
63
- throw new Error(`HTTP error! status: ${response.status}`);
64
- }
65
- const result = await response.json();
66
- // Vérifier le format de la réponse
67
- // Support pour plusieurs formats possibles
68
- if (Array.isArray(result)) {
69
- // Format 1: tableau direct [...]
70
- setItems(result);
71
- }
72
- else if (result.status === 'SUCCESS' && Array.isArray(result.data)) {
73
- // Format 2: { status: "SUCCESS", data: [...] } (format RSU API)
74
- setItems(result.data);
75
- }
76
- else if (result.success && Array.isArray(result.data)) {
77
- // Format 3: { success: true, data: [...] }
78
- setItems(result.data);
36
+ setItems([]);
37
+ setPage(1);
38
+ setHasMore(true);
39
+ try {
40
+ const data = await services.fetchGeographicData(entityType, parentValue || undefined, { searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
41
+ const mapped = data.map(item => ({
42
+ id: item.id,
43
+ code: item.code,
44
+ designation: item.designation,
45
+ }));
46
+ setItems(mapped);
47
+ setHasMore(mapped.length === PAGE_SIZE);
79
48
  }
80
- else if (result.data && Array.isArray(result.data)) {
81
- // Format 4: { data: [...] }
82
- setItems(result.data);
49
+ catch {
50
+ setError(`Erreur de chargement des ${variable.designation?.toLowerCase() || 'données'}`);
51
+ setItems([]);
83
52
  }
84
- else {
85
- console.error('Format de réponse non reconnu:', result);
86
- throw new Error('Format de réponse invalide');
53
+ finally {
54
+ setLoading(false);
87
55
  }
56
+ }, searchTerm ? 300 : 0);
57
+ return () => clearTimeout(timer);
58
+ }, [entityType, effectiveNeedsParent, parentValue, searchTerm, services]);
59
+ const handleScrollEnd = useCallback(async () => {
60
+ if (!hasMore || loadingMore || loading || !services?.fetchGeographicData)
61
+ return;
62
+ const nextPage = page + 1;
63
+ setLoadingMore(true);
64
+ try {
65
+ const data = await services.fetchGeographicData(entityType, parentValue || undefined, { searchText: searchTerm || undefined, page: nextPage, pageSize: PAGE_SIZE });
66
+ const mapped = data.map(item => ({
67
+ id: item.id,
68
+ code: item.code,
69
+ designation: item.designation,
70
+ }));
71
+ setItems(prev => [...prev, ...mapped]);
72
+ setPage(nextPage);
73
+ setHasMore(mapped.length === PAGE_SIZE);
88
74
  }
89
- catch (err) {
90
- console.error(`Error fetching ${variable.typeCode}:`, err);
91
- setError(`Erreur de chargement des ${variable.designation?.toLowerCase() || 'données'}`);
92
- setItems([]);
75
+ catch {
76
+ // Les données existantes restent affichées
93
77
  }
94
78
  finally {
95
- setLoading(false);
79
+ setLoadingMore(false);
96
80
  }
97
- }, [apiEndpoint, effectiveNeedsParent, parentValue, variable.type, variable.libelle]);
98
- // 5. Charger les données quand l'endpoint ou le parent change
99
- useEffect(() => {
100
- fetchData();
101
- }, [fetchData]);
102
- // 6. Réinitialiser la valeur si le parent change
81
+ }, [hasMore, loadingMore, loading, page, searchTerm, entityType, parentValue, services]);
82
+ const handleSearchChange = useCallback((term) => {
83
+ setSearchTerm(term);
84
+ }, []);
85
+ // Réinitialiser la valeur si le parent change
103
86
  const previousParentRef = useRef(undefined);
104
87
  useEffect(() => {
105
- // Si un parent est requis (configuré) et que la valeur du parent a changé
106
88
  if (effectiveNeedsParent) {
107
- // Premier rendu : initialiser la référence sans réinitialiser
108
89
  if (previousParentRef.current === undefined) {
109
90
  previousParentRef.current = parentValue;
110
91
  return;
111
92
  }
112
- // Si le parent a changé et qu'on a une valeur sélectionnée, la réinitialiser
113
93
  if (parentValue !== previousParentRef.current && value) {
114
94
  onChange(null);
115
95
  }
116
96
  previousParentRef.current = parentValue;
117
97
  }
118
98
  }, [parentValue, effectiveNeedsParent, value, onChange]);
119
- // 7. Gérer le changement de valeur
120
99
  const handleChange = (option) => {
121
100
  if (!option) {
122
101
  onChange(null);
123
102
  return;
124
103
  }
125
- // Convertir SelectOption vers SelectDto
126
104
  const selectDto = {
127
105
  id: typeof option.id === 'string' ? parseInt(option.id, 10) : option.id,
128
106
  code: option.code || '',
@@ -130,10 +108,8 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
130
108
  };
131
109
  onChange(selectDto);
132
110
  };
133
- // 8. Déterminer si le champ est désactivé (select ne supporte pas readonly, on utilise disabled)
134
111
  const isReadonly = isComponentReadonly(variable, isConsultationMode);
135
112
  const isDisabled = disabled || isReadonly || loading || (effectiveNeedsParent && !parentValue);
136
- // 9. Déterminer le message du placeholder
137
113
  const getPlaceholder = () => {
138
114
  if (loading)
139
115
  return 'Chargement...';
@@ -145,21 +121,12 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
145
121
  }
146
122
  return `Sélectionner ${variable.designation || 'un élément'}...`;
147
123
  };
148
- // 10. Convertir les items en SelectOption pour SearchableSelect
149
- const options = items.map(item => ({
150
- id: item.id,
151
- code: item.code,
152
- designation: item.designation
153
- }));
154
- // 11. Parser la valeur si c'est une chaîne JSON (cas édition d'enquête existante)
155
124
  const parsedValue = useMemo(() => {
156
125
  if (!value)
157
126
  return null;
158
- // Si c'est déjà un objet avec les propriétés attendues
159
127
  if (typeof value === 'object' && value !== null && 'id' in value) {
160
128
  return value;
161
129
  }
162
- // Si c'est une chaîne JSON, la parser
163
130
  if (typeof value === 'string') {
164
131
  try {
165
132
  const parsed = JSON.parse(value);
@@ -168,23 +135,29 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
168
135
  }
169
136
  }
170
137
  catch {
171
- // Ignorer les erreurs de parsing (valeur non-JSON)
138
+ // Ignorer les erreurs de parsing
172
139
  }
173
140
  }
174
141
  return null;
175
142
  }, [value]);
176
- // 12. Convertir la valeur parsée en SelectOption
143
+ const options = useMemo(() => {
144
+ const mapped = items.map(item => ({
145
+ id: item.id,
146
+ code: item.code,
147
+ designation: item.designation,
148
+ }));
149
+ if (parsedValue && !items.some(item => item.id === parsedValue.id)) {
150
+ return [{ id: parsedValue.id, code: parsedValue.code, designation: parsedValue.designation }, ...mapped];
151
+ }
152
+ return mapped;
153
+ }, [items, parsedValue]);
177
154
  const currentValue = parsedValue ? {
178
155
  id: parsedValue.id,
179
156
  code: parsedValue.code,
180
157
  designation: parsedValue.designation
181
158
  } : null;
182
- // 13. Rendu du composant
183
159
  return (_jsxs("div", { className: "w-full", children: [_jsx(SearchableSelect, { options: options, value: currentValue, onChange: handleChange, placeholder: getPlaceholder(), searchPlaceholder: "Rechercher...", disabled: isDisabled, required: required, loading: loading, error: error || undefined, className: className, noOptionsMessage: effectiveNeedsParent && !parentValue
184
160
  ? `Veuillez d'abord sélectionner ${getParentLabel(variable.typeCode)}`
185
- : `Aucun(e) ${variable.designation?.toLowerCase() || 'élément'} disponible`, formatOptionLabel: (option) => {
186
- // Afficher uniquement la désignation
187
- return option.designation;
188
- } }), effectiveNeedsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 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 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
161
+ : `Aucun(e) ${variable.designation?.toLowerCase() || 'élément'} disponible`, formatOptionLabel: (option) => option.designation, onSearchChange: handleSearchChange, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }), effectiveNeedsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 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 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
189
162
  };
190
163
  export default GeographicCascadeInput;
@@ -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;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"}
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,CA8N5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -31,13 +31,16 @@ export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sél
31
31
  searchInputRef.current.focus();
32
32
  }
33
33
  }, [isOpen]);
34
- // Filtrer les options selon le terme de recherche
35
- const filteredOptions = options.filter(option => {
36
- const label = formatOptionLabel ? formatOptionLabel(option) : option.designation;
37
- const searchLower = searchTerm.toLowerCase();
38
- return (label.toLowerCase().includes(searchLower) ||
39
- (option.code && option.code.toLowerCase().includes(searchLower)));
40
- });
34
+ // Si onSearchChange est fourni, la recherche est côté serveur : pas de filtrage local
35
+ const isServerSearch = !!onSearchChange;
36
+ const filteredOptions = isServerSearch
37
+ ? options
38
+ : options.filter(option => {
39
+ const label = formatOptionLabel ? formatOptionLabel(option) : option.designation;
40
+ const searchLower = searchTerm.toLowerCase();
41
+ return (label.toLowerCase().includes(searchLower) ||
42
+ (option.code && option.code.toLowerCase().includes(searchLower)));
43
+ });
41
44
  // Gérer la sélection d'une option
42
45
  const handleSelect = (option, event) => {
43
46
  event.preventDefault();
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { StructureDto } from '../../types/services';
2
+ import { StructureDto, FetchFilter } from '../../types/services';
3
3
  export interface RSUInputProps {
4
4
  variable: {
5
5
  typeCode: string;
@@ -19,7 +19,7 @@ export interface RSUInputProps {
19
19
  numeroMembre?: number;
20
20
  valeurMin?: number;
21
21
  services?: {
22
- fetchStructures?: () => Promise<StructureDto[]>;
22
+ fetchStructures?: (filter?: FetchFilter) => Promise<StructureDto[]>;
23
23
  };
24
24
  }
25
25
  declare const RSUInput: React.FC<RSUInputProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"RSUInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/RSUInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,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,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KACjD,CAAC;CACH;AAED,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0ErC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"RSUInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/RSUInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,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,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KACrE,CAAC;CACH;AAID,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA6FrC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
@@ -1,53 +1,71 @@
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 RSUInput = ({ variable, value, onChange, error, disabled, services }) => {
6
7
  const [structures, setStructures] = 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
- // Charger les structures au montage du composant
13
+ const [searchTerm, setSearchTerm] = useState('');
10
14
  useEffect(() => {
11
- const loadStructures = async () => {
12
- if (!services?.fetchStructures) {
13
- setLoadError('Service de chargement des structures non disponible');
14
- return;
15
- }
15
+ if (!services?.fetchStructures) {
16
+ setLoadError('Service de chargement des structures non disponible');
17
+ return;
18
+ }
19
+ const timer = setTimeout(async () => {
16
20
  setLoading(true);
17
21
  setLoadError(null);
22
+ setStructures([]);
23
+ setPage(1);
24
+ setHasMore(true);
18
25
  try {
19
- const data = await services.fetchStructures();
26
+ const data = await services.fetchStructures({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
20
27
  setStructures(data);
28
+ setHasMore(data.length === PAGE_SIZE);
21
29
  }
22
- catch (err) {
23
- console.error('Erreur lors du chargement des structures:', err);
30
+ catch {
24
31
  setLoadError('Erreur lors du chargement des structures');
25
32
  }
26
33
  finally {
27
34
  setLoading(false);
28
35
  }
29
- };
30
- loadStructures();
31
- }, [services]);
32
- // Convertir les structures en options pour SearchableSelect
36
+ }, searchTerm ? 300 : 0);
37
+ return () => clearTimeout(timer);
38
+ }, [searchTerm, services]);
39
+ const handleScrollEnd = useCallback(async () => {
40
+ if (!hasMore || loadingMore || loading || !services?.fetchStructures)
41
+ return;
42
+ setLoadingMore(true);
43
+ const nextPage = page + 1;
44
+ try {
45
+ const data = await services.fetchStructures({ searchText: searchTerm || undefined, page: nextPage, pageSize: PAGE_SIZE });
46
+ setStructures(prev => [...prev, ...data]);
47
+ setPage(nextPage);
48
+ setHasMore(data.length === PAGE_SIZE);
49
+ }
50
+ catch {
51
+ // Les données existantes restent affichées
52
+ }
53
+ finally {
54
+ setLoadingMore(false);
55
+ }
56
+ }, [hasMore, loadingMore, loading, page, searchTerm, services]);
33
57
  const options = structures.map(structure => ({
34
58
  id: structure.id,
35
59
  code: structure.code || structure.id.toString(),
36
- designation: structure.designation || `Structure ${structure.id}`
60
+ designation: structure.designation || `Structure ${structure.id}`,
37
61
  }));
38
- // Trouver la structure sélectionnée
39
62
  const structureId = value ? parseInt(value) : null;
40
63
  const selectedOption = structureId ? options.find(opt => opt.id === structureId) : null;
41
- // Gérer le changement de sélection
42
64
  const handleChange = (option) => {
43
65
  const newStructureId = option?.id;
44
66
  onChange(newStructureId?.toString() || null);
45
67
  };
46
- // Format d'affichage: Designation uniquement
47
- const formatOptionLabel = (option) => {
48
- return option.designation;
49
- };
50
- return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une structure RSU...", searchPlaceholder: "Rechercher une structure...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: formatOptionLabel, noOptionsMessage: loading ? "Chargement..." : "Aucune structure trouvée" }));
68
+ return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une structure RSU...", searchPlaceholder: "Rechercher une structure...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune structure trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }));
51
69
  };
52
70
  export { RSUInput };
53
71
  export default RSUInput;
@@ -33,8 +33,8 @@ export interface FormRendererServices {
33
33
  fetchMenages?: (filter?: FetchFilter) => Promise<MenageCompletDto[]>;
34
34
  fetchEnquetes?: (filter?: FetchFilter) => Promise<EnqueteCompletDto[]>;
35
35
  fetchEnqueteDonnees?: (enqueteId: number) => Promise<any>;
36
- fetchStructures?: () => Promise<StructureDto[]>;
37
- fetchGeographicData?: (level: string, parentId?: number) => Promise<GeographicItem[]>;
36
+ fetchStructures?: (filter?: FetchFilter) => Promise<StructureDto[]>;
37
+ fetchGeographicData?: (entityType: string, parentId?: number, filter?: FetchFilter) => Promise<GeographicItem[]>;
38
38
  forceUppercase?: boolean;
39
39
  currentUser?: CurrentUserDto;
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/types/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/types/services.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"variableDependencyResolver.d.ts","sourceRoot":"","sources":["../../src/utils/variableDependencyResolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmCpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CA+Cf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,kBAAkB,GAAE,MAAc,EAClC,mBAAmB,GAAE,OAAc,GAClC,MAAM,GAAG,IAAI,CA+Bf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAY9D"}
1
+ {"version":3,"file":"variableDependencyResolver.d.ts","sourceRoot":"","sources":["../../src/utils/variableDependencyResolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmCpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CA+Cf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,kBAAkB,GAAE,MAAc,EAClC,mBAAmB,GAAE,OAAc,GAClC,MAAM,GAAG,IAAI,CAiBf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAY9D"}
@@ -116,33 +116,19 @@ export function resolveParentValue(variable, reponses) {
116
116
  */
117
117
  export function getApiEndpoint(variableType, parentId, defaultCountryCode = 'CIV', hasParentConfigured = true) {
118
118
  const type = variableType?.toUpperCase();
119
- switch (type) {
120
- case 'DISTRICT':
121
- return `/api/v1/Districts/select`;
122
- case 'REGION':
123
- if (parentId)
124
- return `/api/v1/Regions/${parentId}/select`;
125
- return hasParentConfigured ? null : `/api/v1/Regions/select`;
126
- case 'DEPARTEMENT':
127
- if (parentId)
128
- return `/api/v1/Departements/${parentId}/select`;
129
- return hasParentConfigured ? null : `/api/v1/Departements/select`;
130
- case 'SOUS_PREFECTURE':
131
- case 'SOUSPREFECTURE':
132
- if (parentId)
133
- return `/api/v1/SousPrefectures/${parentId}/select`;
134
- return hasParentConfigured ? null : `/api/v1/SousPrefectures/select`;
135
- case 'QUARTIER':
136
- if (parentId)
137
- return `/api/v1/Quartiers/${parentId}/select`;
138
- return hasParentConfigured ? null : `/api/v1/Quartiers/select`;
139
- case 'VILLAGE':
140
- if (parentId)
141
- return `/api/v1/Villages/${parentId}/select`;
142
- return hasParentConfigured ? null : `/api/v1/Villages/select`;
143
- default:
144
- return null;
145
- }
119
+ // Normaliser SOUS_PREFECTURE → SOUSPREFECTURE pour le endpoint unifié
120
+ const entityType = type === 'SOUS_PREFECTURE' ? 'SOUSPREFECTURE' : type;
121
+ const validTypes = ['DISTRICT', 'REGION', 'DEPARTEMENT', 'SOUSPREFECTURE', 'QUARTIER', 'VILLAGE'];
122
+ if (!validTypes.includes(entityType))
123
+ return null;
124
+ // Si un parent est configuré mais absent, ne pas charger
125
+ if (hasParentConfigured && requiresParent(type) && !parentId)
126
+ return null;
127
+ const params = new URLSearchParams();
128
+ params.set('entityType', entityType);
129
+ if (parentId)
130
+ params.set('parentId', String(parentId));
131
+ return `/api/v1/Select?${params.toString()}`;
146
132
  }
147
133
  /**
148
134
  * Détermine le libellé du parent selon le type de variable
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsuci/shared-form-components",
3
- "version": "1.0.131",
3
+ "version": "1.0.133",
4
4
  "description": "Composants partagés de rendu de formulaires RSU v2 - Package local pour frontend Admin et Public",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",