project-booster-vue 9.42.0 → 9.42.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.42.0",
3
+ "version": "9.42.2",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -143,7 +143,9 @@ export default defineComponent({
143
143
 
144
144
  async handleValidateClicked() {
145
145
  this.$emit('step-completed', {
146
- answers: this.payload.multiSelect.actions.VALIDATE.isAnswer ? [this.payload.multiSelect.actions.VALIDATE] : [],
146
+ answers: this.payload.multiSelect.actions.VALIDATE.isAnswer
147
+ ? [this.payload.multiSelect.actions.VALIDATE]
148
+ : null,
147
149
  nextStep: this.payload.multiSelect.actions.VALIDATE.nextStep,
148
150
  });
149
151
  },
@@ -102,6 +102,7 @@ export default defineComponent({
102
102
  computed: {
103
103
  ...mapGetters('products', {
104
104
  product: 'getCurrentProduct',
105
+ refProduct: 'getRefProduct',
105
106
  }),
106
107
  ...mapGetters('appointmentQualification', {
107
108
  sessions: 'getSessions',
@@ -109,7 +110,6 @@ export default defineComponent({
109
110
  },
110
111
  created() {
111
112
  this.$store.dispatch('products/loadProduct', {
112
- uuid: this.$route.params.refProduct || null,
113
113
  payload: this.payload.viewModel.defaultProduct,
114
114
  sessions: this.sessions,
115
115
  });
@@ -120,10 +120,16 @@ export default defineComponent({
120
120
  if (action.code === '__BACK__') {
121
121
  this.$emit('go-back');
122
122
  } else {
123
+ let product = null;
124
+
125
+ if (this.refProduct) {
126
+ product = this.product;
127
+ }
128
+
123
129
  this.$emit('step-completed', {
124
130
  answers: [
125
131
  {
126
- product: this.product,
132
+ product: product,
127
133
  },
128
134
  ],
129
135
  nextStep: action,
@@ -3,11 +3,8 @@
3
3
  "backLabel": "Question précédente",
4
4
  "label": "Estimer votre projet de rénovation énergétique en 2mn",
5
5
  "defaultProduct": {
6
- "price": {
7
- "initialUnitAmount": 200
8
- },
9
6
  "designation": "Pompe à chaleur air/air",
10
- "photo": "https://storage.googleapis.com/project-booster-media/energyrenovation/heat-pump-air-water/default_heat_pump.jpg"
7
+ "photo": "https://storage.googleapis.com/project-booster-media/energyrenovation/default_heat_pump.jpg"
11
8
  }
12
9
  },
13
10
  "callToActions": [
@@ -138,7 +138,7 @@ export const TemplateSandbox = (args, { argTypes }) => ({
138
138
  <Canvas>
139
139
  <Story
140
140
  name="101 Sandbox"
141
- args={{ payload: DEFAULT_PAYLOAD, runtimeOptions: { isLoggedIn: true } }}
141
+ args={{ payload: DEFAULT_PAYLOAD, runtimeOptions: { isLoggedIn: true, projectMode: true } }}
142
142
  parameters={{
143
143
  msw: [
144
144
  rest.get('/api/inhabitant-projects', getProjectsResolver),
@@ -50,6 +50,13 @@
50
50
  :label="button.label"
51
51
  @click="callAction(button.action)"
52
52
  :theme="button.bordered ? 'bordered' : 'solid'"
53
+ v-if="!button.conditions"
54
+ />
55
+ <m-button
56
+ :label="button.label"
57
+ @click="callAction(button.action)"
58
+ :theme="button.bordered ? 'bordered' : 'solid'"
59
+ v-if="checkConditional(button.conditions) && button.conditions"
53
60
  />
54
61
  </div>
55
62
  <div class="pb-restitution-list__footer__save">
@@ -142,6 +149,7 @@ import { RestitutionPayload, RestitutionPayloadAction } from '@/types/pb/Restitu
142
149
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
143
150
  import PbRestitutionListBlock from './PbRestitutionListBlock.vue';
144
151
  import { Project } from '../../types/pb/Project';
152
+ import { areConditionsValid } from '../../services/scenarioConditionals';
145
153
 
146
154
  export default defineComponent({
147
155
  components: {
@@ -211,11 +219,21 @@ export default defineComponent({
211
219
  created() {
212
220
  if (this.payload?.callToActions) {
213
221
  if (this.payload?.callToActions) {
222
+ const saveAction = Object.values(this.payload.callToActions).find((cta) => {
223
+ return (
224
+ areConditionsValid(cta.conditions!, this.answers, this.runtimeOptions) &&
225
+ cta.action?.type === 'MODAL' &&
226
+ cta.action?.component === 'PbProjectItemSave'
227
+ );
228
+ });
214
229
  this.showSaveProjectItem = this.showSaveEstimate;
215
230
  }
216
231
  }
217
232
  },
218
233
  methods: {
234
+ checkConditional(cta: any) {
235
+ return areConditionsValid(cta, this.answers, this.runtimeOptions);
236
+ },
219
237
  handleShowDialog(content: any) {
220
238
  this.dialogContent = content;
221
239
  this.showDialog = !this.showDialog;
@@ -251,6 +269,11 @@ export default defineComponent({
251
269
  this.showSaveProjectItem = true;
252
270
  }
253
271
 
272
+ this.$emit('click-save-item', {
273
+ answers: [],
274
+ action: action,
275
+ });
276
+ } else if (action.code === 'SAVED_ITEM') {
254
277
  this.$emit('click-save-item', {
255
278
  answers: [],
256
279
  action: action,
@@ -6,9 +6,22 @@
6
6
  {
7
7
  "type": "button",
8
8
  "label": "Être rappelé par un expert",
9
- "href": "",
9
+ "action": {
10
+ "type": "STEP",
11
+ "code": "STEP_CODE"
12
+ },
10
13
  "bordered": false
11
14
  },
15
+ {
16
+ "conditions": ["runtimeOptions.projectMode === true"],
17
+ "type": "button",
18
+ "label": "J'enregistre mon estimation",
19
+ "bordered": true,
20
+ "action": {
21
+ "type": "MODAL",
22
+ "code": "SUMMARY"
23
+ }
24
+ },
12
25
  {
13
26
  "conditions": ["!runtimeOptions.projectMode && !runtimeOptions.estimateCreated"],
14
27
  "type": "button",
@@ -106,6 +106,7 @@ import PbConfigurationsImport from '../question/configurations-import/PbConfigur
106
106
  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
+ import PbTrezor from '../trezor/PbTrezor.vue';
109
110
  import PbIncrementalAmountInput from '../question/incremental-amount-input/PbIncrementalAmountInput.vue';
110
111
  import { areConditionsValid } from '../../services/scenarioConditionals';
111
112
  import {
@@ -146,6 +147,7 @@ export default defineComponent({
146
147
  PbWarningMessage,
147
148
  PbIncrementalAmountInput,
148
149
  PbProducts,
150
+ PbTrezor,
149
151
  },
150
152
 
151
153
  props: {
@@ -1,5 +1,13 @@
1
1
  <template>
2
2
  <m-flex class="pb-trezor" direction="column">
3
+ <m-link
4
+ v-if="showBackButton"
5
+ :left-icon="BACK_ICON"
6
+ :label="payload.viewModel.backLabel || 'Retour'"
7
+ class="pb-trezor__back-button"
8
+ @click.once="$emit('go-back')"
9
+ />
10
+
3
11
  <div class="pb-trezor__title" v-if="payload?.viewModel?.label">
4
12
  {{ payload.viewModel.label }}
5
13
  </div>
@@ -114,9 +122,12 @@ import { useStore } from 'vuex';
114
122
  import MFlex from './../mozaic/flex/MFlex.vue';
115
123
  import MButton from '../mozaic/buttons/MButton.vue';
116
124
  import MCheckbox from '../mozaic/checkbox/MCheckbox.vue';
125
+ import MLink from '../mozaic/link/MLink.vue';
117
126
  import MTextInput from '../mozaic/text-input/MTextInput.vue';
118
127
  import { ScenarioStepAnswer } from '@/types/pb/Scenario';
119
128
  import { object, string, boolean } from 'yup';
129
+ const BACK_ICON =
130
+ 'https://storage.googleapis.com/project-booster-media/mozaic-icons/svg/Navigation_Arrow_Arrow--Left_16px.svg';
120
131
 
121
132
  export default defineComponent({
122
133
  name: 'PbTrezor',
@@ -125,6 +136,7 @@ export default defineComponent({
125
136
  MButton,
126
137
  MTextInput,
127
138
  MCheckbox,
139
+ MLink,
128
140
  },
129
141
  props: {
130
142
  /**
@@ -167,7 +179,7 @@ export default defineComponent({
167
179
  },
168
180
  setup(props, { emit }) {
169
181
  const store = useStore();
170
- let formData = ref({
182
+ let formData = ref<any>({
171
183
  values: {
172
184
  lastname: '',
173
185
  firstname: '',
@@ -209,33 +221,32 @@ export default defineComponent({
209
221
 
210
222
  const validateAllFields = async (action: any) => {
211
223
  await validationSchema.validate(formData.value.values).then(async () => {
212
- const sending = await store.dispatch(
213
- 'trezor/sendFormData',
214
- {
224
+ const sending = await store.dispatch('trezor/sendFormData', {
225
+ payload: {
215
226
  customer: {
216
227
  lastname: formData.value.values.lastname,
217
228
  firstname: formData.value.values.firstname,
218
- zipcode: formData.value.values.zipcode,
229
+ zip: formData.value.values.zipcode,
219
230
  email: formData.value.values.email,
220
231
  phone: formData.value.values.phone,
221
232
  },
222
233
  optin: formData.value.values.optin,
223
234
  optinPartners: formData.value.values.optinPartners,
224
235
  },
225
- props.payload.viewModel.typeLead,
226
- );
236
+ typeLead: props.payload.viewModel.typeLead,
237
+ });
227
238
 
228
239
  if (sending) {
229
240
  emit('step-completed', {
230
- answers: [],
231
- nextStep: action,
241
+ answers: null,
242
+ nextStep: action.action,
232
243
  });
233
244
  }
234
245
  });
235
246
  };
236
247
 
237
248
  const callAction = async (item: any) => {
238
- if (item.action.type === 'submit') {
249
+ if (item.action.type === 'STEP') {
239
250
  await validateAllFields(item);
240
251
  }
241
252
  };
@@ -244,6 +255,7 @@ export default defineComponent({
244
255
  formData,
245
256
  callAction,
246
257
  validate,
258
+ BACK_ICON,
247
259
  };
248
260
  },
249
261
  });
@@ -260,6 +272,20 @@ $responsive-breakpoint: 'm';
260
272
  .pb-trezor {
261
273
  margin: 0 auto;
262
274
  max-width: 1024px;
275
+
276
+ &__back-button {
277
+ align-self: flex-start;
278
+ opacity: 1;
279
+ padding: $mu100 0 $mu100 $mu100;
280
+ transition: opacity 0.15s 0.5s;
281
+ z-index: 2;
282
+
283
+ &--hidden {
284
+ opacity: 0;
285
+ pointer-events: none;
286
+ }
287
+ }
288
+
263
289
  &__title {
264
290
  @include set-font-face('semi-bold');
265
291
  @include set-font-scale('08', 'm');
@@ -269,7 +295,7 @@ $responsive-breakpoint: 'm';
269
295
 
270
296
  @include set-from-screen($responsive-breakpoint) {
271
297
  margin: auto;
272
- padding: $mu250 0 $mu250 0;
298
+ padding: 0 0 $mu250 0;
273
299
  text-align: center;
274
300
  }
275
301
  }
@@ -9,7 +9,8 @@
9
9
  "type": "button",
10
10
  "label": "Envoyer",
11
11
  "action": {
12
- "type": "submit"
12
+ "type": "STEP",
13
+ "code": "STEP_CODE"
13
14
  },
14
15
  "bordered": false
15
16
  }
@@ -20,11 +20,14 @@ export const updateProductApiClient = (config: { apiKey: string; baseUrl: string
20
20
  };
21
21
 
22
22
  export const getProductById = async (productId: string, storeId: string) => {
23
- const response = await clientApi.get(`/product/${productId}${storeId ? '?storeId=' + storeId : ''}`);
24
-
25
- return JSON.parse(
26
- JSON.stringify(response.data).replace(/:"([^"]+)"/g, (match, $1) => {
27
- return `: "${escape($1)}"`;
28
- }),
29
- );
23
+ try {
24
+ const response = await clientApi.get(`/products/${productId}${storeId ? '?storeId=' + storeId : ''}`);
25
+ return JSON.parse(
26
+ JSON.stringify(response.data).replace(/:"([^"]+)"/g, (match, $1) => {
27
+ return `: "${escape($1)}"`;
28
+ }),
29
+ );
30
+ } catch (e) {
31
+ return false;
32
+ }
30
33
  };
@@ -37,12 +37,16 @@ export default {
37
37
  commit('setRefProduct', ref);
38
38
  },
39
39
  async loadProduct({ commit, state }: ProductContext, { payload, sessions }: { payload: object; sessions: any }) {
40
- if (!state.refProduct) {
41
- commit('setCurrentProduct', payload);
42
- } else {
43
- const product = await getProductById(state.refProduct, sessions.storeId);
40
+ if (state.refProduct) {
41
+ const product = await getProductById(state.refProduct, (sessions && sessions.storeId) || null);
44
42
 
45
- commit('setCurrentProduct', product);
43
+ if (product) {
44
+ commit('setCurrentProduct', { ...payload, ...product });
45
+ } else {
46
+ commit('setCurrentProduct', payload);
47
+ }
48
+ } else {
49
+ commit('setCurrentProduct', payload);
46
50
  }
47
51
  },
48
52
  },
@@ -30,7 +30,7 @@ export default {
30
30
  { commit, state }: TrezorContext,
31
31
  { payload, typeLead }: { payload: object; typeLead: string },
32
32
  ) => {
33
- if (!typeLead) {
33
+ if (typeLead) {
34
34
  const sendData = await sendTrezorForm(typeLead, payload);
35
35
  commit('setFormData', sendData);
36
36
  }
@@ -8,6 +8,7 @@ import { PlannerState } from '@/stores/modules/plannerStore';
8
8
  import { ProjectsState } from '@/stores/modules/projectsStore';
9
9
  import { ToolsState } from '@/stores/modules/toolsStore';
10
10
  import { ProductState } from './modules/productsStore';
11
+ import { TrezorState } from './modules/trezorStore';
11
12
 
12
13
  export interface State {
13
14
  appointmentQualification: AppointmentQualificationState;
@@ -20,4 +21,5 @@ export interface State {
20
21
  projects: ProjectsState;
21
22
  tools: ToolsState;
22
23
  products: ProductState;
24
+ trezor: TrezorState;
23
25
  }