1111)
1212import re # Regular expression module for pattern matching
1313from typing import TypedDict
14+ from dataclasses import dataclass
15+
16+
17+ @dataclass
18+ class ImportFlags :
19+ """
20+ Dataclass to hold the import flags for widget generation.
21+ This will make the code more maintainable and less error-prone when adding new flags.
22+ """
23+
24+ # Flags for imports
25+ has_choices_import : bool = False
26+ has_custom_choices_import : bool = False
27+ has_conditionals_import : bool = False
28+ has_input_range_import : bool = False
29+ has_custom_widgets_import : bool = False
30+ has_validations_import : bool = (
31+ True # Default to True for validations.requiredValidation
32+ )
33+ has_custom_validations_import : bool = False
34+ has_custom_conditionals_import : bool = False
35+ has_help_popup_import : bool = False
36+ has_helper_import : bool = False
37+ has_formatter_import : bool = False
38+ has_custom_formatter_import : bool = False
39+
40+ # Flags for specific labels
41+ has_nickname_label : bool = False
42+ has_persons_count_label : bool = False
43+ has_gendered_suffix_label : bool = False
1444
1545
1646class RadioNumberParametersResult (TypedDict ):
@@ -49,8 +79,8 @@ class WidgetResult(TypedDict):
4979
5080 statement : str
5181 has_helper_import : bool
52- has_formatter_import : bool | None
53- has_custom_formatter_import : bool | None
82+ has_formatter_import : bool
83+ has_custom_formatter_import : bool
5484
5585
5686# Function to generate widgets.tsx for each section
@@ -84,83 +114,27 @@ def convert_excel_to_typescript(section):
84114 # Filter rows based on section
85115 section_rows = [row for row in section_rows if row ["section" ] == section ]
86116
87- # Loop the section rows to check if we need to import choices, custom conditionals, input_range, or custom widgets
88- has_choices_import = False
89- has_conditionals_import = False
90- has_input_range_import = False
91- has_custom_widgets_import = False
92- has_custom_validations_import = False
93- has_custom_conditionals_import = False
94- has_help_popup_import = False
95- has_nickname_label = False
96- has_persons_count_label = False
97- has_gendered_suffix_label = False
98- for row in section_rows :
99- if row ["choices" ]:
100- has_choices_import = True
101- if row ["validation" ].endswith ("CustomValidation" ):
102- # Check to see if the validation finish with 'CustomValidation'
103- has_custom_validations_import = True
104- if row ["conditional" ] and row ["conditional" ].endswith (
105- "CustomConditional"
106- ):
107- # Check to see if the conditional finish with 'CustomConditional'
108- has_custom_conditionals_import = True
109- elif row ["conditional" ] and not row ["conditional" ].endswith (
110- "CustomConditional"
111- ):
112- # Check to see if the conditional is not empty and does not finish with 'CustomConditional'
113- has_conditionals_import = True
114- if row ["inputRange" ]:
115- has_input_range_import = True
116- if row ["inputType" ] == "Custom" :
117- has_custom_widgets_import = True
118- if row ["help_popup" ] or row ["confirm_popup" ]:
119- has_help_popup_import = True
120-
121- # Check all rows for label context
122- for row in section_rows :
123- label_fr = row .get ("label::fr" , "" )
124- label_en = row .get ("label::en" , "" )
125- if "{{nickname}}" in label_fr or "{{nickname}}" in label_en :
126- # Check if the label contains '{{nickname}}'
127- has_nickname_label = True
128- if "{{count}}" in label_fr or "{{count}}" in label_en :
129- # Check if the label contains '{{count}}'
130- has_persons_count_label = True
131- if "{{genderedSuffix" in label_fr or "{{genderedSuffix:" in label_en :
132- # Check if the label contains '{{genderedSuffix:...}}'
133- has_gendered_suffix_label = True
117+ # Get the widgets file import flags
118+ import_flags = get_widgets_file_import_flags (section_rows )
134119
135120 # Generate widgets statements
136121 widget_results = [generate_widget_statement (row ) for row in section_rows ]
137- has_helper_import = any (
122+
123+ # Check if any widget has specific import flags and update import_flags accordingly
124+ import_flags .has_helper_import = any (
138125 result ["has_helper_import" ] for result in widget_results
139126 )
140- has_formatter_import = any (
127+ import_flags . has_formatter_import = any (
141128 result .get ("has_formatter_import" ) for result in widget_results
142129 )
143- has_custom_formatter_import = any (
130+ import_flags . has_custom_formatter_import = any (
144131 result .get ("has_custom_formatter_import" ) for result in widget_results
145132 )
146133
147134 # Generate import statements
148- import_statements = generate_import_statements (
149- has_choices_import ,
150- has_conditionals_import ,
151- has_input_range_import ,
152- has_custom_widgets_import ,
153- has_custom_validations_import ,
154- has_custom_conditionals_import ,
155- has_help_popup_import ,
156- has_nickname_label ,
157- has_persons_count_label ,
158- has_gendered_suffix_label ,
159- has_helper_import ,
160- has_formatter_import ,
161- has_custom_formatter_import ,
162- )
135+ import_statements = generate_import_statements (import_flags = import_flags )
163136
137+ # Generate the widgets statements
164138 widgets_statements = [result ["statement" ] for result in widget_results ]
165139 widgets_statements = (
166140 f"{ import_statements } \n { '\n \n ' .join (widgets_statements )} \n "
@@ -376,72 +350,87 @@ def generate_widgets_names_statements(section_rows):
376350
377351
378352# Generate import statement if needed
379- def generate_import_statements (
380- has_choices_import ,
381- has_conditionals_import ,
382- has_input_range_import ,
383- has_custom_widgets_import ,
384- has_custom_validations_import ,
385- has_custom_conditionals_import ,
386- has_help_popup_import ,
387- has_nickname_label ,
388- has_persons_count_label ,
389- has_gendered_suffix_label ,
390- has_helper_import = False ,
391- has_formatter_import = False ,
392- has_custom_formatter_import = False ,
393- ):
394- od_survey_helpers_import = ""
395- if has_nickname_label or has_gendered_suffix_label or has_persons_count_label :
396- od_survey_helpers_import = "import * as odSurveyHelpers from 'evolution-common/lib/services/odSurvey/helpers';\n "
397-
353+ def generate_import_statements (import_flags : ImportFlags ) -> str :
354+ od_survey_helpers_import = (
355+ "import * as odSurveyHelpers from 'evolution-common/lib/services/odSurvey/helpers';\n "
356+ if (
357+ import_flags .has_nickname_label
358+ or import_flags .has_gendered_suffix_label
359+ or import_flags .has_persons_count_label
360+ )
361+ else ""
362+ )
398363 choices_import = (
399- "// " if not has_choices_import else ""
400- ) + "import * as choices from '../../common/choices';\n "
364+ "import * as choices from '../../common/choices';\n "
365+ if import_flags .has_choices_import
366+ else ""
367+ )
368+ custom_choices_import = (
369+ "import * as customChoices from './customChoices';\n "
370+ if import_flags .has_custom_choices_import
371+ else ""
372+ )
401373 conditionals_import = (
402- "// " if not has_conditionals_import else ""
403- ) + "import * as conditionals from '../../common/conditionals';\n "
374+ "import * as conditionals from '../../common/conditionals';\n "
375+ if import_flags .has_conditionals_import
376+ else ""
377+ )
404378 custom_widgets_import = (
405- "// " if not has_custom_widgets_import else ""
406- ) + "import * as customWidgets from './customWidgets';\n "
379+ "import * as customWidgets from './customWidgets';\n "
380+ if import_flags .has_custom_widgets_import
381+ else ""
382+ )
383+ validations_import = (
384+ "import * as validations from 'evolution-common/lib/services/widgets/validations/validations';\n "
385+ if import_flags .has_validations_import
386+ else ""
387+ )
407388 custom_validations_import = (
408- "// " if not has_custom_validations_import else ""
409- ) + "import * as customValidations from '../../common/customValidations';\n "
389+ "import * as customValidations from '../../common/customValidations';\n "
390+ if import_flags .has_custom_validations_import
391+ else ""
392+ )
410393 custom_conditionals_import = (
411- "// " if not has_custom_conditionals_import else ""
412- ) + "import * as customConditionals from '../../common/customConditionals';\n "
394+ "import * as customConditionals from '../../common/customConditionals';\n "
395+ if import_flags .has_custom_conditionals_import
396+ else ""
397+ )
413398 custom_help_popup_import = (
414- "// " if not has_help_popup_import else ""
415- ) + "import * as customHelpPopup from '../../common/customHelpPopup';\n "
399+ "import * as customHelpPopup from '../../common/customHelpPopup';\n "
400+ if import_flags .has_help_popup_import
401+ else ""
402+ )
416403 input_range_import = (
417- "// " if not has_input_range_import else ""
418- ) + "import * as inputRange from '../../common/inputRange';\n "
404+ "import * as inputRange from '../../common/inputRange';\n "
405+ if import_flags .has_input_range_import
406+ else ""
407+ )
419408 gendered_suffix_import = (
420409 "import { getGenderedSuffixes } from '../../helperFunctions/frontendHelper';\n "
421- if has_gendered_suffix_label == True
410+ if import_flags . has_gendered_suffix_label
422411 else ""
423412 )
424413 survey_helper_import = (
425414 "import * as surveyHelper from 'evolution-common/lib/utils/helpers';\n "
426- if has_helper_import == True
415+ if import_flags . has_helper_import
427416 else ""
428417 )
429418 formatter_import = (
430419 "import * as formatters from 'evolution-common/lib/utils/formatters';\n "
431- if has_formatter_import == True
420+ if import_flags . has_formatter_import
432421 else ""
433422 )
434423 custom_formatter_import = (
435424 "import * as customFormatters from '../../common/customFormatters';\n "
436- if has_custom_formatter_import == True
425+ if import_flags . has_custom_formatter_import
437426 else ""
438427 )
439428 return (
440429 f"import {{ TFunction }} from 'i18next';\n "
441430 f"import * as defaultInputBase from 'evolution-frontend/lib/components/inputs/defaultInputBase';\n "
442431 f"import {{ defaultConditional }} from 'evolution-common/lib/services/widgets/conditionals/defaultConditional';\n "
443432 f"import * as WidgetConfig from 'evolution-common/lib/services/questionnaire/types';\n "
444- f"import * as validations from 'evolution-common/lib/services/widgets/validations/validations'; \n "
433+ f"{ validations_import } "
445434 f"{ od_survey_helpers_import } "
446435 f"{ survey_helper_import } "
447436 f"{ choices_import } "
@@ -451,6 +440,7 @@ def generate_import_statements(
451440 f"{ gendered_suffix_import } "
452441 f"{ custom_conditionals_import } "
453442 f"{ custom_widgets_import } "
443+ f"{ custom_choices_import } "
454444 f"{ custom_help_popup_import } "
455445 f"{ custom_validations_import } "
456446 f"{ custom_formatter_import } "
@@ -581,6 +571,20 @@ def generate_confirm_popup(confirm_popup, comma=True, skip_line=True):
581571
582572
583573def generate_choices (choices ):
574+ """
575+ Generates the TypeScript 'choices' property for a widget.
576+
577+ If the choices string ends with 'CustomChoices' (case-insensitive), returns 'choices: customChoices.{choices}'.
578+ Otherwise, returns 'choices: choices.{choices}'.
579+
580+ Args:
581+ choices (str): The choices identifier from the Excel row.
582+
583+ Returns:
584+ str: The TypeScript code for the choices property.
585+ """
586+ if choices .lower ().endswith ("customchoices" ):
587+ return f"{ INDENT } choices: customChoices.{ choices } "
584588 return f"{ INDENT } choices: choices.{ choices } "
585589
586590
@@ -1014,8 +1018,8 @@ def get_string_parameters(row) -> StringParametersResult:
10141018 Returns a dict with keys: formatter.
10151019 Prints warnings for invalid or unrecognized parameters.
10161020 Example valid formats:
1017- - "formatter=eightDigitsAccessCodeFormatter"
1018- - "formatter=someFieldCustomFormatter"
1021+ - "formatter=eightDigitsAccessCodeFormatter"
1022+ - "formatter=someFieldCustomFormatter"
10191023 """
10201024 parameters = row .get ("parameters" , "" )
10211025
@@ -1033,3 +1037,56 @@ def get_string_parameters(row) -> StringParametersResult:
10331037 )
10341038
10351039 return result
1040+
1041+
1042+ def get_widgets_file_import_flags (section_rows ) -> ImportFlags :
1043+ """
1044+ Analyze the section_rows and determine which import flags should be set to True.
1045+
1046+ Returns an ImportFlags dataclass with all the import flag booleans.
1047+ """
1048+ import_flags = ImportFlags ()
1049+
1050+ # Check all rows for import flags
1051+ for row in section_rows :
1052+ if row ["choices" ]:
1053+ # Check to see if the choices finish with 'CustomChoices'
1054+ if row ["choices" ].lower ().endswith ("customchoices" ):
1055+ import_flags .has_custom_choices_import = True
1056+ else :
1057+ import_flags .has_choices_import = True
1058+ if row ["validation" ]:
1059+ # Check to see if the validation finish with 'CustomValidation'
1060+ if row ["validation" ].lower ().endswith ("customvalidation" ):
1061+ import_flags .has_custom_validations_import = True
1062+ else :
1063+ import_flags .has_validations_import = True
1064+ if row ["conditional" ] and row ["conditional" ].lower ().endswith (
1065+ "customconditional"
1066+ ):
1067+ # Check to see if the conditional finish with 'CustomConditional'
1068+ import_flags .has_custom_conditionals_import = True
1069+ elif row ["conditional" ] and not row ["conditional" ].lower ().endswith (
1070+ "customconditional"
1071+ ):
1072+ # Check to see if the conditional is not empty and does not finish with 'CustomConditional'
1073+ import_flags .has_conditionals_import = True
1074+ if row ["inputRange" ]:
1075+ import_flags .has_input_range_import = True
1076+ if row ["inputType" ] == "Custom" :
1077+ import_flags .has_custom_widgets_import = True
1078+ if row ["help_popup" ] or row ["confirm_popup" ]:
1079+ import_flags .has_help_popup_import = True
1080+
1081+ # Check all rows for label context
1082+ label_fr = row .get ("label::fr" , "" )
1083+ label_en = row .get ("label::en" , "" )
1084+ # Check for {{nickname}}, {{count}}, and {{genderedSuffix:...}} in labels
1085+ if "{{nickname}}" in label_fr or "{{nickname}}" in label_en :
1086+ import_flags .has_nickname_label = True
1087+ if "{{count}}" in label_fr or "{{count}}" in label_en :
1088+ import_flags .has_persons_count_label = True
1089+ if "{{genderedSuffix" in label_fr or "{{genderedSuffix" in label_en :
1090+ import_flags .has_gendered_suffix_label = True
1091+
1092+ return import_flags
0 commit comments