project-booster-vue 9.25.0 → 9.28.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-booster-vue",
3
- "version": "9.25.0",
3
+ "version": "9.28.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -5,9 +5,9 @@
5
5
  disabled ? 'pb-card--disabled' : ''
6
6
  }${flattened ? 'pb-card--no-pointer-events' : ''} ${
7
7
  cardMinRatio && cardMinRatio !== 'auto' ? 'm-ratio-container--' + cardMinRatio : ''
8
- }`"
8
+ }${borderTop ? 'pb-card--border-top' : ''}`"
9
9
  :role="!buttonLabel ? 'button' : 'article'"
10
- :style="`min-height: ${cardMinHeight}`"
10
+ :style="`min-height: ${cardMinHeight}; border-color:${borderTop ? borderTop : null}`"
11
11
  @click="handleCardClick"
12
12
  >
13
13
  <m-flex
@@ -309,6 +309,13 @@ export default defineComponent({
309
309
  type: [Boolean, String],
310
310
  default: false,
311
311
  },
312
+ /**
313
+ * Definies if the card has a border top
314
+ */
315
+ borderTop: {
316
+ type: String,
317
+ default: null,
318
+ },
312
319
  },
313
320
 
314
321
  computed: {
@@ -361,6 +368,11 @@ $responsive-breakpoint: 's';
361
368
  overflow: hidden;
362
369
  position: relative;
363
370
 
371
+ &--border-top {
372
+ border-top-style: solid !important;
373
+ border-top-width: 4px !important;
374
+ }
375
+
364
376
  &__items-container:empty ~ &__image-container {
365
377
  height: 100%;
366
378
 
@@ -36,7 +36,8 @@ It is possible to condition the display of certain answers according to previous
36
36
 
37
37
  export const conditionalAnswersPayload = {
38
38
  viewModel: {
39
- label: 'The question title',
39
+ label: 'Quel est votre revenu fiscal de référence annuel de votre foyer fiscal ?',
40
+ subtitle: 'Le revenu fiscal de référence du foyer concerne la somme des revenus des conjoints.',
40
41
  answersComponent: 'PbCard',
41
42
  },
42
43
  answers: {
@@ -0,0 +1,122 @@
1
+ import { nestedAppDecorator } from '../../../.storybook/nested-app-decorator';
2
+ import { Story, Preview, Meta, Props, ArgsTable, Source, Canvas } from '@storybook/addon-docs';
3
+ import PbQuestion from './PbQuestion';
4
+ import { TemplateSandbox } from './PbQuestion.stories.mdx';
5
+
6
+ <Meta
7
+ title="Project Booster/Scenario/Questions/PbQuestion 🦠/Features/Answers/Conditional"
8
+ component={PbQuestion}
9
+ argTypes={{
10
+ onStepCompleted: {
11
+ action: 'Step completed',
12
+ table: { disable: true },
13
+ },
14
+ }}
15
+ decorators={[
16
+ nestedAppDecorator(
17
+ {
18
+ actions: {
19
+ sendEventToBus({}, payload) {
20
+ console.log('Event sent to bus', payload);
21
+ },
22
+ },
23
+ },
24
+ [],
25
+ ),
26
+ ]}
27
+ parameters={{
28
+ layout: 'fullscreen',
29
+ }}
30
+ />
31
+
32
+ # `PbQuestion` - With Modal
33
+
34
+ export const conditionalAnswersPayload = {
35
+ viewModel: {
36
+ label: 'Quel est votre revenu fiscal de référence annuel de votre foyer fiscal ?',
37
+ subtitle: 'Le revenu fiscal de référence du foyer concerne la somme des revenus des conjoints.',
38
+ answersComponent: 'PbCard',
39
+ },
40
+ answers: {
41
+ 'ANSWER-1': {
42
+ code: 'ANSWER-1',
43
+ conditions: [
44
+ "isAnswerMatching('QUESTION_1', 'QUESTION_1--ANSWER_1')",
45
+ "isAnswerMatching('QUESTION_2', 'QUESTION_2--ANSWER_1')",
46
+ ],
47
+ viewModel: {
48
+ title: '15000 - 20000 €',
49
+ borderColor: 'orange',
50
+ },
51
+ },
52
+ 'ANSWER-2': {
53
+ code: 'ANSWER-2',
54
+ conditions: ['runtimeOptions.isElligible'],
55
+ viewModel: {
56
+ title: '20000 - 30000 €',
57
+ borderColor: 'red',
58
+ },
59
+ },
60
+ 'ANSWER-3': {
61
+ code: 'ANSWER-3',
62
+ viewModel: {
63
+ title: '30000 - 40000 €',
64
+ borderColor: 'purple',
65
+ },
66
+ },
67
+ 'ANSWER-4': {
68
+ code: 'ANSWER-4',
69
+ viewModel: {
70
+ title: 'Plus de 50000 €',
71
+ borderColor: 'yellow',
72
+ },
73
+ },
74
+ },
75
+ helpArea: [
76
+ {
77
+ type: 'text',
78
+ label: 'Besoin d’aide pour trouver votre revenu fiscal de référence ?',
79
+ },
80
+ {
81
+ type: 'link',
82
+ label: 'Voir l’aide pour trouver votre revenu fiscal',
83
+ action: {
84
+ type: 'MODAL',
85
+ viewModelDialog: {
86
+ headerTitle: 'Ou trouver votre revenu fiscal de référence ?',
87
+ subTitle: 'Sur votre dernier avis d’imposition disponible dans votre espace impots-gouv.fr',
88
+ imgUrl:
89
+ 'https://www.lerevenu.com/sites/site/files/styles/img_lg/public/field/image/impots_7.jpg?itok=A2rlQzx3',
90
+ },
91
+ },
92
+ },
93
+ ],
94
+ };
95
+
96
+ <Source language="json" code={JSON.stringify(conditionalAnswersPayload, null, ' ')} />
97
+
98
+ export const conditionalAnswersAnswers = {
99
+ QUESTION_1: [{ code: 'QUESTION_1--ANSWER_1' }],
100
+ QUESTION_2: [{ code: 'QUESTION_2--ANSWER_1' }],
101
+ };
102
+
103
+ export const conditionalAnswersRuntimeOptions = {
104
+ isElligible: true,
105
+ };
106
+
107
+ <Canvas>
108
+ <Story
109
+ name="With Modal"
110
+ inline={false}
111
+ height="862px"
112
+ parameters={{ controls: { disable: true } }}
113
+ args={{
114
+ payload: conditionalAnswersPayload,
115
+ answers: new Map(Object.entries(conditionalAnswersAnswers)),
116
+ runtimeOptions: conditionalAnswersRuntimeOptions,
117
+ minHeight: 'auto',
118
+ }}
119
+ >
120
+ {TemplateSandbox.bind({})}
121
+ </Story>
122
+ </Canvas>
@@ -72,6 +72,7 @@
72
72
  :is="payload.viewModel.answersComponent"
73
73
  v-if="payload.viewModel.answersComponent !== 'MButton'"
74
74
  class="pb-question__answer__component"
75
+ :border-top="answer.viewModel.borderColor || null"
75
76
  :image="decorate(answers, runtimeOptions, answer.viewModel.image, payload.defaultDecoratorValue)"
76
77
  :image-title="
77
78
  decorate(answers, runtimeOptions, answer.viewModel.imageTitle, payload.defaultDecoratorValue)
@@ -252,7 +253,59 @@
252
253
  </m-flexy-col>
253
254
  </m-flexy>
254
255
  </m-container>
255
- <div class="pb-question__padding-bottom" />
256
+ <div class="pb-question__padding-bottom" v-if="!payload.helpArea" />
257
+ <m-flex
258
+ class="pb-question__help"
259
+ v-if="payload.helpArea"
260
+ direction="column"
261
+ align-items="center"
262
+ justify-content="center"
263
+ >
264
+ <div v-for="helpItem in payload.helpArea" :key="helpItem.type">
265
+ <div v-if="helpItem.type === 'text'">
266
+ <p class="pb-question__help__text">{{ helpItem.label }}</p>
267
+ </div>
268
+ <div v-if="helpItem.type === 'link'">
269
+ <m-link
270
+ class="pb-question__help__link"
271
+ :label="helpItem.label"
272
+ width="full"
273
+ size="l"
274
+ theme="primary"
275
+ @click="handleHelpClick(helpItem.action)"
276
+ />
277
+ </div>
278
+ </div>
279
+ </m-flex>
280
+
281
+ <m-dialog
282
+ class="pb-question__dialog-help"
283
+ v-model:show-dialog="displayDialogHelp"
284
+ width="771px"
285
+ height="492px"
286
+ maxHeight="100vh"
287
+ >
288
+ <template #header v-if="helpDialog">
289
+ <div class="pb-question__dialog-help__title">
290
+ <h2>{{ helpDialog.viewModelDialog.headerTitle }}</h2>
291
+ <p>{{ helpDialog.viewModelDialog.subTitle }}</p>
292
+ </div>
293
+ </template>
294
+ <template #body>
295
+ <div class="pb-question__dialog-help__body" v-if="helpDialog">
296
+ <div
297
+ :style="`background-image: url(${helpDialog.viewModelDialog.imgUrl});`"
298
+ class="pb-question__dialog-help__body__image"
299
+ />
300
+ </div>
301
+ </template>
302
+ <template v-slot:footer>
303
+ <m-flex class="pb-question__dialog-help__footer" align-items="center" justify-content="center">
304
+ <m-button label="Fermer" theme="bordered-neutral" @click.prevent="displayDialogHelp = false"></m-button>
305
+ </m-flex>
306
+ </template>
307
+ </m-dialog>
308
+
256
309
  <m-dialog class="pb-question__dialog" v-model:show-dialog="displayDialog">
257
310
  <template #header v-if="!displayVideo">
258
311
  <span>{{ dialog.headerTitle }}</span>
@@ -322,6 +375,7 @@ import {
322
375
  ScenarioStepSkippableOptions,
323
376
  ScenarioStepViewModel,
324
377
  ScenarioCondition,
378
+ ScenarioStepDialog,
325
379
  } from '@/types/pb/Scenario';
326
380
 
327
381
  const BACK_ICON =
@@ -460,7 +514,9 @@ export default defineComponent({
460
514
  BACK_ICON,
461
515
  INFO_ICON,
462
516
  displayDialog: false,
517
+ displayDialogHelp: false,
463
518
  dialog: undefined as undefined | ScenarioStepAnswerDialog,
519
+ helpDialog: undefined as undefined | ScenarioStepDialog,
464
520
  displayVideo: false,
465
521
  pbQuestionActionsButtonsMaxHeight: 0,
466
522
  decorate,
@@ -761,6 +817,19 @@ export default defineComponent({
761
817
  },
762
818
  });
763
819
  },
820
+ handleHelpClick(answer: ScenarioStepDialog) {
821
+ this.displayDialogHelp = !this.displayDialogHelp;
822
+ this.helpDialog = answer ?? undefined;
823
+ this.$store.dispatch('sendEventToBus', {
824
+ code: 'LINK-CLICKED',
825
+ payload: {
826
+ context: {
827
+ answer: answer,
828
+ questionId: this.stepName,
829
+ },
830
+ },
831
+ });
832
+ },
764
833
  },
765
834
  });
766
835
  </script>
@@ -1229,8 +1298,37 @@ $answers-apparition-duration: '0.5s';
1229
1298
  }
1230
1299
  }
1231
1300
 
1301
+ &__dialog-help {
1302
+ &__title {
1303
+ padding: $mu250 $mu250 0 $mu250;
1304
+ }
1305
+
1306
+ &__body {
1307
+ padding: 0 $mu250;
1308
+ @include set-font-scale('05', 'l');
1309
+ &__image {
1310
+ background-size: cover;
1311
+ padding: 120px 0;
1312
+ }
1313
+ }
1314
+
1315
+ &__footer {
1316
+ padding: $mu100 $mu250 $mu250 $mu250;
1317
+ }
1318
+ }
1319
+
1232
1320
  &__padding-bottom {
1233
1321
  height: $mu800;
1234
1322
  }
1323
+
1324
+ &__help {
1325
+ margin-bottom: $mu250;
1326
+ &__link,
1327
+ &__text {
1328
+ margin: 0;
1329
+ @include set-font-scale('05', 'l');
1330
+ @include set-font-face('regular');
1331
+ }
1332
+ }
1235
1333
  }
1236
1334
  </style>
@@ -15,6 +15,9 @@
15
15
  <div class="pb-city-search__title">
16
16
  {{ computedPayload.viewModel.label }}
17
17
  </div>
18
+ <div v-if="computedPayload.viewModel.subtitle" class="pb-city-search__subtitle">
19
+ {{ computedPayload.viewModel.subtitle }}
20
+ </div>
18
21
  <div class="pb-city-search__form">
19
22
  <m-flex class="pb-city-search__header" ref="pbCitySearchHeader" direction="column">
20
23
  <m-flex
@@ -178,6 +181,7 @@ export default defineComponent({
178
181
  name: string;
179
182
  region: string;
180
183
  inseeCode: string;
184
+ postalCode: string;
181
185
  } | null,
182
186
  searchKeywordBackup: undefined as string | undefined,
183
187
  displaySuggestions: false,
@@ -218,6 +222,12 @@ export default defineComponent({
218
222
  this?.computedPayload?.value?.city?.inseeCode,
219
223
  this?.computedPayload?.defaultDecoratorValue,
220
224
  ),
225
+ postalCode: decorate(
226
+ this.answers,
227
+ this.runtimeOptions,
228
+ this?.computedPayload?.value?.city?.postalCode,
229
+ this?.computedPayload?.defaultDecoratorValue,
230
+ ),
221
231
  };
222
232
  this.searchKeyword = this?.selectedCity?.name;
223
233
  this.forceHideSuggestions = true;
@@ -301,7 +311,6 @@ export default defineComponent({
301
311
  this.focused = false;
302
312
  this.forceHideSuggestions = true;
303
313
  this.searchKeywordBackup = this.searchKeyword;
304
- this.searchKeyword = suggestion.terms[0].value;
305
314
  this.getPlaceDetails(suggestion.place_id);
306
315
  setTimeout(() => {
307
316
  this.autoFocused = true;
@@ -320,22 +329,23 @@ export default defineComponent({
320
329
  const selectedCity = results[0];
321
330
  this.suggestions = null;
322
331
 
323
- const placeData = await axios.get('https://geo.api.gouv.fr/communes', {
324
- params: {
325
- lat: selectedCity.geometry.location.lat(),
326
- lon: selectedCity.geometry.location.lng(),
327
- fields: 'nom,code',
328
- format: 'json',
329
- geometry: 'centre',
330
- },
331
- });
332
- const selectedCityCode = placeData.data[0].code;
332
+ const placeData = await this.getPlaceFromGeoGouvAPI(
333
+ selectedCity.geometry.location.lat(),
334
+ selectedCity.geometry.location.lng(),
335
+ );
336
+ const postalCode =
337
+ results[0].address_components.filter((field) => field.types.includes('postal_code'))[0]?.short_name ||
338
+ placeData.postalCode;
333
339
 
334
340
  this.selectedCity = {
335
- inseeCode: selectedCityCode,
336
- name: selectedCity.address_components[0].short_name,
341
+ inseeCode: placeData.inseeCode,
342
+ postalCode: postalCode,
343
+ name: placeData.name,
337
344
  region: selectedCity.address_components[2].short_name,
338
345
  };
346
+
347
+ this.searchKeyword =
348
+ this.selectedCity.postalCode + ' ' + this.selectedCity.name + ', ' + this.selectedCity.region;
339
349
  this.$forceUpdate();
340
350
  }
341
351
  });
@@ -356,6 +366,23 @@ export default defineComponent({
356
366
  ],
357
367
  });
358
368
  },
369
+ async getPlaceFromGeoGouvAPI(lat: number, lng: number) {
370
+ const placeData = await axios.get('https://geo.api.gouv.fr/communes', {
371
+ params: {
372
+ lat: lat,
373
+ lon: lng,
374
+ fields: 'nom,code,codesPostaux',
375
+ format: 'json',
376
+ geometry: 'centre',
377
+ },
378
+ });
379
+
380
+ return {
381
+ inseeCode: placeData.data[0].code,
382
+ postalCode: placeData.data[0].codesPostaux[0],
383
+ name: placeData.data[0].nom,
384
+ };
385
+ },
359
386
  },
360
387
  });
361
388
  </script>
@@ -422,12 +449,27 @@ $responsive-breakpoint: 'm';
422
449
  @include set-from-screen($responsive-breakpoint) {
423
450
  @include set-font-scale('08', 'm');
424
451
 
425
- padding: $mu250 $mu100 $mu250 $mu100;
452
+ padding: $mu100 $mu100 $mu100 $mu100;
426
453
  text-align: center;
427
454
  width: auto;
428
455
  }
429
456
  }
430
457
 
458
+ &__subtitle {
459
+ @include set-font-scale('06', 's');
460
+
461
+ color: $color-grey-600;
462
+ padding-bottom: $mu100;
463
+
464
+ @include set-from-screen($responsive-breakpoint) {
465
+ @include set-font-scale('06', 'm');
466
+
467
+ padding-bottom: $mu100;
468
+ text-align: center;
469
+ width: 100%;
470
+ }
471
+ }
472
+
431
473
  &__image {
432
474
  margin: 0 auto;
433
475
  padding-bottom: $mu200;
@@ -2,6 +2,7 @@
2
2
  "viewModel": {
3
3
  "backLabel": "Question précédente",
4
4
  "label": "Dans quelle commune se situe votre projet ?",
5
+ "subtitle": "Cette information nous aide à identifier les aides dont vous pourriez profiter",
5
6
  "placeholder": "Commune",
6
7
  "actionLabel": "Continuer",
7
8
  "image": "https://storage.googleapis.com/project-booster-media/new-house/Estimation%20Construction%20Neuve%20-%20Localisation.png"
@@ -247,3 +247,51 @@ export const customFooter = {
247
247
  {TemplateSandbox.bind({})}
248
248
  </Story>
249
249
  </Canvas>
250
+
251
+ ## With modal support
252
+
253
+ export const withModal = {
254
+ viewModel: {
255
+ validation: {
256
+ maxValue: 10001,
257
+ maxErrorMessage: 'La surface doit être comprise entre 100m² et 10 000m²',
258
+ minValue: 99,
259
+ minErrorMessage: 'La surface doit être comprise entre 100m² et 10 000m²',
260
+ },
261
+ backLabel: 'Question précédente',
262
+ label: 'Quelle est votre surface ?',
263
+ placeholder: 'Votre surface',
264
+ actionLabel: 'Continuer',
265
+ image: null,
266
+ },
267
+ helpArea: [
268
+ {
269
+ type: 'text',
270
+ label: 'Besoin d’aide pour calculer la surface ?',
271
+ },
272
+ {
273
+ type: 'link',
274
+ label: 'Voir le guide pour calculer sa surface',
275
+ action: {
276
+ type: 'MODAL',
277
+ dialogViewModel: {
278
+ headerTitle: 'Pour calculer la surface chauffée c’est facile.',
279
+ htmlContent:
280
+ '<p>Pour calculer la surface chauffée c’est facile.</p><p> Il suffit de déduire de <strong>la surface habitable</strong> de votre habitation, <strong>les surfaces des pièces non chauffées</strong> par la pompe à chaleur. </p><p> Les pièces non chauffées peuvent être des pièces annexes (buanderie, véranda, …) ou de pièces chauffées par un autre mode de chauffage (radiateurs électriques par exemple). </p><p> <strong>Attention :</strong> le garage et le grenier ne sont pas pris en compte dans la surface habitable de base, il ne faut donc pas les déduire </p>',
281
+ },
282
+ },
283
+ },
284
+ ],
285
+ };
286
+
287
+ <Source language="json" code={JSON.stringify(withModal, null, ' ')} />
288
+
289
+ <Canvas>
290
+ <Story
291
+ name="Showcase - Feature with modal"
292
+ parameters={{ controls: { disable: true } }}
293
+ args={{ payload: withModal }}
294
+ >
295
+ {TemplateSandbox.bind({})}
296
+ </Story>
297
+ </Canvas>
@@ -12,6 +12,7 @@
12
12
  @click.once="$emit('go-back')"
13
13
  />
14
14
  </m-flex>
15
+
15
16
  <form
16
17
  class="pb-space-input__form-container"
17
18
  ref="pbSpaceInputFormContainerObserver"
@@ -57,6 +58,30 @@
57
58
  </m-flexy-col>
58
59
  </m-flex>
59
60
 
61
+ <m-flex
62
+ class="pb-space-input__help"
63
+ v-if="computedPayload.helpArea"
64
+ direction="column"
65
+ align-items="center"
66
+ justify-content="center"
67
+ >
68
+ <div v-for="helpItem in computedPayload.helpArea" :key="helpItem.type">
69
+ <div v-if="helpItem.type === 'text'">
70
+ <p class="pb-space-input__help__text">{{ helpItem.label }}</p>
71
+ </div>
72
+ <div v-if="helpItem.type === 'link'">
73
+ <m-link
74
+ class="pb-space-input__help__link"
75
+ :label="helpItem.label"
76
+ width="full"
77
+ size="l"
78
+ theme="primary"
79
+ @click="handleShowModal(helpItem.action.dialogViewModel)"
80
+ />
81
+ </div>
82
+ </div>
83
+ </m-flex>
84
+
60
85
  <m-flex class="pb-space-input__buttons-container" direction="column" align-items="center">
61
86
  <m-button
62
87
  class="pb-space-input__button"
@@ -77,6 +102,30 @@
77
102
  </m-flex>
78
103
  </m-flex>
79
104
  </form>
105
+
106
+ <m-dialog
107
+ class="pb-space-input__dialog"
108
+ :show-dialog="showModal"
109
+ width="680px"
110
+ height="520px"
111
+ maxHeight="100vh"
112
+ @update:show-dialog="handleShowModal"
113
+ v-if="computedPayload.helpArea"
114
+ >
115
+ <template v-slot:header>
116
+ <div class="pb-space-input__dialog__title">
117
+ <h2>{{ contentModal.headerTitle }}</h2>
118
+ </div>
119
+ </template>
120
+ <template v-slot:body>
121
+ <div class="pb-space-input__dialog__body" v-html="contentModal.htmlContent"></div>
122
+ </template>
123
+ <template v-slot:footer>
124
+ <m-flex class="pb-space-input__dialog__footer" align-items="center" justify-content="center">
125
+ <m-button label="Fermer" theme="bordered-neutral" @click.prevent="handleShowModal"></m-button>
126
+ </m-flex>
127
+ </template>
128
+ </m-dialog>
80
129
  </m-flex>
81
130
  </template>
82
131
 
@@ -93,6 +142,7 @@ import MLink from '../../mozaic/link/MLink.vue';
93
142
  import MTextInput from '../../mozaic/text-input/MTextInput.vue';
94
143
  import MFlexyCol from '../../mozaic/grid/MFlexyCol.vue';
95
144
  import MIcon from '../../mozaic/icon/MIcon.vue';
145
+ import MDialog from '../../mozaic/dialog/MDialog.vue';
96
146
  import DEFAULT_PAYLOAD from './default-payload.json';
97
147
  import { SpaceInputPayload } from '@/components/question/space-input/SpaceInput';
98
148
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
@@ -145,6 +195,7 @@ export default defineComponent({
145
195
  MFlexyCol,
146
196
  MTextInput,
147
197
  MIcon,
198
+ MDialog,
148
199
  },
149
200
 
150
201
  props: {
@@ -194,9 +245,19 @@ export default defineComponent({
194
245
  return merge(tempPayload, props.payload);
195
246
  });
196
247
  const pbSpaceInputTextInput = ref<HTMLElement>();
248
+ const showModal = ref(false);
249
+ const contentModal = ref({});
197
250
 
198
251
  const space = computeDefaultValue(props.runtimeOptions, props.answers!, computedPayload);
199
252
 
253
+ const handleShowModal = ({ headerTitle, htmlContent }: { headerTitle: string; htmlContent: string }) => {
254
+ showModal.value = !showModal.value;
255
+
256
+ if (headerTitle && htmlContent) {
257
+ contentModal.value = { headerTitle, htmlContent };
258
+ }
259
+ };
260
+
200
261
  const validationSchema = initValidation(componentId, computedPayload);
201
262
 
202
263
  const { handleSubmit } = useForm({ validationSchema: validationSchema.value });
@@ -250,6 +311,9 @@ export default defineComponent({
250
311
  handleFormSubmit,
251
312
  isShowingFooter,
252
313
  skipQuestion,
314
+ showModal,
315
+ handleShowModal,
316
+ contentModal,
253
317
  };
254
318
  },
255
319
  });
@@ -382,5 +446,29 @@ $responsive-breakpoint: 'm';
382
446
  &__link {
383
447
  margin-top: $mu250;
384
448
  }
449
+
450
+ &__dialog {
451
+ &__title {
452
+ padding: $mu250 $mu250 0 $mu250;
453
+ }
454
+
455
+ &__body {
456
+ padding: 0 $mu250;
457
+ @include set-font-scale('05', 'l');
458
+ }
459
+
460
+ &__footer {
461
+ padding: $mu100 $mu250 $mu250 $mu250;
462
+ }
463
+ }
464
+
465
+ &__help {
466
+ margin-bottom: $mu250;
467
+
468
+ &__link,
469
+ &__text {
470
+ margin: 0;
471
+ }
472
+ }
385
473
  }
386
474
  </style>
@@ -74,6 +74,13 @@ export interface ScenarioStepAnswer {
74
74
  };
75
75
  }
76
76
 
77
+ export interface ScenarioStepDialog {
78
+ viewModelDialog: {
79
+ headerTitle: string;
80
+ imageUrl?: string;
81
+ };
82
+ }
83
+
77
84
  export interface ScenarioStepAnswers {
78
85
  answers: ScenarioStepAnswer[];
79
86
  nextStep?: ScenarioStepNextStep;