project-booster-vue 10.29.0 → 10.30.0

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 (11) hide show
  1. package/package.json +1 -1
  2. package/src/components/cards/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-cards-pb-card-/360/237/247/254-features-image-1-snap.png +0 -0
  3. package/src/components/items/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-ui-items-pb-items-list-/360/237/246/240-features-multiselect-1-snap.png +0 -0
  4. package/src/components/projects/projects/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-/360/237/246/240-showcase-1-snap.png +0 -0
  5. package/src/components/projects/projects-list/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-list-/360/237/246/240-showcase-1-snap.png +0 -0
  6. package/src/components/question/configurations-import/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-scenario-questions-pb-configurations-import-/360/237/246/240-with-simulations-linked-1-snap.png +0 -0
  7. package/src/components/rework/exit-options/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-exit-options-m-pb-exit-options-/360/237/246/240-with-typeform-1-snap.png +0 -0
  8. package/src/components/rework/timify/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-timify-m-pb-timify-/360/237/246/240-101-sandbox-1-snap.png +0 -0
  9. package/src/components/scenario/PbScenario-Appointment-Energy-Renovation.stories.mdx +245 -0
  10. package/src/components/scenario/scenarii/appointment-qualification-energy-renovation.json +289 -0
  11. package/src/services/scenarioConditionals.ts +16 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-booster-vue",
3
- "version": "10.29.0",
3
+ "version": "10.30.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -0,0 +1,245 @@
1
+ import { nestedAppDecorator } from '../../../.storybook/nested-app-decorator';
2
+ import { Anchor, Story, Meta, Source, Canvas } from '@storybook/addon-docs';
3
+ import PbScenario from './PbScenario';
4
+ import estimatesStore from '../../stores/modules/estimatesStore';
5
+ import DEFAULT_PAYLOAD from './scenarii/appointment-qualification-energy-renovation.json';
6
+ import { TemplateSandbox } from './PbScenario.stories.mdx';
7
+ import simpleScenarioSchema from './Simple-scenario.svg';
8
+
9
+ <Meta
10
+ title="Project Booster/Scenario/PbScenario 🦠/Test (locally)/Appointment qualification/Energy Renovation"
11
+ component={PbScenario}
12
+ argTypes={{
13
+ scenarios: {
14
+ table: {
15
+ defaultValue: {
16
+ summary: 'object',
17
+ detail: JSON.stringify(DEFAULT_PAYLOAD, null, ' '),
18
+ },
19
+ },
20
+ control: {
21
+ type: 'object',
22
+ },
23
+ },
24
+ onScenarioCompleted: {
25
+ action: 'Scenario completed',
26
+ table: { disable: true },
27
+ },
28
+ onScenarioEvent: {
29
+ action: 'Scenario event occured',
30
+ table: { disable: true },
31
+ },
32
+ }}
33
+ decorators={[
34
+ nestedAppDecorator(
35
+ {
36
+ modules: {
37
+ estimates: estimatesStore,
38
+ },
39
+ actions: {
40
+ sendEventToBus({}, payload) {
41
+ console.log('Event sent to bus', payload);
42
+ },
43
+ },
44
+ },
45
+ [{ path: '/steps/:stepCode/previous/:answers', component: PbScenario }],
46
+ ),
47
+ ]}
48
+ parameters={{
49
+ layout: 'fullscreen',
50
+ }}
51
+ />
52
+
53
+ <Anchor storyId="project-booster-scenario-pbscenario-features-conditional--101-simple-scenario" />
54
+
55
+ # Features - PbScenario
56
+
57
+ ## Scenarios and steps management
58
+
59
+ The scenario component allows to manage **scenarios** and **steps** :
60
+
61
+ - a **scenario** is a sequence of steps,
62
+ - a **step** is one interaction from the user perspective.
63
+
64
+ ## Simple scenario
65
+
66
+ The scenario component will use the bounded scenarios object containing all the scenarios and steps:
67
+
68
+ <details>
69
+ <summary class="css-1p8ieni">
70
+ Show/Hide <strong>scenario code</strong>:
71
+ </summary>
72
+ <Source language="json" code={JSON.stringify(DEFAULT_PAYLOAD, null, ' ')} />
73
+ </details>
74
+
75
+ A scenario object is composed of a map of steps. A step can be a standard step or a nested scenario.
76
+
77
+ This simple scenario contains:
78
+
79
+ - the `__START__` scenario which is used by the component to know where to find the main scenario, its presence is mandatory,
80
+ - the `MAIN_SCENARIO` (name it as you want) definition, pointing to its first step `MAIN_SCENARIO--STEP_1`,
81
+ - the `MAIN_SCENARIO--STEP_1` (name it as you want) step with the component `PbCard` used for this step and the next
82
+ step `MAIN_SCENARIO--STEP_2` (name it as you want) to reach when completed,
83
+ - the `MAIN_SCENARIO--STEP_2` (name it as you want) step with the component `PbCard` used for this step and the next
84
+ step `__END__` to reach when completed,
85
+ - the `__END__` step with the component `PbCard` used for this step which indicates to the
86
+ component that the main scenario is completed, its presence is mandatory to address properly the nested scenario feature.
87
+
88
+ NB: **`__START__`** and **`__END__`** are mandatory step codes to allow the component to work properly, **DO NOT RENAME THEM**. The `__END__`
89
+ can display a component.
90
+
91
+ <img src={simpleScenarioSchema} />
92
+
93
+ <Canvas>
94
+ <Story
95
+ name="Energy Renovation"
96
+ inline={false}
97
+ height="758px"
98
+ args={{ scenarios: DEFAULT_PAYLOAD, minHeight: 'auto' }}
99
+ parameters={{ storyshots: { disable: true } }}
100
+ >
101
+ {TemplateSandbox.bind({})}
102
+ </Story>
103
+ </Canvas>
104
+
105
+ ## Focus on scenario definition
106
+
107
+ Here is the scenario definition:
108
+
109
+ ```json
110
+ {
111
+ "SCENARIO_CODE": {
112
+ "code": "SCENARIO_CODE",
113
+ "type": "SCENARIO",
114
+ "stepCode": "FIRST_STEP_CODE",
115
+ "meta": {
116
+ "your-stuff": "here"
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ where:
123
+
124
+ | | |
125
+ | --------------- | -------------------------------------------------------------------------------------------------- |
126
+ | `SCENARIO_CODE` | the scenario code uniquely identifying it in the scenario map, |
127
+ | `code` | the same as above, the data is duplicated inside the object to simplify steps/scenarios management |
128
+ | `type` | the type of step, (could be `STEP`, `SCENARIO`) |
129
+ | `stepCode` | the first step of the scenario |
130
+ | `meta` | data needed by the scenario host |
131
+
132
+ ## Focus on step definition
133
+
134
+ ### Mandatory properties
135
+
136
+ Here is the smallest step definition (it can be extended with other properties):
137
+
138
+ ```json
139
+ {
140
+ "STEP_CODE": {
141
+ "code": "STEP_CODE",
142
+ "type": "STEP",
143
+ "component": "PbComponentForStepScreen",
144
+ "payload": {}
145
+ }
146
+ }
147
+ ```
148
+
149
+ | | |
150
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
151
+ | `STEP_CODE` | the step code uniquely identifying it in the scenario map |
152
+ | `type` | the type of step, (could be `STEP` or `SCENARIO`) |
153
+ | `component` | the component that will be used to materialize the step on the screen. See _Step component_ section below for more information |
154
+ | `payload` | the payload containing specific business data for the step |
155
+
156
+ ### Step component
157
+
158
+ The step is associated with a component. This is the component which will be displayed for the step.
159
+ A `payload` property is also available to provide:
160
+
161
+ - the **business data** needed to address the business use case (ex: the answers of a question),
162
+ - the `viewModel` property which contains the component **view model** (ie. the data used to customise the component: label, images, ...).
163
+
164
+ The `payload` property is not mandatory as the component does not always need customisation data.
165
+
166
+ Here is a step definition with the component definition:
167
+
168
+ ```json
169
+ {
170
+ "STEP_CODE": {
171
+ "code": "STEP_CODE",
172
+ "type": "STEP",
173
+ "component": "PbComponentForStepScreen",
174
+ "payload": {}
175
+ }
176
+ }
177
+ ```
178
+
179
+ #### Step components API
180
+
181
+ The components API consists of :
182
+
183
+ - the `payload` provided by the `PbScenario` component which contains business data and view model,
184
+ - the `step-completed` event emitted by the component itself when he has finished its job.
185
+
186
+ ##### Payload bound property
187
+
188
+ The `payload` property bound to the component will contain all the data needed by the component to do its job.
189
+
190
+ This is not mandatory as the component may be self sufficient to execute its tasks.
191
+
192
+ ##### step-completed event
193
+
194
+ The `step-completed` event is raised when the component has finished its job. It contains:
195
+
196
+ - the `answers` property containing the result of the component job,
197
+ - the `nextStep` property containing a step to override the default `nextStep` defined on the current step.
198
+
199
+ ## Going to next step
200
+
201
+ After the user completes the task provided by the component, the component will emit the `step-completed` event.
202
+
203
+ The `step-completed` event payload will contain the `answers` resulting from the user interactions and an optional
204
+ `nextStep`:
205
+
206
+ - If a `nextStep` is provided by the component, the scenario will use this as a next step.
207
+ - If no `nextStep` is provided by the component, the scenario component will look for the `nextStep` property of
208
+ the current step,
209
+ - If no `nextStep` is provided/found, the current scenario will be considered as finished and the scenario component
210
+ will try to resume the parent scenario.
211
+
212
+ The `nextStep` object only contains a `code` property valued with the code of the targeted next step.
213
+ If the code is `null`, it will react as if the `nextStep` is not provided (the current scenario will be considered
214
+ as finished and the scenario component will try to resume the parent scenario, if there is no scenario to resume,
215
+ the scenario will go to the `__END__`).
216
+
217
+ Next step example to navigate to a step or a nested scenario:
218
+
219
+ ```json
220
+ {
221
+ "nextStep": {
222
+ "code": "NEXT_STEP_OR_SCENARIO_CODE"
223
+ }
224
+ }
225
+ ```
226
+
227
+ Next step example to navigate to finish the current (nested) scenario:
228
+
229
+ ```json
230
+ {
231
+ "nextStep": {
232
+ "code": null
233
+ }
234
+ }
235
+ ```
236
+
237
+ Next step example to navigate to end the main scenario:
238
+
239
+ ```json
240
+ {
241
+ "nextStep": {
242
+ "code": "__END__"
243
+ }
244
+ }
245
+ ```
@@ -0,0 +1,289 @@
1
+ {
2
+ "__START__": {
3
+ "code": "__START__",
4
+ "type": "SCENARIO",
5
+ "meta": {
6
+ "businessUnit": "001",
7
+ "webAnalytics": {
8
+ "category": "Rénovation énergétique",
9
+ "scenario": "appointment-qualification-energy-renovation",
10
+ "funnel_name": "Qualifying course energy renovation",
11
+ "tracking": true,
12
+ "cdl": {
13
+ "pageName": "energy renovation qualification",
14
+ "pageType": "Configurators & services",
15
+ "pageSubType": "appointment qualification",
16
+ "pageCategory1": "Rénovation énergétique",
17
+ "pageCategory2": "",
18
+ "booking": {
19
+ "pageType": "Configurators & services",
20
+ "pageSubType": "appointment booking",
21
+ "pageCategory1": "energy renovation",
22
+ "pageCategory2": "energy renovation appointment booking"
23
+ }
24
+ }
25
+ },
26
+ "projectName": "Rénovation énergétique",
27
+ "projectKindHref": "/project-kinds/34048",
28
+ "projectTypeHref": "/project-types/61774",
29
+ "domesticSpaceHref": "/domestic-spaces/59419",
30
+ "configuratorType": "Rénovation énergétique"
31
+ },
32
+ "stepCode": "ENERGY_RENOVATION"
33
+ },
34
+ "ENERGY_RENOVATION": {
35
+ "code": "ENERGY_RENOVATION",
36
+ "type": "SCENARIO",
37
+ "stepCode": "LMFR_QUESTION_WORKS"
38
+ },
39
+
40
+ "LMFR_QUESTION_WORKS": {
41
+ "code": "LMFR_QUESTION_WORKS",
42
+ "type": "STEP",
43
+ "component": "MPbQuestion",
44
+ "slots": {
45
+ "stickyBottom": {
46
+ "display": false
47
+ },
48
+ "beforeContent": {
49
+ "display": true,
50
+ "component": "MPbProgress",
51
+ "totalStep": 1,
52
+ "currentStep": 1,
53
+ "sizeXlWidth": true,
54
+ "label": "Votre projet de rénovation énergétique"
55
+ }
56
+ },
57
+ "payload": {
58
+ "viewModel": {
59
+ "hero": "Estimez votre projet de rénovation énergétique",
60
+ "label": "Quels sont les types de travaux envisagés ?",
61
+ "answersComponent": "MPbCard",
62
+ "progressBar": true,
63
+ "widthFromL": "auto",
64
+ "widthXlSize": true,
65
+ "hideBackButton": true,
66
+ "forceOneCardPerLineOnMobile": true,
67
+ "sortBy": {
68
+ "type": ["numeric", "string"],
69
+ "order": ["Asc"],
70
+ "path": ["meta.ranking", "viewModel.title"]
71
+ }
72
+ },
73
+ "multiSelect": {
74
+ "actions": {
75
+ "VALIDATE": {
76
+ "label": "Étape suivante",
77
+ "nextStep": {
78
+ "conditionals": [
79
+ {
80
+ "conditions": [
81
+ "hasMultipleAnswers('LMFR_QUESTION_WORKS')",
82
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'OTHER')",
83
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'HELP')"
84
+ ],
85
+ "nextStep": {
86
+ "code": "APPOINTMENT_FORM"
87
+ }
88
+ },
89
+ {
90
+ "conditions": [
91
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'EXTERNAL_WALL_INSULATION')",
92
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'ATTIC_INSULATION')",
93
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'WOOD_STOVE')",
94
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'AIR_WATER_HEAT_PUMP')",
95
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'WATER_HEATER')",
96
+ "isAnswerContaining('LMFR_QUESTION_WORKS', 'PHOTOVOLTAIC')"
97
+ ],
98
+ "nextStep": {
99
+ "code": "LMFR_QUESTION_ENERGY_RENOVATION_EXIT_OPTIONS"
100
+ }
101
+ }
102
+ ]
103
+ }
104
+ }
105
+ }
106
+ },
107
+ "answers": {
108
+ "EXTERNAL_WALL_INSULATION": {
109
+ "code": "EXTERNAL_WALL_INSULATION",
110
+ "viewModel": {
111
+ "title": "Isolation des murs par l'extérieur"
112
+ },
113
+ "meta": {
114
+ "ranking": 1
115
+ }
116
+ },
117
+ "ATTIC_INSULATION": {
118
+ "code": "ATTIC_INSULATION",
119
+ "viewModel": {
120
+ "title": "Isolation des combles perdus"
121
+ },
122
+ "meta": {
123
+ "ranking": 2
124
+ }
125
+ },
126
+ "WOOD_STOVE": {
127
+ "code": "WOOD_STOVE",
128
+ "viewModel": {
129
+ "title": "Poêle à bois"
130
+ },
131
+ "meta": {
132
+ "ranking": 3
133
+ }
134
+ },
135
+ "AIR_WATER_HEAT_PUMP": {
136
+ "code": "AIR_WATER_HEAT_PUMP",
137
+ "viewModel": {
138
+ "title": "Pompe à chaleur air/eau"
139
+ },
140
+ "meta": {
141
+ "ranking": 4
142
+ }
143
+ },
144
+ "WATER_HEATER": {
145
+ "code": "WATER_HEATER",
146
+ "viewModel": {
147
+ "title": "Chauffe-eau"
148
+ },
149
+ "meta": {
150
+ "ranking": 5
151
+ }
152
+ },
153
+ "PHOTOVOLTAIC": {
154
+ "code": "PHOTOVOLTAIC",
155
+ "viewModel": {
156
+ "title": "Panneaux solaires"
157
+ },
158
+ "meta": {
159
+ "ranking": 6
160
+ }
161
+ },
162
+ "OTHER": {
163
+ "code": "OTHER",
164
+ "viewModel": {
165
+ "title": "Autre"
166
+ },
167
+ "meta": {
168
+ "ranking": 7
169
+ }
170
+ },
171
+ "HELP": {
172
+ "code": "HELP",
173
+ "viewModel": {
174
+ "title": "Je cherche des informations sur les aides à la rénovation énergétique"
175
+ },
176
+ "meta": {
177
+ "ranking": 8
178
+ }
179
+ }
180
+ }
181
+ }
182
+ },
183
+ "LMFR_QUESTION_ENERGY_RENOVATION_EXIT_OPTIONS": {
184
+ "code": "LMFR_QUESTION_ENERGY_RENOVATION_EXIT_OPTIONS",
185
+ "type": "STEP",
186
+ "component": "MPbExitOptions",
187
+ "slots": {
188
+ "beforeContent": {
189
+ "display": true,
190
+ "component": "MPbProgress",
191
+ "totalStep": 1,
192
+ "currentStep": 1,
193
+ "sizeXlWidth": true,
194
+ "label": "Votre projet de rénovation énergétique"
195
+ }
196
+ },
197
+ "payload": {
198
+ "viewModel": {
199
+ "conditionals": [
200
+ {
201
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'EXTERNAL_WALL_INSULATION')"],
202
+ "viewModel": {
203
+ "title": "Votre projet concerne uniquement l'isolation de vos murs par l'extérieur ?",
204
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
205
+ "nextStep": {
206
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-de-isolation/pose-isolation-exterieure-par-un-professionnel.html",
207
+ "label": "Être rappelé par nos conseillers"
208
+ }
209
+ }
210
+ },
211
+ {
212
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'ATTIC_INSULATION')"],
213
+ "viewModel": {
214
+ "title": "Votre projet concerne uniquement l'isolation de vos combles ?",
215
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
216
+ "nextStep": {
217
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-de-isolation/isolation-de-vos-combles-perdus.html",
218
+ "label": "Être rappelé par nos conseillers"
219
+ }
220
+ }
221
+ },
222
+ {
223
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'WOOD_STOVE')"],
224
+ "viewModel": {
225
+ "title": "Votre projet concerne uniquement un poêle à bois ?",
226
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
227
+ "nextStep": {
228
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-du-poele-a-bois/votre-poele-a-bois-livre-et-installe-par-un-professionnel.html",
229
+ "label": "Être rappelé par nos conseillers"
230
+ }
231
+ }
232
+ },
233
+ {
234
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'AIR_WATER_HEAT_PUMP')"],
235
+ "viewModel": {
236
+ "title": "Votre projet concerne uniquement une pompe à chaleur air/eau ?",
237
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
238
+ "nextStep": {
239
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-de-pompe-a-chaleur/votre-pompe-a-chaleur-air-eau-livree-et-installee-par-un-professionnel.html",
240
+ "label": "Être rappelé par nos conseillers"
241
+ }
242
+ }
243
+ },
244
+ {
245
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'WATER_HEATER')"],
246
+ "viewModel": {
247
+ "title": "Votre projet concerne uniquement un chauffe-eau ?",
248
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
249
+ "nextStep": {
250
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-du-chauffe-eau/votre-chauffe-eau-thermodynamique-livre-et-installe-par-un-professionnel.html",
251
+ "label": "Être rappelé par nos conseillers"
252
+ }
253
+ }
254
+ },
255
+ {
256
+ "conditions": ["isAnswerContaining('LMFR_QUESTION_WORKS', 'PHOTOVOLTAIC')"],
257
+ "viewModel": {
258
+ "title": "Votre projet concerne uniquement des panneaux photovoltaïques ?",
259
+ "content": "<p>Définissez votre projet. Nos conseillers vous accueillent également en magasin sans rendez-vous pour réaliser ensemble votre projet.</p>",
260
+ "nextStep": {
261
+ "link": "https://www.leroymerlin.fr/services/tous-nos-services-autour-du-panneau-solaire/installation-panneaux-photovoltaiques-economisez-jusqu-a-50-sur-vos-factures-electricite.html",
262
+ "label": "Être rappelé par nos conseillers"
263
+ }
264
+ }
265
+ }
266
+ ],
267
+ "backButton": {
268
+ "label": "Précédent",
269
+ "theme": "bordered-neutral",
270
+ "nextStep": {
271
+ "code": "LMFR_QUESTION_WORKS"
272
+ }
273
+ }
274
+ }
275
+ }
276
+ },
277
+
278
+ "APPOINTMENT_FORM": {
279
+ "code": "APPOINTMENT_FORM",
280
+ "type": "STEP",
281
+ "component": "MPbTimify",
282
+ "payload": {
283
+ "viewModel": {
284
+ "title": "Votre prise de rendez-vous pour de la rénovation énergétique",
285
+ "appointmentCategory": "ENERGY_RENOVATION"
286
+ }
287
+ }
288
+ }
289
+ }
@@ -31,16 +31,31 @@ const Condition = (
31
31
  const questionAnswers = answers.get(questionCode)!;
32
32
  return questionAnswers.length > 0;
33
33
  };
34
+ const hasMultipleAnswers = (questionCode: string): boolean => {
35
+ const questionAnswers = answers.get(questionCode)!;
36
+ return questionAnswers.length > 1;
37
+ };
34
38
  const isValid: boolean = new Function(
35
39
  'isAnswerMatching',
36
40
  'isAnswerContaining',
37
41
  'isAnswerValue',
38
42
  'isJsonEmpty',
39
43
  'hasAnswers',
44
+ 'hasMultipleAnswers',
40
45
  'answers',
41
46
  'runtimeOptions',
42
47
  `return ${condition}`,
43
- ).call(this, isAnswerMatching, isAnswerContaining, isAnswerValue, isJsonEmpty, hasAnswers, answers, runtimeOptions);
48
+ ).call(
49
+ this,
50
+ isAnswerMatching,
51
+ isAnswerContaining,
52
+ isAnswerValue,
53
+ isJsonEmpty,
54
+ hasAnswers,
55
+ hasMultipleAnswers,
56
+ answers,
57
+ runtimeOptions,
58
+ );
44
59
  return { isValid };
45
60
  };
46
61