project-booster-vue 9.24.0 → 9.26.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 +1 -1
- package/src/components/mozaic/buttons/MButton.vue +26 -0
- package/src/components/mozaic/quantityselector/MQuantitySelector.stories.mdx +48 -0
- package/src/components/mozaic/quantityselector/MQuantitySelector.vue +188 -0
- package/src/components/mozaic/text-input/MTextInput.vue +59 -4
- package/src/components/pedagogy/PbPedagogy.vue +1 -3
- package/src/components/question/incremental-amount-input/IncrementalAmount.ts +24 -0
- package/src/components/question/incremental-amount-input/PbIncrementalAmountInput.stories.mdx +50 -0
- package/src/components/question/incremental-amount-input/PbIncrementalAmountInput.vue +332 -0
- package/src/components/question/incremental-amount-input/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-scenario-questions-pb-incremental-amount-input-/360/237/246/240-101-sandbox-1-snap.png +0 -0
- package/src/components/question/incremental-amount-input/default-payload.json +12 -0
- package/src/components/question/space-input/PbSpaceInput.stories.mdx +48 -0
- package/src/components/question/space-input/PbSpaceInput.vue +88 -0
- package/src/components/scenario/PbScenario.vue +4 -0
- package/src/components/warning-message/PbWarningMessage.vue +1 -1
package/package.json
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
class="mc-button"
|
|
36
36
|
:class="[...themeClasses, ...sizeClasses, ...widthClasses, $attrs.class]"
|
|
37
37
|
:aria-label="label"
|
|
38
|
+
:disabled="disabled"
|
|
38
39
|
>
|
|
39
40
|
<!-- Add wrapper to mitigate iOS 10 bug: https://github.com/philipwalton/flexbugs#9-some-html-elements-cant-be-flex-containers -->
|
|
40
41
|
<m-flex class="mc-button__content" direction="row" align-items="center" justify-content="center">
|
|
@@ -70,6 +71,8 @@ export const M_BUTTON_VALIDATOR = {
|
|
|
70
71
|
null,
|
|
71
72
|
'solid',
|
|
72
73
|
'bordered',
|
|
74
|
+
'bordered-left',
|
|
75
|
+
'bordered-right',
|
|
73
76
|
'bordered-neutral',
|
|
74
77
|
'solid-neutral',
|
|
75
78
|
'solid-primary-02',
|
|
@@ -94,6 +97,13 @@ export default defineComponent({
|
|
|
94
97
|
},
|
|
95
98
|
|
|
96
99
|
props: {
|
|
100
|
+
/**
|
|
101
|
+
* Disabled button
|
|
102
|
+
*/
|
|
103
|
+
disabled: {
|
|
104
|
+
type: Boolean,
|
|
105
|
+
default: false,
|
|
106
|
+
},
|
|
97
107
|
/**
|
|
98
108
|
* The button label
|
|
99
109
|
*/
|
|
@@ -531,6 +541,22 @@ $text-neutral: (
|
|
|
531
541
|
.mc-button--text-neutral {
|
|
532
542
|
@include set-button-theme($text-neutral);
|
|
533
543
|
}
|
|
544
|
+
|
|
545
|
+
.mc-button--bordered-left {
|
|
546
|
+
background: transparent;
|
|
547
|
+
border-color: $color-success-500;
|
|
548
|
+
border-radius: 0.25rem 0 0 0.25rem;
|
|
549
|
+
color: $color-success-500;
|
|
550
|
+
padding: 0.375rem;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.mc-button--bordered-right {
|
|
554
|
+
background: transparent;
|
|
555
|
+
border-color: $color-success-500;
|
|
556
|
+
border-radius: 0 0.25rem 0.25rem 0;
|
|
557
|
+
color: $color-success-500;
|
|
558
|
+
padding: 0.375rem;
|
|
559
|
+
}
|
|
534
560
|
</style>
|
|
535
561
|
|
|
536
562
|
<style lang="scss">
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Meta, Canvas, Story, ArgsTable } from '@storybook/addon-docs';
|
|
2
|
+
import MQuantitySelector, { M_NOTIFICATION_VALIDATOR } from './MQuantitySelector';
|
|
3
|
+
|
|
4
|
+
<Meta title="Mozaic/Components/MQuantitySelector 🧬" component={MQuantitySelector} argTypes={{}} />
|
|
5
|
+
|
|
6
|
+
# 🧬 `MQuantitySelector` - Component
|
|
7
|
+
|
|
8
|
+
[](http://mozaic.adeo.cloud/Components/Notification/)
|
|
9
|
+
[](https://www.figma.com/file/XqqYm6Trew66wygIrVdH6r/%5BLIBRAIRIE%5D-Composants-Project-Booster?node-id=389%3A0)
|
|
10
|
+
[](https://github.com/adeo/project-booster-vue/tree/master/src/components/mozaic/notifications)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
The `MQuantitySelector` Vue component is the implementation of the [mozaic design system **notification** component](http://mozaic.adeo.cloud/Components/Notification/).
|
|
15
|
+
|
|
16
|
+
# `MQuantitySelector` - Component props
|
|
17
|
+
|
|
18
|
+
export const TemplateSandbox = (args, { argTypes }) => ({
|
|
19
|
+
props: Object.keys(argTypes),
|
|
20
|
+
components: { MQuantitySelector },
|
|
21
|
+
setup() {
|
|
22
|
+
return { args };
|
|
23
|
+
},
|
|
24
|
+
template: `<m-quantity-selector
|
|
25
|
+
:value="4"
|
|
26
|
+
:valuemin="0"
|
|
27
|
+
:valuemax="50"
|
|
28
|
+
/>`,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
<Canvas>
|
|
32
|
+
<Story
|
|
33
|
+
name="101 Sandbox"
|
|
34
|
+
inline={false}
|
|
35
|
+
height="512px"
|
|
36
|
+
args={{
|
|
37
|
+
title: 'Notification title',
|
|
38
|
+
text: 'Notification text',
|
|
39
|
+
linkLabel: 'Notification link',
|
|
40
|
+
closable: true,
|
|
41
|
+
}}
|
|
42
|
+
parameters={{ storyshots: { disable: true } }}
|
|
43
|
+
>
|
|
44
|
+
{TemplateSandbox.bind({})}
|
|
45
|
+
</Story>
|
|
46
|
+
</Canvas>
|
|
47
|
+
|
|
48
|
+
<ArgsTable story="101 Sandbox" />
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mc-quantity-selector">
|
|
3
|
+
<m-flex class="mc-quantity-selector__container" :class="cssFieldElementClass">
|
|
4
|
+
<m-button
|
|
5
|
+
class="mc-quantity-selector__button-left"
|
|
6
|
+
theme="bordered-left"
|
|
7
|
+
leftIcon="https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Control_Less_32px.svg"
|
|
8
|
+
icon-position="left"
|
|
9
|
+
:aria-label="decrementAriaLabel"
|
|
10
|
+
:aria-controls="id"
|
|
11
|
+
:disabled="currentValue <= valuemin"
|
|
12
|
+
:size="small ? 's' : null"
|
|
13
|
+
tabindex="-1"
|
|
14
|
+
type="button"
|
|
15
|
+
aria-hidden="true"
|
|
16
|
+
@click="decrement()"
|
|
17
|
+
/>
|
|
18
|
+
|
|
19
|
+
<m-text-input
|
|
20
|
+
:id="id"
|
|
21
|
+
v-model="currentValue"
|
|
22
|
+
type="number"
|
|
23
|
+
class="mc-quantity-selector__input"
|
|
24
|
+
name="quantity-selector-input"
|
|
25
|
+
:aria-label="inputAriaLabel"
|
|
26
|
+
:aria-valuenow="currentValue"
|
|
27
|
+
:aria-valuemin="valuemin"
|
|
28
|
+
:aria-valuemax="valuemax"
|
|
29
|
+
:placeholder="placeholder"
|
|
30
|
+
:rounded="false"
|
|
31
|
+
:textCenter="true"
|
|
32
|
+
:blankField="true"
|
|
33
|
+
:size="small ? 's' : null"
|
|
34
|
+
role="spinbutton"
|
|
35
|
+
@input="handle($event.target.value)"
|
|
36
|
+
@keypress="integerOnly && formatValue($event)"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<m-button
|
|
40
|
+
class="mc-quantity-selector__button-right"
|
|
41
|
+
theme="bordered-right"
|
|
42
|
+
leftIcon="https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Control_More_32px.svg"
|
|
43
|
+
icon-position="right"
|
|
44
|
+
:aria-label="incrementAriaLabel"
|
|
45
|
+
:aria-controls="id"
|
|
46
|
+
:disabled="currentValue === valuemax"
|
|
47
|
+
:size="small ? 's' : null"
|
|
48
|
+
tabindex="-1"
|
|
49
|
+
aria-hidden="true"
|
|
50
|
+
type="button"
|
|
51
|
+
@click="increment()"
|
|
52
|
+
/>
|
|
53
|
+
</m-flex>
|
|
54
|
+
<div v-if="!(error || errorMessage) && !info" class="m-text-input__error-placeholder mc-field__error-message">
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
<div v-else-if="error || errorMessage" class="m-text-input__error mc-field__error-message">
|
|
58
|
+
{{ error || errorMessage }}
|
|
59
|
+
</div>
|
|
60
|
+
<div v-else-if="info" class="m-text-input__info mc-field__error-message">
|
|
61
|
+
{{ info }}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<script>
|
|
67
|
+
import MButton from '../buttons/MButton.vue';
|
|
68
|
+
import MTextInput from '../text-input/MTextInput.vue';
|
|
69
|
+
import MFlex from '../flex/MFlex.vue';
|
|
70
|
+
|
|
71
|
+
export default {
|
|
72
|
+
name: 'MQuantitySelector',
|
|
73
|
+
|
|
74
|
+
components: {
|
|
75
|
+
MButton,
|
|
76
|
+
MTextInput,
|
|
77
|
+
MFlex,
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
inject: {
|
|
81
|
+
cssFieldElementClass: {
|
|
82
|
+
default: '',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
props: {
|
|
87
|
+
id: {
|
|
88
|
+
type: String,
|
|
89
|
+
default: 'qty-selector',
|
|
90
|
+
},
|
|
91
|
+
value: {
|
|
92
|
+
type: Number,
|
|
93
|
+
default: 0,
|
|
94
|
+
},
|
|
95
|
+
inputAriaLabel: {
|
|
96
|
+
type: String,
|
|
97
|
+
default: 'Quantity Selector',
|
|
98
|
+
},
|
|
99
|
+
decrementAriaLabel: {
|
|
100
|
+
type: String,
|
|
101
|
+
default: 'Decrement',
|
|
102
|
+
},
|
|
103
|
+
incrementAriaLabel: {
|
|
104
|
+
type: String,
|
|
105
|
+
default: 'Increment',
|
|
106
|
+
},
|
|
107
|
+
valuemin: {
|
|
108
|
+
type: Number,
|
|
109
|
+
default: 1,
|
|
110
|
+
},
|
|
111
|
+
valuemax: {
|
|
112
|
+
type: Number,
|
|
113
|
+
default: 100,
|
|
114
|
+
},
|
|
115
|
+
placeholder: {
|
|
116
|
+
type: String,
|
|
117
|
+
default: null,
|
|
118
|
+
},
|
|
119
|
+
small: {
|
|
120
|
+
type: Boolean,
|
|
121
|
+
default: false,
|
|
122
|
+
},
|
|
123
|
+
integerOnly: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: false,
|
|
126
|
+
},
|
|
127
|
+
error: {
|
|
128
|
+
type: String,
|
|
129
|
+
default: null,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
emits: ['input', 'increment', 'decrement'],
|
|
134
|
+
|
|
135
|
+
data() {
|
|
136
|
+
return {
|
|
137
|
+
currentValue: this.value || this.valuemin,
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
watch: {
|
|
142
|
+
currentValue(newValue, oldValue) {
|
|
143
|
+
this.handle(newValue);
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
methods: {
|
|
148
|
+
handle(value) {
|
|
149
|
+
this.currentValue = value;
|
|
150
|
+
if (this.currentValue > this.valuemax) {
|
|
151
|
+
this.currentValue = this.valuemax;
|
|
152
|
+
}
|
|
153
|
+
if (this.currentValue < this.valuemin) {
|
|
154
|
+
this.currentValue = this.valuemin;
|
|
155
|
+
}
|
|
156
|
+
this.$emit('input', this.currentValue);
|
|
157
|
+
},
|
|
158
|
+
increment() {
|
|
159
|
+
if (this.currentValue < this.valuemax) {
|
|
160
|
+
this.currentValue++;
|
|
161
|
+
this.$emit('increment', this.currentValue);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
decrement() {
|
|
165
|
+
if (this.currentValue > this.valuemin) {
|
|
166
|
+
this.currentValue--;
|
|
167
|
+
this.$emit('decrement', this.currentValue);
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
formatValue(e) {
|
|
171
|
+
const INTEGER_ONLY_REGEX = /[0-9/]+/;
|
|
172
|
+
if (!INTEGER_ONLY_REGEX.test(e.key)) {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
</script>
|
|
179
|
+
|
|
180
|
+
<style lang="scss">
|
|
181
|
+
@import 'settings-tools/_all-settings';
|
|
182
|
+
@import 'components/_c.quantity-selector';
|
|
183
|
+
|
|
184
|
+
.mc-quantity-selector__button-left,
|
|
185
|
+
.mc-quantity-selector__button-right {
|
|
186
|
+
margin: 0.5rem 0;
|
|
187
|
+
}
|
|
188
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-text-input mc-field">
|
|
2
|
+
<div class="m-text-input mc-field" :class="{ 'm-text-input__nomargin': blankField }">
|
|
3
3
|
<label v-if="label" class="m-text-input__label mc-field__label" :for="`input-${id}`">
|
|
4
4
|
{{ label }}
|
|
5
5
|
<span v-if="required" class="mc-field__requirement" aria-hidden="true"> obligatoire </span>
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
'is-valid': valid,
|
|
32
32
|
'is-invalid': invalid || errorMessage,
|
|
33
33
|
'mc-text-input--s': size === 's',
|
|
34
|
+
'unrounded': !rounded,
|
|
35
|
+
'text-center': textCenter,
|
|
34
36
|
}"
|
|
35
37
|
:name="name"
|
|
36
38
|
:disabled="disabled"
|
|
@@ -45,13 +47,25 @@
|
|
|
45
47
|
@blur="handleBlurEvent"
|
|
46
48
|
/>
|
|
47
49
|
</div>
|
|
48
|
-
<div
|
|
50
|
+
<div
|
|
51
|
+
v-if="!(error || errorMessage) && !info"
|
|
52
|
+
class="m-text-input__error-placeholder mc-field__error-message"
|
|
53
|
+
:class="{ 'm-text-input__blank': blankField }"
|
|
54
|
+
>
|
|
49
55
|
|
|
50
56
|
</div>
|
|
51
|
-
<div
|
|
57
|
+
<div
|
|
58
|
+
v-else-if="error || errorMessage"
|
|
59
|
+
class="m-text-input__error mc-field__error-message"
|
|
60
|
+
:class="{ 'm-text-input__blank': blankField }"
|
|
61
|
+
>
|
|
52
62
|
{{ error || errorMessage }}
|
|
53
63
|
</div>
|
|
54
|
-
<div
|
|
64
|
+
<div
|
|
65
|
+
v-else-if="info"
|
|
66
|
+
class="m-text-input__info mc-field__error-message"
|
|
67
|
+
:class="{ 'm-text-input__blank': blankField }"
|
|
68
|
+
>
|
|
55
69
|
{{ info }}
|
|
56
70
|
</div>
|
|
57
71
|
</div>
|
|
@@ -225,6 +239,27 @@ export default defineComponent({
|
|
|
225
239
|
type: Number,
|
|
226
240
|
default: -1,
|
|
227
241
|
},
|
|
242
|
+
/**
|
|
243
|
+
* Defines if this input has bordered
|
|
244
|
+
*/
|
|
245
|
+
rounded: {
|
|
246
|
+
type: Boolean,
|
|
247
|
+
default: true,
|
|
248
|
+
},
|
|
249
|
+
/**
|
|
250
|
+
* Defines text alignment inside input
|
|
251
|
+
*/
|
|
252
|
+
textCenter: {
|
|
253
|
+
type: Boolean,
|
|
254
|
+
default: false,
|
|
255
|
+
},
|
|
256
|
+
/**
|
|
257
|
+
* Definies if input has blank fields
|
|
258
|
+
*/
|
|
259
|
+
blankField: {
|
|
260
|
+
type: Boolean,
|
|
261
|
+
default: false,
|
|
262
|
+
},
|
|
228
263
|
},
|
|
229
264
|
|
|
230
265
|
setup(props, { emit, expose }) {
|
|
@@ -354,4 +389,24 @@ export default defineComponent({
|
|
|
354
389
|
@import 'components/c.text-input';
|
|
355
390
|
@import 'components/c.left-icon-input';
|
|
356
391
|
@import 'components/c.fields';
|
|
392
|
+
|
|
393
|
+
.unrounded {
|
|
394
|
+
border-left: 0;
|
|
395
|
+
border-radius: 0;
|
|
396
|
+
border-right: 0;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.text-center {
|
|
400
|
+
text-align: center;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.m-text-input__blank {
|
|
404
|
+
display: none !important;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.m-text-input__nomargin {
|
|
408
|
+
input {
|
|
409
|
+
margin-top: 0 !important;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
357
412
|
</style>
|
|
@@ -136,9 +136,7 @@ export default defineComponent({
|
|
|
136
136
|
|
|
137
137
|
async handleValidateClicked() {
|
|
138
138
|
this.$emit('step-completed', {
|
|
139
|
-
answers: this.payload.multiSelect.actions.VALIDATE.isAnswer
|
|
140
|
-
? [this.payload.multiSelect.actions.VALIDATE.code]
|
|
141
|
-
: [],
|
|
139
|
+
answers: this.payload.multiSelect.actions.VALIDATE.isAnswer ? [this.payload.multiSelect.actions.VALIDATE] : [],
|
|
142
140
|
nextStep: this.payload.multiSelect.actions.VALIDATE.nextStep,
|
|
143
141
|
});
|
|
144
142
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface IncrementalAmountValidation {
|
|
2
|
+
minValue: number;
|
|
3
|
+
maxValue: number;
|
|
4
|
+
defaultValue: number;
|
|
5
|
+
requiredErrorMessage: string;
|
|
6
|
+
thresholdsIncluded: number;
|
|
7
|
+
minValueErrorMessage: string;
|
|
8
|
+
maxValueErrorMessage: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IncrementalAmountViewModel {
|
|
12
|
+
backLabel: string;
|
|
13
|
+
label: string;
|
|
14
|
+
actionLabel: string;
|
|
15
|
+
validation: IncrementalAmountValidation;
|
|
16
|
+
minValue: number;
|
|
17
|
+
maxValue: number;
|
|
18
|
+
defaultValue: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IncrementalAmountPayload {
|
|
22
|
+
viewModel: IncrementalAmountViewModel;
|
|
23
|
+
defaultDecoratorValue: string;
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
|
|
2
|
+
import { ArgsTable, Canvas, Meta, Source, Story } from '@storybook/addon-docs';
|
|
3
|
+
import PbIncrementalAmountInput from './PbIncrementalAmountInput';
|
|
4
|
+
import DEFAULT_PAYLOAD from './default-payload.json';
|
|
5
|
+
|
|
6
|
+
<Meta
|
|
7
|
+
title="Project Booster/Scenario/Questions/PbIncrementalAmountInput 🦠"
|
|
8
|
+
component={PbIncrementalAmountInput}
|
|
9
|
+
decorators={[nestedAppDecorator({}, [])]}
|
|
10
|
+
parameters={{ layout: 'fullscreen' }}
|
|
11
|
+
/>
|
|
12
|
+
|
|
13
|
+
# 🦠 `PbFamilyAmountInput` - Components
|
|
14
|
+
|
|
15
|
+
[](https://github.com/adeo/project-booster-vue/tree/master/src/components/question)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
The `PbIncrementalAmountInput` Vue component allows select family amount persons. It
|
|
20
|
+
is customizable through the payload property. It has the same
|
|
21
|
+
behaviour as the `PbQuestion` component and is designed to work in scenarii.
|
|
22
|
+
|
|
23
|
+
It has a default provided payload, used in the Sandbox below.
|
|
24
|
+
|
|
25
|
+
The input field is automatically focused.
|
|
26
|
+
|
|
27
|
+
The back button will make `vue-router` trigger the history back feature from the browser. It can be hidden with the
|
|
28
|
+
`showBackButton` flag.
|
|
29
|
+
|
|
30
|
+
# `PbIncrementalAmountInput` - Component props
|
|
31
|
+
|
|
32
|
+
export const TemplateSandbox = (args, { argTypes }) => ({
|
|
33
|
+
props: Object.keys(argTypes),
|
|
34
|
+
components: { PbIncrementalAmountInput },
|
|
35
|
+
setup() {
|
|
36
|
+
return { args };
|
|
37
|
+
},
|
|
38
|
+
template: `<pb-incremental-amount-input
|
|
39
|
+
:payload="args.payload"
|
|
40
|
+
:show-back-button="args.showBackButton"
|
|
41
|
+
:completed-event-name="args.completedEventName"
|
|
42
|
+
@step-completed="args.onStepCompleted"
|
|
43
|
+
/>`,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
<Canvas>
|
|
47
|
+
<Story name="101 Sandbox" args={{ payload: DEFAULT_PAYLOAD }}>
|
|
48
|
+
{TemplateSandbox.bind({})}
|
|
49
|
+
</Story>
|
|
50
|
+
</Canvas>
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<m-flex class="pb-incremental-amount-input" direction="column" align-items="center">
|
|
3
|
+
<m-flex class="pb-incremental-amount-input__back-button-container" align-items="stretch">
|
|
4
|
+
<m-link
|
|
5
|
+
:label="computedPayload.viewModel.backLabel"
|
|
6
|
+
:left-icon="BACK_ICON"
|
|
7
|
+
:class="{
|
|
8
|
+
'pb-incremental-amount-input__back-button': true,
|
|
9
|
+
'pb-incremental-amount-input__back-button--hidden':
|
|
10
|
+
!showBackButton && !decorate(answers, runtimeOptions, payload.viewModel.forceBackButton),
|
|
11
|
+
}"
|
|
12
|
+
@click.once="$emit('go-back')"
|
|
13
|
+
/>
|
|
14
|
+
</m-flex>
|
|
15
|
+
|
|
16
|
+
<div class="pb-incremental-amount-input__title">
|
|
17
|
+
{{ computedPayload.viewModel.label }}
|
|
18
|
+
</div>
|
|
19
|
+
<div class="pb-incremental-amount-input__subtitle">
|
|
20
|
+
{{ computedPayload.viewModel.subtitle }}
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<form
|
|
24
|
+
class="pb-incremental-amount-input__form-container"
|
|
25
|
+
ref="pbDimensionsInputFormContainerObserver"
|
|
26
|
+
@submit.prevent="handleFormSubmit"
|
|
27
|
+
>
|
|
28
|
+
<m-flex class="pb-incremental-amount-input__form" direction="column" align-items="stretch">
|
|
29
|
+
<m-flex class="pb-incremental-amount-input__header" ref="PbIncrementalAmountInput" direction="column">
|
|
30
|
+
<m-flex
|
|
31
|
+
v-if="computedPayload.viewModel.image"
|
|
32
|
+
class="pb-incremental-amount-input__image"
|
|
33
|
+
direction="column"
|
|
34
|
+
align-items="center"
|
|
35
|
+
>
|
|
36
|
+
<img :src="computedPayload.viewModel.image" alt="Image décorative" />
|
|
37
|
+
</m-flex>
|
|
38
|
+
</m-flex>
|
|
39
|
+
</m-flex>
|
|
40
|
+
|
|
41
|
+
<m-flex class="pb-incremental-amount-input__body" justify-content="start" align-items="start">
|
|
42
|
+
<m-quantity-selector
|
|
43
|
+
:value="computedPayload.viewModel.defaultValue"
|
|
44
|
+
:valuemin="computedPayload.viewModel.minValue"
|
|
45
|
+
:valuemax="computedPayload.viewModel.maxValue"
|
|
46
|
+
@input="handleQuantitySelector"
|
|
47
|
+
:integerOnly="true"
|
|
48
|
+
/>
|
|
49
|
+
</m-flex>
|
|
50
|
+
|
|
51
|
+
<m-flex class="pb-incremental-amount-input__buttons-container" direction="column" align-items="center">
|
|
52
|
+
<m-button
|
|
53
|
+
class="pb-incremental-amount-input__button"
|
|
54
|
+
:label="computedPayload.viewModel.actionLabel"
|
|
55
|
+
width="full"
|
|
56
|
+
size="l"
|
|
57
|
+
type="submit"
|
|
58
|
+
/>
|
|
59
|
+
</m-flex>
|
|
60
|
+
</form>
|
|
61
|
+
</m-flex>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script lang="ts">
|
|
65
|
+
import { defineComponent, computed, onMounted, ComputedRef, PropType, Ref } from 'vue';
|
|
66
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
67
|
+
import cloneDeep from 'lodash.clonedeep';
|
|
68
|
+
import merge from 'lodash.merge';
|
|
69
|
+
import MFlex from './../../mozaic/flex/MFlex.vue';
|
|
70
|
+
import DEFAULT_PAYLOAD from './default-payload.json';
|
|
71
|
+
import MLink from '../../mozaic/link/MLink.vue';
|
|
72
|
+
import MButton from '../../mozaic/buttons/MButton.vue';
|
|
73
|
+
import { ref } from 'vue';
|
|
74
|
+
import { ScenarioStepAnswer } from '@/types/pb/Scenario';
|
|
75
|
+
import { decorate } from '@/components/question/PbQuestion.vue';
|
|
76
|
+
import MQuantitySelector from '../../mozaic/quantityselector/MQuantitySelector.vue';
|
|
77
|
+
|
|
78
|
+
const BACK_ICON =
|
|
79
|
+
'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
|
|
80
|
+
|
|
81
|
+
export default defineComponent({
|
|
82
|
+
name: 'PbIncrementalAmountInput',
|
|
83
|
+
components: {
|
|
84
|
+
MFlex,
|
|
85
|
+
MLink,
|
|
86
|
+
MButton,
|
|
87
|
+
MQuantitySelector,
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
props: {
|
|
91
|
+
/**
|
|
92
|
+
* The component view model and business data as an object. The provided prop
|
|
93
|
+
* is merged with the default payload value so only overriden values will change
|
|
94
|
+
* from the default ones.
|
|
95
|
+
*/
|
|
96
|
+
payload: {
|
|
97
|
+
type: Object,
|
|
98
|
+
default: () => ({}),
|
|
99
|
+
},
|
|
100
|
+
/**
|
|
101
|
+
* The options provided at runtime to customize component behaviour
|
|
102
|
+
*/
|
|
103
|
+
runtimeOptions: {
|
|
104
|
+
type: Object,
|
|
105
|
+
default: () => ({}),
|
|
106
|
+
},
|
|
107
|
+
/**
|
|
108
|
+
* Indicates whether the back button should be displayed
|
|
109
|
+
*/
|
|
110
|
+
showBackButton: {
|
|
111
|
+
type: Boolean,
|
|
112
|
+
default: true,
|
|
113
|
+
},
|
|
114
|
+
/**
|
|
115
|
+
* Name for the event to send when the step is questio is answered
|
|
116
|
+
*/
|
|
117
|
+
completedEventName: {
|
|
118
|
+
type: String,
|
|
119
|
+
default: 'step-completed',
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* The previous answers to inject
|
|
123
|
+
*/
|
|
124
|
+
answers: {
|
|
125
|
+
type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
|
|
126
|
+
default: () => new Map<string, ScenarioStepAnswer[]>(),
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* Define default value
|
|
130
|
+
*/
|
|
131
|
+
defaultValue: {
|
|
132
|
+
type: Number,
|
|
133
|
+
default: 1,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
setup(props, { emit }) {
|
|
137
|
+
const componentId = uuidv4();
|
|
138
|
+
const computedPayload = computed(() => {
|
|
139
|
+
const tempPayload = cloneDeep(DEFAULT_PAYLOAD);
|
|
140
|
+
return merge(tempPayload, props.payload);
|
|
141
|
+
});
|
|
142
|
+
const pbIncrementalAmountInput = ref<HTMLElement>();
|
|
143
|
+
let quantitySelector = props.payload.viewModel.defaultValue || props.defaultValue;
|
|
144
|
+
|
|
145
|
+
const handleFormSubmit = () => {
|
|
146
|
+
emit(props.completedEventName, {
|
|
147
|
+
answers: [
|
|
148
|
+
{
|
|
149
|
+
value: quantitySelector,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const handleQuantitySelector = (value: number): void => {
|
|
156
|
+
quantitySelector = value;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
onMounted(() => {
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
pbIncrementalAmountInput.value?.focus();
|
|
162
|
+
}, 150);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
id: componentId,
|
|
167
|
+
handleFormSubmit,
|
|
168
|
+
BACK_ICON,
|
|
169
|
+
computedPayload,
|
|
170
|
+
pbIncrementalAmountInput,
|
|
171
|
+
quantitySelector,
|
|
172
|
+
handleQuantitySelector,
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
</script>
|
|
177
|
+
|
|
178
|
+
<style lang="scss" scoped>
|
|
179
|
+
@import 'pb-variables';
|
|
180
|
+
|
|
181
|
+
$small-responsive-breakpoint: 's-large';
|
|
182
|
+
$responsive-breakpoint: 'm';
|
|
183
|
+
|
|
184
|
+
.pb-incremental-amount-input {
|
|
185
|
+
@include set-font-face('regular');
|
|
186
|
+
|
|
187
|
+
flex-grow: 1;
|
|
188
|
+
margin: 0 auto;
|
|
189
|
+
width: calc(100% - #{$mu050} - #{$mu050});
|
|
190
|
+
|
|
191
|
+
&__back-button-container {
|
|
192
|
+
align-self: flex-start;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
&__back-button {
|
|
196
|
+
opacity: 1;
|
|
197
|
+
padding: $mu100 0 $mu100 $mu025;
|
|
198
|
+
transition: opacity 0.15s 0.5s;
|
|
199
|
+
|
|
200
|
+
&--hidden {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
pointer-events: none;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
&__body {
|
|
207
|
+
flex-wrap: wrap;
|
|
208
|
+
margin-bottom: $mu250;
|
|
209
|
+
max-width: 100%;
|
|
210
|
+
|
|
211
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
212
|
+
flex-wrap: nowrap;
|
|
213
|
+
width: 161px;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
&--input-container {
|
|
217
|
+
width: 100%;
|
|
218
|
+
|
|
219
|
+
&__validator {
|
|
220
|
+
width: 100%;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
&__center {
|
|
225
|
+
width: 65px;
|
|
226
|
+
|
|
227
|
+
input {
|
|
228
|
+
border-left: 0;
|
|
229
|
+
border-radius: 0;
|
|
230
|
+
border-right: 0;
|
|
231
|
+
margin-top: 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
&__reduce,
|
|
236
|
+
&__up {
|
|
237
|
+
margin-top: 0.5rem;
|
|
238
|
+
|
|
239
|
+
svg {
|
|
240
|
+
height: 1rem;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
&__form-container {
|
|
246
|
+
align-items: center;
|
|
247
|
+
display: flex;
|
|
248
|
+
flex-direction: column;
|
|
249
|
+
flex-grow: 1;
|
|
250
|
+
|
|
251
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
252
|
+
//width: calc(100% - #{$mu050} - #{$mu050});
|
|
253
|
+
width: 314px;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
&__form {
|
|
258
|
+
flex-grow: 1;
|
|
259
|
+
max-width: 100%;
|
|
260
|
+
width: 384px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
&__title {
|
|
264
|
+
@include set-font-face('semi-bold');
|
|
265
|
+
@include set-font-scale('07', 's');
|
|
266
|
+
|
|
267
|
+
color: $color-grey-700;
|
|
268
|
+
max-width: 100%;
|
|
269
|
+
padding: 0 0 0 0;
|
|
270
|
+
width: 384px;
|
|
271
|
+
|
|
272
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
273
|
+
@include set-font-scale('08', 'm');
|
|
274
|
+
|
|
275
|
+
padding: $mu250 $mu100 $mu100 $mu100;
|
|
276
|
+
text-align: center;
|
|
277
|
+
width: auto;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
&__subtitle {
|
|
282
|
+
color: $color-grey-700;
|
|
283
|
+
max-width: 100%;
|
|
284
|
+
padding: 0 0 $mu250 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
&__image {
|
|
288
|
+
padding-bottom: $mu200;
|
|
289
|
+
|
|
290
|
+
img {
|
|
291
|
+
display: none;
|
|
292
|
+
width: 70%;
|
|
293
|
+
|
|
294
|
+
@include set-from-screen($small-responsive-breakpoint) {
|
|
295
|
+
display: block;
|
|
296
|
+
width: 70%;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
300
|
+
width: 90%;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
&__text-input {
|
|
306
|
+
width: 100%;
|
|
307
|
+
z-index: 2;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
&__separator {
|
|
311
|
+
color: $color-grey-500;
|
|
312
|
+
display: none;
|
|
313
|
+
padding: $mu125 $mu100 0 $mu100;
|
|
314
|
+
|
|
315
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
316
|
+
display: flex;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
&__buttons-container {
|
|
321
|
+
justify-content: flex-end !important;
|
|
322
|
+
margin-bottom: $mu100;
|
|
323
|
+
position: sticky;
|
|
324
|
+
width: 100%;
|
|
325
|
+
z-index: 1;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
&__link {
|
|
329
|
+
margin-top: $mu250;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"viewModel": {
|
|
3
|
+
"backLabel": "Question précédente",
|
|
4
|
+
"label": "Combien de personnes vivent dans votre foyer fiscal ?",
|
|
5
|
+
"subtitle": "Cette information est utile pour le calcul des aides",
|
|
6
|
+
"actionLabel": "Continuer",
|
|
7
|
+
"image": "https://storage.googleapis.com/project-booster-media/new-house/Estimation%20Construction%20Neuve%20-%20Localisation.png",
|
|
8
|
+
"minValue": 1,
|
|
9
|
+
"maxValue": 20,
|
|
10
|
+
"defaultValue": 1
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -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>
|
|
@@ -103,6 +103,8 @@ import PbSpaceInput from '../question/space-input/PbSpaceInput.vue';
|
|
|
103
103
|
import PbUploadDocument from '../question/upload-document/PbUploadDocument.vue';
|
|
104
104
|
import PbConfigurationsImport from '../question/configurations-import/PbConfigurationsImport.vue';
|
|
105
105
|
import PbCitySearch from '../question/city-search/PbCitySearch.vue';
|
|
106
|
+
import PbWarningMessage from '../warning-message/PbWarningMessage.vue';
|
|
107
|
+
import PbIncrementalAmountInput from '../question/incremental-amount-input/PbIncrementalAmountInput.vue';
|
|
106
108
|
import { areConditionsValid } from '../../services/scenarioConditionals';
|
|
107
109
|
import {
|
|
108
110
|
Scenario,
|
|
@@ -138,6 +140,8 @@ export default defineComponent({
|
|
|
138
140
|
PbConfigurationsImport,
|
|
139
141
|
PbAppointmentForm,
|
|
140
142
|
PbCitySearch,
|
|
143
|
+
PbWarningMessage,
|
|
144
|
+
PbIncrementalAmountInput,
|
|
141
145
|
},
|
|
142
146
|
|
|
143
147
|
props: {
|