project-booster-vue 9.16.3 → 9.17.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-booster-vue",
3
- "version": "9.16.3",
3
+ "version": "9.17.2",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -53,6 +53,14 @@
53
53
  Vous retrouverez ici vos simulation de budgets pour ce projet
54
54
  </div>
55
55
  </m-flex>
56
+ <m-flex class="pb-configurations-section__link-container" v-if="readOnly && project">
57
+ <m-link
58
+ class="pb-configurations-section__link-portal-oaa"
59
+ label="Lien vers le portail OAA"
60
+ size="s"
61
+ @click="window.open(linkPortalOaa, '_blank')"
62
+ />
63
+ </m-flex>
56
64
  </m-flex>
57
65
  </template>
58
66
 
@@ -64,6 +72,7 @@ import MFlex from '../../mozaic/flex/MFlex.vue';
64
72
  import PbAnimableLoader from '../../loader/PbAnimableLoader.vue';
65
73
  import PbConfigurationsList, { CONFIGURATION_ANIMATION_DURATION } from '../list/PbConfigurationsList.vue';
66
74
  import { mapGetters } from 'vuex';
75
+ import MLink from '../../mozaic/link/MLink.vue';
67
76
 
68
77
  export default defineComponent({
69
78
  name: 'PbConfigurationsSection',
@@ -73,6 +82,7 @@ export default defineComponent({
73
82
  MFlex,
74
83
  PbAnimableLoader,
75
84
  PbConfigurationsList,
85
+ MLink,
76
86
  },
77
87
 
78
88
  props: {
@@ -97,6 +107,14 @@ export default defineComponent({
97
107
  configurationsPerPageCount: 'getConfigurationsPerPageCount',
98
108
  hasStillConfigurations: 'hasStillConfigurations',
99
109
  }),
110
+ ...mapGetters('projects', {
111
+ project: 'getProject',
112
+ }),
113
+ linkPortalOaa() {
114
+ return this.project
115
+ ? `http://rcloset.fr.corp.leroymerlin.com:81/page_tunnel_oaa/?mag=${this.project.store}`
116
+ : null;
117
+ },
100
118
  },
101
119
 
102
120
  methods: {
@@ -7,7 +7,8 @@
7
7
  :left-icon="BACK_ICON"
8
8
  :class="{
9
9
  'pb-question__back-button': true,
10
- 'pb-question__back-button--hidden': !showBackButton && !decorateBoolean(payload.viewModel.forceBackButton),
10
+ 'pb-question__back-button--hidden':
11
+ !showBackButton && !decorate(answers, runtimeOptions, payload.viewModel.forceBackButton),
11
12
  }"
12
13
  @click="navigateTo(payload.viewModel)"
13
14
  />
@@ -19,10 +20,10 @@
19
20
  <div
20
21
  v-if="payload.viewModel.label"
21
22
  class="pb-question__title"
22
- v-html="decorate(payload.viewModel.label, payload.defaultDecoratorValue)"
23
+ v-html="decorate(answers, runtimeOptions, payload.viewModel.label, payload.defaultDecoratorValue)"
23
24
  />
24
25
  <div v-if="payload.viewModel.subtitle" class="pb-question__subtitle">
25
- {{ decorate(payload.viewModel.subtitle, payload.defaultDecoratorValue) }}
26
+ {{ decorate(answers, runtimeOptions, payload.viewModel.subtitle, payload.defaultDecoratorValue) }}
26
27
  <m-link
27
28
  v-if="payload.viewModel.video"
28
29
  :label="payload.viewModel.video.label"
@@ -35,14 +36,14 @@
35
36
  <div class="pb-question__video-block-image-container">
36
37
  <m-image
37
38
  class="pb-question__video-block-image"
38
- :src="decorate(payload.viewModel.videoBlock.image)"
39
+ :src="decorate(answers, runtimeOptions, payload.viewModel.videoBlock.image)"
39
40
  cover
40
41
  />
41
42
  </div>
42
43
  <div class="pb-question__video-block-buttons-container">
43
44
  <m-button
44
- :label="decorate(payload.viewModel.videoBlock.buttonLabel)"
45
- :left-icon="decorate(payload.viewModel.videoBlock.icon)"
45
+ :label="decorate(answers, runtimeOptions, payload.viewModel.videoBlock.buttonLabel)"
46
+ :left-icon="decorate(answers, runtimeOptions, payload.viewModel.videoBlock.icon)"
46
47
  theme="bordered-neutral"
47
48
  @click="displayVideoGuide('')"
48
49
  />
@@ -71,25 +72,47 @@
71
72
  :is="payload.viewModel.answersComponent"
72
73
  v-if="payload.viewModel.answersComponent !== 'MButton'"
73
74
  class="pb-question__answer__component"
74
- :image="decorate(answer.viewModel.image, payload.defaultDecoratorValue)"
75
- :image-title="decorate(answer.viewModel.imageTitle, payload.defaultDecoratorValue)"
76
- :image-ratio="decorate(answer.viewModel.imageRatio, payload.defaultDecoratorValue)"
77
- :flag-label="decorate(answer.viewModel.flagLabel, payload.defaultDecoratorValue)"
78
- :hero="decorate(answer.viewModel.hero, payload.defaultDecoratorValue)"
79
- :title="decorate(answer.viewModel.title, payload.defaultDecoratorValue)"
80
- :text="decorate(answer.viewModel.text, payload.defaultDecoratorValue)"
81
- :button-label="decorate(answer.viewModel.buttonLabel, payload.defaultDecoratorValue)"
82
- :button-href="decorate(answer.viewModel.href, payload.defaultDecoratorValue)"
83
- :link-label="decorate(answer.viewModel.linkLabel, payload.defaultDecoratorValue)"
84
- :type-icon="decorate(answer.viewModel.typeIcon, payload.defaultDecoratorValue)"
85
- :card-min-ratio="decorate(answer.viewModel.cardMinRatio, payload.defaultDecoratorValue)"
86
- :align-vertical="decorate(answer.viewModel.alignVertical, payload.defaultDecoratorValue)"
87
- :align-horizontal="decorate(answer.viewModel.alignHorizontal, payload.defaultDecoratorValue)"
88
- :align-text="decorate(answer.viewModel.alignText, payload.defaultDecoratorValue)"
75
+ :image="decorate(answers, runtimeOptions, answer.viewModel.image, payload.defaultDecoratorValue)"
76
+ :image-title="
77
+ decorate(answers, runtimeOptions, answer.viewModel.imageTitle, payload.defaultDecoratorValue)
78
+ "
79
+ :image-ratio="
80
+ decorate(answers, runtimeOptions, answer.viewModel.imageRatio, payload.defaultDecoratorValue)
81
+ "
82
+ :flag-label="
83
+ decorate(answers, runtimeOptions, answer.viewModel.flagLabel, payload.defaultDecoratorValue)
84
+ "
85
+ :hero="decorate(answers, runtimeOptions, answer.viewModel.hero, payload.defaultDecoratorValue)"
86
+ :title="decorate(answers, runtimeOptions, answer.viewModel.title, payload.defaultDecoratorValue)"
87
+ :text="decorate(answers, runtimeOptions, answer.viewModel.text, payload.defaultDecoratorValue)"
88
+ :button-label="
89
+ decorate(answers, runtimeOptions, answer.viewModel.buttonLabel, payload.defaultDecoratorValue)
90
+ "
91
+ :button-href="decorate(answers, runtimeOptions, answer.viewModel.href, payload.defaultDecoratorValue)"
92
+ :link-label="
93
+ decorate(answers, runtimeOptions, answer.viewModel.linkLabel, payload.defaultDecoratorValue)
94
+ "
95
+ :type-icon="
96
+ decorate(answers, runtimeOptions, answer.viewModel.typeIcon, payload.defaultDecoratorValue)
97
+ "
98
+ :card-min-ratio="
99
+ decorate(answers, runtimeOptions, answer.viewModel.cardMinRatio, payload.defaultDecoratorValue)
100
+ "
101
+ :align-vertical="
102
+ decorate(answers, runtimeOptions, answer.viewModel.alignVertical, payload.defaultDecoratorValue)
103
+ "
104
+ :align-horizontal="
105
+ decorate(answers, runtimeOptions, answer.viewModel.alignHorizontal, payload.defaultDecoratorValue)
106
+ "
107
+ :align-text="
108
+ decorate(answers, runtimeOptions, answer.viewModel.alignText, payload.defaultDecoratorValue)
109
+ "
89
110
  :selectable="!!payload.multiSelect"
90
111
  :selected="selectedAnswers.get(answer.code)"
91
112
  :disabled="isAnswerDisabled(answer)"
92
- :flattened="decorate(answer.viewModel.flattened, payload.defaultDecoratorValue)"
113
+ :flattened="
114
+ decorate(answers, runtimeOptions, answer.viewModel.flattened, payload.defaultDecoratorValue)
115
+ "
93
116
  @card-click="answer.viewModel.href ? '' : selectAnswer(payload.code, answer)"
94
117
  @button-click="handleAnswerButtonClick"
95
118
  @link-click="handleLinkClick(answer)"
@@ -97,14 +120,20 @@
97
120
  <m-button
98
121
  v-else
99
122
  :disabled="isAnswerDisabled(answer)"
100
- :label="decorate(answer.viewModel.label, payload.defaultDecoratorValue)"
101
- :type="decorate(answer.viewModel.type, payload.defaultDecoratorValue)"
102
- :theme="decorate(answer.viewModel.theme, payload.defaultDecoratorValue)"
103
- :left-icon="decorate(answer.viewModel.leftIcon, payload.defaultDecoratorValue)"
104
- :right-icon="decorate(answer.viewModel.rightIcon, payload.defaultDecoratorValue)"
105
- :href="decorate(answer.viewModel.href, payload.defaultDecoratorValue)"
106
- :width="decorate(answer.viewModel.width, payload.defaultDecoratorValue)"
107
- :widthFromM="decorate(answer.viewModel.widthFromM, payload.defaultDecoratorValue)"
123
+ :label="decorate(answers, runtimeOptions, answer.viewModel.label, payload.defaultDecoratorValue)"
124
+ :type="decorate(answers, runtimeOptions, answer.viewModel.type, payload.defaultDecoratorValue)"
125
+ :theme="decorate(answers, runtimeOptions, answer.viewModel.theme, payload.defaultDecoratorValue)"
126
+ :left-icon="
127
+ decorate(answers, runtimeOptions, answer.viewModel.leftIcon, payload.defaultDecoratorValue)
128
+ "
129
+ :right-icon="
130
+ decorate(answers, runtimeOptions, answer.viewModel.rightIcon, payload.defaultDecoratorValue)
131
+ "
132
+ :href="decorate(answers, runtimeOptions, answer.viewModel.href, payload.defaultDecoratorValue)"
133
+ :width="decorate(answers, runtimeOptions, answer.viewModel.width, payload.defaultDecoratorValue)"
134
+ :widthFromM="
135
+ decorate(answers, runtimeOptions, answer.viewModel.widthFromM, payload.defaultDecoratorValue)
136
+ "
108
137
  @click="selectAnswer(payload.code, answer)"
109
138
  />
110
139
  </div>
@@ -296,6 +325,51 @@ const BACK_ICON =
296
325
  const INFO_ICON =
297
326
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Notification_Information_24px.svg';
298
327
 
328
+ // Function used by the scenario conditions
329
+ const getAnswerValue = (answers: Map<string, ScenarioStepAnswer[]>) => {
330
+ return (answerCode: string, path: string) => {
331
+ let answerValue: ScenarioStepAnswer | undefined = undefined;
332
+ if (answers?.get(answerCode)) {
333
+ const answerValues = answers.get(answerCode) ?? [];
334
+ answerValue = objectPath.get(answerValues[0], path);
335
+ }
336
+ return answerValue;
337
+ };
338
+ };
339
+
340
+ export const doEval = (
341
+ answers: Map<string, ScenarioStepAnswer[]>,
342
+ valueToEval: string,
343
+ defaultValue: string,
344
+ runtimeOptions: any,
345
+ ) => {
346
+ return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
347
+ this,
348
+ getAnswerValue(answers),
349
+ Object.fromEntries(answers),
350
+ defaultValue,
351
+ runtimeOptions,
352
+ );
353
+ };
354
+
355
+ export const decorate = (
356
+ answers: Map<string, ScenarioStepAnswer[]>,
357
+ runtimeOptions = {},
358
+ valueToDecorate: string,
359
+ defaultValue = '',
360
+ ) => {
361
+ let decoratedValue = valueToDecorate;
362
+ if (valueToDecorate) {
363
+ const stringToEval = `\`${valueToDecorate}\``;
364
+ try {
365
+ decoratedValue = doEval(answers, stringToEval, defaultValue, runtimeOptions);
366
+ } catch (error) {
367
+ decoratedValue = valueToDecorate || defaultValue;
368
+ }
369
+ }
370
+ return decoratedValue;
371
+ };
372
+
299
373
  export default defineComponent({
300
374
  name: 'PbQuestion',
301
375
 
@@ -385,6 +459,7 @@ export default defineComponent({
385
459
  dialog: undefined as undefined | ScenarioStepAnswerDialog,
386
460
  displayVideo: false,
387
461
  pbQuestionActionsButtonsMaxHeight: 0,
462
+ decorate,
388
463
  }),
389
464
 
390
465
  computed: {
@@ -474,33 +549,6 @@ export default defineComponent({
474
549
 
475
550
  this.updatePbQuestionActionsButtonsSizeHeight();
476
551
  },
477
- decorate(valueToDecorate: string, defaultValue = '') {
478
- if (valueToDecorate) {
479
- valueToDecorate = `\`${valueToDecorate}\``;
480
- try {
481
- return this.doEval(valueToDecorate, defaultValue);
482
- } catch (e) {
483
- console.error(e);
484
- return valueToDecorate;
485
- }
486
- }
487
- return valueToDecorate;
488
- },
489
- decorateBoolean(valueToDecorate: string, defaultValue = false) {
490
- if (valueToDecorate) {
491
- return this.doEval(valueToDecorate, defaultValue);
492
- }
493
- return valueToDecorate;
494
- },
495
- doEval(valueToEval: string, defaultValue: string | boolean) {
496
- return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
497
- this,
498
- this.getAnswerValue,
499
- Object.fromEntries(this.answers),
500
- defaultValue,
501
- this.runtimeOptions,
502
- );
503
- },
504
552
  isShowingFooter(viewModel: ScenarioStepAnswerViewModel) {
505
553
  return viewModel.footer && areConditionsValid(viewModel.footer.conditions!, this.answers, this.runtimeOptions);
506
554
  },
@@ -548,14 +596,6 @@ export default defineComponent({
548
596
  });
549
597
  },
550
598
  // Function used by the scenario conditions
551
- getAnswerValue(answerCode: string, path: string) {
552
- if (!this.answers.get(answerCode) || this.answers.get(answerCode)?.length === 0) {
553
- return null;
554
- }
555
-
556
- return objectPath.get(this.answers.get(answerCode)?.at(0) as any, path);
557
- },
558
- // Function used by the scenario conditions
559
599
  selectedAnswersNumber() {
560
600
  let selectedAnswersNumber = 0;
561
601
 
@@ -642,7 +682,7 @@ export default defineComponent({
642
682
  },
643
683
  navigateTo(viewModel: ScenarioStepViewModel) {
644
684
  if (viewModel.backLink) {
645
- window.location = this.decorate(viewModel.backLink);
685
+ window.location = decorate(this.answers, this.runtimeOptions, viewModel.backLink, '');
646
686
  } else {
647
687
  /**
648
688
  * Emitted when go back link is clicked
@@ -120,7 +120,7 @@ It is possible to inject a value for the component from a previous answer. To do
120
120
 
121
121
  export const valuePayload = {
122
122
  value: {
123
- amount: "getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForAmount')",
123
+ amount: "${getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForAmount')}",
124
124
  },
125
125
  };
126
126
 
@@ -137,7 +137,7 @@ export const valueWithFallbackPayload = {
137
137
  amount: '123',
138
138
  },
139
139
  value: {
140
- amount: "getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForAmount') || defaultValue.amount",
140
+ amount: "${getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForAmount') || defaultValue.amount}",
141
141
  },
142
142
  };
143
143
 
@@ -149,13 +149,15 @@ parameter is the answer Id, the second is an optionnal path to extract a spcific
149
149
  It will try to find a value in a previous answer for a question with id `LMFR_PREVIOUS_QUESTION`,
150
150
  provided thanks to the `answers` prop. If no value is found, it will use the `defaultDecoratorValue` as a fallback.
151
151
 
152
- export const previousAnswers = {
153
- LMFR_PREVIOUS_QUESTION: [
154
- {
155
- pathForAmount: '456',
156
- },
157
- ],
158
- };
152
+ export const previousAnswers = new Map(
153
+ Object.entries({
154
+ LMFR_PREVIOUS_QUESTION: [
155
+ {
156
+ pathForAmount: '456',
157
+ },
158
+ ],
159
+ }),
160
+ );
159
161
 
160
162
  <Source language="json" code={JSON.stringify(previousAnswers, null, ' ')} />
161
163
 
@@ -7,7 +7,7 @@
7
7
  :class="{
8
8
  'pb-amount-input__back-button': true,
9
9
  'pb-amount-input__back-button--hidden':
10
- !showBackButton && !decorateBoolean(payload.viewModel.forceBackButton),
10
+ !showBackButton && !decorate(answers, runtimeOptions, payload.viewModel.forceBackButton),
11
11
  }"
12
12
  @click.once="$emit('go-back')"
13
13
  />
@@ -64,6 +64,7 @@ import MTextInput from './../../mozaic/text-input/MTextInput.vue';
64
64
  import DEFAULT_PAYLOAD from './default-payload.json';
65
65
  import { AmountInputPayload } from '@/components/question/amount-input/AmountInput';
66
66
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
67
+ import { decorate } from '@/components/question/PbQuestion.vue';
67
68
 
68
69
  const BACK_ICON =
69
70
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
@@ -85,45 +86,6 @@ const initValidation = (componentId: string, computedPayload: ComputedRef<Amount
85
86
  return validationSchema;
86
87
  };
87
88
 
88
- // Function used by the scenario conditions
89
- const getAnswerValue = (answers: Map<string, ScenarioStepAnswer[]>) => {
90
- return (answerCode: string, path: string) => {
91
- let answerValue: ScenarioStepAnswer | undefined = undefined;
92
- if (answers?.get(answerCode)) {
93
- const answerValues = answers.get(answerCode) ?? [];
94
- answerValue = objectPath.get(answerValues[0], path);
95
- }
96
- return answerValue;
97
- };
98
- };
99
-
100
- const doEval = (
101
- answers: Map<string, ScenarioStepAnswer[]>,
102
- valueToEval: string,
103
- defaultValue: string,
104
- runtimeOptions: any,
105
- ) => {
106
- return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
107
- this,
108
- getAnswerValue(answers),
109
- answers,
110
- defaultValue,
111
- runtimeOptions,
112
- );
113
- };
114
-
115
- const decorate = (
116
- answers: Map<string, ScenarioStepAnswer[]>,
117
- valueToDecorate: string,
118
- defaultValue = '',
119
- runtimeOptions: any,
120
- ) => {
121
- if (valueToDecorate) {
122
- return doEval(answers, valueToDecorate, defaultValue, runtimeOptions);
123
- }
124
- return valueToDecorate;
125
- };
126
-
127
89
  const computeDefaultValue = (
128
90
  runtimeOptions: any,
129
91
  answers: Map<string, ScenarioStepAnswer[]>,
@@ -133,9 +95,9 @@ const computeDefaultValue = (
133
95
  if (computedPayload?.value?.value) {
134
96
  amount = decorate(
135
97
  answers,
98
+ runtimeOptions,
136
99
  computedPayload?.value?.value?.amount,
137
100
  computedPayload?.value?.defaultDecoratorValue,
138
- runtimeOptions,
139
101
  );
140
102
  }
141
103
  return amount;
@@ -188,7 +150,7 @@ export default defineComponent({
188
150
  */
189
151
  answers: {
190
152
  type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
191
- default: () => ({}),
153
+ default: () => new Map<string, ScenarioStepAnswer[]>(),
192
154
  },
193
155
  },
194
156
 
@@ -132,9 +132,9 @@ export const valuePayload = {
132
132
  },
133
133
  value: {
134
134
  city: {
135
- name: "getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForName') || defaultValue.city.name",
136
- region: "getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForRegion') || defaultValue.city.region",
137
- inseeCode: "getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForInseeCode') || defaultValue.city.inseeCode",
135
+ name: "${getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForName') || defaultValue.city.name}",
136
+ region: "${getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForRegion') || defaultValue.city.region}",
137
+ inseeCode: "${getAnswerValue('LMFR_PREVIOUS_QUESTION', 'pathForInseeCode') || defaultValue.city.inseeCode}",
138
138
  },
139
139
  },
140
140
  };
@@ -159,15 +159,17 @@ parameter is the answer Id, the second is an optionnal path to extract a spcific
159
159
 
160
160
  ## Value injection from previous answer
161
161
 
162
- export const previousAnswers = {
163
- LMFR_PREVIOUS_QUESTION: [
164
- {
165
- pathForName: 'Ronchin',
166
- pathForRegion: 'Hauts-de-France',
167
- pathForInseeCode: '59507',
168
- },
169
- ],
170
- };
162
+ export const previousAnswers = new Map(
163
+ Object.entries({
164
+ LMFR_PREVIOUS_QUESTION: [
165
+ {
166
+ pathForName: 'Ronchin',
167
+ pathForRegion: 'Hauts-de-France',
168
+ pathForInseeCode: '59507',
169
+ },
170
+ ],
171
+ }),
172
+ );
171
173
 
172
174
  Reuse the same payload as for default value and add an answer object to the component props :
173
175
 
@@ -6,7 +6,8 @@
6
6
  :left-icon="BACK_ICON"
7
7
  :class="{
8
8
  'pb-city-search__back-button': true,
9
- 'pb-city-search__back-button--hidden': !showBackButton && !decorateBoolean(payload.viewModel.forceBackButton),
9
+ 'pb-city-search__back-button--hidden':
10
+ !showBackButton && !decorate(answers, runtimeOptions, payload.viewModel.forceBackButton),
10
11
  }"
11
12
  @click.once="$router.go(-1)"
12
13
  />
@@ -96,7 +97,7 @@
96
97
  </template>
97
98
 
98
99
  <script lang="ts">
99
- import { defineComponent } from 'vue';
100
+ import { defineComponent, PropType } from 'vue';
100
101
  import cloneDeep from 'lodash.clonedeep';
101
102
  import debounce from 'lodash.debounce';
102
103
  import merge from 'lodash.merge';
@@ -109,6 +110,8 @@ import MLink from '../../mozaic/link/MLink.vue';
109
110
  import MTextInput from '../../mozaic/text-input/MTextInput.vue';
110
111
  import DEFAULT_PAYLOAD from './default-payload.json';
111
112
  import { DebouncedFunc } from 'lodash-es';
113
+ import { decorate } from '@/components/question/PbQuestion.vue';
114
+ import { ScenarioStepAnswer } from '@/types/pb/Scenario';
112
115
 
113
116
  const BACK_ICON =
114
117
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
@@ -158,8 +161,8 @@ export default defineComponent({
158
161
  * The previous answers to inject
159
162
  */
160
163
  answers: {
161
- type: Object,
162
- default: () => ({}),
164
+ type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
165
+ default: () => new Map<string, ScenarioStepAnswer[]>(),
163
166
  },
164
167
  },
165
168
 
@@ -197,9 +200,21 @@ export default defineComponent({
197
200
 
198
201
  if (this.computedPayload?.value) {
199
202
  this.selectedCity = {
200
- name: this.decorate(this?.computedPayload?.value?.city?.name, this?.computedPayload?.defaultDecoratorValue),
201
- region: this.decorate(this?.computedPayload?.value?.city?.region, this?.computedPayload?.defaultDecoratorValue),
202
- inseeCode: this.decorate(
203
+ name: decorate(
204
+ this.answers,
205
+ this.runtimeOptions,
206
+ this?.computedPayload?.value?.city?.name,
207
+ this?.computedPayload?.defaultDecoratorValue,
208
+ ),
209
+ region: decorate(
210
+ this.answers,
211
+ this.runtimeOptions,
212
+ this?.computedPayload?.value?.city?.region,
213
+ this?.computedPayload?.defaultDecoratorValue,
214
+ ),
215
+ inseeCode: decorate(
216
+ this.answers,
217
+ this.runtimeOptions,
203
218
  this?.computedPayload?.value?.city?.inseeCode,
204
219
  this?.computedPayload?.defaultDecoratorValue,
205
220
  ),
@@ -228,27 +243,6 @@ export default defineComponent({
228
243
  updateHeaderHeight() {
229
244
  this.headerHeight = this.$refs?.pbCitySearchHeader?.$el?.offsetHeight;
230
245
  },
231
- decorate(valueToDecorate: string, defaultValue = '') {
232
- if (valueToDecorate) {
233
- return this.doEval(valueToDecorate, defaultValue);
234
- }
235
- return valueToDecorate;
236
- },
237
- decorateBoolean(valueToDecorate: string, defaultValue = '') {
238
- if (valueToDecorate) {
239
- return this.doEval(valueToDecorate, defaultValue);
240
- }
241
- return valueToDecorate;
242
- },
243
- doEval(valueToEval: string, defaultValue: string) {
244
- return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
245
- this,
246
- this.getAnswerValue,
247
- this.answers,
248
- defaultValue,
249
- this.runtimeOptions,
250
- );
251
- },
252
246
  formatSuggestion(suggestion: google.maps.places.AutocompletePrediction) {
253
247
  let text = '';
254
248
  for (let i = 0; i < suggestion.terms.length - 1; i++) {
@@ -349,14 +343,6 @@ export default defineComponent({
349
343
  console.error(`Could not get place details for ${placeId}`, error);
350
344
  }
351
345
  },
352
- // Function used by the scenario conditions
353
- getAnswerValue(answerCode: string, path: string) {
354
- if (!this.answers[answerCode] || this.answers[answerCode].length === 0) {
355
- return null;
356
- }
357
-
358
- return objectPath.get(this.answers[answerCode][0], path);
359
- },
360
346
  async handleFormValidation() {
361
347
  /**
362
348
  * Emitted when step is completed
@@ -8,7 +8,7 @@
8
8
  :class="{
9
9
  'pb-configurations-import__back-button': true,
10
10
  'pb-configurations-import__back-button--hidden':
11
- !showBackButton && !decorateBoolean(payload.viewModel.forceBackButton),
11
+ !showBackButton && !decorate(answers, runtimeOptions, payload.viewModel.forceBackButton),
12
12
  }"
13
13
  @click="navigateTo(payload.viewModel)"
14
14
  />
@@ -174,6 +174,7 @@ import {
174
174
  } from '@/components/question/configurations-import/ConfigurationsImport';
175
175
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
176
176
  import { Configuration } from '@/types/pb/Configuration';
177
+ import { decorate } from '@/components/question/PbQuestion.vue';
177
178
 
178
179
  const BACK_ICON =
179
180
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
@@ -232,7 +233,7 @@ export default defineComponent({
232
233
  */
233
234
  answers: {
234
235
  type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
235
- default: () => ({}),
236
+ default: () => new Map<string, ScenarioStepAnswer[]>(),
236
237
  },
237
238
  /**
238
239
  * Define the offset for question sticky bottom elements.
@@ -255,7 +256,7 @@ export default defineComponent({
255
256
 
256
257
  const navigateTo = (viewModel: ConfigurationsImportViewModel) => {
257
258
  if (viewModel.backLink) {
258
- window.location = decorate(viewModel.backLink);
259
+ window.location = decorate(props.answers, props.runtimeOptions, viewModel.backLink);
259
260
  } else {
260
261
  /**
261
262
  * Emitted when go back link is clicked
@@ -265,39 +266,6 @@ export default defineComponent({
265
266
  }
266
267
  };
267
268
 
268
- const decorate = (valueToDecorate: string, defaultValue = '') => {
269
- if (valueToDecorate) {
270
- return doEval(valueToDecorate, defaultValue);
271
- }
272
- return valueToDecorate;
273
- };
274
-
275
- const decorateBoolean = (valueToDecorate: string, defaultValue = '') => {
276
- if (valueToDecorate) {
277
- return doEval(valueToDecorate, defaultValue);
278
- }
279
- return valueToDecorate;
280
- };
281
-
282
- const doEval = (valueToEval: string, defaultValue: string) => {
283
- return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
284
- this,
285
- getAnswerValue,
286
- props.answers,
287
- defaultValue,
288
- props.runtimeOptions,
289
- );
290
- };
291
-
292
- const getAnswerValue = (answerCode: string, path: string) => {
293
- let answerValue: ScenarioStepAnswer | undefined = undefined;
294
- if (props.answers?.get(answerCode)) {
295
- const answerValues = props.answers.get(answerCode) ?? [];
296
- answerValue = objectPath.get(answerValues[0], path);
297
- }
298
- return answerValue;
299
- };
300
-
301
269
  const displayConfigurationDialog = () => {
302
270
  showImportConfigurationDialog.value = true;
303
271
  };
@@ -342,7 +310,6 @@ export default defineComponent({
342
310
  BACK_ICON,
343
311
  INFO_ICON,
344
312
  navigateTo,
345
- decorateBoolean,
346
313
  displayConfigurationDialog,
347
314
  importConfiguration,
348
315
  formatDate,