project-booster-vue 9.4.0 → 9.7.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/appointment/PbAppointmentForm.stories.mdx +94 -0
- package/src/components/appointment/PbAppointmentForm.vue +57 -0
- package/src/components/appointment/PbAppointmentStartSection.vue +52 -1
- package/src/components/appointment/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-appointment-qualification-pb-appointment-form-/360/237/246/240-101-sandbox-1-snap.png +0 -0
- package/src/components/pedagogy/PbPedagogy.stories.mdx +2 -2
- package/src/components/pedagogy/PbPedagogy.vue +41 -9
- package/src/components/pedagogy/default-payload.json +6 -1
- package/src/components/projects/project-hub/PbProjectHub-Features-Appointment.stories.mdx +21 -4
- package/src/components/projects/project-hub/PbProjectHub.vue +24 -4
- package/src/components/projects/project-hub/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-project-hub-/360/237/246/240-features-appointment-showcase-with-store-appointment-1-snap.png +0 -0
- package/src/components/projects/project-hub/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-project-hub-/360/237/246/240-features-appointment-showcase-with-visio-appointment-1-snap.png +0 -0
- package/src/components/question/PbQuestion.vue +11 -13
- package/src/components/question/list-select/PbListSelect.vue +1 -1
- package/src/components/scenario/{PbScenario-Features-Test.stories.mdx → PbScenario-Features-Appointment.stories.mdx} +59 -3
- package/src/components/scenario/PbScenario.vue +15 -2
- package/src/components/scenario/scenarii/appointment-qualification-kitchen.json +242 -69
- package/src/services/api/appointmentQualificationsApi.ts +35 -1
- package/src/services/api/mocks/inhabitantsMock.ts +1 -0
- package/src/services/api/mocks/jsons/projects.json +8 -1
- package/src/services/api/mocks/projectsMock.ts +14 -3
- package/src/stores/modules/appointmentQualificationStore.ts +58 -0
- package/src/components/pedagogy/PbPedagogyStore.ts +0 -17
package/package.json
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Story, Meta, ArgsTable, Canvas } from '@storybook/addon-docs';
|
|
2
|
+
import { nestedAppDecorator } from '../../../.storybook/nested-app-decorator';
|
|
3
|
+
import PbAppointmentForm from './PbAppointmentForm';
|
|
4
|
+
import appointmentQualificationStore from '../../stores/modules/appointmentQualificationStore';
|
|
5
|
+
import inhabitantsStore from '../../stores/modules/inhabitantsStore';
|
|
6
|
+
import { rest } from 'msw';
|
|
7
|
+
import { useStore } from 'vuex';
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
import { getInhabitantByIdResolver } from '../../services/api/mocks/inhabitantsMock';
|
|
10
|
+
import { declarationsWithAppointmentResolver } from '../../services/api/mocks/appointmentQualificationMock';
|
|
11
|
+
import SCENARIO from '../scenario/scenarii/appointment-qualification-kitchen.json';
|
|
12
|
+
|
|
13
|
+
<Meta
|
|
14
|
+
title="Project Booster/Components/Appointment qualification/ PbAppointmentForm 🦠"
|
|
15
|
+
component={PbAppointmentForm}
|
|
16
|
+
argTypes={{}}
|
|
17
|
+
parameters={{
|
|
18
|
+
layout: 'fullscreen',
|
|
19
|
+
}}
|
|
20
|
+
decorators={[
|
|
21
|
+
nestedAppDecorator(
|
|
22
|
+
{
|
|
23
|
+
modules: {
|
|
24
|
+
appointmentQualification: appointmentQualificationStore,
|
|
25
|
+
inhabitants: inhabitantsStore,
|
|
26
|
+
},
|
|
27
|
+
mutations: {
|
|
28
|
+
eventBusSendEvent(state, { code, payload }) {
|
|
29
|
+
console.log('event bus data : ', code, payload);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
actions: {
|
|
33
|
+
sendEventToBus({ commit }, action) {
|
|
34
|
+
commit('eventBusSendEvent', action);
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
[],
|
|
39
|
+
),
|
|
40
|
+
]}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
# 🦠 `PbAppointmentForm` - Component
|
|
44
|
+
|
|
45
|
+
The `PbAppointmentForm` component that include in a iframe the clicRDV form.
|
|
46
|
+
|
|
47
|
+
export const TemplateSandbox = (args, { argTypes }) => ({
|
|
48
|
+
props: Object.keys(argTypes),
|
|
49
|
+
components: { PbAppointmentForm },
|
|
50
|
+
setup() {
|
|
51
|
+
const store = useStore();
|
|
52
|
+
store.dispatch('appointmentQualification/initSessions', {
|
|
53
|
+
formId: 'appointment-qualification-kitchen',
|
|
54
|
+
correlationId: uuidv4(),
|
|
55
|
+
businessUnit: '001',
|
|
56
|
+
source: 'APPOINTMENT_QUALIFICATION',
|
|
57
|
+
sourceDetail: 'KITCHEN',
|
|
58
|
+
calendarId: '375615',
|
|
59
|
+
storeId: '006',
|
|
60
|
+
appointmentQualificationFormStructure: SCENARIO,
|
|
61
|
+
});
|
|
62
|
+
store.commit('appointmentQualification/setCurrentAppointmentQualification', {
|
|
63
|
+
inhabitantProjectId: uuidv4(),
|
|
64
|
+
appointmentQualificationId: uuidv4(),
|
|
65
|
+
});
|
|
66
|
+
store.commit('inhabitants/setCurrentInhabitant', {
|
|
67
|
+
firstName: 'Jean',
|
|
68
|
+
lastName: 'Dupont',
|
|
69
|
+
email: 'jean.dupont@yopmail.com',
|
|
70
|
+
});
|
|
71
|
+
store.commit('appointmentQualification/setClicRDVBaseUrl', 'https://sandbox-user.clicrdv.com');
|
|
72
|
+
return { args };
|
|
73
|
+
},
|
|
74
|
+
template: `<pb-appointment-form />
|
|
75
|
+
/>`,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
<Canvas>
|
|
79
|
+
<Story
|
|
80
|
+
inline={false}
|
|
81
|
+
height="862px"
|
|
82
|
+
name="101 Sandbox"
|
|
83
|
+
parameters={{
|
|
84
|
+
msw: [
|
|
85
|
+
rest.get('/api/inhabitant-api/users/:buId/:inhabitantId', getInhabitantByIdResolver),
|
|
86
|
+
rest.post('/api/declarations-without-appointment', declarationsWithAppointmentResolver),
|
|
87
|
+
],
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
{TemplateSandbox.bind({})}
|
|
91
|
+
</Story>
|
|
92
|
+
</Canvas>
|
|
93
|
+
|
|
94
|
+
<ArgsTable story="101 Sandbox" />
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<m-flex class="pb-appointment-form__container">
|
|
3
|
+
<iframe v-if="appointmentFormUrl" :src="appointmentFormUrl" style="border: 0; min-height: 110rem; width: 100%">
|
|
4
|
+
<p>
|
|
5
|
+
Your browser doesn't support iframes. To book an appointment, please follow this link :
|
|
6
|
+
<a :href="appointmentFormUrl">{{ appointmentFormUrl }}</a>
|
|
7
|
+
</p>
|
|
8
|
+
</iframe>
|
|
9
|
+
</m-flex>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { computed, defineComponent } from 'vue';
|
|
14
|
+
import { useStore } from 'vuex';
|
|
15
|
+
import MFlex from '../mozaic/flex/MFlex.vue';
|
|
16
|
+
|
|
17
|
+
export default defineComponent({
|
|
18
|
+
name: 'PbAppointmentForm',
|
|
19
|
+
components: { MFlex },
|
|
20
|
+
|
|
21
|
+
setup() {
|
|
22
|
+
const store = useStore();
|
|
23
|
+
|
|
24
|
+
const appointmentFormUrl = computed(() => {
|
|
25
|
+
const sessions = store.getters['appointmentQualification/getSessions'];
|
|
26
|
+
const currentAppointmentQualification =
|
|
27
|
+
store.getters['appointmentQualification/getCurrentAppointmentQualification'];
|
|
28
|
+
const currentUser = store.getters['inhabitants/getCurrentInhabitant'];
|
|
29
|
+
const baseUrl = store.getters['appointmentQualification/getClicRDVBaseUrl'];
|
|
30
|
+
|
|
31
|
+
let url = `${baseUrl}{/leroy-merlin-${sessions.storeId}`;
|
|
32
|
+
url += `?calendar_id=${sessions.calendarId}`;
|
|
33
|
+
url += `&vevent[str5]=${currentAppointmentQualification.inhabitantProjectId}`;
|
|
34
|
+
url += `&fiche[email]=${currentUser.email}`;
|
|
35
|
+
url += `&fiche[lastname]=${currentUser.lastName}`;
|
|
36
|
+
url += `&fiche[firstname]=${currentUser.firstName}`;
|
|
37
|
+
|
|
38
|
+
return url;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
appointmentFormUrl,
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<style lang="scss" scoped>
|
|
49
|
+
@import 'pb-variables';
|
|
50
|
+
|
|
51
|
+
.pb-appointment-form {
|
|
52
|
+
&__container {
|
|
53
|
+
margin: 0 auto;
|
|
54
|
+
width: 100%;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<m-flex full-width class="pb-appointment-section">
|
|
3
3
|
<m-flex align-items="center" full-width class="pb-appointment-section__content" direction="column">
|
|
4
|
-
<div class="pb-appointment-section__content-title">
|
|
4
|
+
<div class="pb-appointment-section__content-title">
|
|
5
|
+
{{ decorate(payload.viewModel.title, payload.defaultDecoratorValue) }}
|
|
6
|
+
</div>
|
|
5
7
|
<m-flex
|
|
6
8
|
justify-content="center"
|
|
7
9
|
align-items="center"
|
|
@@ -50,6 +52,7 @@ import MFlex from '../mozaic/flex/MFlex.vue';
|
|
|
50
52
|
import PbItemsList from '../items/PbItemsList.vue';
|
|
51
53
|
import MButton from '../mozaic/buttons/MButton.vue';
|
|
52
54
|
import { ScenarioStepAnswer, ScenarioStepPayload } from '@/types/pb/Scenario';
|
|
55
|
+
import objectPath from 'object-path';
|
|
53
56
|
|
|
54
57
|
export default defineComponent({
|
|
55
58
|
name: 'PbAppointmentStartSection',
|
|
@@ -62,6 +65,20 @@ export default defineComponent({
|
|
|
62
65
|
type: Object as PropType<ScenarioStepPayload>,
|
|
63
66
|
default: () => null,
|
|
64
67
|
},
|
|
68
|
+
/**
|
|
69
|
+
* The options provided at runtime to customize component behaviour
|
|
70
|
+
*/
|
|
71
|
+
runtimeOptions: {
|
|
72
|
+
type: Object,
|
|
73
|
+
default: () => ({}),
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* The previous answers to inject
|
|
77
|
+
*/
|
|
78
|
+
answers: {
|
|
79
|
+
type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
|
|
80
|
+
default: () => new Map<string, ScenarioStepAnswer[]>(),
|
|
81
|
+
},
|
|
65
82
|
},
|
|
66
83
|
methods: {
|
|
67
84
|
selectAnswer(answer: ScenarioStepAnswer) {
|
|
@@ -70,6 +87,40 @@ export default defineComponent({
|
|
|
70
87
|
nextStep: undefined,
|
|
71
88
|
});
|
|
72
89
|
},
|
|
90
|
+
decorate(valueToDecorate: string, defaultValue = '') {
|
|
91
|
+
if (valueToDecorate) {
|
|
92
|
+
valueToDecorate = `\`${valueToDecorate}\``;
|
|
93
|
+
try {
|
|
94
|
+
return this.doEval(valueToDecorate, defaultValue);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.error(e);
|
|
97
|
+
return valueToDecorate;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return valueToDecorate;
|
|
101
|
+
},
|
|
102
|
+
decorateBoolean(valueToDecorate: string, defaultValue = false) {
|
|
103
|
+
if (valueToDecorate) {
|
|
104
|
+
return this.doEval(valueToDecorate, defaultValue);
|
|
105
|
+
}
|
|
106
|
+
return valueToDecorate;
|
|
107
|
+
},
|
|
108
|
+
doEval(valueToEval: string, defaultValue: string | boolean) {
|
|
109
|
+
return new Function('getAnswerValue', 'answers', 'defaultValue', 'runtimeOptions', `return ${valueToEval}`).call(
|
|
110
|
+
this,
|
|
111
|
+
this.getAnswerValue,
|
|
112
|
+
Object.fromEntries(this.answers),
|
|
113
|
+
defaultValue,
|
|
114
|
+
this.runtimeOptions,
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
getAnswerValue(answerCode: string, path: string) {
|
|
118
|
+
if (!this.answers.get(answerCode) || this.answers.get(answerCode)?.length === 0) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return objectPath.get(this.answers.get(answerCode)?.at(0) as any, path);
|
|
123
|
+
},
|
|
73
124
|
},
|
|
74
125
|
});
|
|
75
126
|
</script>
|
|
@@ -2,7 +2,7 @@ import { Anchor, Story, Preview, Meta, Props, ArgsTable, Source, Canvas } from '
|
|
|
2
2
|
import DEFAULT_PAYLOAD from './default-payload';
|
|
3
3
|
import { nestedAppDecorator } from '../../../.storybook/nested-app-decorator';
|
|
4
4
|
import PbPedagogy from './PbPedagogy';
|
|
5
|
-
import
|
|
5
|
+
import store from '../../stores/store';
|
|
6
6
|
|
|
7
7
|
<Meta
|
|
8
8
|
title="Project Booster/Components/Pedagogy/ PbPedagogy 🦠"
|
|
@@ -23,7 +23,7 @@ import { pbPedagogyStore } from './PbPedagogyStore';
|
|
|
23
23
|
parameters={{
|
|
24
24
|
layout: 'fullscreen',
|
|
25
25
|
}}
|
|
26
|
-
decorators={[nestedAppDecorator(
|
|
26
|
+
decorators={[nestedAppDecorator(store, [])]}
|
|
27
27
|
/>
|
|
28
28
|
|
|
29
29
|
# 🦠 `PbPedagogy` - Component
|
|
@@ -4,10 +4,16 @@
|
|
|
4
4
|
<m-icon class="pb-pedagogy__content-icon" :icon="payload.viewModel.icon" color="primary-01-500" size="xl" />
|
|
5
5
|
<div class="pb-pedagogy__content-title">{{ payload.viewModel.title }}</div>
|
|
6
6
|
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
<m-flex class="pb-pedagogy__content-description" v-if="payload.viewModel.description" direction="column">
|
|
8
|
+
<div
|
|
9
|
+
class="pb-pedagogy__content-description-line"
|
|
10
|
+
v-for="(line, index) in payload.viewModel.description"
|
|
11
|
+
:key="index"
|
|
12
|
+
>
|
|
13
|
+
<m-icon :icon="line.icon" v-if="line.icon" />
|
|
14
|
+
<div class="pb-pedagogy__content-description-line-text" v-html="line.label" />
|
|
15
|
+
</div>
|
|
16
|
+
</m-flex>
|
|
11
17
|
<m-button
|
|
12
18
|
v-if="payload.viewModel.downloadButton"
|
|
13
19
|
:theme="payload.viewModel.downloadButton.theme"
|
|
@@ -15,12 +21,20 @@
|
|
|
15
21
|
class="pb-pedagogy__content-upload-button"
|
|
16
22
|
@click="handleButtonLinkClicked"
|
|
17
23
|
/>
|
|
24
|
+
<m-button
|
|
25
|
+
v-if="payload.multiSelect"
|
|
26
|
+
theme="primary"
|
|
27
|
+
:label="payload.multiSelect.actions.VALIDATE.label"
|
|
28
|
+
class="pb-pedagogy__content-action-button"
|
|
29
|
+
@click="handleValidateClicked"
|
|
30
|
+
/>
|
|
18
31
|
<m-flex
|
|
19
32
|
justify-content="center"
|
|
20
33
|
align-items="center"
|
|
21
34
|
full-width
|
|
22
35
|
class="pb-pedagogy__content-cards"
|
|
23
36
|
direction="column"
|
|
37
|
+
v-if="payload.cards"
|
|
24
38
|
>
|
|
25
39
|
<div class="pb-pedagogy__content-cards-title">Pour aller plus loin</div>
|
|
26
40
|
<pb-cards-list :cards="payload.cards" @card-click="handleCardClick" />
|
|
@@ -35,6 +49,7 @@ import MButton from '../mozaic/buttons/MButton.vue';
|
|
|
35
49
|
import MFlex from '../mozaic/flex/MFlex.vue';
|
|
36
50
|
import MIcon from '../mozaic/icon/MIcon.vue';
|
|
37
51
|
import PbCardsList from '../cards/PbCardsList.vue';
|
|
52
|
+
import { mapGetters } from 'vuex';
|
|
38
53
|
|
|
39
54
|
interface PedagogyCardViewmodel {
|
|
40
55
|
url: string;
|
|
@@ -51,8 +66,6 @@ interface PedagogyCard {
|
|
|
51
66
|
viewModel: PedagogyCardViewmodel;
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
const IMAGE_SRC = 'https://storage.googleapis.com/project-booster-media/vad/lm-advisor.png';
|
|
55
|
-
|
|
56
69
|
export default defineComponent({
|
|
57
70
|
name: 'PbPedagogy',
|
|
58
71
|
components: { PbCardsList, MButton, MIcon, MFlex },
|
|
@@ -66,9 +79,13 @@ export default defineComponent({
|
|
|
66
79
|
},
|
|
67
80
|
},
|
|
68
81
|
data: () => ({
|
|
69
|
-
IMAGE_SRC,
|
|
70
82
|
value: [],
|
|
71
83
|
}),
|
|
84
|
+
computed: {
|
|
85
|
+
...mapGetters('appointmentQualification', {
|
|
86
|
+
currentAppointmentQualification: 'getCurrentAppointmentQualification',
|
|
87
|
+
}),
|
|
88
|
+
},
|
|
72
89
|
watch: {
|
|
73
90
|
value(newValue) {
|
|
74
91
|
const selectedCard = this.payload.cards.find((card: PedagogyCard) => card.value === newValue);
|
|
@@ -107,7 +124,18 @@ export default defineComponent({
|
|
|
107
124
|
},
|
|
108
125
|
},
|
|
109
126
|
});
|
|
110
|
-
|
|
127
|
+
const targetUrl = card.viewModel.url.replace(
|
|
128
|
+
'@@PB_PROJECT_ID_FILLER@@',
|
|
129
|
+
this.currentAppointmentQualification.inhabitantProjectId,
|
|
130
|
+
);
|
|
131
|
+
window.open(targetUrl, '_blank');
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
async handleValidateClicked() {
|
|
135
|
+
this.$emit('step-completed', {
|
|
136
|
+
answers: [],
|
|
137
|
+
nextStep: this.payload.multiSelect.actions.VALIDATE.nextStep,
|
|
138
|
+
});
|
|
111
139
|
},
|
|
112
140
|
},
|
|
113
141
|
});
|
|
@@ -154,7 +182,7 @@ $responsive-breakpoint: 'm';
|
|
|
154
182
|
min-height: $mu400;
|
|
155
183
|
}
|
|
156
184
|
|
|
157
|
-
&-description {
|
|
185
|
+
&-description-line {
|
|
158
186
|
align-items: center;
|
|
159
187
|
display: flex;
|
|
160
188
|
flex-direction: column;
|
|
@@ -185,6 +213,10 @@ $responsive-breakpoint: 'm';
|
|
|
185
213
|
margin-top: $mu200;
|
|
186
214
|
}
|
|
187
215
|
|
|
216
|
+
&-action-button {
|
|
217
|
+
margin-top: $mu200;
|
|
218
|
+
}
|
|
219
|
+
|
|
188
220
|
&-cards {
|
|
189
221
|
margin-top: $mu200;
|
|
190
222
|
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
"viewModel": {
|
|
3
3
|
"title": "Un email de rappel pour préparer votre RDV vous sera envoyé",
|
|
4
4
|
"icon": "https://storage.googleapis.com/project-booster-media/vad/fin-de-parcours/mail_80.svg",
|
|
5
|
-
"description":
|
|
5
|
+
"description": [
|
|
6
|
+
{
|
|
7
|
+
"label": "Les mesures et <span class='pb-pedagogy__content-description-bold'> plans de votre pièce </span> sont importants pour le rendez-vous. Ils\n permettront à votre conseiller de créer un <span class='pb-pedagogy__content-description-bold'> plan 3D adapté </span> à votre cuisine.\n <span class='pb-pedagogy__content-description-bold'> Vous pouvez les ajouter à partir à partir du mail que vous avez reçu. </span>",
|
|
8
|
+
"icon": "https://storage.googleapis.com/project-booster-media/vad/lm-advisor.png"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
6
11
|
"downloadButton": {
|
|
7
12
|
"label": "Comment faire son plan ? (PDF)",
|
|
8
13
|
"theme": "bordered",
|
|
@@ -7,7 +7,8 @@ import { successResolver, internalServerErrorResolver } from '../../../services/
|
|
|
7
7
|
import {
|
|
8
8
|
getProjectByIdResolver,
|
|
9
9
|
getDoneAppointmentByIdResolver,
|
|
10
|
-
|
|
10
|
+
getStoreAppointmentByIdResolver,
|
|
11
|
+
getVisioAppointmentByIdResolver,
|
|
11
12
|
} from '../../../services/api/mocks/projectsMock';
|
|
12
13
|
|
|
13
14
|
<Meta
|
|
@@ -54,12 +55,28 @@ The `PbProjectHub` component to access your project.
|
|
|
54
55
|
|
|
55
56
|
<Canvas>
|
|
56
57
|
<Story
|
|
57
|
-
name="Showcase with appointment"
|
|
58
|
+
name="Showcase with store appointment"
|
|
58
59
|
parameters={{
|
|
59
60
|
controls: { disable: true },
|
|
60
61
|
msw: [
|
|
61
62
|
rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
|
|
62
|
-
rest.get('/api/inhabitant-projects/:projectId/main-appointment',
|
|
63
|
+
rest.get('/api/inhabitant-projects/:projectId/main-appointment', getStoreAppointmentByIdResolver),
|
|
64
|
+
],
|
|
65
|
+
}}
|
|
66
|
+
height="100vh"
|
|
67
|
+
>
|
|
68
|
+
{TemplateSandbox.bind({})}
|
|
69
|
+
</Story>
|
|
70
|
+
</Canvas>
|
|
71
|
+
|
|
72
|
+
<Canvas>
|
|
73
|
+
<Story
|
|
74
|
+
name="Showcase with visio appointment"
|
|
75
|
+
parameters={{
|
|
76
|
+
controls: { disable: true },
|
|
77
|
+
msw: [
|
|
78
|
+
rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
|
|
79
|
+
rest.get('/api/inhabitant-projects/:projectId/main-appointment', getVisioAppointmentByIdResolver),
|
|
63
80
|
],
|
|
64
81
|
}}
|
|
65
82
|
height="100vh"
|
|
@@ -77,7 +94,7 @@ The `PbProjectHub` component to access your project.
|
|
|
77
94
|
controls: { disable: true },
|
|
78
95
|
msw: [
|
|
79
96
|
rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
|
|
80
|
-
rest.get('/api/inhabitant-projects/:projectId/main-appointment',
|
|
97
|
+
rest.get('/api/inhabitant-projects/:projectId/main-appointment', getStoreAppointmentByIdResolver),
|
|
81
98
|
],
|
|
82
99
|
}}
|
|
83
100
|
args={{
|
|
@@ -72,12 +72,20 @@
|
|
|
72
72
|
class="pb-project-hub__appointment-notification"
|
|
73
73
|
type="appointment"
|
|
74
74
|
:title="appointment.appointmentDate"
|
|
75
|
-
:
|
|
76
|
-
:link-href="
|
|
75
|
+
:text="
|
|
77
76
|
readOnly
|
|
78
77
|
? ''
|
|
79
|
-
:
|
|
78
|
+
: appointment.appointmentDate.endsWith('en magasin')
|
|
79
|
+
? 'N’oubliez pas !'
|
|
80
|
+
: 'Retrouvez le lien d\'accès à la visio-conférence dans le mail qui vous est envoyé. \n' +
|
|
81
|
+
'N’oubliez pas !'
|
|
80
82
|
"
|
|
83
|
+
:link-label="
|
|
84
|
+
readOnly
|
|
85
|
+
? ''
|
|
86
|
+
: 'Ajoutez des plans aux mesures de votre pièce et des photos pour bien préparer le rendez-vous.'
|
|
87
|
+
"
|
|
88
|
+
@link-click="handleAppointmentLinkClick"
|
|
81
89
|
/>
|
|
82
90
|
</m-flex>
|
|
83
91
|
</m-flex>
|
|
@@ -773,7 +781,7 @@
|
|
|
773
781
|
</template>
|
|
774
782
|
|
|
775
783
|
<script lang="ts">
|
|
776
|
-
import { defineComponent } from 'vue';
|
|
784
|
+
import { defineComponent, nextTick } from 'vue';
|
|
777
785
|
import { format } from 'date-fns';
|
|
778
786
|
import Velocity from 'velocity-animate';
|
|
779
787
|
import { mapGetters } from 'vuex';
|
|
@@ -1370,6 +1378,18 @@ export default defineComponent({
|
|
|
1370
1378
|
handleMediaUploaded() {
|
|
1371
1379
|
this.$store.dispatch('media/refreshMediaList');
|
|
1372
1380
|
},
|
|
1381
|
+
|
|
1382
|
+
handleAppointmentLinkClick() {
|
|
1383
|
+
this.$store.dispatch('sendEventToBus', {
|
|
1384
|
+
code: 'appointmentLinkClicked',
|
|
1385
|
+
payload: this.project.id,
|
|
1386
|
+
});
|
|
1387
|
+
nextTick(() => {
|
|
1388
|
+
(<any>(
|
|
1389
|
+
window
|
|
1390
|
+
)).location = `/projets/preparation-rendez-vous/cuisine.html?inhabitantProjectId=${this.project.id}&appointmentId=${this.appointment.appointmentId}&groupId=${this.appointment.groupId}&calendarId=${this.appointment.calendarId}&leadSourceDetail=Project_Space`;
|
|
1391
|
+
});
|
|
1392
|
+
},
|
|
1373
1393
|
},
|
|
1374
1394
|
});
|
|
1375
1395
|
</script>
|
|
@@ -297,7 +297,7 @@ export default defineComponent({
|
|
|
297
297
|
props: {
|
|
298
298
|
/**
|
|
299
299
|
* The component view model and business data as an object. The provided prop
|
|
300
|
-
* is merged with the default payload value so only
|
|
300
|
+
* is merged with the default payload value so only overridden values will change
|
|
301
301
|
* from the default ones.
|
|
302
302
|
*/
|
|
303
303
|
payload: {
|
|
@@ -320,7 +320,7 @@ export default defineComponent({
|
|
|
320
320
|
default: true,
|
|
321
321
|
},
|
|
322
322
|
/**
|
|
323
|
-
* Name for the event to send when the step is
|
|
323
|
+
* Name for the event to send when the step is question is answered
|
|
324
324
|
*/
|
|
325
325
|
completedEventName: {
|
|
326
326
|
type: String,
|
|
@@ -432,14 +432,13 @@ export default defineComponent({
|
|
|
432
432
|
const questionPossibleAnswer = this.questionPossibleAnswers.get(answerCode);
|
|
433
433
|
if (
|
|
434
434
|
questionPossibleAnswer &&
|
|
435
|
-
(
|
|
436
|
-
|
|
437
|
-
(answer
|
|
438
|
-
|
|
439
|
-
(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
) >= 0) &&
|
|
435
|
+
answerValues.findIndex(
|
|
436
|
+
(answer: ScenarioStepAnswer | string) =>
|
|
437
|
+
(typeof answer === 'string' && answer === answerCode) ||
|
|
438
|
+
(typeof answer === 'object' &&
|
|
439
|
+
(<ScenarioStepAnswer>answer)?.code === answerCode &&
|
|
440
|
+
(<ScenarioStepAnswer>answer)?.selected),
|
|
441
|
+
) >= 0 &&
|
|
443
442
|
areConditionsValid(questionPossibleAnswer.conditions!, this.answers, this.runtimeOptions)
|
|
444
443
|
) {
|
|
445
444
|
this.selectedAnswers.set(answerCode, true);
|
|
@@ -499,10 +498,9 @@ export default defineComponent({
|
|
|
499
498
|
if (!this.payload.multiSelect) {
|
|
500
499
|
this.initAnswersSelectedState(this.payload.answers);
|
|
501
500
|
}
|
|
502
|
-
answer.selected = !answer.selected;
|
|
503
501
|
|
|
504
502
|
if (this.payload.multiSelect) {
|
|
505
|
-
this.selectedAnswers.set(answer.code, answer.
|
|
503
|
+
this.selectedAnswers.set(answer.code, !this.selectedAnswers.get(answer.code) ?? true);
|
|
506
504
|
|
|
507
505
|
const selected = Object.fromEntries(Object.entries(this.selectedAnswers).filter(([, value]) => value === true));
|
|
508
506
|
/**
|
|
@@ -514,7 +512,7 @@ export default defineComponent({
|
|
|
514
512
|
Object.keys(Object.fromEntries(this.selectedAnswers)).forEach((answerCode) => {
|
|
515
513
|
this.selectedAnswers.set(answerCode, false);
|
|
516
514
|
});
|
|
517
|
-
this.selectedAnswers.set(answer.code, answer.
|
|
515
|
+
this.selectedAnswers.set(answer.code, !this.selectedAnswers.get(answer.code) ?? true);
|
|
518
516
|
|
|
519
517
|
/**
|
|
520
518
|
* Emitted when step is completed
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
justify-content="center"
|
|
45
45
|
>
|
|
46
46
|
<m-button
|
|
47
|
-
v-if="payload.skippable && !hasSelectedAnswers"
|
|
47
|
+
v-if="payload.skippable && (!hasSelectedAnswers || payload.viewModel.alwaysDisplaySkippable)"
|
|
48
48
|
class="pb-list-select__next-button"
|
|
49
49
|
:label="payload.skippable.label"
|
|
50
50
|
:left-icon="payload.skippable.leftIcon"
|