1
- import React , { useCallback , useEffect } from 'react' ;
1
+ import React , { useCallback } from 'react' ;
2
2
import { useTranslation } from 'react-i18next' ;
3
3
import flattenDeep from 'lodash-es/flattenDeep' ;
4
4
import {
@@ -82,18 +82,15 @@ const allowedQuestionOptionsMapping: Record<string, string[]> = {
82
82
function cleanQuestionOptionsForType ( options : any , newType : string ) : any {
83
83
const allowedOpts = allowedQuestionOptionsMapping [ newType ] || [ ] ;
84
84
const cleanedOpts = Object . fromEntries ( Object . entries ( options ) . filter ( ( [ optKey ] ) => allowedOpts . includes ( optKey ) ) ) ;
85
- // Ensure required property 'rendering' exists if present in the original options.
86
- if ( ! ( 'rendering' in cleanedOpts ) && options . rendering ) {
87
- cleanedOpts . rendering = options . rendering ;
88
- }
85
+ cleanedOpts . rendering = options . rendering ;
89
86
return cleanedOpts ;
90
87
}
91
88
92
89
/**
93
90
* Cleans the given form field by retaining only allowed top‑level properties for the new type.
94
91
* Also cleans nested questionOptions using the nested mapping.
95
92
*/
96
- function cleanFormFieldForType ( field : FormField , newType : string ) : FormField {
93
+ export function cleanFormFieldForType ( field : FormField , newType : string ) : FormField {
97
94
const allowedKeys = allowedPropertiesMapping [ newType ] || [ ] ;
98
95
const cleaned : Partial < FormField > = { } ;
99
96
@@ -109,10 +106,14 @@ function cleanFormFieldForType(field: FormField, newType: string): FormField {
109
106
}
110
107
111
108
cleaned . type = newType ;
112
-
113
109
return cleaned as FormField ;
114
110
}
115
111
112
+ const getAllQuestionIds = ( questions ?: FormField [ ] ) : string [ ] => {
113
+ if ( ! questions ) return [ ] ;
114
+ return flattenDeep ( questions . map ( ( question ) => [ question . id , getAllQuestionIds ( question . questions ) ] ) ) ;
115
+ } ;
116
+
116
117
const QuestionModalContent : React . FC < QuestionModalProps > = ( {
117
118
formField : formFieldProp ,
118
119
closeModal,
@@ -124,39 +125,41 @@ const QuestionModalContent: React.FC<QuestionModalProps> = ({
124
125
} ) => {
125
126
const { t } = useTranslation ( ) ;
126
127
const { formField, setFormField } = useFormField ( ) ;
127
- useEffect ( ( ) => {
128
- if ( formField && formField . type ) {
129
- const cleaned = cleanFormFieldForType ( formField , formField . type ) ;
130
- if ( JSON . stringify ( cleaned ) !== JSON . stringify ( formField ) ) {
131
- setFormField ( cleaned ) ;
132
- }
133
- }
134
- } , [ formField ?. type , formField , setFormField ] ) ;
135
-
136
- const getAllQuestionIds = useCallback ( ( questions ?: FormField [ ] ) : string [ ] => {
137
- if ( ! questions ) return [ ] ;
138
- return flattenDeep ( questions . map ( ( question ) => [ question . id , getAllQuestionIds ( question . questions ) ] ) ) ;
139
- } , [ ] ) ;
140
-
141
128
const checkIfQuestionIdExists = useCallback (
142
129
( idToTest : string ) : boolean => {
143
130
// Get all IDs from the schema
144
131
const schemaIds : string [ ] =
145
132
schema ?. pages ?. flatMap ( ( page ) => page ?. sections ?. flatMap ( ( section ) => getAllQuestionIds ( section . questions ) ) ) ||
146
133
[ ] ;
147
134
148
- // Get all IDs from the current formField's questions array
135
+ // Get all IDs from the obsGroup questions
149
136
const formFieldIds : string [ ] = formField ?. questions ? getAllQuestionIds ( formField . questions ) : [ ] ;
150
137
138
+ // The main question's id
139
+ formFieldIds . push ( formField . id ) ;
140
+
141
+ const originalFormFieldQuestionIds =
142
+ formFieldProp && formFieldProp . id !== '' ? getAllQuestionIds ( formFieldProp . questions ) : [ ] ;
143
+
144
+ if ( formFieldProp && formFieldProp . id !== '' ) originalFormFieldQuestionIds . push ( formFieldProp . id ) ;
145
+
146
+ // Remove the ids from the original question from the schema ids
147
+ const filteredSchemaIds = schemaIds . slice ( ) ; // Create a copy to modify
148
+ originalFormFieldQuestionIds . forEach ( ( idToRemove ) => {
149
+ const indexToRemove = filteredSchemaIds . indexOf ( idToRemove ) ;
150
+ if ( indexToRemove !== - 1 ) {
151
+ filteredSchemaIds . splice ( indexToRemove , 1 ) ;
152
+ }
153
+ } ) ;
154
+
151
155
// Combine both arrays, along with the parent question ID and count occurrences of the ID
152
- const allIds = [ ...schemaIds , ...formFieldIds ] ;
153
- if ( ! formFieldProp || formFieldProp . id !== formField . id ) {
154
- allIds . push ( formField . id ) ;
155
- }
156
+ const allIds = [ ...filteredSchemaIds , ...formFieldIds ] ;
156
157
const occurrences = allIds . filter ( ( id ) => id === idToTest ) . length ;
158
+
159
+ // Return true if ID occurs more than once
157
160
return occurrences > 1 ;
158
161
} ,
159
- [ schema , getAllQuestionIds , formField , formFieldProp ] ,
162
+ [ schema , formField , formFieldProp ] ,
160
163
) ;
161
164
162
165
const addObsGroupQuestion = useCallback ( ( ) => {
0 commit comments