project-booster-vue 8.93.5 → 8.94.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/package.json +1 -1
- package/src/components/inspiration/PbInspiration.vue +65 -22
- package/src/components/inspiration/__snapshots__/storyshots-puppeteer-test-puppeteer-js-image-storyshots-project-booster-components-/360/237/246/240-pb-inspiration-empty-state-1-snap.png +0 -0
- package/src/components/media/upload/PbMediaUpload.stories.mdx +47 -5
- package/src/components/media/upload/PbMediaUpload.vue +19 -48
- package/src/components/media/upload/__snapshots__/storyshots-puppeteer-test-puppeteer-js-image-storyshots-project-booster-components-/360/237/246/240-pb-media-upload-name-already-used-1-snap.png +0 -0
- package/src/components/project-item-save/PbProjectItemSaveProjectsList.vue +3 -2
- package/src/components/project-item-save/PbProjectItemSaveStore.js +0 -8
- package/src/components/question/PbQuestion.vue +14 -9
- package/src/components/question/upload-document/__snapshots__/storyshots-puppeteer-test-puppeteer-js-image-storyshots-project-booster-scenario-/360/237/246/240-questions-/360/237/246/240-pb-upload-document-101-sandbox-1-snap.png +0 -0
- package/src/components/question/upload-document/__snapshots__/storyshots-puppeteer-test-puppeteer-js-image-storyshots-project-booster-scenario-/360/237/246/240-questions-/360/237/246/240-pb-upload-document-showcase-with-show-more-documents-1-snap.png +0 -0
- package/src/components/sticky-footer/PbStickyFooter.stories.mdx +32 -0
- package/src/components/sticky-footer/PbStickyFooter.vue +79 -0
- package/src/components/sticky-footer/__snapshots__/storyshots-puppeteer-test-puppeteer-js-image-storyshots-project-booster-components-/360/237/246/240-pb-sticky-footer-101-sandbox-1-snap.png +0 -0
- package/src/service/api/mocks/commonMock.js +3 -5
- package/src/store/modules/mediaStore.js +13 -69
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<m-flex class="pb-inspiration" direction="column" full-width>
|
|
2
|
+
<m-flex class="pb-inspiration" direction="column" full-width ref="pbInspiration">
|
|
3
3
|
<m-link
|
|
4
4
|
v-if="project"
|
|
5
5
|
:label="project.name"
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
font-weight="semi-bold"
|
|
15
15
|
size="s"
|
|
16
16
|
/>
|
|
17
|
-
<
|
|
17
|
+
<div
|
|
18
|
+
class="pb-inspiration__header-upload-button"
|
|
19
|
+
v-if="(!isLoadingMedia || mediaList.length > 0) && !mediaLoadError"
|
|
20
|
+
>
|
|
18
21
|
<pb-media-upload namespace="media" @media-uploaded="handleMediaUploaded" ref="pbMediaUpload" />
|
|
19
|
-
</
|
|
22
|
+
</div>
|
|
20
23
|
</m-flex>
|
|
21
24
|
<m-flex class="pb-inspiration__container">
|
|
22
25
|
<m-flex
|
|
@@ -124,19 +127,31 @@
|
|
|
124
127
|
@link-click="$store.dispatch('media/deleteMedia')"
|
|
125
128
|
@close="resetMediaDeletionError"
|
|
126
129
|
/>
|
|
130
|
+
<pb-sticky-footer
|
|
131
|
+
class="pb-inspiration__sticky-upload-button"
|
|
132
|
+
v-if="(!isLoadingMedia || mediaList.length > 0) && !mediaLoadError"
|
|
133
|
+
>
|
|
134
|
+
<pb-media-upload
|
|
135
|
+
class="pb-inspiration__sticky-upload-button-content"
|
|
136
|
+
namespace="media"
|
|
137
|
+
@media-uploaded="handleMediaUploaded"
|
|
138
|
+
ref="pbMediaUpload"
|
|
139
|
+
/>
|
|
140
|
+
</pb-sticky-footer>
|
|
127
141
|
</m-flex>
|
|
128
142
|
</template>
|
|
129
143
|
|
|
130
144
|
<script>
|
|
131
145
|
import MButton from '../mozaic/buttons/MButton';
|
|
132
146
|
import MDialog from '../mozaic/dialog/MDialog';
|
|
133
|
-
import
|
|
147
|
+
import MFlex from '../mozaic/flex/MFlex';
|
|
134
148
|
import MHeading from '../mozaic/heading/MHeading';
|
|
149
|
+
import MLink from '../mozaic/link/MLink';
|
|
150
|
+
import MNotification from '../mozaic/notifications/MNotification';
|
|
135
151
|
import PbLoader from '../loader/PbLoader';
|
|
136
152
|
import PbMediaList from '../media/list/PbMediaList';
|
|
137
153
|
import PbMediaUpload from '../media/upload/PbMediaUpload';
|
|
138
|
-
import
|
|
139
|
-
import MNotification from '../mozaic/notifications/MNotification';
|
|
154
|
+
import PbStickyFooter from '../sticky-footer/PbStickyFooter';
|
|
140
155
|
import { mapGetters } from 'vuex';
|
|
141
156
|
|
|
142
157
|
const BACK_ICON =
|
|
@@ -145,15 +160,16 @@ const BACK_ICON =
|
|
|
145
160
|
export default {
|
|
146
161
|
name: 'PbInspiration',
|
|
147
162
|
components: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
163
|
+
MButton,
|
|
164
|
+
MDialog,
|
|
165
|
+
MFlex,
|
|
151
166
|
MHeading,
|
|
152
167
|
MLink,
|
|
153
|
-
|
|
154
|
-
MDialog,
|
|
155
|
-
MButton,
|
|
168
|
+
MNotification,
|
|
156
169
|
PbLoader,
|
|
170
|
+
PbMediaList,
|
|
171
|
+
PbMediaUpload,
|
|
172
|
+
PbStickyFooter,
|
|
157
173
|
},
|
|
158
174
|
|
|
159
175
|
data: () => ({
|
|
@@ -182,6 +198,10 @@ export default {
|
|
|
182
198
|
this.$store.dispatch('sendEventToBus', { code: 'mediaHubLanded', payload: {} });
|
|
183
199
|
},
|
|
184
200
|
|
|
201
|
+
mounted() {
|
|
202
|
+
this.scrollToTop();
|
|
203
|
+
},
|
|
204
|
+
|
|
185
205
|
methods: {
|
|
186
206
|
handleMediaUploaded() {
|
|
187
207
|
this.$store.dispatch('media/refreshMediaList');
|
|
@@ -223,6 +243,16 @@ export default {
|
|
|
223
243
|
}
|
|
224
244
|
next();
|
|
225
245
|
},
|
|
246
|
+
scrollToTop() {
|
|
247
|
+
setTimeout(() => {
|
|
248
|
+
const top = this.$refs.pbInspiration.$el.offsetTop;
|
|
249
|
+
window.scroll({
|
|
250
|
+
top,
|
|
251
|
+
left: 0,
|
|
252
|
+
behavior: 'smooth',
|
|
253
|
+
});
|
|
254
|
+
}, 200);
|
|
255
|
+
},
|
|
226
256
|
},
|
|
227
257
|
};
|
|
228
258
|
</script>
|
|
@@ -235,25 +265,24 @@ $responsive-breakpoint: 'l';
|
|
|
235
265
|
.pb-inspiration {
|
|
236
266
|
@include set-font-face('regular');
|
|
237
267
|
|
|
268
|
+
box-sizing: border-box;
|
|
269
|
+
height: 100vh;
|
|
270
|
+
height: stretch;
|
|
238
271
|
margin: 0 auto;
|
|
239
272
|
max-width: 1024px;
|
|
273
|
+
padding: 0 $mu100;
|
|
240
274
|
width: 100%;
|
|
275
|
+
|
|
241
276
|
&__header {
|
|
242
277
|
&-heading {
|
|
243
278
|
flex-grow: 1;
|
|
244
279
|
}
|
|
245
280
|
|
|
246
|
-
&-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
&-disabled-text {
|
|
250
|
-
@include set-font-scale('04', 'm');
|
|
281
|
+
&-upload-button {
|
|
282
|
+
display: none;
|
|
251
283
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
padding-top: $mu025;
|
|
255
|
-
text-align: center;
|
|
256
|
-
width: 100%;
|
|
284
|
+
@include set-from-screen('m') {
|
|
285
|
+
display: block;
|
|
257
286
|
}
|
|
258
287
|
}
|
|
259
288
|
}
|
|
@@ -278,6 +307,7 @@ $responsive-breakpoint: 'l';
|
|
|
278
307
|
}
|
|
279
308
|
|
|
280
309
|
&__container {
|
|
310
|
+
padding-bottom: $mu100;
|
|
281
311
|
width: 100%;
|
|
282
312
|
}
|
|
283
313
|
|
|
@@ -360,5 +390,18 @@ $responsive-breakpoint: 'l';
|
|
|
360
390
|
&__notification {
|
|
361
391
|
z-index: 200;
|
|
362
392
|
}
|
|
393
|
+
|
|
394
|
+
:deep(.pb-inspiration__sticky-upload-button) {
|
|
395
|
+
margin: 0 -$mu100;
|
|
396
|
+
width: calc(100% + 2 * #{$mu100});
|
|
397
|
+
|
|
398
|
+
@include set-from-screen('m') {
|
|
399
|
+
display: none;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
&__sticky-upload-button-content {
|
|
404
|
+
padding: $mu100;
|
|
405
|
+
}
|
|
363
406
|
}
|
|
364
407
|
</style>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import PbMediaUpload from './PbMediaUpload';
|
|
2
2
|
import { Anchor, Story, Preview, Meta, Props, ArgsTable, Source, Canvas } from '@storybook/addon-docs';
|
|
3
3
|
import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
|
|
4
|
-
import
|
|
4
|
+
import mediaStore from '../../../store/modules/mediaStore';
|
|
5
5
|
import { rest } from 'msw';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getAllMediaPaginationResolver,
|
|
8
|
+
nameAlreadyUsedResolver,
|
|
9
|
+
uploadMediaResolver,
|
|
10
|
+
} from '../../../service/api/mocks/mediaMock';
|
|
7
11
|
import { notContentResolver, successResolver } from '../../../service/api/mocks/commonMock';
|
|
8
12
|
|
|
9
13
|
<Meta
|
|
@@ -12,7 +16,26 @@ import { notContentResolver, successResolver } from '../../../service/api/mocks/
|
|
|
12
16
|
parameters={{
|
|
13
17
|
layout: 'fullscreen',
|
|
14
18
|
}}
|
|
15
|
-
decorators={[
|
|
19
|
+
decorators={[
|
|
20
|
+
nestedAppDecorator(
|
|
21
|
+
{
|
|
22
|
+
modules: {
|
|
23
|
+
media: mediaStore,
|
|
24
|
+
},
|
|
25
|
+
mutations: {
|
|
26
|
+
eventBusSendEvent(state, { code, payload }) {
|
|
27
|
+
console.log('event bus data : ', code, payload);
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
actions: {
|
|
31
|
+
sendEventToBus({ commit }, action) {
|
|
32
|
+
commit('eventBusSendEvent', action);
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
[],
|
|
37
|
+
),
|
|
38
|
+
]}
|
|
16
39
|
/>
|
|
17
40
|
|
|
18
41
|
# 🦠 `PbMediaUpload` - Component
|
|
@@ -24,8 +47,7 @@ export const TemplateSandbox = (args, { argTypes }) => ({
|
|
|
24
47
|
return { args };
|
|
25
48
|
},
|
|
26
49
|
template: `<pb-media-upload
|
|
27
|
-
:
|
|
28
|
-
:namespace="namespace"
|
|
50
|
+
:namespace="args.namespace"
|
|
29
51
|
/>`,
|
|
30
52
|
});
|
|
31
53
|
|
|
@@ -51,3 +73,23 @@ export const TemplateSandbox = (args, { argTypes }) => ({
|
|
|
51
73
|
{TemplateSandbox.bind({})}
|
|
52
74
|
</Story>
|
|
53
75
|
</Canvas>
|
|
76
|
+
|
|
77
|
+
## Name already used
|
|
78
|
+
|
|
79
|
+
<Canvas>
|
|
80
|
+
<Story
|
|
81
|
+
name="Name already used"
|
|
82
|
+
parameters={{
|
|
83
|
+
controls: { disabled: true },
|
|
84
|
+
msw: [rest.post('/api/media', nameAlreadyUsedResolver)],
|
|
85
|
+
}}
|
|
86
|
+
inline={false}
|
|
87
|
+
height="1024px"
|
|
88
|
+
args={{
|
|
89
|
+
acceptedFileTypes: 'image/jpeg, image/png, image/heif, image/heic, image/heif-sequence, image/heic-sequence',
|
|
90
|
+
namespace: 'media',
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
{TemplateSandbox.bind({})}
|
|
94
|
+
</Story>
|
|
95
|
+
</Canvas>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="pb-media-upload">
|
|
3
3
|
<form class="pb-media-upload__form" ref="pbMediaUploadForm" enctype="multipart/form-data" novalidate>
|
|
4
4
|
<div
|
|
5
|
-
class="pb-media-upload__form-button mc-button mc-button--s"
|
|
5
|
+
class="pb-media-upload__form-button mc-button mc-button--s@from-m"
|
|
6
6
|
:class="{ 'is-disabled': isAddPhotoDisabled }"
|
|
7
7
|
id="pbMediaUploadButton"
|
|
8
8
|
@click="addMedia"
|
|
@@ -280,6 +280,9 @@ export default {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
},
|
|
283
|
+
fileName() {
|
|
284
|
+
this.isNameAlreadyUsed = false;
|
|
285
|
+
},
|
|
283
286
|
},
|
|
284
287
|
|
|
285
288
|
mounted() {
|
|
@@ -322,19 +325,23 @@ export default {
|
|
|
322
325
|
this.$store.dispatch(this.storePrefix + 'resetMediaUploadContext');
|
|
323
326
|
},
|
|
324
327
|
|
|
325
|
-
upload() {
|
|
328
|
+
async upload() {
|
|
326
329
|
if (!this.disabled && !this.isMediaUploaded) {
|
|
327
330
|
this.isMediaUploading = true;
|
|
328
331
|
this.isMediaUploaded = false;
|
|
329
332
|
try {
|
|
330
|
-
this.$store.dispatch(this.storePrefix + 'uploadFile', {
|
|
333
|
+
await this.$store.dispatch(this.storePrefix + 'uploadFile', {
|
|
331
334
|
formData: this.formData,
|
|
332
335
|
fileName: this.fileName,
|
|
333
336
|
isRoomPicture: this.isRoomPicture,
|
|
334
337
|
});
|
|
335
338
|
this.isMediaUploaded = true;
|
|
336
339
|
} catch (error) {
|
|
337
|
-
|
|
340
|
+
if (error.response?.body?.code === 'NAME_ALREADY_USED') {
|
|
341
|
+
this.isNameAlreadyUsed = true;
|
|
342
|
+
} else {
|
|
343
|
+
this.mediaUploadError = error;
|
|
344
|
+
}
|
|
338
345
|
}
|
|
339
346
|
this.isMediaUploading = false;
|
|
340
347
|
} else {
|
|
@@ -459,57 +466,20 @@ $responsive-breakpoint: 'l';
|
|
|
459
466
|
}
|
|
460
467
|
|
|
461
468
|
:deep(.m-dialog) {
|
|
462
|
-
|
|
463
|
-
max-height: 1100px;
|
|
464
|
-
min-height: 500px;
|
|
465
|
-
width: 100%;
|
|
466
|
-
|
|
467
|
-
@include set-from-screen('m') {
|
|
468
|
-
height: 80vh;
|
|
469
|
-
max-height: 700px;
|
|
470
|
-
max-width: 900px;
|
|
471
|
-
min-height: 500px;
|
|
472
|
-
min-width: 450px;
|
|
473
|
-
width: 90vw;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
@include set-from-screen('l') {
|
|
477
|
-
height: 90vh;
|
|
478
|
-
max-height: 1100px;
|
|
479
|
-
max-width: 1000px;
|
|
480
|
-
min-height: 500px;
|
|
481
|
-
min-width: 450px;
|
|
482
|
-
width: 90vw;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
@include set-from-screen('xl') {
|
|
486
|
-
height: 90vh;
|
|
487
|
-
max-height: 700px;
|
|
488
|
-
max-width: 1300px;
|
|
489
|
-
min-height: 500px;
|
|
490
|
-
min-width: 450px;
|
|
491
|
-
width: 60vw;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
@include set-from-screen('xxl') {
|
|
495
|
-
height: 90vh;
|
|
496
|
-
max-height: 900px;
|
|
497
|
-
max-width: 1300px;
|
|
498
|
-
min-height: 500px;
|
|
499
|
-
min-width: 450px;
|
|
500
|
-
width: 60vw;
|
|
501
|
-
}
|
|
469
|
+
overflow-y: scroll;
|
|
502
470
|
}
|
|
503
471
|
|
|
504
472
|
:deep(.m-dialog__header) {
|
|
505
|
-
|
|
473
|
+
flex-shrink: 0;
|
|
506
474
|
}
|
|
507
475
|
|
|
508
476
|
:deep(.m-dialog__body) {
|
|
509
|
-
|
|
510
|
-
display: flex;
|
|
511
|
-
justify-content: center;
|
|
477
|
+
flex: 0 0 30vh;
|
|
512
478
|
overflow: visible;
|
|
479
|
+
|
|
480
|
+
@include set-from-screen($responsive-breakpoint) {
|
|
481
|
+
flex: 0 0 40vh;
|
|
482
|
+
}
|
|
513
483
|
}
|
|
514
484
|
|
|
515
485
|
:deep(.m-dialog__footer) {
|
|
@@ -593,6 +563,7 @@ $responsive-breakpoint: 'l';
|
|
|
593
563
|
}
|
|
594
564
|
|
|
595
565
|
&-input {
|
|
566
|
+
margin-bottom: $mu200;
|
|
596
567
|
margin-top: $mu050;
|
|
597
568
|
width: 100%;
|
|
598
569
|
:deep(.mc-textarea.mc-field__input) {
|
|
@@ -75,8 +75,9 @@ export default {
|
|
|
75
75
|
},
|
|
76
76
|
methods: {
|
|
77
77
|
handleInput(newValue) {
|
|
78
|
-
|
|
79
|
-
this.$
|
|
78
|
+
const selectedProjectCode = Object.entries(newValue).find(([key, value]) => value)[0];
|
|
79
|
+
this.$store.dispatch('loadProject', selectedProjectCode);
|
|
80
|
+
this.$emit('save-in-existing-project', selectedProjectCode);
|
|
80
81
|
this.$forceUpdate();
|
|
81
82
|
},
|
|
82
83
|
reloadProjects() {
|
|
@@ -197,19 +197,11 @@ const PbProjectItemSaveStore = {
|
|
|
197
197
|
if (selectedProject) {
|
|
198
198
|
commit('setIsLoadingProject', true);
|
|
199
199
|
commit('setCurrentProjectId', selectedProject.code);
|
|
200
|
-
const projects = state.projects.map((project) => {
|
|
201
|
-
const selected = project.code === selectedProject.code;
|
|
202
|
-
return Object.assign({}, project, { selected: selected });
|
|
203
|
-
});
|
|
204
|
-
commit('setProjects', projects);
|
|
205
200
|
commit('setIsLoadingProject', false);
|
|
206
201
|
}
|
|
207
202
|
},
|
|
208
203
|
resetSelectedProjects({ commit, state }) {
|
|
209
204
|
const projects = state.projects.map((project) => {
|
|
210
|
-
if (project.selected) {
|
|
211
|
-
return Object.assign({}, project, { selected: false });
|
|
212
|
-
}
|
|
213
205
|
return project;
|
|
214
206
|
});
|
|
215
207
|
commit('setCurrentProjectId', null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="pb-question__container"
|
|
4
|
-
:style="`padding-bottom: calc(${stickyBottomOffset} +
|
|
4
|
+
:style="`padding-bottom: calc(${stickyBottomOffset} + ${pbQuestionActionsButtonsMaxSize}px);`"
|
|
5
5
|
>
|
|
6
6
|
<div class="pb-question">
|
|
7
7
|
<m-flex align-items="center">
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
<div
|
|
120
120
|
v-if="payload.multiSelect"
|
|
121
121
|
class="pb-question__actions-container"
|
|
122
|
-
:style="`bottom: calc(${stickyBottomOffset} + ${pbQuestionActionsButtons1Size.height});`"
|
|
122
|
+
:style="`bottom: calc(${stickyBottomOffset} + ${pbQuestionActionsButtons1Size.height}px);`"
|
|
123
123
|
>
|
|
124
124
|
<div class="pb-question__actions">
|
|
125
125
|
<div class="pb-question__actions-buttons-container">
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
<div
|
|
160
160
|
v-if="payload.skippable"
|
|
161
161
|
class="pb-question__actions-container"
|
|
162
|
-
:style="`bottom: calc(${stickyBottomOffset} + ${pbQuestionActionsButtons2Size.height});`"
|
|
162
|
+
:style="`bottom: calc(${stickyBottomOffset} + ${pbQuestionActionsButtons2Size.height}px);`"
|
|
163
163
|
>
|
|
164
164
|
<div
|
|
165
165
|
class="pb-question__actions"
|
|
@@ -352,8 +352,9 @@ export default {
|
|
|
352
352
|
pageSize: 8,
|
|
353
353
|
showMoreAnimation: '',
|
|
354
354
|
showAnswerDelay: 0,
|
|
355
|
-
pbQuestionActionsButtons1Size: { height:
|
|
356
|
-
pbQuestionActionsButtons2Size: { height:
|
|
355
|
+
pbQuestionActionsButtons1Size: { height: 0 },
|
|
356
|
+
pbQuestionActionsButtons2Size: { height: 0 },
|
|
357
|
+
pbQuestionActionsButtonsMaxSize: 0,
|
|
357
358
|
BACK_ICON,
|
|
358
359
|
INFO_ICON,
|
|
359
360
|
displayDialog: false,
|
|
@@ -648,20 +649,24 @@ export default {
|
|
|
648
649
|
updatePbQuestionActionsButtonsSizeHeight() {
|
|
649
650
|
setTimeout(() => {
|
|
650
651
|
if (this.$refs.pbQuestionActionsButtons1) {
|
|
651
|
-
this.pbQuestionActionsButtons1Size.height = `${this.$refs.pbQuestionActionsButtons1.$el.clientHeight}
|
|
652
|
+
this.pbQuestionActionsButtons1Size.height = `${this.$refs.pbQuestionActionsButtons1.$el.clientHeight}`;
|
|
652
653
|
} else {
|
|
653
654
|
setTimeout(() => {
|
|
654
|
-
this.pbQuestionActionsButtons1Size.height =
|
|
655
|
+
this.pbQuestionActionsButtons1Size.height = 0;
|
|
655
656
|
}, 250);
|
|
656
657
|
}
|
|
657
658
|
|
|
658
659
|
if (this.$refs.pbQuestionActionsButtons2) {
|
|
659
|
-
this.pbQuestionActionsButtons2Size.height = `${this.$refs.pbQuestionActionsButtons2.$el.clientHeight}
|
|
660
|
+
this.pbQuestionActionsButtons2Size.height = `${this.$refs.pbQuestionActionsButtons2.$el.clientHeight}`;
|
|
660
661
|
} else {
|
|
661
662
|
setTimeout(() => {
|
|
662
|
-
this.pbQuestionActionsButtons2Size.height =
|
|
663
|
+
this.pbQuestionActionsButtons2Size.height = 0;
|
|
663
664
|
}, 250);
|
|
664
665
|
}
|
|
666
|
+
this.pbQuestionActionsButtonsMaxSize = Math.max(
|
|
667
|
+
this.pbQuestionActionsButtons1Size.height,
|
|
668
|
+
this.pbQuestionActionsButtons2Size.height,
|
|
669
|
+
);
|
|
665
670
|
});
|
|
666
671
|
},
|
|
667
672
|
handleLinkClick(answer) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Meta, Canvas, Story, ArgsTable } from '@storybook/addon-docs';
|
|
2
|
+
import PbStickyFooter from './PbStickyFooter';
|
|
3
|
+
|
|
4
|
+
<Meta title="Project Booster/Components/ 🦠 PbStickyFooter" component={PbStickyFooter} />
|
|
5
|
+
|
|
6
|
+
# 🦠 `PbStickyFooter` - Component
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# `PbStickyFooter` - Component props
|
|
11
|
+
|
|
12
|
+
export const TemplateSandbox = (args, { argTypes }) => ({
|
|
13
|
+
props: Object.keys(argTypes),
|
|
14
|
+
components: { PbStickyFooter },
|
|
15
|
+
template: `
|
|
16
|
+
<div style="width: 100%; background-image: url('https://images.unsplash.com/photo-1620995487063-a07efd2a9438?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=3150&q=80');">
|
|
17
|
+
<div style="height: 150vh;">Content</div>
|
|
18
|
+
<pb-sticky-footer>
|
|
19
|
+
<div style="margin: 1rem; padding: 1rem;background-color: #1e5f82;color: white;">Sticky Footer</div>
|
|
20
|
+
</pb-sticky-footer>
|
|
21
|
+
<div style="height: 120vh;">Footer</div>
|
|
22
|
+
</div>
|
|
23
|
+
`,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
<Canvas>
|
|
27
|
+
<Story name="101 Sandbox" args={{}} parameters={{ layout: 'fullscreen' }}>
|
|
28
|
+
{TemplateSandbox.bind({})}
|
|
29
|
+
</Story>
|
|
30
|
+
</Canvas>
|
|
31
|
+
|
|
32
|
+
<ArgsTable story="101 Sandbox" />
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div ref="pbStickyFooter" class="pb-sticky-footer" :class="{ stuck: stuck }" v-bind="$attrs">
|
|
3
|
+
<div class="pb-sticky-footer__content">
|
|
4
|
+
<slot />
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { ref, onMounted } from 'vue';
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
name: 'PbStickyFooter',
|
|
14
|
+
|
|
15
|
+
setup() {
|
|
16
|
+
const pbStickyFooter = ref(null);
|
|
17
|
+
|
|
18
|
+
const stuck = ref(false);
|
|
19
|
+
|
|
20
|
+
onMounted(() => {
|
|
21
|
+
const observer = new IntersectionObserver(
|
|
22
|
+
(entries) => {
|
|
23
|
+
if (entries[0].intersectionRatio > 0.99) {
|
|
24
|
+
stuck.value = false;
|
|
25
|
+
} else if (entries[0].intersectionRatio > 0.9 && entries[0].intersectionRect.top > 4) {
|
|
26
|
+
stuck.value = true;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
root: null,
|
|
31
|
+
threshold: [0.1, 0.99, 1],
|
|
32
|
+
rootMargin: '0px 0px -1px 0px',
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
observer.observe(pbStickyFooter.value);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
stuck,
|
|
40
|
+
pbStickyFooter,
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<style lang="scss" scoped>
|
|
47
|
+
@import 'variables';
|
|
48
|
+
|
|
49
|
+
.pb-sticky-footer {
|
|
50
|
+
bottom: -1px;
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
position: sticky;
|
|
55
|
+
width: 100%;
|
|
56
|
+
|
|
57
|
+
&::before {
|
|
58
|
+
background-color: white;
|
|
59
|
+
bottom: -1px;
|
|
60
|
+
box-shadow: -#{$mu050} -#{$mu100} $mu150 rgba(0, 0, 0, 0.35);
|
|
61
|
+
content: '';
|
|
62
|
+
left: 0;
|
|
63
|
+
opacity: 0;
|
|
64
|
+
position: absolute;
|
|
65
|
+
right: 0;
|
|
66
|
+
top: 0;
|
|
67
|
+
transition: opacity 100ms ease-out;
|
|
68
|
+
z-index: 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&__content {
|
|
72
|
+
z-index: 2;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.stuck::before {
|
|
76
|
+
opacity: 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { compose, context } from 'msw';
|
|
2
|
+
|
|
1
3
|
export const successResolver = (req, res, ctx) => {
|
|
2
4
|
return res(ctx.delay(200), ctx.status(200));
|
|
3
5
|
};
|
|
@@ -32,9 +34,5 @@ export const serverUnavailableResolver = (req, res, ctx) => {
|
|
|
32
34
|
|
|
33
35
|
// use to redirect response;
|
|
34
36
|
export function redirect(destination, statusCode) {
|
|
35
|
-
return (
|
|
36
|
-
res.status = statusCode;
|
|
37
|
-
res.headers.set('Location', destination);
|
|
38
|
-
return res;
|
|
39
|
-
};
|
|
37
|
+
return compose(context.delay(), context.status(statusCode), context.set('Location', destination));
|
|
40
38
|
}
|
|
@@ -18,12 +18,7 @@ export default {
|
|
|
18
18
|
isAddPhotoDisabled: false,
|
|
19
19
|
uploadProgress: 0,
|
|
20
20
|
uploadedMediaId: null,
|
|
21
|
-
mediaUploadError: null,
|
|
22
21
|
mediaCorrelationId: null,
|
|
23
|
-
isMediaNameSaving: false,
|
|
24
|
-
isMediaNameSaved: false,
|
|
25
|
-
isNameAlreadyUsed: false,
|
|
26
|
-
mediaNameSaveError: null,
|
|
27
22
|
currentMedia: null,
|
|
28
23
|
},
|
|
29
24
|
getters: {
|
|
@@ -72,21 +67,6 @@ export default {
|
|
|
72
67
|
getMediaCorrelationId(state) {
|
|
73
68
|
return state.mediaCorrelationId;
|
|
74
69
|
},
|
|
75
|
-
getMediaUploadError(state) {
|
|
76
|
-
return state.mediaUploadError;
|
|
77
|
-
},
|
|
78
|
-
isMediaNameSaving(state) {
|
|
79
|
-
return state.isMediaNameSaving;
|
|
80
|
-
},
|
|
81
|
-
isMediaNameSaved(state) {
|
|
82
|
-
return state.isMediaNameSaved;
|
|
83
|
-
},
|
|
84
|
-
isNameAlreadyUsed(state) {
|
|
85
|
-
return state.isNameAlreadyUsed;
|
|
86
|
-
},
|
|
87
|
-
getMediaNameSaveError(state) {
|
|
88
|
-
return state.mediaNameSaveError;
|
|
89
|
-
},
|
|
90
70
|
getCurrentMedia(state) {
|
|
91
71
|
return state.currentMedia;
|
|
92
72
|
},
|
|
@@ -128,21 +108,6 @@ export default {
|
|
|
128
108
|
setMediaCorrelationId(state, mediaCorrelationId) {
|
|
129
109
|
state.mediaCorrelationId = mediaCorrelationId;
|
|
130
110
|
},
|
|
131
|
-
setMediaUploadError(state, mediaUploadError) {
|
|
132
|
-
state.mediaUploadError = mediaUploadError;
|
|
133
|
-
},
|
|
134
|
-
setIsMediaNameSaving(state, isMediaNameSaving) {
|
|
135
|
-
state.isMediaNameSaving = isMediaNameSaving;
|
|
136
|
-
},
|
|
137
|
-
setIsMediaNameSaved(state, isMediaNameSaved) {
|
|
138
|
-
state.isMediaNameSaved = isMediaNameSaved;
|
|
139
|
-
},
|
|
140
|
-
setIsNameAlreadyUsed(state, isNameAlreadyUsed) {
|
|
141
|
-
state.isNameAlreadyUsed = isNameAlreadyUsed;
|
|
142
|
-
},
|
|
143
|
-
setMediaNameSaveError(state, mediaNameSaveError) {
|
|
144
|
-
state.mediaNameSaveError = mediaNameSaveError;
|
|
145
|
-
},
|
|
146
111
|
setCurrentMedia(state, currentMedia) {
|
|
147
112
|
state.currentMedia = currentMedia;
|
|
148
113
|
},
|
|
@@ -158,11 +123,6 @@ export default {
|
|
|
158
123
|
},
|
|
159
124
|
resetMediaUploadContext({ commit }) {
|
|
160
125
|
commit('setUploadProgress', 0);
|
|
161
|
-
commit('setMediaUploadError', null);
|
|
162
|
-
commit('setIsMediaNameSaving', false);
|
|
163
|
-
commit('setIsMediaNameSaved', false);
|
|
164
|
-
commit('setIsNameAlreadyUsed', false);
|
|
165
|
-
commit('setMediaNameSaveError', null);
|
|
166
126
|
},
|
|
167
127
|
async loadMedia({ commit, state }) {
|
|
168
128
|
commit('setIsLoadingMedia', true);
|
|
@@ -224,21 +184,9 @@ export default {
|
|
|
224
184
|
media.publicUrl = state.publicMediaUrl;
|
|
225
185
|
},
|
|
226
186
|
async updateMediaName({ commit, dispatch, state }, { id: mediaId, name: mediaName }) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
commit('setIsMediaNameSaved', true);
|
|
230
|
-
dispatch('refreshMediaList');
|
|
231
|
-
} catch (err) {
|
|
232
|
-
console.log(err);
|
|
233
|
-
if (err.response?.body?.code === 'NAME_ALREADY_USED') {
|
|
234
|
-
commit('setIsNameAlreadyUsed', true);
|
|
235
|
-
} else {
|
|
236
|
-
commit('setMediaNameSaveError', err);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
commit('setIsMediaNameSaving', false);
|
|
187
|
+
await updateMediaName(mediaId, mediaName);
|
|
188
|
+
dispatch('refreshMediaList');
|
|
240
189
|
},
|
|
241
|
-
|
|
242
190
|
async deleteMedia({ commit, state, dispatch }, mediaToDelete) {
|
|
243
191
|
commit('eventBusSendEvent', { code: 'interactedMedia', payload: {} }, { root: true });
|
|
244
192
|
await deleteMedia(mediaToDelete.id);
|
|
@@ -260,21 +208,17 @@ export default {
|
|
|
260
208
|
|
|
261
209
|
const correlationId = state.mediaCorrelationId ?? uuidv4();
|
|
262
210
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
commit('setUploadedMediaId', mediaId);
|
|
275
|
-
} catch (e) {
|
|
276
|
-
commit('setMediaUploadError', e);
|
|
277
|
-
}
|
|
211
|
+
const response = await uploadMedia(
|
|
212
|
+
uploadFile.formData,
|
|
213
|
+
projectId,
|
|
214
|
+
correlationId,
|
|
215
|
+
uploadFile.fileName,
|
|
216
|
+
uploadFile.isRoomPicture,
|
|
217
|
+
trackProgress,
|
|
218
|
+
);
|
|
219
|
+
const location = response.headers.location;
|
|
220
|
+
const [mediaId] = location.split('/').slice(-1);
|
|
221
|
+
commit('setUploadedMediaId', mediaId);
|
|
278
222
|
},
|
|
279
223
|
generateCorrelationId({ commit }) {
|
|
280
224
|
commit('setMediaCorrelationId', uuidv4());
|