project-booster-vue 8.129.0 → 8.131.1

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/README.md CHANGED
@@ -46,13 +46,7 @@ yarn serve
46
46
  yarn build
47
47
  ```
48
48
 
49
- ### Build the bundle for npm publication and publish
50
-
51
- Check and bump the `version` in `package.json`, then build the bundle:
52
-
53
- ```
54
- yarn build:bundle
55
- ```
49
+ ### Publish
56
50
 
57
51
  Publish to npm:
58
52
 
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "project-booster-vue",
3
- "version": "8.129.0",
3
+ "version": "8.131.1",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "test:unit": "vue-cli-service test:unit --forceExit --detectOpenHandles",
7
- "build:bundle": "vue-cli-service build --target lib --name project-booster-vue ./src/index.js",
8
7
  "kozikaza-tokens-build": "env PB_THEME=kozikaza mozaic-tokens-build",
9
8
  "lint:js": "vue-cli-service lint --no-fix -- ./",
10
9
  "lint:js:fix": "vue-cli-service lint --fix -- ./",
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <m-flex direction="column" full-width class="pb-consent">
3
+ <span class="pb-consent__label">
4
+ Faites le plein d’inspirations et de promotions pour votre projet chaque semaine en vous abonnant à notre
5
+ newsletter
6
+ </span>
7
+ <m-flex
8
+ v-if="isMailConsentUpdating"
9
+ class="pb-consent__loading"
10
+ direction="column"
11
+ align-items="center"
12
+ justify-content="center"
13
+ align-content="center"
14
+ >
15
+ <pb-animable-loader class="pb-consent__loading-loader" />
16
+ <div class="pb-consent__loading-label">Chargement...</div>
17
+ </m-flex>
18
+ <m-flex v-else class="pb-consent__actions">
19
+ <m-button
20
+ class="pb-consent__actions--button"
21
+ label="S'abonner à la newsletter"
22
+ theme="bordered"
23
+ @click="handleUpdateConsent"
24
+ v-if="!errorUpdateMailConsent && !isMailConsentUpdated"
25
+ />
26
+ <m-notification
27
+ v-if="isMailConsentUpdated"
28
+ class="pb-consent__actions--notification"
29
+ type="success"
30
+ text="Merci, votre inscription à la newsletter est confirmée"
31
+ />
32
+ <m-notification
33
+ v-if="errorUpdateMailConsent"
34
+ class="pb-consent__actions--notification"
35
+ type="warning"
36
+ text="Une erreur est survenue"
37
+ link-label="Merci de réessayer"
38
+ @link-click="handleRetry"
39
+ />
40
+ </m-flex>
41
+ </m-flex>
42
+ </template>
43
+
44
+ <script>
45
+ import MFlex from '../mozaic/flex/MFlex';
46
+ import MButton from '../mozaic/buttons/MButton';
47
+ import MNotification from '../mozaic/notifications/MNotification';
48
+ import PbAnimableLoader from '../loader/PbAnimableLoader';
49
+ import { useStore } from 'vuex';
50
+ import { computed, onMounted } from 'vue';
51
+
52
+ export default {
53
+ name: 'PbConsent',
54
+
55
+ components: {
56
+ MFlex,
57
+ MButton,
58
+ MNotification,
59
+ PbAnimableLoader,
60
+ },
61
+
62
+ setup() {
63
+ const store = useStore();
64
+ const isMailConsentUpdating = computed(() => store.getters['consent/isMailConsentUpdating']);
65
+ const isMailConsentUpdated = computed(() => store.getters['consent/isMailConsentUpdated']);
66
+ const errorUpdateMailConsent = computed(() => store.getters['consent/getErrorUpdateMailConsent']);
67
+
68
+ const handleUpdateConsent = () => {
69
+ store.dispatch('sendEventToBus', {
70
+ code: 'UPDATE-MAIL-CONSENT',
71
+ payload: {},
72
+ });
73
+ store.dispatch('consent/updateMailConsent');
74
+ };
75
+
76
+ const handleRetry = () => {
77
+ store.dispatch('sendEventToBus', {
78
+ code: 'RETRY-UPDATE-MAIL-CONSENT',
79
+ payload: {},
80
+ });
81
+ store.dispatch('consent/updateMailConsent');
82
+ };
83
+
84
+ onMounted(() => {
85
+ store.dispatch('sendEventToBus', {
86
+ code: 'DISPLAY-MAIL-CONSENT',
87
+ payload: {},
88
+ });
89
+ });
90
+
91
+ return {
92
+ isMailConsentUpdating,
93
+ isMailConsentUpdated,
94
+ errorUpdateMailConsent,
95
+ handleUpdateConsent,
96
+ handleRetry,
97
+ };
98
+ },
99
+ };
100
+ </script>
101
+
102
+ <style lang="scss" scoped>
103
+ @import 'pb-variables';
104
+
105
+ .pb-consent {
106
+ &__label {
107
+ @include set-font-face('regular');
108
+ @include set-font-scale('06', 'm');
109
+
110
+ color: $color-grey-900;
111
+ }
112
+
113
+ &__actions {
114
+ width: 100%;
115
+
116
+ &--notification {
117
+ width: 100%;
118
+ }
119
+
120
+ &--button {
121
+ margin-top: $mu150;
122
+ }
123
+ }
124
+
125
+ &__loading {
126
+ margin: auto;
127
+ padding-top: $mu100;
128
+
129
+ &-loader {
130
+ height: $mu300;
131
+ width: $mu300;
132
+ }
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,123 @@
1
+ import { Story, Meta, Canvas } from '@storybook/addon-docs';
2
+ import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
3
+ import PbProjectHub from './PbProjectHub';
4
+ import store from '../../../stores/store';
5
+ import { rest } from 'msw';
6
+ import { internalServerErrorResolver } from '../../../services/api/mocks/commonMock';
7
+ import { getProjectByIdResolver } from '../../../services/api/mocks/projectsMock';
8
+ import {
9
+ getMailConsentToUpdateResolver,
10
+ getMailConsentUpdatedResolver,
11
+ putConsentsUpdateResolver,
12
+ putConsentsUpdateWithDelayResolver,
13
+ } from '../../../services/api/mocks/consentMock';
14
+
15
+ <Meta
16
+ title="Project Booster/Components/Projects/PbProjectHub 🦠/Features/Consent (Mail)"
17
+ component={PbProjectHub}
18
+ parameters={{
19
+ layout: 'fullscreen',
20
+ }}
21
+ decorators={[
22
+ nestedAppDecorator(store, [
23
+ {
24
+ name: 'ProjectHub',
25
+ path: '/',
26
+ component: PbProjectHub,
27
+ beforeEnter: async (to, from, next, store) => {
28
+ store.dispatch('projects/loadProject', '001');
29
+ store.dispatch('consent/checkMailConsent');
30
+ next();
31
+ },
32
+ },
33
+ ]),
34
+ ]}
35
+ />
36
+
37
+ export const TemplateSandbox = (args, { argTypes }) => ({
38
+ props: Object.keys(argTypes),
39
+ template: `<div style="margin: 0 auto;min-height: 100vh;width: 100%;">
40
+ <router-view v-slot="{ Component }">
41
+ <component :is="Component" :key="$route.fullPath" />
42
+ </router-view>
43
+ </div>`,
44
+ });
45
+
46
+ # 🦠 `PbProjectHub` - Component
47
+
48
+ The `PbProjectHub` component to access your project.
49
+
50
+ ## Showcase with consent section to display
51
+
52
+ <Canvas>
53
+ <Story
54
+ name="Showcase with consent section"
55
+ parameters={{
56
+ controls: { disable: true },
57
+ msw: [
58
+ rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
59
+ rest.get('/api/users/current/consents', getMailConsentToUpdateResolver),
60
+ rest.put('/api/users/current/consents', putConsentsUpdateResolver),
61
+ ],
62
+ }}
63
+ height="100vh"
64
+ >
65
+ {TemplateSandbox.bind({})}
66
+ </Story>
67
+ </Canvas>
68
+
69
+ ## Showcase with consent section to hide
70
+
71
+ <Canvas>
72
+ <Story
73
+ name="Showcase with consent section hidden"
74
+ parameters={{
75
+ controls: { disable: true },
76
+ msw: [
77
+ rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
78
+ rest.get('/api/users/current/consents', getMailConsentUpdatedResolver),
79
+ ],
80
+ }}
81
+ height="100vh"
82
+ >
83
+ {TemplateSandbox.bind({})}
84
+ </Story>
85
+ </Canvas>
86
+
87
+ ## Showcase with failure on update consent
88
+
89
+ <Canvas>
90
+ <Story
91
+ name="Showcase with update failure"
92
+ parameters={{
93
+ controls: { disable: true },
94
+ msw: [
95
+ rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
96
+ rest.get('/api/users/current/consents', getMailConsentToUpdateResolver),
97
+ rest.put('/api/users/current/consents', internalServerErrorResolver),
98
+ ],
99
+ }}
100
+ height="100vh"
101
+ >
102
+ {TemplateSandbox.bind({})}
103
+ </Story>
104
+ </Canvas>
105
+
106
+ ## Showcase with delay on update
107
+
108
+ <Canvas>
109
+ <Story
110
+ name="Showcase with delay on update"
111
+ parameters={{
112
+ controls: { disable: true },
113
+ msw: [
114
+ rest.get('/api/inhabitant-projects/:projectId', getProjectByIdResolver),
115
+ rest.get('/api/users/current/consents', getMailConsentToUpdateResolver),
116
+ rest.put('/api/users/current/consents', putConsentsUpdateWithDelayResolver),
117
+ ],
118
+ }}
119
+ height="100vh"
120
+ >
121
+ {TemplateSandbox.bind({})}
122
+ </Story>
123
+ </Canvas>
@@ -492,6 +492,14 @@
492
492
  </m-flex>
493
493
  </div>
494
494
  </m-flex>
495
+ <m-flex v-if="isMailConsentDisplayed" class="pb-project-hub__section" direction="column" full-width>
496
+ <div class="pb-project-hub__section-header">
497
+ <div class="pb-project-hub__section-title" ref="pbConsent">Souscription newsletter</div>
498
+ </div>
499
+ <div class="pb-project-hub__section-content">
500
+ <pb-consent />
501
+ </div>
502
+ </m-flex>
495
503
  <m-flex
496
504
  v-if="!readOnly"
497
505
  class="pb-project-hub__section pb-project-hub__section-separator"
@@ -794,6 +802,7 @@ import PbMOpinion from '../../mopinion/PbMOpinion';
794
802
  import PbProjectAttributes from '../project-attributes/PbProjectAttributes';
795
803
  import PbRestitution from '../../restitution/PbRestitution';
796
804
  import PbTasksPreview from '../../tasks/preview/PbTasksPreview';
805
+ import PbConsent from '../../consent/PbConsent';
797
806
  import TASK_MODEL from './plannerTask.json';
798
807
  import ESTIMATES_PAYLOAD from './../../estimates/estimates-payload.json';
799
808
  import cloneDeep from 'lodash.clonedeep';
@@ -852,6 +861,7 @@ export default {
852
861
  PbProjectAttributes,
853
862
  PbRestitution,
854
863
  PbTasksPreview,
864
+ PbConsent,
855
865
  },
856
866
 
857
867
  props: {
@@ -1001,6 +1011,10 @@ export default {
1001
1011
  configurationsLoadError: 'getConfigurationsLoadError',
1002
1012
  }),
1003
1013
 
1014
+ ...mapGetters('consent', {
1015
+ isMailConsentDisplayed: 'isMailConsentDisplayed',
1016
+ }),
1017
+
1004
1018
  ...mapGetters('inhabitants', {
1005
1019
  isInhabitantDisplayed: 'isInhabitantDisplayed',
1006
1020
  currentInhabitantId: 'getCurrentInhabitantId',
@@ -0,0 +1,33 @@
1
+ import axios from 'axios';
2
+ import he from 'he';
3
+
4
+ export const clientApi = axios.create({
5
+ baseURL: '/project-booster/api',
6
+ });
7
+
8
+ if (global.window.config) {
9
+ clientApi.defaults.baseURL = global.window.config.VUE_APP_DEFAULT_BASE_URL;
10
+ }
11
+
12
+ export const updateConsentApiClient = (config) => {
13
+ if (config.apiKey) {
14
+ clientApi.defaults.headers.common['X-ClientApiKey'] = config.apiKey;
15
+ }
16
+ if (config.baseUrl) {
17
+ clientApi.defaults.baseURL = config.baseUrl;
18
+ }
19
+ };
20
+
21
+ export const getConsents = async () => {
22
+ const response = await clientApi.get('/users/current/consents');
23
+
24
+ return JSON.parse(
25
+ JSON.stringify(response.data).replace(/:"([^"]+)"/g, (match, $1) => {
26
+ return `: "${he.escape($1)}"`;
27
+ }),
28
+ );
29
+ };
30
+
31
+ export const updateMailConsent = async (mailConsent) => {
32
+ return await clientApi.put('/users/current/consents', { mail: mailConsent });
33
+ };
@@ -0,0 +1,25 @@
1
+ export const getMailConsentToUpdateResolver = (req, res, ctx) => {
2
+ return res.once(
3
+ ctx.status(200),
4
+ ctx.json({
5
+ mail: false,
6
+ }),
7
+ );
8
+ };
9
+
10
+ export const getMailConsentUpdatedResolver = (req, res, ctx) => {
11
+ return res.once(
12
+ ctx.status(200),
13
+ ctx.json({
14
+ mail: true,
15
+ }),
16
+ );
17
+ };
18
+
19
+ export const putConsentsUpdateResolver = (req, res, ctx) => {
20
+ return res.once(ctx.status(204));
21
+ };
22
+
23
+ export const putConsentsUpdateWithDelayResolver = (req, res, ctx) => {
24
+ return res.once(ctx.delay(1000), ctx.status(204));
25
+ };
@@ -0,0 +1,68 @@
1
+ import { updateMailConsent, getConsents } from '../../services/api/consentApi';
2
+
3
+ export default {
4
+ namespaced: true,
5
+
6
+ state: {
7
+ isMailConsentDisplayed: false,
8
+ isMailConsentUpdated: false,
9
+ isMailConsentUpdating: false,
10
+ errorUpdateMailConsent: null,
11
+ },
12
+
13
+ getters: {
14
+ isMailConsentDisplayed(state) {
15
+ return state.isMailConsentDisplayed;
16
+ },
17
+ isMailConsentUpdated(state) {
18
+ return state.isMailConsentUpdated;
19
+ },
20
+ getErrorUpdateMailConsent(state) {
21
+ return state.errorUpdateMailConsent;
22
+ },
23
+ isMailConsentUpdating(state) {
24
+ return state.isMailConsentUpdating;
25
+ },
26
+ },
27
+
28
+ mutations: {
29
+ setIsMailConsentDisplayed(state, isDisplayed) {
30
+ state.isMailConsentDisplayed = isDisplayed;
31
+ },
32
+ setIsMailConsentUpdated(state, isUpdated) {
33
+ state.isMailConsentUpdated = isUpdated;
34
+ },
35
+ setErrorUpdateMailConsent(state, error) {
36
+ state.errorUpdateMailConsent = error;
37
+ },
38
+ setIsMailConsentUpdating(state, isUpdating) {
39
+ state.isMailConsentUpdating = isUpdating;
40
+ },
41
+ },
42
+
43
+ actions: {
44
+ async checkMailConsent({ commit }) {
45
+ try {
46
+ const consents = await getConsents();
47
+ if (!consents.mail) {
48
+ commit('setIsMailConsentDisplayed', true);
49
+ }
50
+ } catch (error) {
51
+ console.error(error);
52
+ }
53
+ },
54
+ setMailConsentDisplayed({ commit }, isDisplayed) {
55
+ commit('setIsMailConsentDisplayed', isDisplayed);
56
+ },
57
+ async updateMailConsent({ commit }) {
58
+ commit('setIsMailConsentUpdating', true);
59
+ try {
60
+ await updateMailConsent(true);
61
+ commit('setIsMailConsentUpdated', true);
62
+ } catch (error) {
63
+ commit('setErrorUpdateMailConsent', error);
64
+ }
65
+ commit('setIsMailConsentUpdating', false);
66
+ },
67
+ },
68
+ };
@@ -8,6 +8,7 @@ import plannerStore from './modules/plannerStore';
8
8
  import projectsStore from './modules/projectsStore';
9
9
  import toolsStore from './modules/toolsStore';
10
10
  import mediaDocumentsStore from './modules/mediaDocumentsStore';
11
+ import consentStore from './modules/consentStore';
11
12
  import cloneDeep from 'lodash.clonedeep';
12
13
 
13
14
  export default {
@@ -25,6 +26,7 @@ export default {
25
26
  media: cloneDeep(mediaDocumentsStore),
26
27
  documentsPlans: cloneDeep(mediaDocumentsStore),
27
28
  documentsPictures: cloneDeep(mediaDocumentsStore),
29
+ consent: consentStore,
28
30
  },
29
31
  mutations: {
30
32
  eventBusSendEvent(state, { code, payload }) {
package/dist/demo.html DELETED
@@ -1 +0,0 @@
1
- <!doctype html><meta charset="utf-8"><title>project-booster-vue demo</title><script src="./project-booster-vue.umd.js"></script><link rel="stylesheet" href="./project-booster-vue.css"><script>console.log(project-booster-vue)</script>