@rsuci/shared-form-components 1.0.29 → 1.0.33
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/ConfirmationModal.d.ts +20 -0
- package/dist/components/form-renderer/ConfirmationModal.d.ts.map +1 -0
- package/dist/components/form-renderer/ConfirmationModal.js +79 -0
- package/dist/components/form-renderer/FormActions.d.ts +23 -0
- package/dist/components/form-renderer/FormActions.d.ts.map +1 -0
- package/dist/components/form-renderer/FormActions.js +116 -0
- package/dist/components/form-renderer/FormNavigationButtons.d.ts +23 -0
- package/dist/components/form-renderer/FormNavigationButtons.d.ts.map +1 -0
- package/dist/components/form-renderer/FormNavigationButtons.js +35 -0
- package/dist/components/form-renderer/FormProgress.d.ts +19 -0
- package/dist/components/form-renderer/FormProgress.d.ts.map +1 -0
- package/dist/components/form-renderer/FormProgress.js +26 -0
- package/dist/components/form-renderer/FormRenderer.d.ts +39 -0
- package/dist/components/form-renderer/FormRenderer.d.ts.map +1 -0
- package/dist/components/form-renderer/FormRenderer.js +113 -0
- package/dist/components/form-renderer/FormRendererContext.d.ts +109 -0
- package/dist/components/form-renderer/FormRendererContext.d.ts.map +1 -0
- package/dist/components/form-renderer/FormRendererContext.js +114 -0
- package/dist/components/form-renderer/GroupeInstanceTabs.d.ts +18 -0
- package/dist/components/form-renderer/GroupeInstanceTabs.d.ts.map +1 -0
- package/dist/components/form-renderer/GroupeInstanceTabs.js +174 -0
- package/dist/components/form-renderer/ValidationModal.d.ts +25 -0
- package/dist/components/form-renderer/ValidationModal.d.ts.map +1 -0
- package/dist/components/form-renderer/ValidationModal.js +37 -0
- package/dist/components/form-renderer/index.d.ts +19 -0
- package/dist/components/form-renderer/index.d.ts.map +1 -0
- package/dist/components/form-renderer/index.js +24 -0
- package/dist/hooks/useFormInstances.d.ts +87 -0
- package/dist/hooks/useFormInstances.d.ts.map +1 -0
- package/dist/hooks/useFormInstances.js +197 -0
- package/dist/hooks/useFormNavigation.d.ts +72 -0
- package/dist/hooks/useFormNavigation.d.ts.map +1 -0
- package/dist/hooks/useFormNavigation.js +147 -0
- package/dist/hooks/useFormRenderer.d.ts +87 -0
- package/dist/hooks/useFormRenderer.d.ts.map +1 -0
- package/dist/hooks/useFormRenderer.js +177 -0
- package/dist/hooks/useFormValidation.d.ts +50 -0
- package/dist/hooks/useFormValidation.d.ts.map +1 -0
- package/dist/hooks/useFormValidation.js +175 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/lib/__tests__/date-functions.test.d.ts +5 -0
- package/dist/lib/__tests__/date-functions.test.d.ts.map +1 -0
- package/dist/lib/__tests__/date-functions.test.js +184 -0
- package/dist/lib/utils/groupeInstanceManager.d.ts +88 -0
- package/dist/lib/utils/groupeInstanceManager.d.ts.map +1 -0
- package/dist/lib/utils/groupeInstanceManager.js +606 -0
- package/dist/types/form-renderer.d.ts +115 -1
- package/dist/types/form-renderer.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRendererContext.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/FormRendererContext.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contexte React pour le FormRenderer
|
|
3
|
+
* Partage l'état et les fonctions entre tous les sous-composants
|
|
4
|
+
* RSU v2 - Package Partagé
|
|
5
|
+
*/
|
|
6
|
+
'use client';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
9
|
+
import { useFormRenderer } from '../../hooks/useFormRenderer';
|
|
10
|
+
// Création du contexte avec valeur par défaut null
|
|
11
|
+
const FormRendererContext = createContext(null);
|
|
12
|
+
/**
|
|
13
|
+
* Provider pour le contexte FormRenderer
|
|
14
|
+
* Encapsule useFormRenderer et fournit l'état à tous les enfants
|
|
15
|
+
*/
|
|
16
|
+
export const FormRendererProvider = ({ children, formulaire, enquete, initialResponses, config, callbacks, services, geographicComponents, disabled, isSubmitting: externalIsSubmitting, isVariableVisible, debug }) => {
|
|
17
|
+
// Utiliser le hook principal
|
|
18
|
+
const formRenderer = useFormRenderer(formulaire, enquete, {
|
|
19
|
+
config,
|
|
20
|
+
initialResponses: initialResponses || enquete?.reponses,
|
|
21
|
+
onResponsesChange: callbacks.onResponsesChange,
|
|
22
|
+
onGroupChange: callbacks.onGroupChange,
|
|
23
|
+
isVariableVisible,
|
|
24
|
+
debug
|
|
25
|
+
});
|
|
26
|
+
// Construire la valeur du contexte
|
|
27
|
+
const contextValue = useMemo(() => ({
|
|
28
|
+
...formRenderer,
|
|
29
|
+
// Données initiales
|
|
30
|
+
formulaire,
|
|
31
|
+
enquete,
|
|
32
|
+
// Configuration
|
|
33
|
+
config,
|
|
34
|
+
// Callbacks
|
|
35
|
+
callbacks,
|
|
36
|
+
// Services
|
|
37
|
+
services,
|
|
38
|
+
geographicComponents,
|
|
39
|
+
// Surcharges externes
|
|
40
|
+
isSubmitting: externalIsSubmitting ?? formRenderer.isSubmitting,
|
|
41
|
+
effectiveDisabled: disabled ?? formRenderer.effectiveDisabled
|
|
42
|
+
}), [
|
|
43
|
+
formRenderer,
|
|
44
|
+
formulaire,
|
|
45
|
+
enquete,
|
|
46
|
+
config,
|
|
47
|
+
callbacks,
|
|
48
|
+
services,
|
|
49
|
+
geographicComponents,
|
|
50
|
+
externalIsSubmitting,
|
|
51
|
+
disabled
|
|
52
|
+
]);
|
|
53
|
+
return (_jsx(FormRendererContext.Provider, { value: contextValue, children: children }));
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Hook pour accéder au contexte FormRenderer
|
|
57
|
+
* Doit être utilisé à l'intérieur d'un FormRendererProvider
|
|
58
|
+
*/
|
|
59
|
+
export function useFormRendererContext() {
|
|
60
|
+
const context = useContext(FormRendererContext);
|
|
61
|
+
if (!context) {
|
|
62
|
+
throw new Error('useFormRendererContext doit être utilisé à l\'intérieur d\'un FormRendererProvider');
|
|
63
|
+
}
|
|
64
|
+
return context;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Hook pour accéder uniquement à la navigation
|
|
68
|
+
*/
|
|
69
|
+
export function useFormRendererNavigation() {
|
|
70
|
+
const { navigation } = useFormRendererContext();
|
|
71
|
+
return navigation;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Hook pour accéder uniquement à la validation
|
|
75
|
+
*/
|
|
76
|
+
export function useFormRendererValidation() {
|
|
77
|
+
const { validation } = useFormRendererContext();
|
|
78
|
+
return validation;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Hook pour accéder uniquement aux instances
|
|
82
|
+
*/
|
|
83
|
+
export function useFormRendererInstances() {
|
|
84
|
+
const { instances } = useFormRendererContext();
|
|
85
|
+
return instances;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Hook pour accéder à la configuration
|
|
89
|
+
*/
|
|
90
|
+
export function useFormRendererConfig() {
|
|
91
|
+
const { mode, features, config } = useFormRendererContext();
|
|
92
|
+
return { mode, features, config };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Hook pour accéder aux réponses
|
|
96
|
+
*/
|
|
97
|
+
export function useFormRendererResponses() {
|
|
98
|
+
const { responses, updateResponse, getResponseValue } = useFormRendererContext();
|
|
99
|
+
return { responses, updateResponse, getResponseValue };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Hook pour accéder à l'état global
|
|
103
|
+
*/
|
|
104
|
+
export function useFormRendererState() {
|
|
105
|
+
const { hasUnsavedChanges, isSubmitting, effectiveDisabled, isReadOnly, isConsultationMode } = useFormRendererContext();
|
|
106
|
+
return {
|
|
107
|
+
hasUnsavedChanges,
|
|
108
|
+
isSubmitting,
|
|
109
|
+
effectiveDisabled,
|
|
110
|
+
isReadOnly,
|
|
111
|
+
isConsultationMode
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export default FormRendererContext;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composant d'interface à onglets pour les instances multiples de groupes
|
|
3
|
+
* RSU v2 - Moteur de Rendu des Formulaires d'Enquête
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { GroupeFormulaire, EnqueteReponse, GroupeInstance } from '../../types/enquete';
|
|
7
|
+
export interface GroupeInstanceTabsProps {
|
|
8
|
+
groupe: GroupeFormulaire;
|
|
9
|
+
currentInstanceIndex: number;
|
|
10
|
+
responses: Record<string, EnqueteReponse>;
|
|
11
|
+
onInstanceChange: (instanceIndex: number) => void;
|
|
12
|
+
onInstanceAdded: (instance: GroupeInstance) => void;
|
|
13
|
+
onInstanceRemoved: (instanceNumber: number) => void;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare const GroupeInstanceTabs: React.FC<GroupeInstanceTabsProps>;
|
|
17
|
+
export default GroupeInstanceTabs;
|
|
18
|
+
//# sourceMappingURL=GroupeInstanceTabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupeInstanceTabs.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/GroupeInstanceTabs.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA0RzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composant d'interface à onglets pour les instances multiples de groupes
|
|
3
|
+
* RSU v2 - Moteur de Rendu des Formulaires d'Enquête
|
|
4
|
+
*/
|
|
5
|
+
'use client';
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useState, useEffect } from 'react';
|
|
8
|
+
import { Plus, Minus, AlertTriangle, Check, AlertCircle, AlertTriangle as ExclamationIcon } from 'lucide-react';
|
|
9
|
+
import { GroupeInstanceManager } from '../../lib/utils/groupeInstanceManager';
|
|
10
|
+
import ConfirmationModal from './ConfirmationModal';
|
|
11
|
+
const GroupeInstanceTabs = ({ groupe, currentInstanceIndex, responses, onInstanceChange, onInstanceAdded, onInstanceRemoved, disabled = false }) => {
|
|
12
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [forceUpdate, setForceUpdate] = useState(0);
|
|
15
|
+
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
|
|
16
|
+
// Ne pas afficher pour les groupes non multiples
|
|
17
|
+
if (!groupe.estMultiple || !groupe.instances) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Calculer les informations sur les instances
|
|
21
|
+
const currentCount = GroupeInstanceManager.getInstancesCount(groupe, responses);
|
|
22
|
+
const maxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
|
|
23
|
+
const canAdd = GroupeInstanceManager.canAddInstance(groupe, responses);
|
|
24
|
+
const canRemove = GroupeInstanceManager.canRemoveInstance(groupe, responses);
|
|
25
|
+
// CORRECTION: Détecter les changements de maxInstances et forcer le re-rendu
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const newMaxInstances = GroupeInstanceManager.getMaxInstances(groupe, responses);
|
|
28
|
+
if (newMaxInstances !== maxInstances) {
|
|
29
|
+
console.log('GroupeInstanceTabs - Changement de maxInstances détecté:', {
|
|
30
|
+
groupeCode: groupe.code,
|
|
31
|
+
oldMaxInstances: maxInstances,
|
|
32
|
+
newMaxInstances,
|
|
33
|
+
codeVariable: groupe.codeVariable
|
|
34
|
+
});
|
|
35
|
+
setForceUpdate(prev => prev + 1);
|
|
36
|
+
}
|
|
37
|
+
}, [responses, groupe.codeVariable, groupe.maxInstances]);
|
|
38
|
+
// PROTECTION DES DONNÉES: Afficher toutes les instances existantes, même si la variable de contrôle est plus petite
|
|
39
|
+
// Le nombre d'onglets affichés = Math.max(maxInstances, instances existantes)
|
|
40
|
+
const minDisplayCount = Math.max(maxInstances, groupe.instances.length);
|
|
41
|
+
const displayedInstances = groupe.instances.slice(0, minDisplayCount);
|
|
42
|
+
console.log('GroupeInstanceTabs - Debug avec protection:', {
|
|
43
|
+
groupeCode: groupe.code,
|
|
44
|
+
codeVariable: groupe.codeVariable,
|
|
45
|
+
maxInstances,
|
|
46
|
+
totalInstances: groupe.instances.length,
|
|
47
|
+
minDisplayCount,
|
|
48
|
+
displayedInstances: displayedInstances.length,
|
|
49
|
+
canAdd: canAdd.canProceed,
|
|
50
|
+
canRemove: canRemove.canProceed,
|
|
51
|
+
canAddMessage: canAdd.constraints[0]?.message,
|
|
52
|
+
canRemoveMessage: canRemove.constraints[0]?.message
|
|
53
|
+
});
|
|
54
|
+
// Fonction pour déterminer l'état d'une instance
|
|
55
|
+
const getInstanceState = (instance) => {
|
|
56
|
+
const responseCount = Object.keys(instance.reponses).length;
|
|
57
|
+
if (responseCount === 0) {
|
|
58
|
+
return 'empty';
|
|
59
|
+
}
|
|
60
|
+
if (GroupeInstanceManager.isInstanceComplete(instance, groupe)) {
|
|
61
|
+
return 'complete';
|
|
62
|
+
}
|
|
63
|
+
return 'incomplete';
|
|
64
|
+
};
|
|
65
|
+
// Fonction pour obtenir l'icône et la couleur selon l'état
|
|
66
|
+
const getInstanceDisplay = (instance, isActive) => {
|
|
67
|
+
const state = getInstanceState(instance);
|
|
68
|
+
const baseClasses = `
|
|
69
|
+
flex items-center justify-center min-w-[3rem] h-10 px-3 rounded-lg font-medium text-sm
|
|
70
|
+
transition-all duration-200 cursor-pointer border-2
|
|
71
|
+
`;
|
|
72
|
+
let stateClasses = '';
|
|
73
|
+
let icon = null;
|
|
74
|
+
switch (state) {
|
|
75
|
+
case 'complete':
|
|
76
|
+
stateClasses = isActive
|
|
77
|
+
? 'bg-blue-600 text-white border-blue-600 shadow-lg'
|
|
78
|
+
: 'bg-green-100 text-green-700 border-green-300 hover:bg-green-200';
|
|
79
|
+
icon = _jsx(Check, { className: "h-4 w-4 ml-1" });
|
|
80
|
+
break;
|
|
81
|
+
case 'incomplete':
|
|
82
|
+
stateClasses = isActive
|
|
83
|
+
? 'bg-blue-600 text-white border-blue-600 shadow-lg'
|
|
84
|
+
: 'bg-green-100 text-orange-700 border-green-300 hover:bg-green-200';
|
|
85
|
+
icon = _jsx(AlertCircle, { className: "h-4 w-4 ml-1" });
|
|
86
|
+
break;
|
|
87
|
+
case 'empty':
|
|
88
|
+
stateClasses = isActive
|
|
89
|
+
? 'bg-blue-600 text-white border-blue-600 shadow-lg'
|
|
90
|
+
: 'bg-gray-600 text-white border-gray-600 hover:bg-gray-700';
|
|
91
|
+
icon = _jsx(ExclamationIcon, { className: "h-4 w-4 ml-1" });
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
className: `${baseClasses} ${stateClasses}`,
|
|
96
|
+
icon
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
const handleInstanceClick = (instanceIndex) => {
|
|
100
|
+
// En mode consultation, permettre la navigation entre onglets mais pas les modifications
|
|
101
|
+
if (isProcessing)
|
|
102
|
+
return;
|
|
103
|
+
onInstanceChange(instanceIndex);
|
|
104
|
+
};
|
|
105
|
+
const handleAddInstance = async () => {
|
|
106
|
+
if (disabled || isProcessing)
|
|
107
|
+
return;
|
|
108
|
+
setIsProcessing(true);
|
|
109
|
+
setError(null);
|
|
110
|
+
try {
|
|
111
|
+
const result = GroupeInstanceManager.addInstance(groupe, responses);
|
|
112
|
+
if (result.success && result.instance) {
|
|
113
|
+
onInstanceAdded(result.instance);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
setError(result.error || 'Erreur lors de l\'ajout de l\'instance');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
setError('Erreur inattendue lors de l\'ajout de l\'instance');
|
|
121
|
+
console.error('Erreur ajout instance:', err);
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
setIsProcessing(false);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const handleRemoveInstanceClick = () => {
|
|
128
|
+
if (disabled || isProcessing || !groupe.instances)
|
|
129
|
+
return;
|
|
130
|
+
setShowDeleteConfirmation(true);
|
|
131
|
+
};
|
|
132
|
+
const handleConfirmRemoveInstance = async () => {
|
|
133
|
+
if (disabled || isProcessing || !groupe.instances)
|
|
134
|
+
return;
|
|
135
|
+
setShowDeleteConfirmation(false);
|
|
136
|
+
setIsProcessing(true);
|
|
137
|
+
setError(null);
|
|
138
|
+
try {
|
|
139
|
+
// Supprimer l'instance actuellement affichée (correction du bug)
|
|
140
|
+
const currentInstance = groupe.instances[currentInstanceIndex];
|
|
141
|
+
if (!currentInstance) {
|
|
142
|
+
setError('Aucune instance sélectionnée à supprimer');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const result = GroupeInstanceManager.removeInstance(groupe, currentInstance.numeroInstance, responses);
|
|
146
|
+
if (result.success) {
|
|
147
|
+
onInstanceRemoved(currentInstance.numeroInstance);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
setError(result.error || 'Erreur lors de la suppression de l\'instance');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
setError('Erreur inattendue lors de la suppression de l\'instance');
|
|
155
|
+
console.error('Erreur suppression instance:', err);
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
setIsProcessing(false);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const handleCancelRemoveInstance = () => {
|
|
162
|
+
setShowDeleteConfirmation(false);
|
|
163
|
+
};
|
|
164
|
+
return (_jsxs("div", { className: "w-full", children: [_jsxs("div", { className: "flex items-center space-x-2 overflow-x-auto pb-2 relative", children: [_jsx("div", { className: "flex space-x-2 flex-shrink-0", children: displayedInstances.map((instance, index) => {
|
|
165
|
+
const isActive = index === currentInstanceIndex;
|
|
166
|
+
const display = getInstanceDisplay(instance, isActive);
|
|
167
|
+
return (_jsxs("button", { onClick: () => handleInstanceClick(index), disabled: isProcessing, className: display.className, title: `Instance ${instance.numeroInstance} - ${getInstanceState(instance) === 'complete' ? 'Complète' : getInstanceState(instance) === 'incomplete' ? 'Incomplète' : 'Vide'}`, children: [_jsx("span", { className: "font-semibold", children: instance.numeroInstance }), display.icon] }, instance.numeroInstance));
|
|
168
|
+
}) }), _jsx("div", { className: "h-6 w-px bg-gray-300 flex-shrink-0" }), _jsxs("div", { className: "flex items-center space-x-2 flex-shrink-0", children: [_jsx("button", { type: "button", onClick: handleAddInstance, disabled: disabled || isProcessing || !canAdd.canProceed, className: `p-2 rounded-lg transition-colors flex-shrink-0 ${disabled || isProcessing || !canAdd.canProceed
|
|
169
|
+
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
|
170
|
+
: 'bg-green-500 text-white hover:bg-green-600 focus:ring-2 focus:ring-green-500 focus:ring-offset-2'}`, title: canAdd.canProceed ? 'Ajouter une instance' : canAdd.constraints[0]?.message, children: _jsx(Plus, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: handleRemoveInstanceClick, disabled: disabled || isProcessing || !canRemove.canProceed, className: `p-2 rounded-lg transition-colors flex-shrink-0 ${disabled || isProcessing || !canRemove.canProceed
|
|
171
|
+
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
|
172
|
+
: 'bg-red-500 text-white hover:bg-red-600 focus:ring-2 focus:ring-red-500 focus:ring-offset-2'}`, title: canRemove.canProceed ? 'Supprimer l\'instance courante' : canRemove.constraints[0]?.message, children: _jsx(Minus, { className: "h-4 w-4" }) }), isProcessing && (_jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 flex-shrink-0" }))] })] }), error && (_jsxs("div", { className: "mt-2 p-2 bg-red-50 border border-red-200 rounded-lg shadow-sm", children: [_jsxs("div", { className: "flex items-start space-x-2", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 flex-shrink-0 mt-0.5" }), _jsx("div", { className: "text-sm text-red-700", children: error })] }), _jsx("button", { onClick: () => setError(null), className: "absolute top-1 right-1 text-red-400 hover:text-red-600", children: "\u00D7" })] })), showDeleteConfirmation && (_jsx(ConfirmationModal, { isOpen: showDeleteConfirmation, title: "Confirmer la suppression", message: `Êtes-vous sûr de vouloir supprimer l'instance ${groupe.instances?.[currentInstanceIndex]?.numeroInstance || currentInstanceIndex + 1} ? Cette action est irréversible.`, confirmText: "Supprimer", cancelText: "Annuler", onConfirm: handleConfirmRemoveInstance, onCancel: handleCancelRemoveInstance, type: "danger" }))] }));
|
|
173
|
+
};
|
|
174
|
+
export default GroupeInstanceTabs;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal de validation/rejet DR pour le FormRenderer
|
|
3
|
+
* RSU v2 - Package Partagé
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
export interface ValidationModalProps {
|
|
7
|
+
/** État d'ouverture de la modal */
|
|
8
|
+
isOpen: boolean;
|
|
9
|
+
/** Callback de fermeture */
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
/** Callback de confirmation avec commentaire optionnel */
|
|
12
|
+
onConfirm: (commentaire?: string) => Promise<void>;
|
|
13
|
+
/** Action à effectuer: valider ou rejeter */
|
|
14
|
+
action: 'valider' | 'rejeter';
|
|
15
|
+
/** Nombre d'enquêtes concernées */
|
|
16
|
+
enquetesCount?: number;
|
|
17
|
+
/** État de chargement externe */
|
|
18
|
+
loading?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Modal de validation/rejet d'enquête par le DR
|
|
22
|
+
*/
|
|
23
|
+
export declare const ValidationModal: React.FC<ValidationModalProps>;
|
|
24
|
+
export default ValidationModal;
|
|
25
|
+
//# sourceMappingURL=ValidationModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationModal.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/ValidationModal.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,mCAAmC;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,0DAA0D;IAC1D,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,6CAA6C;IAC7C,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAwI1D,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal de validation/rejet DR pour le FormRenderer
|
|
3
|
+
* RSU v2 - Package Partagé
|
|
4
|
+
*/
|
|
5
|
+
'use client';
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
/**
|
|
9
|
+
* Modal de validation/rejet d'enquête par le DR
|
|
10
|
+
*/
|
|
11
|
+
export const ValidationModal = ({ isOpen, onClose, onConfirm, action, enquetesCount = 1, loading = false }) => {
|
|
12
|
+
const [commentaire, setCommentaire] = useState('');
|
|
13
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
14
|
+
if (!isOpen)
|
|
15
|
+
return null;
|
|
16
|
+
const handleConfirm = async () => {
|
|
17
|
+
setIsSubmitting(true);
|
|
18
|
+
try {
|
|
19
|
+
await onConfirm(commentaire || undefined);
|
|
20
|
+
setCommentaire('');
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
setIsSubmitting(false);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const handleClose = () => {
|
|
27
|
+
if (!isSubmitting) {
|
|
28
|
+
setCommentaire('');
|
|
29
|
+
onClose();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const isValider = action === 'valider';
|
|
33
|
+
const titre = isValider ? 'Valider l\'enquête' : 'Rejeter l\'enquête';
|
|
34
|
+
const couleurBouton = isValider ? 'bg-green-600 hover:bg-green-700' : 'bg-red-600 hover:bg-red-700';
|
|
35
|
+
return (_jsxs("div", { className: "fixed inset-0 z-50 overflow-y-auto", children: [_jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 transition-opacity", onClick: handleClose }), _jsx("div", { className: "flex min-h-full items-center justify-center p-4", children: _jsxs("div", { className: "relative bg-white rounded-lg shadow-xl max-w-md w-full p-6", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center space-x-3", children: [_jsx("div", { className: `${isValider ? 'text-green-600' : 'text-red-600'}`, children: isValider ? (_jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) })) : (_jsx("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) })) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: titre })] }), _jsx("button", { onClick: handleClose, disabled: isSubmitting, className: "text-gray-400 hover:text-gray-600 transition-colors disabled:opacity-50", children: _jsx("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsxs("div", { className: "mb-6", children: [_jsxs("p", { className: "text-gray-700 mb-4", children: ["\u00CAtes-vous s\u00FBr de vouloir ", isValider ? 'valider' : 'rejeter', ' ', _jsxs("span", { className: "font-semibold", children: [enquetesCount, " enqu\u00EAte", enquetesCount > 1 ? 's' : ''] }), " ?"] }), !isValider && (_jsxs("div", { children: [_jsx("label", { htmlFor: "commentaire", className: "block text-sm font-medium text-gray-700 mb-2", children: "Commentaire (optionnel)" }), _jsx("textarea", { id: "commentaire", value: commentaire, onChange: (e) => setCommentaire(e.target.value), disabled: isSubmitting, rows: 4, className: "w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-red-500 disabled:bg-gray-100 disabled:cursor-not-allowed text-gray-900 placeholder:text-gray-400", placeholder: "Indiquez la raison du rejet (optionnel)..." }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Maximum 500 caract\u00E8res" })] }))] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx("button", { onClick: handleClose, disabled: isSubmitting, className: "px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: "Annuler" }), _jsx("button", { onClick: handleConfirm, disabled: isSubmitting, className: `px-4 py-2 text-sm font-medium text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${couleurBouton}`, children: isSubmitting ? (_jsxs("span", { className: "flex items-center", children: [_jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-white", 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" })] }), "Traitement..."] })) : ('Confirmer') })] })] }) })] }));
|
|
36
|
+
};
|
|
37
|
+
export default ValidationModal;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exports du module form-renderer
|
|
3
|
+
* RSU v2 - Composants partagés de rendu de formulaires
|
|
4
|
+
*/
|
|
5
|
+
export { default as ConfirmationModal } from './ConfirmationModal';
|
|
6
|
+
export type { ConfirmationModalProps, ConfirmationModalType } from './ConfirmationModal';
|
|
7
|
+
export { default as ValidationModal } from './ValidationModal';
|
|
8
|
+
export type { ValidationModalProps } from './ValidationModal';
|
|
9
|
+
export { default as GroupeInstanceTabs } from './GroupeInstanceTabs';
|
|
10
|
+
export type { GroupeInstanceTabsProps } from './GroupeInstanceTabs';
|
|
11
|
+
export { FormRendererProvider, useFormRendererContext, useFormRendererNavigation, useFormRendererValidation, useFormRendererInstances, useFormRendererConfig, useFormRendererResponses, useFormRendererState, type FormRendererContextValue, type FormRendererProviderProps } from './FormRendererContext';
|
|
12
|
+
export { default as FormProgress } from './FormProgress';
|
|
13
|
+
export type { FormProgressProps } from './FormProgress';
|
|
14
|
+
export { default as FormNavigationButtons } from './FormNavigationButtons';
|
|
15
|
+
export type { FormNavigationButtonsProps } from './FormNavigationButtons';
|
|
16
|
+
export { default as FormActions } from './FormActions';
|
|
17
|
+
export type { FormActionsProps } from './FormActions';
|
|
18
|
+
export { default as FormRenderer, type FormRendererProps } from './FormRenderer';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/form-renderer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAMpE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EACL,OAAO,IAAI,YAAY,EACvB,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exports du module form-renderer
|
|
3
|
+
* RSU v2 - Composants partagés de rendu de formulaires
|
|
4
|
+
*/
|
|
5
|
+
// ========================================
|
|
6
|
+
// COMPOSANTS UI DE BASE
|
|
7
|
+
// ========================================
|
|
8
|
+
export { default as ConfirmationModal } from './ConfirmationModal';
|
|
9
|
+
export { default as ValidationModal } from './ValidationModal';
|
|
10
|
+
export { default as GroupeInstanceTabs } from './GroupeInstanceTabs';
|
|
11
|
+
// ========================================
|
|
12
|
+
// CONTEXTE ET PROVIDER
|
|
13
|
+
// ========================================
|
|
14
|
+
export { FormRendererProvider, useFormRendererContext, useFormRendererNavigation, useFormRendererValidation, useFormRendererInstances, useFormRendererConfig, useFormRendererResponses, useFormRendererState } from './FormRendererContext';
|
|
15
|
+
// ========================================
|
|
16
|
+
// SOUS-COMPOSANTS DU FORM RENDERER
|
|
17
|
+
// ========================================
|
|
18
|
+
export { default as FormProgress } from './FormProgress';
|
|
19
|
+
export { default as FormNavigationButtons } from './FormNavigationButtons';
|
|
20
|
+
export { default as FormActions } from './FormActions';
|
|
21
|
+
// ========================================
|
|
22
|
+
// COMPOSANT PRINCIPAL FORM RENDERER
|
|
23
|
+
// ========================================
|
|
24
|
+
export { default as FormRenderer } from './FormRenderer';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook de gestion des instances multiples pour les formulaires d'enquête
|
|
3
|
+
* Gère l'ajout, la suppression et la synchronisation des instances de groupes
|
|
4
|
+
* RSU v2 - Package Partagé
|
|
5
|
+
*/
|
|
6
|
+
import { GroupeFormulaire, GroupeInstance, EnqueteReponse } from '../types/enquete';
|
|
7
|
+
export interface UseFormInstancesOptions {
|
|
8
|
+
/** Callback appelé lors de l'ajout d'une instance */
|
|
9
|
+
onInstanceAdded?: (instance: GroupeInstance) => void;
|
|
10
|
+
/** Callback appelé lors de la suppression d'une instance */
|
|
11
|
+
onInstanceRemoved?: (instanceNumber: number) => void;
|
|
12
|
+
/** Callback appelé lors du changement d'instance active */
|
|
13
|
+
onInstanceChange?: (instanceIndex: number) => void;
|
|
14
|
+
/** Callback appelé lors de la mise à jour des groupes */
|
|
15
|
+
onGroupesUpdated?: (groupes: GroupeFormulaire[]) => void;
|
|
16
|
+
/** Mode debug */
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface UseFormInstancesResult {
|
|
20
|
+
/** Groupes avec leurs instances initialisées */
|
|
21
|
+
groupesWithInstances: GroupeFormulaire[];
|
|
22
|
+
/** Index de l'instance actuellement active */
|
|
23
|
+
currentInstanceIndex: number;
|
|
24
|
+
/** Instance actuellement active */
|
|
25
|
+
currentInstance: GroupeInstance | undefined;
|
|
26
|
+
/** Ajouter une instance au groupe actuel */
|
|
27
|
+
addInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
|
|
28
|
+
success: boolean;
|
|
29
|
+
instance?: GroupeInstance;
|
|
30
|
+
error?: string;
|
|
31
|
+
};
|
|
32
|
+
/** Supprimer une instance du groupe actuel */
|
|
33
|
+
removeInstance: (groupe: GroupeFormulaire, instanceNumber: number, responses: Record<string, EnqueteReponse>) => {
|
|
34
|
+
success: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Changer d'instance active */
|
|
38
|
+
changeInstance: (instanceIndex: number) => void;
|
|
39
|
+
/** Synchroniser les réponses avec l'instance */
|
|
40
|
+
syncInstanceResponses: (instance: GroupeInstance, groupe: GroupeFormulaire, allResponses: Record<string, EnqueteReponse>) => void;
|
|
41
|
+
/** Mettre à jour les propriétés d'un groupe */
|
|
42
|
+
updateGroupeProperties: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => void;
|
|
43
|
+
/** Initialiser les groupes avec instances */
|
|
44
|
+
initializeGroupesWithInstances: (groupes: GroupeFormulaire[], responses: Record<string, EnqueteReponse>) => GroupeFormulaire[];
|
|
45
|
+
/** Vérifier si une instance est complète */
|
|
46
|
+
isInstanceComplete: (instance: GroupeInstance, groupe: GroupeFormulaire) => boolean;
|
|
47
|
+
/** Peut-on ajouter une instance ? */
|
|
48
|
+
canAddInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
|
|
49
|
+
canProceed: boolean;
|
|
50
|
+
constraints: Array<{
|
|
51
|
+
message: string;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
/** Peut-on supprimer une instance ? */
|
|
55
|
+
canRemoveInstance: (groupe: GroupeFormulaire, responses: Record<string, EnqueteReponse>) => {
|
|
56
|
+
canProceed: boolean;
|
|
57
|
+
constraints: Array<{
|
|
58
|
+
message: string;
|
|
59
|
+
}>;
|
|
60
|
+
};
|
|
61
|
+
/** Mettre à jour les groupes avec instances */
|
|
62
|
+
setGroupesWithInstances: React.Dispatch<React.SetStateAction<GroupeFormulaire[]>>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Hook pour gérer les instances multiples dans un formulaire d'enquête
|
|
66
|
+
*
|
|
67
|
+
* @param initialGroupes - Liste initiale des groupes du formulaire
|
|
68
|
+
* @param initialResponses - Réponses initiales
|
|
69
|
+
* @param options - Options de configuration
|
|
70
|
+
* @returns Objet contenant l'état et les fonctions de gestion des instances
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```tsx
|
|
74
|
+
* const {
|
|
75
|
+
* groupesWithInstances,
|
|
76
|
+
* addInstance,
|
|
77
|
+
* removeInstance,
|
|
78
|
+
* currentInstance
|
|
79
|
+
* } = useFormInstances(formulaire.groupes, enquete.reponses, {
|
|
80
|
+
* onInstanceAdded: (instance) => console.log('Added:', instance),
|
|
81
|
+
* onInstanceRemoved: (num) => console.log('Removed:', num)
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function useFormInstances(initialGroupes: GroupeFormulaire[], initialResponses: Record<string, EnqueteReponse>, options?: UseFormInstancesOptions): UseFormInstancesResult;
|
|
86
|
+
export default useFormInstances;
|
|
87
|
+
//# sourceMappingURL=useFormInstances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormInstances.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormInstances.ts"],"names":[],"mappings":"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"}
|