@inseefr/lunatic 0.2.3-experimental → 0.2.3-prisme

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.
Files changed (230) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +25 -23
  3. package/lib/index.js +1191 -475
  4. package/lib/index.js.map +1 -1
  5. package/package.json +174 -172
  6. package/src/components/breadcrumb/breadcrumb.scss +22 -22
  7. package/src/components/checkbox/boolean.js +172 -172
  8. package/src/components/checkbox/checkbox.scss +73 -73
  9. package/src/components/checkbox/group.js +231 -231
  10. package/src/components/checkbox/one.js +11 -11
  11. package/src/components/component-wrapper/controls/component.js +70 -0
  12. package/src/components/component-wrapper/controls/controls.scss +6 -0
  13. package/src/components/component-wrapper/controls/index.js +1 -0
  14. package/src/components/component-wrapper/controls/validators/datepicker.js +44 -0
  15. package/src/components/component-wrapper/controls/validators/index.js +16 -0
  16. package/src/components/component-wrapper/controls/validators/input-number.js +23 -0
  17. package/src/components/{missing-wrapper → component-wrapper}/index.js +0 -0
  18. package/src/components/component-wrapper/missing/component.js +200 -0
  19. package/src/components/component-wrapper/missing/index.js +1 -0
  20. package/src/components/{missing-wrapper → component-wrapper/missing}/missing.scss +32 -32
  21. package/src/components/component-wrapper/wrapper.js +23 -0
  22. package/src/components/components.js +1 -0
  23. package/src/components/datepicker/component.js +26 -11
  24. package/src/components/declarations/component.js +46 -46
  25. package/src/components/declarations/declarations.scss +40 -40
  26. package/src/components/declarations/wrappers/input-declarations-wrapper.js +328 -274
  27. package/src/components/declarations/wrappers/simple-declarations-wrapper.js +54 -54
  28. package/src/components/dropdown/commons/actions.js +65 -56
  29. package/src/components/dropdown/commons/children-to-option.js +9 -9
  30. package/src/components/dropdown/commons/cleaner-callbacks.js +58 -58
  31. package/src/components/dropdown/commons/components/dropdown-container.js +29 -29
  32. package/src/components/dropdown/commons/components/dropdown.js +204 -183
  33. package/src/components/dropdown/commons/event-callbacks/on-mousedown-callback.js +15 -15
  34. package/src/components/dropdown/commons/reducer.js +3 -0
  35. package/src/components/dropdown/commons/tools/index.js +17 -17
  36. package/src/components/dropdown/component.js +135 -135
  37. package/src/components/dropdown/dropdown-edit/dropdown-edit.js +194 -185
  38. package/src/components/dropdown/dropdown-edit/index.js +11 -11
  39. package/src/components/dropdown/dropdown-simple/dropdown.js +173 -164
  40. package/src/components/dropdown/dropdown-simple/index.js +20 -20
  41. package/src/components/dropdown/dropdown.scss +178 -178
  42. package/src/components/icon/icon.scss +15 -15
  43. package/src/components/index.js +2 -0
  44. package/src/components/index.scss +177 -175
  45. package/src/components/input/input-number.js +30 -54
  46. package/src/components/input/input.js +11 -11
  47. package/src/components/input/input.scss +31 -37
  48. package/src/components/loop/component.js +170 -169
  49. package/src/components/loop/loop.scss +13 -13
  50. package/src/components/loop/wrapper.js +1 -1
  51. package/src/components/loop-constructor/block/block.scss +10 -10
  52. package/src/components/loop-constructor/block/component.js +9 -9
  53. package/src/components/loop-constructor/roster/component.js +8 -8
  54. package/src/components/loop-constructor/wrapper/body-component.js +146 -125
  55. package/src/components/loop-constructor/wrapper/component.js +190 -190
  56. package/src/components/modal/component.js +36 -0
  57. package/src/components/modal/index.js +1 -0
  58. package/src/components/modal/modal.scss +33 -0
  59. package/src/components/progress-bar/progress-bar.scss +54 -54
  60. package/src/components/radio/component.js +9 -9
  61. package/src/components/radio/radio.scss +59 -59
  62. package/src/components/sequence/component.js +50 -50
  63. package/src/components/sequence/sequence.scss +10 -10
  64. package/src/components/subsequence/component.js +49 -49
  65. package/src/components/suggester/check-store.js +2 -4
  66. package/src/components/suggester/components/panel/default-option-renderer.js +27 -27
  67. package/src/components/suggester/components/panel/option-container.js +61 -61
  68. package/src/components/suggester/components/panel/panel.js +47 -47
  69. package/src/components/suggester/components/selection/default-label-renderer.js +31 -31
  70. package/src/components/suggester/components/selection/label.js +35 -35
  71. package/src/components/suggester/components/selection/selection.js +50 -50
  72. package/src/components/suggester/components/suggester-content.js +2 -2
  73. package/src/components/suggester/components/suggester.js +128 -88
  74. package/src/components/suggester/components/suggester.scss +101 -101
  75. package/src/components/suggester/default-style.scss +125 -125
  76. package/src/components/suggester/find-best-label/find-best-label.js +51 -49
  77. package/src/components/suggester/find-best-label/index.js +1 -1
  78. package/src/components/suggester/idb-suggester.js +73 -67
  79. package/src/components/suggester/lunatic-suggester.js +140 -137
  80. package/src/components/suggester/searching/create-searching.js +49 -47
  81. package/src/components/suggester/searching/index.js +1 -1
  82. package/src/components/suggester/state-management/actions.js +38 -38
  83. package/src/components/suggester/state-management/reducer/reduce-on-delete-search.js +11 -11
  84. package/src/components/suggester/state-management/reducer/reduce-on-init.js +29 -29
  85. package/src/components/suggester/state-management/reducer/reducer.js +38 -38
  86. package/src/components/suggester/suggester-wrapper.js +127 -121
  87. package/src/components/suggester-loader-widget/loader.js +67 -67
  88. package/src/components/suggester-loader-widget/widget.js +123 -123
  89. package/src/components/table/table.js +173 -171
  90. package/src/components/table/table.scss +26 -26
  91. package/src/components/textarea/component.js +11 -11
  92. package/src/components/textarea/textarea.scss +8 -8
  93. package/src/components/tooltip/tooltip.scss +30 -30
  94. package/src/stories/breadcrumb/breadcrumb.stories.js +21 -21
  95. package/src/stories/checkbox-boolean/data.json +78 -78
  96. package/src/stories/datepicker/data.json +3 -1
  97. package/src/stories/declarations/declarations.stories.js +116 -116
  98. package/src/stories/dropdown/README.md +44 -44
  99. package/src/stories/dropdown/data.json +98 -98
  100. package/src/stories/dropdown/dropdown.stories.js +89 -89
  101. package/src/stories/progress-bar/progress-bar.stories.js +24 -24
  102. package/src/stories/questionnaire/arithmetic-management.json +47 -0
  103. package/src/stories/questionnaire/arithmetic.json +247 -247
  104. package/src/stories/questionnaire/calc-var.json +187 -187
  105. package/src/stories/questionnaire/data-logement.json +2691 -2691
  106. package/src/stories/questionnaire/kish.json +275 -0
  107. package/src/stories/questionnaire/logement-queen.json +23390 -0
  108. package/src/stories/questionnaire/logement-s2.json +46028 -44537
  109. package/src/stories/questionnaire/logement-sequence.json +26741 -26741
  110. package/src/stories/questionnaire/logement.json +21073 -26813
  111. package/src/stories/questionnaire/loop-and-controls.json +481 -0
  112. package/src/stories/questionnaire/questionnaire.stories.js +236 -154
  113. package/src/stories/questionnaire/update-external/data.json +1 -0
  114. package/src/stories/questionnaire/update-external/questionnaire.json +75 -0
  115. package/src/stories/sequence/sequence.stories.js +32 -32
  116. package/src/stories/subsequence/subsequence.stories.js +32 -32
  117. package/src/stories/suggester/README.md +46 -46
  118. package/src/stories/suggester/bailleurs-sociaux/fetch-bailleurs.js +15 -15
  119. package/src/stories/suggester/bailleurs-sociaux/index.js +2 -2
  120. package/src/stories/suggester/bailleurs-sociaux/option-bailleur-renderer.js +58 -58
  121. package/src/stories/suggester/bailleurs-sociaux/preloader.svg +51 -51
  122. package/src/stories/suggester/bailleurs-sociaux/theme.scss +22 -22
  123. package/src/stories/suggester/bailleurs-sociaux-2021/fetch-bailleurs.js +12 -0
  124. package/src/stories/suggester/bailleurs-sociaux-2021/index.js +1 -0
  125. package/src/stories/suggester/cog-communes/fetch-cog.js +15 -15
  126. package/src/stories/suggester/data-auto.json +232 -231
  127. package/src/stories/suggester/data-vtl.json +82 -82
  128. package/src/stories/suggester/data.json +169 -136
  129. package/src/stories/suggester/naf-rev2/index.js +2 -2
  130. package/src/stories/suggester/naf-rev2/option-naf-renderer.js +17 -17
  131. package/src/stories/suggester/suggester-workers.stories.js +226 -179
  132. package/src/stories/suggester/suggester.stories.js +138 -133
  133. package/src/stories/utils/orchestrator-split.js +119 -0
  134. package/src/stories/utils/orchestrator.js +119 -108
  135. package/src/tests/components/input-number.spec.js +6 -12
  136. package/src/tests/components/loops/roster-loop.json +71 -71
  137. package/src/tests/components/missing-wrapper.spec.js +0 -1
  138. package/src/tests/utils/lib/table/roster.spec.js +25 -25
  139. package/src/tests/utils/to-expose/handler/results/res-input-edited.json +1 -1
  140. package/src/tests/utils/to-expose/init-questionnaire/questionnaire.json +148 -148
  141. package/src/tests/utils/to-expose/init-questionnaire/result.json +181 -181
  142. package/src/utils/components/dragger/dragger.scss +7 -7
  143. package/src/utils/idb-tools/create-db-opener.js +43 -43
  144. package/src/utils/idb-tools/create-open-db.js +25 -25
  145. package/src/utils/idb-tools/idb-bulk-insert.js +96 -96
  146. package/src/utils/idb-tools/index.js +10 -10
  147. package/src/utils/idb-tools/insert-entity.js +15 -15
  148. package/src/utils/idb-tools/open-db.js +13 -13
  149. package/src/utils/idb-tools/open-or-create-db.js +34 -34
  150. package/src/utils/lib/controls/index.js +1 -0
  151. package/src/utils/lib/controls/utils.js +152 -0
  152. package/src/utils/lib/decorator/title-decorator.js +16 -16
  153. package/src/utils/lib/env.js +2 -2
  154. package/src/utils/lib/index.js +2 -0
  155. package/src/utils/lib/input-number.js +1 -1
  156. package/src/utils/lib/options-positioning.js +9 -9
  157. package/src/utils/lib/pagination/navigation/shared.js +256 -253
  158. package/src/utils/lib/prop-types/lines.js +6 -6
  159. package/src/utils/lib/responses.js +11 -9
  160. package/src/utils/lib/splitting.js +142 -0
  161. package/src/utils/lib/style.js +10 -10
  162. package/src/utils/store-tools/auto-load.js +74 -73
  163. package/src/utils/suggester-workers/append-to-index/append.js +25 -25
  164. package/src/utils/suggester-workers/append-to-index/append.worker.js +16 -16
  165. package/src/utils/suggester-workers/append-to-index/create-append-task.js +45 -43
  166. package/src/utils/suggester-workers/append-to-index/index.js +2 -2
  167. package/src/utils/suggester-workers/append-to-index/prepare-entities.js +61 -61
  168. package/src/utils/suggester-workers/append-to-index/store-messages.js +21 -21
  169. package/src/utils/suggester-workers/commons-tokenizer/create-entity-tokenizer.js +56 -0
  170. package/src/utils/suggester-workers/commons-tokenizer/create-fields-tokenizer.js +56 -0
  171. package/src/utils/suggester-workers/commons-tokenizer/create-filter-stop-words.js +17 -17
  172. package/src/utils/suggester-workers/commons-tokenizer/filters/compose-filters.js +10 -0
  173. package/src/utils/suggester-workers/commons-tokenizer/filters/create-filter-stop-words.js +17 -0
  174. package/src/utils/suggester-workers/commons-tokenizer/filters/create-filter-stop-words.spec.js +14 -0
  175. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-accents.js +12 -0
  176. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-accents.spec.js +12 -0
  177. package/src/utils/suggester-workers/commons-tokenizer/{filter-double.js → filters/filter-double.js} +12 -12
  178. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-double.spec.js +20 -0
  179. package/src/utils/suggester-workers/commons-tokenizer/{filter-length.js → filters/filter-length.js} +7 -7
  180. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-length.spec.js +18 -0
  181. package/src/utils/suggester-workers/commons-tokenizer/{filter-stemmer.js → filters/filter-stemmer.js} +13 -13
  182. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-stemmer.spec.js +12 -0
  183. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.js +36 -0
  184. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.spec.js +12 -0
  185. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.js +10 -0
  186. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.spec.js +12 -0
  187. package/src/utils/suggester-workers/commons-tokenizer/filters/index.js +2 -0
  188. package/src/utils/suggester-workers/commons-tokenizer/{stop-words.js → filters/stop-words.js} +118 -118
  189. package/src/utils/suggester-workers/commons-tokenizer/get-regexp-from-pattern.js +8 -8
  190. package/src/utils/suggester-workers/commons-tokenizer/get-stemmer.js +18 -18
  191. package/src/utils/suggester-workers/commons-tokenizer/index.js +9 -8
  192. package/src/utils/suggester-workers/commons-tokenizer/prepare-string-indexation.js +13 -9
  193. package/src/utils/suggester-workers/commons-tokenizer/soft-tokenizer.js +7 -7
  194. package/src/utils/suggester-workers/create-worker.js +56 -0
  195. package/src/utils/suggester-workers/find-best-label/find-best-label.js +39 -39
  196. package/src/utils/suggester-workers/find-best-label/find-best-label.worker.js +40 -40
  197. package/src/utils/suggester-workers/find-best-label/tokenize.js +30 -33
  198. package/src/utils/suggester-workers/find-best-label/tokenize.spec.js +19 -19
  199. package/src/utils/suggester-workers/searching/compute-score.js +33 -33
  200. package/src/utils/suggester-workers/searching/get-db.js +18 -18
  201. package/src/utils/suggester-workers/searching/index.js +1 -1
  202. package/src/utils/suggester-workers/searching/order/create-alphanumeric-orderer.js +20 -20
  203. package/src/utils/suggester-workers/searching/order/index.js +19 -19
  204. package/src/utils/suggester-workers/{query-parser → searching/query-parser}/index.js +2 -2
  205. package/src/utils/suggester-workers/searching/query-parser/query-parser-soft.js +7 -0
  206. package/src/utils/suggester-workers/{query-parser → searching/query-parser}/query-parser-soft.spec.js +24 -24
  207. package/src/utils/suggester-workers/searching/query-parser/query-parser-tokenized.js +34 -0
  208. package/src/utils/suggester-workers/searching/resolve-query-parser.js +27 -27
  209. package/src/utils/suggester-workers/searching/search-in-index.js +17 -17
  210. package/src/utils/suggester-workers/searching/searching.js +70 -70
  211. package/src/utils/suggester-workers/searching/searching.worker.js +11 -11
  212. package/src/utils/to-expose/calculated-variables.js +113 -113
  213. package/src/utils/to-expose/handler.js +149 -112
  214. package/src/utils/to-expose/hooks/filter-components.js +27 -12
  215. package/src/utils/to-expose/hooks/index.js +2 -1
  216. package/src/utils/to-expose/hooks/lunatic-split.js +428 -0
  217. package/src/utils/to-expose/hooks/lunatic.js +284 -188
  218. package/src/utils/to-expose/index.js +1 -1
  219. package/src/utils/to-expose/init-questionnaire.js +164 -164
  220. package/src/utils/to-expose/interpret/vtl.js +18 -18
  221. package/src/utils/to-expose/state.js +66 -58
  222. package/src/components/missing-wrapper/component.js +0 -120
  223. package/src/components/missing-wrapper/wrapper.js +0 -10
  224. package/src/tests/utils/to-expose/hooks/use-lunatic.spec.js +0 -46
  225. package/src/utils/suggester-workers/commons-tokenizer/create-tokenizer.js +0 -103
  226. package/src/utils/suggester-workers/commons-tokenizer/filter-accents-to-lower.js +0 -9
  227. package/src/utils/suggester-workers/commons-tokenizer/filter-synonyms.js +0 -10
  228. package/src/utils/suggester-workers/query-parser/query-parser-soft.js +0 -7
  229. package/src/utils/suggester-workers/query-parser/query-parser-tokenized.js +0 -31
  230. package/src/utils/suggester-workers/query-parser/query-parser-tokenized.spec.js +0 -32
@@ -1,125 +1,146 @@
1
- import React from 'react';
2
- import * as lunatic from '../../components';
3
- import * as U from '../../../utils/lib';
4
- import { interpret } from '../../../utils/to-expose';
5
- import { buildContentForLoopConstructor } from './build-components';
6
-
7
- const BodyComponent = ({
8
- componentType,
9
- mainId,
10
- headers,
11
- components,
12
- bindings,
13
- width,
14
- preferences,
15
- positioning,
16
- management,
17
- features,
18
- setTodo,
19
- logFunction,
20
- ...otherProps
21
- }) => {
22
- const uiComponents = buildContentForLoopConstructor({
23
- components,
24
- headers,
25
- });
26
- if (componentType === 'RosterForLoop')
27
- return (
28
- <table id={`table-${mainId}`} className="table-lunatic">
29
- <tbody>
30
- {uiComponents.map((row, i) => (
31
- <tr key={`table-${mainId}-row${i}`}>
32
- {row.map((component, j) => {
33
- const {
34
- label,
35
- headerCell,
36
- colspan,
37
- rowspan,
38
- componentType,
39
- id,
40
- rowNumber,
41
- ...componentProps
42
- } = component;
43
- const localBindings =
44
- U.buildBindingsForDeeperComponents(rowNumber)(bindings);
45
- if (componentType) {
46
- const Component = lunatic[componentType];
47
- return (
48
- <td
49
- key={`table-${mainId}-row-${i}-cell-${j}`}
50
- style={{ width }}
51
- >
52
- <Component
53
- {...otherProps}
54
- {...componentProps}
55
- id={`${id}-row-${i}`}
56
- label={label}
57
- handleChange={(up) => {
58
- setTodo({ up, rowNumber });
59
- }}
60
- preferences={preferences}
61
- positioning={positioning}
62
- management={management}
63
- features={features}
64
- bindings={localBindings}
65
- zIndex={uiComponents.length - i || 0}
66
- logFunction={logFunction}
67
- />
68
- </td>
69
- );
70
- }
71
- const cellOptions = {
72
- key: `table-${mainId}-row-${i}-cell-${j}`,
73
- style: { width },
74
- colSpan: colspan || 1,
75
- rowSpan: rowspan || 1,
76
- };
77
- const interpretedLabel = interpret(
78
- features,
79
- logFunction
80
- )(bindings)(label);
81
- return headerCell ? (
82
- <th {...cellOptions}>{interpretedLabel}</th>
83
- ) : (
84
- <td {...cellOptions}>{interpretedLabel}</td>
85
- );
86
- })}
87
- </tr>
88
- ))}
89
- </tbody>
90
- </table>
91
- );
92
- else
93
- return (
94
- <div className="block-for-loop">
95
- {uiComponents.map((row, i) =>
96
- row.map(({ componentType, id, label, ...componentProps }) => {
97
- const Component = lunatic[componentType];
98
- const localBindings =
99
- U.buildBindingsForDeeperComponents(i)(bindings);
100
- return (
101
- <div className="block-component" key={`${id}-row-${i}`}>
102
- <Component
103
- {...otherProps}
104
- {...componentProps}
105
- id={`${id}-row-${i}`}
106
- label={label}
107
- handleChange={(up) => {
108
- setTodo({ up, rowNumber: i });
109
- }}
110
- preferences={preferences}
111
- positioning={positioning}
112
- management={management}
113
- features={features}
114
- bindings={localBindings}
115
- logFunction={logFunction}
116
- />
117
- </div>
118
- );
119
- })
120
- )}
121
- </div>
122
- );
123
- };
124
-
125
- export default BodyComponent;
1
+ import React from 'react';
2
+ import * as lunatic from '../../components';
3
+ import * as U from '../../../utils/lib';
4
+ import { interpret } from '../../../utils/to-expose';
5
+ import { buildContentForLoopConstructor } from './build-components';
6
+
7
+ const BodyComponent = ({
8
+ componentType,
9
+ mainId,
10
+ headers,
11
+ components,
12
+ bindings,
13
+ width,
14
+ preferences,
15
+ positioning,
16
+ management,
17
+ features,
18
+ setTodo,
19
+ logFunction,
20
+ ...otherProps
21
+ }) => {
22
+ const uiComponents = buildContentForLoopConstructor({
23
+ components,
24
+ headers,
25
+ });
26
+ const featuresWithoutMD = features.filter((f) => f !== 'MD');
27
+ if (componentType === 'RosterForLoop')
28
+ return (
29
+ <table id={`table-${mainId}`} className="table-lunatic">
30
+ <tbody>
31
+ {uiComponents.map((row, i) => (
32
+ <tr key={`table-${mainId}-row${i}`}>
33
+ {row.map((component, j) => {
34
+ const {
35
+ label,
36
+ headerCell,
37
+ colspan,
38
+ rowspan,
39
+ componentType,
40
+ id,
41
+ rowNumber,
42
+ conditionFilter,
43
+ ...componentProps
44
+ } = component;
45
+ const localBindings =
46
+ U.buildBindingsForDeeperComponents(rowNumber)(bindings);
47
+ if (conditionFilter) {
48
+ const { value = '' } = conditionFilter;
49
+ if (!interpret(featuresWithoutMD)(localBindings)(value))
50
+ return null;
51
+ }
52
+ if (componentType) {
53
+ const Component = lunatic[componentType];
54
+ return (
55
+ <td
56
+ key={`table-${mainId}-row-${i}-cell-${j}`}
57
+ style={{ width }}
58
+ >
59
+ <Component
60
+ {...otherProps}
61
+ {...componentProps}
62
+ id={`${id}-row-${i}`}
63
+ label={label}
64
+ handleChange={(up) => {
65
+ setTodo({ up, rowNumber });
66
+ }}
67
+ preferences={preferences}
68
+ positioning={positioning}
69
+ management={management}
70
+ features={features}
71
+ bindings={localBindings}
72
+ fullBindings={bindings}
73
+ missingLoopIteration={i}
74
+ zIndex={uiComponents.length - i || 0}
75
+ logFunction={logFunction}
76
+ focused={i === 0 && j === 0}
77
+ />
78
+ </td>
79
+ );
80
+ }
81
+ const cellOptions = {
82
+ key: `table-${mainId}-row-${i}-cell-${j}`,
83
+ style: { width },
84
+ colSpan: colspan || 1,
85
+ rowSpan: rowspan || 1,
86
+ };
87
+ const interpretedLabel = interpret(
88
+ features,
89
+ logFunction
90
+ )(bindings)(label);
91
+ return headerCell ? (
92
+ <th {...cellOptions}>{interpretedLabel}</th>
93
+ ) : (
94
+ <td {...cellOptions}>{interpretedLabel}</td>
95
+ );
96
+ })}
97
+ </tr>
98
+ ))}
99
+ </tbody>
100
+ </table>
101
+ );
102
+ else
103
+ return (
104
+ <div className="block-for-loop">
105
+ {uiComponents.map((row, i) =>
106
+ row.map(({ componentType, id, label, ...componentProps }) => {
107
+ const Component = lunatic[componentType];
108
+ const localBindings =
109
+ U.buildBindingsForDeeperComponents(i)(bindings);
110
+ // ensure to have only N-1 missingResponse
111
+ const { missingResponse, conditionFilter } = componentProps;
112
+ if (conditionFilter) {
113
+ const { value = '' } = conditionFilter;
114
+ if (!interpret(featuresWithoutMD)(localBindings)(value))
115
+ return null;
116
+ }
117
+ return (
118
+ <div className="block-component" key={`${id}-row-${i}`}>
119
+ <Component
120
+ {...otherProps}
121
+ {...componentProps}
122
+ missingResponse={missingResponse}
123
+ id={`${id}-row-${i}`}
124
+ label={label}
125
+ handleChange={(up) => {
126
+ setTodo({ up, rowNumber: i });
127
+ }}
128
+ preferences={preferences}
129
+ positioning={positioning}
130
+ management={management}
131
+ features={features}
132
+ bindings={localBindings}
133
+ fullBindings={bindings}
134
+ missingLoopIteration={i}
135
+ logFunction={logFunction}
136
+ focused={i === 0}
137
+ />
138
+ </div>
139
+ );
140
+ })
141
+ )}
142
+ </div>
143
+ );
144
+ };
145
+
146
+ export default BodyComponent;
@@ -1,190 +1,190 @@
1
- import React, { useState, useEffect } from 'react';
2
- import PropTypes from 'prop-types';
3
- import * as lunatic from '../../components';
4
- import BodyComponent from './body-component';
5
- import Declarations from '../../declarations';
6
- import * as U from '../../../utils/lib';
7
- import * as C from '../../../constants';
8
- import { interpret } from '../../../utils/to-expose';
9
-
10
- const LoopConstructorWrapper = ({
11
- id: mainId,
12
- label: mainLabel,
13
- components,
14
- handleChange,
15
- lines,
16
- declarations,
17
- features,
18
- bindings,
19
- addBtnLabel,
20
- hideBtn,
21
- componentType,
22
- ...otherProps
23
- }) => {
24
- const [todo, setTodo] = useState({});
25
-
26
- const featuresWithoutMD = features.filter((f) => f !== 'MD');
27
-
28
- const minLines = Math.max(
29
- parseInt(interpret(featuresWithoutMD)(bindings)(lines.min), 10) || 1,
30
- U.getLoopConstructorInitLines(components)
31
- );
32
- const maxLines = lines
33
- ? parseInt(interpret(featuresWithoutMD)(bindings)(lines.max), 10)
34
- : undefined;
35
-
36
- const width = `${100 / Math.max(...components.map((row) => row.length))}%`;
37
- const Button = lunatic.Button;
38
- const involvedVariables = U.getInvolvedVariables(components);
39
-
40
- const values = components.reduce(
41
- (acc, c) => `${acc}|${Object.values(c.response?.values || {}).join('|')}`,
42
- ''
43
- );
44
-
45
- // TEMP: Set static number of occurence if min = max
46
- useEffect(() => {
47
- if (lines.min && lines.min === lines.max) {
48
- const min =
49
- parseInt(interpret(featuresWithoutMD)(bindings)(lines.min), 10) || 1;
50
- const up = involvedVariables.reduce((acc, { name }) => {
51
- if (min === bindings[name].length) return acc;
52
- if (min < bindings[name].length)
53
- return { ...acc, [name]: [...bindings[name].slice(0, min)] };
54
- const toAdd = [...Array(min - bindings[name].length).keys()].map(
55
- () => null
56
- );
57
- return { ...acc, [name]: [...bindings[name], ...toAdd] };
58
- }, {});
59
- if (Object.keys(up).length !== 0) handleChange(up);
60
- }
61
- // Assume to only execute this side effect at mount
62
- // eslint-disable-next-line react-hooks/exhaustive-deps
63
- }, [values]);
64
-
65
- useEffect(() => {
66
- if (Object.keys(todo).length !== 0) {
67
- const { up, rowNumber } = todo;
68
- const entries = Object.entries(up);
69
- const toUpdate = entries.reduce((_, [key, value]) => {
70
- const previousValue = bindings[key];
71
- const newValue = previousValue.map((v, i) =>
72
- i === rowNumber ? value : v
73
- );
74
- return { ..._, [key]: newValue };
75
- }, {});
76
- handleChange(toUpdate);
77
- setTodo({});
78
- }
79
- }, [bindings, todo, handleChange]);
80
-
81
- const addLine = () => {
82
- const toHandle = involvedVariables.reduce(
83
- (acc, { name: iv }) => ({
84
- ...acc,
85
- [iv]: [...bindings[iv], null],
86
- }),
87
- {}
88
- );
89
- handleChange(toHandle);
90
- };
91
-
92
- const customBtnLabel =
93
- (componentType === 'Loop' &&
94
- interpret(features, otherProps?.logFunction)(bindings)(mainLabel)) ||
95
- addBtnLabel;
96
-
97
- return (
98
- <>
99
- <Declarations
100
- id={mainId}
101
- type={C.BEFORE_QUESTION_TEXT}
102
- declarations={declarations}
103
- features={features}
104
- bindings={bindings}
105
- />
106
- {componentType === 'RosterForLoop' && mainLabel && (
107
- <label
108
- htmlFor={`loops-constructor-${mainId}`}
109
- id={`loops-constructor-label-${mainId}`}
110
- >
111
- {interpret(features, otherProps?.logFunction)(bindings)(mainLabel)}
112
- </label>
113
- )}
114
- <Declarations
115
- id={mainId}
116
- type={C.AFTER_QUESTION_TEXT}
117
- declarations={declarations}
118
- features={features}
119
- bindings={bindings}
120
- />
121
- <BodyComponent
122
- mainId={mainId}
123
- componentType={componentType}
124
- components={components}
125
- bindings={bindings}
126
- width={width}
127
- features={features}
128
- setTodo={setTodo}
129
- {...otherProps}
130
- />
131
- {!hideBtn && Number.isInteger(minLines) && minLines !== maxLines && (
132
- <Button
133
- label="addLine"
134
- value={customBtnLabel}
135
- // disabled={
136
- // Number.isInteger(minLines) && minLines === maxLines
137
- //||
138
- // Want to enable addition depsite of empty lines?
139
- // U.lastLoopChildLineIsEmpty(bindings)(involvedVariables)
140
- // }
141
- onClick={addLine}
142
- id={mainId}
143
- logFunction={otherProps?.logFunction}
144
- />
145
- )}
146
- <Declarations
147
- id={mainId}
148
- type={C.DETACHABLE}
149
- declarations={declarations}
150
- features={features}
151
- bindings={bindings}
152
- />
153
- </>
154
- );
155
- };
156
-
157
- LoopConstructorWrapper.defaultProps = {
158
- label: '',
159
- preferences: ['COLLECTED'],
160
- components: [],
161
- lines: {},
162
- positioning: 'DEFAULT',
163
- declarations: [],
164
- features: [],
165
- bindings: {},
166
- addBtnLabel: 'Add a line',
167
- management: false,
168
- hideBtn: false,
169
- style: {},
170
- };
171
-
172
- LoopConstructorWrapper.propTypes = {
173
- componentType: PropTypes.string.isRequired,
174
- id: PropTypes.string.isRequired,
175
- label: PropTypes.string,
176
- preferences: PropTypes.arrayOf(U.valueTypePropTypes),
177
- components: PropTypes.array,
178
- handleChange: PropTypes.func.isRequired,
179
- lines: U.linesPropTypes,
180
- positioning: PropTypes.oneOf(['DEFAULT', 'HORIZONTAL', 'VERTICAL']),
181
- declarations: U.declarationsPropTypes,
182
- features: PropTypes.arrayOf(PropTypes.string),
183
- bindings: PropTypes.object,
184
- addBtnLabel: PropTypes.string,
185
- hideBtn: PropTypes.bool,
186
- management: PropTypes.bool,
187
- style: PropTypes.object,
188
- };
189
-
190
- export default React.memo(LoopConstructorWrapper, U.areEqual);
1
+ import React, { useState, useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import * as lunatic from '../../components';
4
+ import BodyComponent from './body-component';
5
+ import Declarations from '../../declarations';
6
+ import * as U from '../../../utils/lib';
7
+ import * as C from '../../../constants';
8
+ import { interpret } from '../../../utils/to-expose';
9
+
10
+ const LoopConstructorWrapper = ({
11
+ id: mainId,
12
+ label: mainLabel,
13
+ components,
14
+ handleChange,
15
+ lines,
16
+ declarations,
17
+ features,
18
+ bindings,
19
+ addBtnLabel,
20
+ hideBtn,
21
+ componentType,
22
+ ...otherProps
23
+ }) => {
24
+ const [todo, setTodo] = useState({});
25
+
26
+ const featuresWithoutMD = features.filter((f) => f !== 'MD');
27
+
28
+ const minLines = Math.max(
29
+ parseInt(interpret(featuresWithoutMD)(bindings)(lines.min), 10) || 1,
30
+ U.getLoopConstructorInitLines(components)
31
+ );
32
+ const maxLines = lines
33
+ ? parseInt(interpret(featuresWithoutMD)(bindings)(lines.max), 10)
34
+ : undefined;
35
+
36
+ const width = `${100 / Math.max(...components.map((row) => row.length))}%`;
37
+ const Button = lunatic.Button;
38
+ const involvedVariables = U.getInvolvedVariables(components);
39
+
40
+ const values = components.reduce(
41
+ (acc, c) => `${acc}|${Object.values(c.response?.values || {}).join('|')}`,
42
+ ''
43
+ );
44
+
45
+ // TEMP: Set static number of occurence if min = max
46
+ useEffect(() => {
47
+ if (lines.min && lines.min === lines.max) {
48
+ const min =
49
+ parseInt(interpret(featuresWithoutMD)(bindings)(lines.min), 10) || 1;
50
+ const up = involvedVariables.reduce((acc, { name }) => {
51
+ if (min === bindings[name].length) return acc;
52
+ if (min < bindings[name].length)
53
+ return { ...acc, [name]: [...bindings[name].slice(0, min)] };
54
+ const toAdd = [...Array(min - bindings[name].length).keys()].map(
55
+ () => null
56
+ );
57
+ return { ...acc, [name]: [...bindings[name], ...toAdd] };
58
+ }, {});
59
+ if (Object.keys(up).length !== 0) handleChange(up);
60
+ }
61
+ // Assume to only execute this side effect at mount
62
+ // eslint-disable-next-line react-hooks/exhaustive-deps
63
+ }, [values]);
64
+
65
+ useEffect(() => {
66
+ if (Object.keys(todo).length !== 0) {
67
+ const { up, rowNumber } = todo;
68
+ const entries = Object.entries(up);
69
+ const toUpdate = entries.reduce((_, [key, value]) => {
70
+ const previousValue = bindings[key];
71
+ const newValue = previousValue.map((v, i) =>
72
+ i === rowNumber ? value : v
73
+ );
74
+ return { ..._, [key]: newValue };
75
+ }, {});
76
+ handleChange(toUpdate);
77
+ setTodo({});
78
+ }
79
+ }, [bindings, todo, handleChange]);
80
+
81
+ const addLine = () => {
82
+ const toHandle = involvedVariables.reduce(
83
+ (acc, { name: iv }) => ({
84
+ ...acc,
85
+ [iv]: [...bindings[iv], null],
86
+ }),
87
+ {}
88
+ );
89
+ handleChange(toHandle);
90
+ };
91
+
92
+ const customBtnLabel =
93
+ (componentType === 'Loop' &&
94
+ interpret(features, otherProps?.logFunction)(bindings)(mainLabel)) ||
95
+ addBtnLabel;
96
+
97
+ return (
98
+ <>
99
+ <Declarations
100
+ id={mainId}
101
+ type={C.BEFORE_QUESTION_TEXT}
102
+ declarations={declarations}
103
+ features={features}
104
+ bindings={bindings}
105
+ />
106
+ {componentType === 'RosterForLoop' && mainLabel && (
107
+ <label
108
+ htmlFor={`loops-constructor-${mainId}`}
109
+ id={`loops-constructor-label-${mainId}`}
110
+ >
111
+ {interpret(features, otherProps?.logFunction)(bindings)(mainLabel)}
112
+ </label>
113
+ )}
114
+ <Declarations
115
+ id={mainId}
116
+ type={C.AFTER_QUESTION_TEXT}
117
+ declarations={declarations}
118
+ features={features}
119
+ bindings={bindings}
120
+ />
121
+ <BodyComponent
122
+ mainId={mainId}
123
+ componentType={componentType}
124
+ components={components}
125
+ bindings={bindings}
126
+ width={width}
127
+ features={features}
128
+ setTodo={setTodo}
129
+ {...otherProps}
130
+ />
131
+ {!hideBtn && Number.isInteger(minLines) && minLines !== maxLines && (
132
+ <Button
133
+ label="addLine"
134
+ value={customBtnLabel}
135
+ // disabled={
136
+ // Number.isInteger(minLines) && minLines === maxLines
137
+ //||
138
+ // Want to enable addition depsite of empty lines?
139
+ // U.lastLoopChildLineIsEmpty(bindings)(involvedVariables)
140
+ // }
141
+ onClick={addLine}
142
+ id={mainId}
143
+ logFunction={otherProps?.logFunction}
144
+ />
145
+ )}
146
+ <Declarations
147
+ id={mainId}
148
+ type={C.DETACHABLE}
149
+ declarations={declarations}
150
+ features={features}
151
+ bindings={bindings}
152
+ />
153
+ </>
154
+ );
155
+ };
156
+
157
+ LoopConstructorWrapper.defaultProps = {
158
+ label: '',
159
+ preferences: ['COLLECTED'],
160
+ components: [],
161
+ lines: {},
162
+ positioning: 'DEFAULT',
163
+ declarations: [],
164
+ features: [],
165
+ bindings: {},
166
+ addBtnLabel: 'Add a line',
167
+ management: false,
168
+ hideBtn: false,
169
+ style: {},
170
+ };
171
+
172
+ LoopConstructorWrapper.propTypes = {
173
+ componentType: PropTypes.string.isRequired,
174
+ id: PropTypes.string.isRequired,
175
+ label: PropTypes.string,
176
+ preferences: PropTypes.arrayOf(U.valueTypePropTypes),
177
+ components: PropTypes.array,
178
+ handleChange: PropTypes.func.isRequired,
179
+ lines: U.linesPropTypes,
180
+ positioning: PropTypes.oneOf(['DEFAULT', 'HORIZONTAL', 'VERTICAL']),
181
+ declarations: U.declarationsPropTypes,
182
+ features: PropTypes.arrayOf(PropTypes.string),
183
+ bindings: PropTypes.object,
184
+ addBtnLabel: PropTypes.string,
185
+ hideBtn: PropTypes.bool,
186
+ management: PropTypes.bool,
187
+ style: PropTypes.object,
188
+ };
189
+
190
+ export default React.memo(LoopConstructorWrapper, U.areEqual);