project-booster-vue 9.37.0 → 9.38.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/projects/projects/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-/360/237/246/240-showcase-1-snap.png +0 -0
- package/src/components/projects/projects/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-/360/237/246/240-showcase-empty-state-1-snap.png +0 -0
- package/src/components/projects/projects-list/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-list-/360/237/246/240-showcase-1-snap.png +0 -0
- package/src/components/projects/projects-list/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-projects-pb-projects-list-/360/237/246/240-showcase-empty-state-1-snap.png +0 -0
- package/src/components/restitution/PbRestitutionList.stories.mdx +147 -0
- package/src/components/restitution/PbRestitutionList.vue +354 -0
- package/src/components/restitution/PbRestitutionListBlock.vue +171 -0
- package/src/components/restitution/PbRestitutionListLine.vue +80 -0
package/package.json
CHANGED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import PbRestitutionList from './PbRestitutionList.vue';
|
|
2
|
+
import { Meta, Canvas, Story, ArgsTable, Source } from '@storybook/addon-docs';
|
|
3
|
+
import { useStore } from 'vuex';
|
|
4
|
+
import { nestedAppDecorator } from '../../../.storybook/nested-app-decorator';
|
|
5
|
+
import store from './../../stores/store';
|
|
6
|
+
import { rest } from 'msw';
|
|
7
|
+
import { successResolver, internalServerErrorResolver } from '../../services/api/mocks/commonMock';
|
|
8
|
+
import { getProjectsResolver } from '../../services/api/mocks/projectsMock';
|
|
9
|
+
import DEFAULT_PAYLOAD from './restitution-default.json';
|
|
10
|
+
import NO_PRICE_BAR from './restitution-no-pricebar.json';
|
|
11
|
+
import SAVE_ITEM from './restitution-with-save-item.json';
|
|
12
|
+
import EXIT_OPTIONS from './restitution-with-exit-options.json';
|
|
13
|
+
import EXIT_OPTIONS_WITH_CONDITIONNAL from './restitution-with-conditionnal-exit-options.json';
|
|
14
|
+
import CALL_TO_ACTION_WITH_MODAL from './restitution-call-to-actions-with-modal.json';
|
|
15
|
+
|
|
16
|
+
<Meta
|
|
17
|
+
title="Project Booster/Components/Restitution/PbRestitutionList 🦠"
|
|
18
|
+
component={PbRestitutionList}
|
|
19
|
+
decorators={[nestedAppDecorator(store, [])]}
|
|
20
|
+
parameters={{
|
|
21
|
+
layout: 'fullscreen',
|
|
22
|
+
}}
|
|
23
|
+
/>
|
|
24
|
+
|
|
25
|
+
export const summary = {
|
|
26
|
+
subprojectId: 'ae62d167-e02e-4744-81b1-102cc5816be2',
|
|
27
|
+
subprojectTemplateId: '22248ac3-9391-47f4-8a54-6fe280c2fa5b',
|
|
28
|
+
businessUnit: 'LMFR',
|
|
29
|
+
summaryDate: '2020-05-13T09:49:45.886602047Z',
|
|
30
|
+
subprojectTemplateLabel: '<strong>Pompe à chaleur air/air</strong>',
|
|
31
|
+
cost: {
|
|
32
|
+
min: 3139.99,
|
|
33
|
+
max: 3939.99,
|
|
34
|
+
currency: 'EURO',
|
|
35
|
+
},
|
|
36
|
+
components: [
|
|
37
|
+
{
|
|
38
|
+
componentId: 'LAND',
|
|
39
|
+
title: '<strong>Pompe à chaleur installée</strong> (hors aides)',
|
|
40
|
+
cost: {
|
|
41
|
+
min: 3139.99,
|
|
42
|
+
max: 3939.99,
|
|
43
|
+
currency: 'EURO',
|
|
44
|
+
},
|
|
45
|
+
lines: [
|
|
46
|
+
{
|
|
47
|
+
text: '<strong>Pompe à chaleur installée</strong> (hors aides)',
|
|
48
|
+
details: 'Terrain constructible, délimité et viabilisé. La nature du sous-sol est garantie.',
|
|
49
|
+
cost: {
|
|
50
|
+
min: 6499,
|
|
51
|
+
max: 7299,
|
|
52
|
+
currency: 'EURO',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
text: '<strong>Pompe à chaleur installée</strong> (hors aides)',
|
|
57
|
+
cost: {
|
|
58
|
+
min: 6499,
|
|
59
|
+
max: 7299,
|
|
60
|
+
currency: 'EURO',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
text: '<strong>Aide estimées</strong> (MaPrimeRénov, Prime Energie)',
|
|
65
|
+
type: 'REDUCTION',
|
|
66
|
+
cost: {
|
|
67
|
+
reduce: -3600,
|
|
68
|
+
currency: 'EURO',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
subprojectAttributes: {
|
|
75
|
+
finish: 'PARTIALLY_BY_MYSELF',
|
|
76
|
+
houseType: 'CONTEMPORARY',
|
|
77
|
+
inseeCode: '59350',
|
|
78
|
+
land: 'NOT_YET',
|
|
79
|
+
landSurfaceInSquareMeters: 123,
|
|
80
|
+
landType: 'IN_A_LOT',
|
|
81
|
+
livingAreaInSquareMeters: 465,
|
|
82
|
+
},
|
|
83
|
+
suggestedTypologies: [
|
|
84
|
+
{
|
|
85
|
+
domesticSpaceLabel: 'Cuisine',
|
|
86
|
+
domesticSpaceHref: '/domestic-spaces/59405',
|
|
87
|
+
projectKindHref: '/project-kinds/34048',
|
|
88
|
+
projectTypeHref: '/project-types/29239',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
domesticSpaceLabel: 'Tout le logement',
|
|
92
|
+
domesticSpaceHref: '/domestic-spaces/59461',
|
|
93
|
+
projectKindHref: '/project-kinds/34048',
|
|
94
|
+
projectTypeHref: '/project-types/61855',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
legalMentions: [
|
|
98
|
+
"Les prix ci-dessus ne sont proposés qu'à titre indicatif et sont basés sur les prix du marché.",
|
|
99
|
+
"L'outil d'estimation ne vaut pas offre de vente.",
|
|
100
|
+
"La disponibilité des produits au moment de l'achat n'est pas garantie.",
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
# 🦠 `PbRestitutionList` - Component
|
|
105
|
+
|
|
106
|
+
The `PbRestitutionList` component allows to display the summary of an estimate.
|
|
107
|
+
|
|
108
|
+
export const TemplateSandbox = (args, { argTypes }) => ({
|
|
109
|
+
props: Object.keys(argTypes),
|
|
110
|
+
components: { PbRestitutionList },
|
|
111
|
+
setup() {
|
|
112
|
+
const store = useStore();
|
|
113
|
+
store.dispatch('projects/loadProjects');
|
|
114
|
+
store.dispatch('estimates/setSummary', summary);
|
|
115
|
+
store.dispatch('projects/loadTypologies');
|
|
116
|
+
store.dispatch('estimates/initSessions', {
|
|
117
|
+
formId: 'FORM_ID',
|
|
118
|
+
correlationId: 'CORRELATION_ID',
|
|
119
|
+
estimatorId: 'ESTIMATOR_ID',
|
|
120
|
+
businessUnit: 'BU',
|
|
121
|
+
subprojectFormStructure: {},
|
|
122
|
+
source: 'SOURCE',
|
|
123
|
+
sourceDetail: 'SOURCE_DETAIL',
|
|
124
|
+
});
|
|
125
|
+
return { args };
|
|
126
|
+
},
|
|
127
|
+
template: `<pb-restitution-list :payload="args.payload" :answers="args.answers" :show-save-estimate="args.showSaveEstimate" :runtime-options="args.runtimeOptions" :show-back-button="args.showBackButton" />`,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
<Canvas>
|
|
131
|
+
<Story
|
|
132
|
+
name="101 Sandbox"
|
|
133
|
+
args={{ payload: DEFAULT_PAYLOAD }}
|
|
134
|
+
parameters={{
|
|
135
|
+
msw: [
|
|
136
|
+
rest.get('/api/inhabitant-projects', getProjectsResolver),
|
|
137
|
+
rest.post('/api/estimates', successResolver),
|
|
138
|
+
rest.post('/api/inhabitant-projects', successResolver),
|
|
139
|
+
],
|
|
140
|
+
storyshots: { disable: true },
|
|
141
|
+
}}
|
|
142
|
+
inline={false}
|
|
143
|
+
height="1024px"
|
|
144
|
+
>
|
|
145
|
+
{TemplateSandbox.bind({})}
|
|
146
|
+
</Story>
|
|
147
|
+
</Canvas>
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<m-flex align-items="center" direction="column">
|
|
3
|
+
<m-flex
|
|
4
|
+
:class="`pb-restitution-list`"
|
|
5
|
+
align-items="center"
|
|
6
|
+
justify-content="center"
|
|
7
|
+
direction="column"
|
|
8
|
+
ref="pbRestitutionList"
|
|
9
|
+
>
|
|
10
|
+
<m-link
|
|
11
|
+
v-if="showBackButton"
|
|
12
|
+
:left-icon="BACK_ICON"
|
|
13
|
+
:label="payload.backLabel || 'Modifier l\'estimation'"
|
|
14
|
+
class="pb-restitution-list__back-button"
|
|
15
|
+
@click.once="$emit('go-back')"
|
|
16
|
+
/>
|
|
17
|
+
</m-flex>
|
|
18
|
+
<div class="pb-restitution-list__title">Votre estimation par travaux</div>
|
|
19
|
+
|
|
20
|
+
<div class="pb-restitution-list__line">
|
|
21
|
+
<pb-restitution-list-block
|
|
22
|
+
@button="handleShowDialog"
|
|
23
|
+
v-for="component in summary.components"
|
|
24
|
+
:key="component.componentId"
|
|
25
|
+
:payload="component"
|
|
26
|
+
></pb-restitution-list-block>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<m-flex class="pb-restitution-list__footer" direction="row" align-items="center" justify-content="center">
|
|
30
|
+
<div class="pb-restitution-list__footer__call">
|
|
31
|
+
<m-button label="Être rappelé par un expert"></m-button>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="pb-restitution-list__footer__save">
|
|
34
|
+
<m-button label="Enregistrer mon estimation" theme="bordered"></m-button>
|
|
35
|
+
</div>
|
|
36
|
+
</m-flex>
|
|
37
|
+
|
|
38
|
+
<m-dialog
|
|
39
|
+
class="pb-restitution-list__modal"
|
|
40
|
+
:show-dialog="showDialog"
|
|
41
|
+
width="771px"
|
|
42
|
+
maxHeight="100vh"
|
|
43
|
+
@update:show-dialog="handleShowDialog"
|
|
44
|
+
>
|
|
45
|
+
<template #body>
|
|
46
|
+
<m-flex class="pb-restitution-list__modal__details" direction="column">
|
|
47
|
+
<div class="pb-restitution-list__modal__details__title" v-html="summary.subprojectTemplateLabel"></div>
|
|
48
|
+
|
|
49
|
+
<div class="pb-restitution-list__modal__details__row">
|
|
50
|
+
<m-flex class="pb-restitution-list__modal__details__row__title" justify-content="space-between">
|
|
51
|
+
<div v-html="summary.components[0].title"></div>
|
|
52
|
+
<div>
|
|
53
|
+
<strong>{{ summary.components[0].cost.min }}€ - {{ summary.components[0].cost.max }}€</strong>
|
|
54
|
+
</div>
|
|
55
|
+
</m-flex>
|
|
56
|
+
|
|
57
|
+
<div v-for="line in summary.components[0].lines" :key="line.text">
|
|
58
|
+
<div class="pb-restitution-list__modal__details__row__label" v-if="line.details">
|
|
59
|
+
{{ line.details }}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="pb-restitution-list__modal__details__row__list pb-restitution-list__modal__details__row">
|
|
64
|
+
<ul>
|
|
65
|
+
<div v-for="line in summary.components[0].lines" :key="line.text">
|
|
66
|
+
<li v-if="!line.cost.reduce">
|
|
67
|
+
<div v-html="line.text" v-if="!line.cost.reduce"></div>
|
|
68
|
+
<div v-if="!line.cost.reduce">{{ line.cost.min }}€ - {{ line.cost.max }}€</div>
|
|
69
|
+
</li>
|
|
70
|
+
</div>
|
|
71
|
+
</ul>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<m-flex
|
|
75
|
+
class="pb-restitution-list__modal__details__row__title help border-bottom"
|
|
76
|
+
justify-content="space-between"
|
|
77
|
+
>
|
|
78
|
+
<span v-for="line in summary.components[0].lines" :key="line" :class="{ hidden: !line.cost.reduce }">
|
|
79
|
+
<div v-if="line.cost.reduce">
|
|
80
|
+
<div v-html="line.text" class="green"></div>
|
|
81
|
+
</div>
|
|
82
|
+
</span>
|
|
83
|
+
|
|
84
|
+
<div v-for="line in summary.components[0].lines" :key="line">
|
|
85
|
+
<div v-if="line.cost.reduce" class="green">
|
|
86
|
+
<strong>{{ line.cost.reduce }}€</strong>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</m-flex>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<m-flex
|
|
93
|
+
class="pb-restitution-list__modal__details__totals"
|
|
94
|
+
justify-content="space-between"
|
|
95
|
+
align-items="center"
|
|
96
|
+
>
|
|
97
|
+
<div><strong>Montant total</strong> (aides déduites)</div>
|
|
98
|
+
<div>
|
|
99
|
+
entre <strong>{{ summary.cost.min }}€</strong> et <strong>{{ summary.cost.max }}€</strong>
|
|
100
|
+
</div>
|
|
101
|
+
</m-flex>
|
|
102
|
+
</m-flex>
|
|
103
|
+
</template>
|
|
104
|
+
<template #footer>
|
|
105
|
+
<m-flex class="pb-restitution-list__modal__footer" align-items="center" justify-content="center">
|
|
106
|
+
<m-button label="Fermer" theme="bordered-neutral" @click.prevent="handleShowDialog"></m-button>
|
|
107
|
+
</m-flex>
|
|
108
|
+
</template>
|
|
109
|
+
</m-dialog>
|
|
110
|
+
</m-flex>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<script lang="ts">
|
|
114
|
+
import { defineComponent, PropType } from 'vue';
|
|
115
|
+
import { mapGetters } from 'vuex';
|
|
116
|
+
import MButton from '../mozaic/buttons/MButton.vue';
|
|
117
|
+
import MDialog from '../mozaic/dialog/MDialog.vue';
|
|
118
|
+
import MFlex from '../mozaic/flex/MFlex.vue';
|
|
119
|
+
import MLink from '../mozaic/link/MLink.vue';
|
|
120
|
+
|
|
121
|
+
import { RestitutionPayload } from '@/types/pb/Restitution';
|
|
122
|
+
import { ScenarioStepAnswer } from '@/types/pb/Scenario';
|
|
123
|
+
import PbRestitutionListBlock from './PbRestitutionListBlock.vue';
|
|
124
|
+
|
|
125
|
+
export default defineComponent({
|
|
126
|
+
components: {
|
|
127
|
+
MButton,
|
|
128
|
+
MDialog,
|
|
129
|
+
MFlex,
|
|
130
|
+
MLink,
|
|
131
|
+
PbRestitutionListBlock,
|
|
132
|
+
},
|
|
133
|
+
data() {
|
|
134
|
+
return {
|
|
135
|
+
showDialog: false,
|
|
136
|
+
dialogContent: null,
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
// eslint-disable-next-line vue/order-in-components
|
|
140
|
+
props: {
|
|
141
|
+
/**
|
|
142
|
+
* The component view model and business data as an object. The provided prop
|
|
143
|
+
* is merged with the default payload value so only overriden values will change
|
|
144
|
+
* from the default ones.
|
|
145
|
+
*/
|
|
146
|
+
payload: {
|
|
147
|
+
type: Object as PropType<RestitutionPayload>,
|
|
148
|
+
default: () => ({}),
|
|
149
|
+
required: true,
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* The previous answers to inject
|
|
153
|
+
*/
|
|
154
|
+
answers: {
|
|
155
|
+
type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
|
|
156
|
+
default: () => null,
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* The options provided at runtime to customize component behaviour
|
|
160
|
+
*/
|
|
161
|
+
runtimeOptions: {
|
|
162
|
+
type: Object,
|
|
163
|
+
default: () => ({}),
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Flag indidicating whether the back button should be displayed
|
|
167
|
+
*/
|
|
168
|
+
showBackButton: {
|
|
169
|
+
type: Boolean,
|
|
170
|
+
default: true,
|
|
171
|
+
},
|
|
172
|
+
/**
|
|
173
|
+
* Flag to show/hide the save estimate button
|
|
174
|
+
*/
|
|
175
|
+
showSaveEstimate: {
|
|
176
|
+
type: Boolean,
|
|
177
|
+
default: false,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
computed: {
|
|
181
|
+
...mapGetters('estimates', { summary: 'getSummary' }),
|
|
182
|
+
},
|
|
183
|
+
methods: {
|
|
184
|
+
handleShowDialog(content: any) {
|
|
185
|
+
this.dialogContent = content;
|
|
186
|
+
this.showDialog = !this.showDialog;
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
</script>
|
|
191
|
+
|
|
192
|
+
<style lang="scss" scoped>
|
|
193
|
+
@import 'pb-variables';
|
|
194
|
+
|
|
195
|
+
.hidden {
|
|
196
|
+
display: none;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.pb-restitution-list {
|
|
200
|
+
@include set-font-face('regular');
|
|
201
|
+
|
|
202
|
+
align-items: center;
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
flex-grow: 1;
|
|
206
|
+
margin: 0 auto;
|
|
207
|
+
padding-bottom: $mu250;
|
|
208
|
+
position: relative;
|
|
209
|
+
width: calc(100% - #{$mu050} - #{$mu050});
|
|
210
|
+
|
|
211
|
+
&__back-button {
|
|
212
|
+
align-self: flex-start;
|
|
213
|
+
opacity: 1;
|
|
214
|
+
padding: $mu100 0 $mu100 $mu025;
|
|
215
|
+
transition: opacity 0.15s 0.5s;
|
|
216
|
+
z-index: 2;
|
|
217
|
+
|
|
218
|
+
&--hidden {
|
|
219
|
+
opacity: 0;
|
|
220
|
+
pointer-events: none;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
&__title {
|
|
225
|
+
@include set-font-face('semi-bold');
|
|
226
|
+
@include set-font-scale('07', 's');
|
|
227
|
+
left: 0;
|
|
228
|
+
padding: $mu100 0 $mu100 $mu025;
|
|
229
|
+
position: absolute;
|
|
230
|
+
right: 0;
|
|
231
|
+
text-align: center;
|
|
232
|
+
top: 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
&__footer {
|
|
236
|
+
background: #ffffff;
|
|
237
|
+
bottom: 0;
|
|
238
|
+
left: 0;
|
|
239
|
+
padding: $mu100 0 $mu100 $mu025;
|
|
240
|
+
position: fixed;
|
|
241
|
+
right: 0;
|
|
242
|
+
@include set-box-shadow('l');
|
|
243
|
+
|
|
244
|
+
&__save,
|
|
245
|
+
&__call {
|
|
246
|
+
margin: 0 $mu050;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
&__line {
|
|
251
|
+
margin-top: $mu250;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
&__modal {
|
|
255
|
+
&__details {
|
|
256
|
+
padding: $mu250 $mu250 0 $mu250;
|
|
257
|
+
|
|
258
|
+
.green {
|
|
259
|
+
color: $color-secondary-green-600;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
&__title {
|
|
263
|
+
@include set-font-face('semi-bold');
|
|
264
|
+
@include set-font-scale('07', 's');
|
|
265
|
+
margin-bottom: $mu150;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
&__row {
|
|
269
|
+
border-bottom: 1px solid $color-grey-600;
|
|
270
|
+
margin-bottom: $mu150;
|
|
271
|
+
width: 100%;
|
|
272
|
+
|
|
273
|
+
&__title {
|
|
274
|
+
&.help {
|
|
275
|
+
margin-bottom: $mu150;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
&__label {
|
|
280
|
+
background: $color-primary-01-100;
|
|
281
|
+
border-radius: 4px;
|
|
282
|
+
color: $color-grey-600;
|
|
283
|
+
margin-top: 10px;
|
|
284
|
+
padding: $mu075;
|
|
285
|
+
position: relative;
|
|
286
|
+
@include set-font-scale('05', 's');
|
|
287
|
+
|
|
288
|
+
&::before {
|
|
289
|
+
border-color: transparent transparent $color-primary-01-100 transparent;
|
|
290
|
+
border-style: solid;
|
|
291
|
+
border-width: 0 10px 16px 10px;
|
|
292
|
+
content: '';
|
|
293
|
+
height: 0;
|
|
294
|
+
left: 10px;
|
|
295
|
+
position: absolute;
|
|
296
|
+
top: -8px;
|
|
297
|
+
width: 0;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
&__list {
|
|
302
|
+
color: $color-grey-600;
|
|
303
|
+
list-style: disc;
|
|
304
|
+
|
|
305
|
+
ul {
|
|
306
|
+
padding: 0 0 0 $mu100;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
li {
|
|
310
|
+
display: flex;
|
|
311
|
+
justify-content: space-between;
|
|
312
|
+
margin-bottom: $mu075;
|
|
313
|
+
|
|
314
|
+
&::before {
|
|
315
|
+
content: '•';
|
|
316
|
+
margin-right: 5px;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
div {
|
|
320
|
+
&:first-child {
|
|
321
|
+
@include set-font-face('regular');
|
|
322
|
+
@include set-font-scale('05', 's');
|
|
323
|
+
width: 60%;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
&:last-child {
|
|
327
|
+
@include set-font-face('semi-bold');
|
|
328
|
+
text-align: right;
|
|
329
|
+
width: 40%;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
&__totals {
|
|
337
|
+
width: 100%;
|
|
338
|
+
|
|
339
|
+
div {
|
|
340
|
+
&:last-child {
|
|
341
|
+
strong {
|
|
342
|
+
@include set-font-scale('07', 's');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
&__footer {
|
|
350
|
+
padding: $mu150 0;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
</style>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<m-flex align-items="center" direction="column">
|
|
3
|
+
<m-flex :class="`pb-restitution-list-block`" direction="column" ref="pbRestitutionListBlock">
|
|
4
|
+
<div class="pb-restitution-list-block__title" v-html="summary.subprojectTemplateLabel"></div>
|
|
5
|
+
|
|
6
|
+
<div class="pb-restitution-list-block__body" v-if="payload">
|
|
7
|
+
<m-flex class="pb-restitution-list-line" justify-content="space-between">
|
|
8
|
+
<div class="pb-restitution-list-line__title" v-html="summary.components[0].title"></div>
|
|
9
|
+
<m-flex class="pb-restitution-list-line__price" justify-content="flex-end" wrap>
|
|
10
|
+
<div class="pb-restitution-list-line__price__min">{{ summary.components[0].cost.min }}€ - </div>
|
|
11
|
+
<div class="pb-restitution-list-line__price__max">{{ summary.components[0].cost.max }}€</div>
|
|
12
|
+
</m-flex>
|
|
13
|
+
</m-flex>
|
|
14
|
+
|
|
15
|
+
<pb-restitution-list-line
|
|
16
|
+
v-for="line in payload.lines"
|
|
17
|
+
:key="line.componentId"
|
|
18
|
+
:component="line"
|
|
19
|
+
:line="line"
|
|
20
|
+
></pb-restitution-list-line>
|
|
21
|
+
|
|
22
|
+
<m-flex class="pb-restitution-list-block__body__row unbordered">
|
|
23
|
+
<m-flex
|
|
24
|
+
class="pb-restitution-list-block__body__row__title full"
|
|
25
|
+
align-items="center"
|
|
26
|
+
justify-content="space-between"
|
|
27
|
+
>
|
|
28
|
+
<div><strong>Montant total</strong> (aides déduites)</div>
|
|
29
|
+
<div class="pb-restitution-list-block__body__row__title__amount">
|
|
30
|
+
entre <strong>{{ summary.cost.min }}€</strong> et <strong>{{ summary.cost.max }}€</strong>
|
|
31
|
+
</div>
|
|
32
|
+
</m-flex>
|
|
33
|
+
</m-flex>
|
|
34
|
+
|
|
35
|
+
<m-button
|
|
36
|
+
theme="bordered-neutral"
|
|
37
|
+
size="s"
|
|
38
|
+
class="pb-restitution-list-block__body__show"
|
|
39
|
+
label="Voir le détail de l'estimation"
|
|
40
|
+
@click="handleLinkClick(payload)"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</m-flex>
|
|
44
|
+
</m-flex>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script lang="ts">
|
|
48
|
+
import { defineComponent } from 'vue';
|
|
49
|
+
import MFlex from '../mozaic/flex/MFlex.vue';
|
|
50
|
+
import MButton from '../mozaic/buttons/MButton.vue';
|
|
51
|
+
import ObjectType from '@storybook/addon-knobs/dist/components/types/Object';
|
|
52
|
+
import PbRestitutionListLine from './PbRestitutionListLine.vue';
|
|
53
|
+
import { mapGetters } from 'vuex';
|
|
54
|
+
|
|
55
|
+
export default defineComponent({
|
|
56
|
+
components: {
|
|
57
|
+
MFlex,
|
|
58
|
+
MButton,
|
|
59
|
+
PbRestitutionListLine,
|
|
60
|
+
},
|
|
61
|
+
props: {
|
|
62
|
+
payload: {
|
|
63
|
+
type: ObjectType,
|
|
64
|
+
default: () => ({}),
|
|
65
|
+
required: true,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
computed: {
|
|
69
|
+
...mapGetters('estimates', { summary: 'getSummary' }),
|
|
70
|
+
},
|
|
71
|
+
methods: {
|
|
72
|
+
handleLinkClick(details: any) {
|
|
73
|
+
this.$emit('button', details);
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<style lang="scss" scoped>
|
|
80
|
+
@import 'pb-variables';
|
|
81
|
+
|
|
82
|
+
.pb-restitution-list-block {
|
|
83
|
+
@include set-box-shadow('l');
|
|
84
|
+
margin-bottom: $mu250;
|
|
85
|
+
padding: $mu250;
|
|
86
|
+
width: calc(710px - ($mu250 * 2));
|
|
87
|
+
|
|
88
|
+
&__title {
|
|
89
|
+
@include set-font-face('semi-bold');
|
|
90
|
+
@include set-font-scale('07', 's');
|
|
91
|
+
margin-bottom: $mu050;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&__body {
|
|
95
|
+
width: 100%;
|
|
96
|
+
|
|
97
|
+
&__row {
|
|
98
|
+
border-bottom: 1px solid $color-grey-500;
|
|
99
|
+
padding: $mu100 0 $mu075 0;
|
|
100
|
+
width: 100%;
|
|
101
|
+
|
|
102
|
+
&.unbordered {
|
|
103
|
+
border-bottom: 0;
|
|
104
|
+
margin-bottom: $mu050;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&.green {
|
|
108
|
+
color: $color-secondary-green-600;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&__title {
|
|
112
|
+
@include set-font-face('regular');
|
|
113
|
+
width: 70%;
|
|
114
|
+
|
|
115
|
+
&.full {
|
|
116
|
+
display: grid;
|
|
117
|
+
width: 100%;
|
|
118
|
+
@include set-font-scale('06', 's');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
&__amount {
|
|
122
|
+
@include set-font-scale('06', 's');
|
|
123
|
+
justify-self: flex-end;
|
|
124
|
+
margin-left: $mu100;
|
|
125
|
+
|
|
126
|
+
strong {
|
|
127
|
+
@include set-font-scale('07', 's');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&__price {
|
|
133
|
+
@include set-font-face('semi-bold');
|
|
134
|
+
@include set-font-scale('05', 's');
|
|
135
|
+
text-align: right;
|
|
136
|
+
width: 30%;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.pb-restitution-list-line {
|
|
143
|
+
border-bottom: 1px solid $color-grey-500;
|
|
144
|
+
padding: $mu150 0 $mu075 0;
|
|
145
|
+
|
|
146
|
+
&__title {
|
|
147
|
+
@include set-font-face('regular');
|
|
148
|
+
@include set-font-scale('06', 's');
|
|
149
|
+
width: 70%;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&__price {
|
|
153
|
+
@include set-font-face('semi-bold');
|
|
154
|
+
@include set-font-scale('06', 's');
|
|
155
|
+
text-align: right;
|
|
156
|
+
width: 30%;
|
|
157
|
+
|
|
158
|
+
strong {
|
|
159
|
+
@include set-font-scale('07', 's');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
&.unbordered {
|
|
163
|
+
border-bottom: 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
&.green {
|
|
168
|
+
color: $color-secondary-green-600;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
</style>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<m-flex
|
|
3
|
+
class="pb-restitution-list-line"
|
|
4
|
+
:class="{ green: line.type === 'REDUCTION' }"
|
|
5
|
+
justify-content="space-between"
|
|
6
|
+
v-if="line.type"
|
|
7
|
+
>
|
|
8
|
+
<div class="pb-restitution-list-line__title" v-html="line.text"></div>
|
|
9
|
+
<m-flex class="pb-restitution-list-line__price" justify-content="flex-end" wrap v-if="line.type != 'REDUCTION'">
|
|
10
|
+
<div class="pb-restitution-list-line__price__min">
|
|
11
|
+
{{ formatPriceRange(line.cost.min, line.cost.max).min }}€ -
|
|
12
|
+
</div>
|
|
13
|
+
<div class="pb-restitution-list-line__price__max">{{ formatPriceRange(line.cost.min, line.cost.max).max }}€</div>
|
|
14
|
+
</m-flex>
|
|
15
|
+
<m-flex class="pb-restitution-list-line__price" justify-content="flex-end" wrap v-else>
|
|
16
|
+
{{ line.cost.reduce }}€
|
|
17
|
+
</m-flex>
|
|
18
|
+
</m-flex>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script lang="ts">
|
|
22
|
+
import { defineComponent } from 'vue';
|
|
23
|
+
import MFlex from '../mozaic/flex/MFlex.vue';
|
|
24
|
+
|
|
25
|
+
export default defineComponent({
|
|
26
|
+
components: {
|
|
27
|
+
MFlex,
|
|
28
|
+
},
|
|
29
|
+
props: {
|
|
30
|
+
line: {
|
|
31
|
+
type: Object,
|
|
32
|
+
default: () => ({}),
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
methods: {
|
|
36
|
+
handleLinkClick() {
|
|
37
|
+
this.$emit('button', true);
|
|
38
|
+
},
|
|
39
|
+
formatPriceRange(min: number, max: number) {
|
|
40
|
+
if (min < max) {
|
|
41
|
+
return { min, max };
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<style lang="scss" scoped>
|
|
49
|
+
@import 'pb-variables';
|
|
50
|
+
|
|
51
|
+
.pb-restitution-list-line {
|
|
52
|
+
border-bottom: 1px solid $color-grey-500;
|
|
53
|
+
padding: $mu150 0 $mu075 0;
|
|
54
|
+
|
|
55
|
+
&__title {
|
|
56
|
+
@include set-font-face('regular');
|
|
57
|
+
@include set-font-scale('06', 's');
|
|
58
|
+
width: 70%;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&__price {
|
|
62
|
+
@include set-font-face('semi-bold');
|
|
63
|
+
@include set-font-scale('06', 's');
|
|
64
|
+
text-align: right;
|
|
65
|
+
width: 30%;
|
|
66
|
+
|
|
67
|
+
strong {
|
|
68
|
+
@include set-font-scale('07', 's');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&.unbordered {
|
|
72
|
+
border-bottom: 0;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&.green {
|
|
77
|
+
color: $color-secondary-green-600;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
</style>
|