project-booster-vue 9.47.1 → 9.49.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.47.1",
3
+ "version": "9.49.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -36,8 +36,10 @@
36
36
  "@mozaic-ds/icons": "^1.49.0",
37
37
  "@mozaic-ds/styles": "^1.49.1",
38
38
  "@mozaic-ds/tokens": "^1.47.0",
39
+ "@mozaic-ds/vue-3": "^0.35.1",
39
40
  "@mozaic-ds/web-fonts": "^1.22.0",
40
41
  "@types/lodash.isempty": "4.4.6",
42
+ "@vue/test-utils": "^2.2.6",
41
43
  "@xstate/vue": "0.8.1",
42
44
  "ajv": "8.6.0",
43
45
  "axios": "0.25.0",
@@ -61,7 +63,7 @@
61
63
  "uuid": "8.3.2",
62
64
  "vee-validate": "4.4.5",
63
65
  "velocity-animate": "1.5.2",
64
- "vue": "3.2.31",
66
+ "vue": "^3.2.41",
65
67
  "vue-router": "4.0.12",
66
68
  "vue3-cookies": "1.0.6",
67
69
  "vuex": "4.0.2",
@@ -130,7 +132,6 @@
130
132
  "@vue/eslint-config-prettier": "6.0.0",
131
133
  "@vue/eslint-config-standard": "6.0.0",
132
134
  "@vue/eslint-config-typescript": "10.0.0",
133
- "@vue/test-utils": "2.0.0-rc.10",
134
135
  "axios-curl": "2.0.1",
135
136
  "babel-eslint": "10.1.0",
136
137
  "babel-jest": "26.6.3",
@@ -39,6 +39,7 @@
39
39
  class="pb-space-input__text-input"
40
40
  :placeholder="computedPayload.viewModel.placeholder"
41
41
  v-model="space"
42
+ :data-cerberus="sanitizeCerberusAttribut('PB-SPACE-INPUT', 'SURFACE')"
42
43
  />
43
44
  <div class="pb-space-input__unit">
44
45
  <span v-if="computedPayload.viewModel.unitLabel">{{ computedPayload.viewModel.unitLabel }}</span>
@@ -77,6 +78,7 @@
77
78
  size="l"
78
79
  theme="primary"
79
80
  @click="handleShowModal(helpItem.action.dialogViewModel)"
81
+ :data-cerberus="sanitizeCerberusAttribut('PB-SPACE-INPUT', helpItem.label)"
80
82
  />
81
83
  </div>
82
84
  </div>
@@ -90,6 +92,7 @@
90
92
  size="l"
91
93
  @click="handleFormSubmit"
92
94
  :disabled="disabledNextStep"
95
+ :data-cerberus="sanitizeCerberusAttribut('PB-SPACE-INPUT', computedPayload.viewModel.actionLabel)"
93
96
  />
94
97
  <m-link
95
98
  v-if="payload.skippable"
@@ -99,6 +102,7 @@
99
102
  width="full"
100
103
  size="l"
101
104
  @click="skipQuestion"
105
+ :data-cerberus="sanitizeCerberusAttribut('PB-SPACE-INPUT', payload.skippable.label)"
102
106
  />
103
107
  </m-flex>
104
108
  </m-flex>
@@ -149,6 +153,7 @@ import { SpaceInputPayload } from '@/components/question/space-input/SpaceInput'
149
153
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
150
154
  import { decorate } from '@/services/decorate';
151
155
  import { id } from 'date-fns/locale';
156
+ import { sanitizeCerberusAttribut } from '@/services/sanitize';
152
157
 
153
158
  const BACK_ICON =
154
159
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
@@ -333,6 +338,7 @@ export default defineComponent({
333
338
  handleShowModal,
334
339
  contentModal,
335
340
  disabledNextStep,
341
+ sanitizeCerberusAttribut,
336
342
  };
337
343
  },
338
344
  });
@@ -3,10 +3,17 @@
3
3
  <m-flex full-width>
4
4
  <div class="pb-restitution-line__label" v-html="line.text"></div>
5
5
  <m-flex class="pb-restitution-line__price" v-if="line.cost" justify-content="flex-end" wrap>
6
- <div v-if="line.cost.min !== line.cost.max" class="pb-restitution-line__price-min">
6
+ <div
7
+ v-if="line.cost.min !== line.cost.max"
8
+ class="pb-restitution-line__price-min"
9
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESITUTION-LINE', 'MIN-COST')"
10
+ >
7
11
  {{ formatPriceRange(line.cost.min, line.cost.max).min }}&nbsp;-&nbsp;
8
12
  </div>
9
- <div class="pb-restitution-line__price-max">
13
+ <div
14
+ class="pb-restitution-line__price-max"
15
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESITUTION-LINE', 'MAX-COST')"
16
+ >
10
17
  {{ formatPriceRange(line.cost.min, line.cost.max).max }}
11
18
  </div>
12
19
  </m-flex>
@@ -18,6 +25,7 @@
18
25
  <script lang="ts">
19
26
  import { defineComponent } from 'vue';
20
27
  import MFlex from '../mozaic/flex/MFlex.vue';
28
+ import { sanitizeCerberusAttribut } from '@/services/sanitize';
21
29
 
22
30
  const CROSS_ICON =
23
31
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Control_Cross_24px.svg';
@@ -46,6 +54,9 @@ export default defineComponent({
46
54
  CROSS_ICON,
47
55
  INFO_ICON,
48
56
  }),
57
+ methods: {
58
+ sanitizeCerberusAttribut,
59
+ },
49
60
  });
50
61
  </script>
51
62
 
@@ -44,13 +44,20 @@
44
44
  </m-flex>
45
45
  </m-flex>
46
46
 
47
- <m-flex class="pb-restitution-list__footer" direction="row" align-items="center" justify-content="center">
47
+ <m-flex
48
+ class="pb-restitution-list__footer"
49
+ direction="row"
50
+ align-items="center"
51
+ justify-content="center"
52
+ v-if="showButtonBar"
53
+ >
48
54
  <div class="pb-restitution-list__footer__call" v-for="button in payload.callToActions" :key="button.label">
49
55
  <m-button
50
56
  :label="button.label"
51
57
  @click="callAction(button.action)"
52
58
  :theme="button.bordered ? 'bordered' : 'solid'"
53
59
  v-if="areConditionsValid(button.conditions)"
60
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', button.label)"
54
61
  />
55
62
  </div>
56
63
  <div class="pb-restitution-list__footer__save">
@@ -59,6 +66,7 @@
59
66
  @item-saved="handleItemCreated"
60
67
  @dialog-close="handleDialogClose"
61
68
  v-if="isLoggedIn"
69
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', 'save-estimate')"
62
70
  />
63
71
  </div>
64
72
  </m-flex>
@@ -84,7 +92,7 @@
84
92
  >
85
93
  <div v-html="component.title"></div>
86
94
  <div v-if="component.cost.min != component.cost.max">
87
- <strong>
95
+ <strong :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', 'TOP-RESTITUTION-RANGE')">
88
96
  {{ formattedPriceRange(component.cost.min) }} et
89
97
  {{ formattedPriceRange(component.cost.max) }}
90
98
  </strong>
@@ -125,9 +133,15 @@
125
133
  <div><strong>Montant total</strong>&nbsp; (aides déduites)</div>
126
134
  <div class="space-mx">entre</div>
127
135
  <div>
128
- <strong v-html="formattedPriceRange(summary.cost.min)"></strong>
136
+ <strong
137
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', 'BOTTOM-MIN-RESTITUTION-RANGE')"
138
+ v-html="formattedPriceRange(summary.cost.min)"
139
+ ></strong>
129
140
  <div class="space-mx">et</div>
130
- <strong v-html="formattedPriceRange(summary.cost.max)"></strong>
141
+ <strong
142
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', 'BOTTOM-MAX-RESTITUTION-RANGE')"
143
+ v-html="formattedPriceRange(summary.cost.max)"
144
+ ></strong>
131
145
  </div>
132
146
  </div>
133
147
 
@@ -164,6 +178,7 @@ import { Project } from '../../types/pb/Project';
164
178
  import { areConditionsValid } from '../../services/scenarioConditionals';
165
179
  const BACK_ICON =
166
180
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
181
+ import { sanitizeCerberusAttribut } from '@/services/sanitize';
167
182
 
168
183
  export default defineComponent({
169
184
  components: {
@@ -225,6 +240,13 @@ export default defineComponent({
225
240
  type: Boolean,
226
241
  default: false,
227
242
  },
243
+ /**
244
+ * Show button bar save/another actions
245
+ */
246
+ showButtonBar: {
247
+ type: Boolean,
248
+ default: true,
249
+ },
228
250
  },
229
251
  computed: {
230
252
  ...mapGetters('estimates', { summary: 'getSummary' }),
@@ -304,6 +326,7 @@ export default defineComponent({
304
326
  areConditionsValid(conditions: string[]) {
305
327
  return areConditionsValid(conditions, this.answers, this.runtimeOptions);
306
328
  },
329
+ sanitizeCerberusAttribut,
307
330
  },
308
331
  });
309
332
  </script>
@@ -27,6 +27,7 @@
27
27
  class="pb-restitution-list-block__body__show"
28
28
  label="Voir le détail de l'estimation"
29
29
  @click="handleLinkClick(payload)"
30
+ :data-cerberus="sanitizeCerberusAttribut('PB-RESTITUTION', 'VIEW-DETAILS')"
30
31
  />
31
32
  </div>
32
33
  </m-flex>
@@ -44,6 +45,7 @@ import MButton from '../mozaic/buttons/MButton.vue';
44
45
  import PbRestitutionListLine from './PbRestitutionListLine.vue';
45
46
  import { mapGetters } from 'vuex';
46
47
  import { Restitution } from '@/types/pb/Restitution';
48
+ import { sanitizeCerberusAttribut } from '@/services/sanitize';
47
49
 
48
50
  export default defineComponent({
49
51
  components: {
@@ -72,6 +74,7 @@ export default defineComponent({
72
74
  formattedPriceRange(price: any) {
73
75
  return Math.round(price).toLocaleString() + '€';
74
76
  },
77
+ sanitizeCerberusAttribut,
75
78
  },
76
79
  });
77
80
  </script>
@@ -0,0 +1,48 @@
1
+ import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
2
+ import { ArgsTable, Canvas, Meta, Source, Story } from '@storybook/addon-docs';
3
+ import cloneDeep from 'lodash.clonedeep';
4
+ import MPbProducts from './MPbProducts';
5
+ import productsStore from '../../../stores/modules/productsStore';
6
+ import metaDataStore from '../../../stores/modules/metaDataStore';
7
+ import DEFAULT_PAYLOAD from './default-payload.json';
8
+
9
+ <Meta
10
+ title="Project Booster/Rework/Products/MPbProducts 🦠"
11
+ component={MPbProducts}
12
+ decorators={[
13
+ nestedAppDecorator(
14
+ {
15
+ modules: {
16
+ products: productsStore,
17
+ metaData: metaDataStore,
18
+ },
19
+ mutations: {},
20
+ actions: {},
21
+ },
22
+ [],
23
+ ),
24
+ ]}
25
+ parameters={{ layout: 'fullscreen' }}
26
+ />
27
+
28
+ # `MPbProducts` - Component
29
+
30
+ export const TemplateSandbox = (args, { argTypes }) => ({
31
+ props: Object.keys(argTypes),
32
+ components: { MPbProducts },
33
+ setup() {
34
+ return { args };
35
+ },
36
+ template: `<m-pb-products
37
+ :payload="args.payload"
38
+ :show-back-button="args.showBackButton"
39
+ :completed-event-name="args.completedEventName"
40
+ @step-completed="args.onStepCompleted"
41
+ />`,
42
+ });
43
+
44
+ <Canvas>
45
+ <Story name="101 Sandbox" args={{ payload: DEFAULT_PAYLOAD }}>
46
+ {TemplateSandbox.bind({})}
47
+ </Story>
48
+ </Canvas>
@@ -0,0 +1,231 @@
1
+ <template>
2
+ <div class="pb-products">
3
+ <div class="pb-products__back-button-container">
4
+ <m-link
5
+ icon="ArrowArrowLeft48"
6
+ :class="{
7
+ 'pb-products__back-button': true,
8
+ }"
9
+ @click.once="emit('go-back')"
10
+ >
11
+ {{ payload.viewModel.backLabel }}
12
+ </m-link>
13
+ </div>
14
+
15
+ <div class="pb-products__body row-flex column" v-if="product">
16
+ <div class="pb-products__title">
17
+ {{ payload.viewModel.label }}
18
+ </div>
19
+
20
+ <div class="pb-products__body__item" v-if="product">
21
+ <div class="pb-products__body__item__thumbnail">
22
+ <img :src="product.photo" alt="" />
23
+ </div>
24
+ <div class="pb-products__body__item__title">{{ product.designation }}</div>
25
+ </div>
26
+
27
+ <div class="pb-products__container--button">
28
+ <m-button
29
+ :theme="action.bordered ? 'bordered' : 'solid'"
30
+ class="pb-products__container--button__ok"
31
+ :type="action.type"
32
+ :label="action.label"
33
+ icon-position="right"
34
+ size="m"
35
+ :href="action.href"
36
+ v-for="action in payload.callToActions"
37
+ :key="action.label"
38
+ @click="callAction(action.action)"
39
+ />
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </template>
44
+
45
+ <script lang="ts" setup>
46
+ import { useStore } from 'vuex';
47
+ import { MButton, MLink } from '@mozaic-ds/vue-3';
48
+ import { ScenarioStepAnswer } from '@/types/pb/Scenario';
49
+ import { defineProps, PropType, onMounted, ref } from 'vue';
50
+ import { PayloadAction } from '../types/genericPayload';
51
+
52
+ const emit = defineEmits(['go-back', 'step-completed']);
53
+
54
+ const store = useStore();
55
+ const metadata = store.getters['metaData/metaData'];
56
+ const refProduct = store.getters['products/getRefProduct'];
57
+ const product = ref({});
58
+
59
+ const props = defineProps({
60
+ /**
61
+ * The component view model and business data as an object. The provided prop
62
+ * is merged with the default payload value so only overriden values will change
63
+ * from the default ones.
64
+ */
65
+ payload: {
66
+ type: Object,
67
+ default: () => ({}),
68
+ },
69
+ /**
70
+ * The options provided at runtime to customize component behaviour
71
+ */
72
+ runtimeOptions: {
73
+ type: Object,
74
+ default: () => ({}),
75
+ },
76
+ /**
77
+ * Indicates whether the back button should be displayed
78
+ */
79
+ showBackButton: {
80
+ type: Boolean,
81
+ default: true,
82
+ },
83
+ /**
84
+ * Name for the event to send when the step is questio is answered
85
+ */
86
+ completedEventName: {
87
+ type: String,
88
+ default: 'step-completed',
89
+ },
90
+ /**
91
+ * The previous answers to inject
92
+ */
93
+ answers: {
94
+ type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
95
+ default: () => new Map<string, ScenarioStepAnswer[]>(),
96
+ },
97
+ });
98
+
99
+ /**
100
+ * onMounted load product and load this
101
+ */
102
+ onMounted(() => {
103
+ store.dispatch('products/loadProduct', {
104
+ payload: props.payload.viewModel.defaultProduct,
105
+ storeId: metadata && metadata.storeId ? metadata.storeId : '',
106
+ });
107
+ product.value = store.getters['products/getCurrentProduct'];
108
+ });
109
+
110
+ /**
111
+ * Send action to completed step
112
+ * @param action
113
+ */
114
+ const callAction = (action: PayloadAction) => {
115
+ if (action.type === 'STEP') {
116
+ if (action.code === '__BACK__') {
117
+ emit('go-back');
118
+ } else {
119
+ let productToSend = null;
120
+
121
+ if (refProduct) {
122
+ productToSend = product;
123
+ }
124
+
125
+ emit('step-completed', {
126
+ answers: [
127
+ {
128
+ product: productToSend,
129
+ },
130
+ ],
131
+ nextStep: action,
132
+ });
133
+ }
134
+ }
135
+ };
136
+ </script>
137
+
138
+ <style lang="scss" scoped>
139
+ @import 'pb-variables';
140
+ @import 'settings-tools/all-settings';
141
+ @import 'typography/_t.bodys';
142
+ @import '../styles/global.scss';
143
+
144
+ $small-responsive-breakpoint: 's-large';
145
+ $responsive-breakpoint: 'm';
146
+
147
+ .pb-products {
148
+ @include set-font-face('regular');
149
+
150
+ flex-grow: 1;
151
+ margin: 0 auto;
152
+ padding: 0 $mu100;
153
+ width: calc(100% - #{$mu100} - #{$mu100});
154
+
155
+ @include set-from-screen($responsive-breakpoint) {
156
+ width: calc(100% - #{$mu200} - #{$mu200});
157
+ }
158
+
159
+ &__back-button-container {
160
+ align-self: flex-start;
161
+ }
162
+ &__back-button {
163
+ opacity: 1;
164
+ padding: $mu100 0 $mu100 $mu025;
165
+ transition: opacity 0.15s 0.5s;
166
+ &--hidden {
167
+ opacity: 0;
168
+ pointer-events: none;
169
+ }
170
+ }
171
+
172
+ &__title {
173
+ @include set-font-face('semi-bold');
174
+ @include set-font-scale('08', 'm');
175
+
176
+ color: $color-grey-999;
177
+ max-width: 100%;
178
+ padding: 0;
179
+ text-align: left;
180
+ margin-top: $mu150;
181
+
182
+ &::after {
183
+ display: block;
184
+ width: 72px;
185
+ height: 4px;
186
+ content: '';
187
+ margin: $mu100 0 $mu150 0;
188
+ background: $color-primary-01-500;
189
+ }
190
+
191
+ @include set-from-screen($responsive-breakpoint) {
192
+ @include set-font-scale('08', 'm');
193
+
194
+ width: auto;
195
+ }
196
+ }
197
+
198
+ &__body {
199
+ margin: auto;
200
+
201
+ @include set-from-screen($responsive-breakpoint) {
202
+ width: 591px;
203
+ }
204
+
205
+ &__item {
206
+ &__thumbnail {
207
+ margin-bottom: $mu150;
208
+
209
+ img {
210
+ width: 230px;
211
+ }
212
+ }
213
+
214
+ &__title {
215
+ @include set-font-face('semi-bold');
216
+ @include set-font-scale('07', 's');
217
+
218
+ color: $color-grey-800;
219
+ }
220
+ }
221
+ }
222
+
223
+ &__container--button {
224
+ margin-top: $mu100;
225
+
226
+ &__ok {
227
+ margin-bottom: $mu100;
228
+ }
229
+ }
230
+ }
231
+ </style>
@@ -0,0 +1,21 @@
1
+ {
2
+ "viewModel": {
3
+ "backLabel": "Question précédente",
4
+ "label": "Estimer vos aides pour votre projet",
5
+ "defaultProduct": {
6
+ "designation": "Installation d'une chaudière à",
7
+ "photo": "https://storage.googleapis.com/project-booster-media/energyrenovation/default_heat_pump.jpg"
8
+ }
9
+ },
10
+ "callToActions": [
11
+ {
12
+ "type": "button",
13
+ "label": "Commencer la simulation",
14
+ "action": {
15
+ "type": "STEP",
16
+ "code": "__END__"
17
+ },
18
+ "bordered": false
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,15 @@
1
+ .row-flex {
2
+ display: flex;
3
+
4
+ &.column {
5
+ flex-direction: column;
6
+ }
7
+
8
+ &.justify-center {
9
+ justify-content: center;
10
+ }
11
+
12
+ &.align-center {
13
+ align-items: center;
14
+ }
15
+ }
@@ -0,0 +1,8 @@
1
+ export interface PayloadAction {
2
+ type: string;
3
+ code: string;
4
+ component?: string;
5
+ payload?: {
6
+ link: string;
7
+ };
8
+ }
@@ -107,6 +107,7 @@ import PbCitySearch from '../question/city-search/PbCitySearch.vue';
107
107
  import PbWarningMessage from '../warning-message/PbWarningMessage.vue';
108
108
  import PbProducts from '../products/PbProducts.vue';
109
109
  import PbTrezor from '../trezor/PbTrezor.vue';
110
+ import MPbProductsVue from '../rework/products/MPbProducts.vue';
110
111
  import PbIncrementalAmountInput from '../question/incremental-amount-input/PbIncrementalAmountInput.vue';
111
112
  import { areConditionsValid } from '../../services/scenarioConditionals';
112
113
  import {
@@ -148,6 +149,7 @@ export default defineComponent({
148
149
  PbIncrementalAmountInput,
149
150
  PbProducts,
150
151
  PbTrezor,
152
+ MPbProductsVue,
151
153
  },
152
154
 
153
155
  props: {
@@ -21,6 +21,7 @@
21
21
  label="Nom"
22
22
  :required="true"
23
23
  class="pb-trezor__input"
24
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'LASTNAME')"
24
25
  ></m-text-input>
25
26
  </m-flex>
26
27
 
@@ -32,6 +33,7 @@
32
33
  label="Prénom"
33
34
  :required="true"
34
35
  class="pb-trezor__input"
36
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'FIRSTNAME')"
35
37
  ></m-text-input>
36
38
  </m-flex>
37
39
 
@@ -43,6 +45,7 @@
43
45
  label="Code postal"
44
46
  :required="true"
45
47
  class="pb-trezor__input"
48
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'ZIPCODE')"
46
49
  ></m-text-input>
47
50
  </m-flex>
48
51
 
@@ -54,6 +57,7 @@
54
57
  label="E-mail"
55
58
  :required="true"
56
59
  class="pb-trezor__input"
60
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'EMAIL')"
57
61
  ></m-text-input>
58
62
  </m-flex>
59
63
 
@@ -65,6 +69,7 @@
65
69
  label="Numéro de téléphone"
66
70
  :required="true"
67
71
  class="pb-trezor__input"
72
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'PHONE')"
68
73
  ></m-text-input>
69
74
  </m-flex>
70
75
 
@@ -75,6 +80,7 @@
75
80
  :required="true"
76
81
  label="J'ai lu est accepte sans réserve les conditions générales d'utilisation"
77
82
  v-model="formData.values.optin"
83
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'CGU')"
78
84
  ></m-checkbox>
79
85
  </m-flex>
80
86
 
@@ -84,6 +90,7 @@
84
90
  :required="false"
85
91
  v-model="formData.values.optinPartners"
86
92
  label="J'autorise Leroy Merlin à transmettre les données collectées ici à l'un de nos partenaires susceptibles de réaliser le chantier (en fonction des critères géographiques)"
93
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'PARTNER')"
87
94
  ></m-checkbox>
88
95
  </m-flex>
89
96
 
@@ -99,6 +106,7 @@
99
106
  v-for="action in payload.callToActions"
100
107
  :key="action.label"
101
108
  @click.prevent="callAction(action)"
109
+ :data-cerberus="sanitizeCerberusAttribut('PB-TREZOR', 'SENDFORM')"
102
110
  />
103
111
  </m-flex>
104
112
  </div>
@@ -120,6 +128,7 @@ import { TrezorInterface } from './PbTrezorInterface';
120
128
  import objectPath from 'object-path';
121
129
  const BACK_ICON =
122
130
  'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
131
+ import { sanitizeCerberusAttribut } from '@/services/sanitize';
123
132
 
124
133
  export default defineComponent({
125
134
  name: 'PbTrezor',
@@ -295,6 +304,7 @@ export default defineComponent({
295
304
  formData,
296
305
  callAction,
297
306
  BACK_ICON,
307
+ sanitizeCerberusAttribut,
298
308
  };
299
309
  },
300
310
  });