@saooti/octopus-sdk 41.0.15 → 41.0.16
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/index.ts +6 -1
- package/package.json +1 -2
- package/src/components/display/playlist/PodcastList.vue +12 -1
- package/src/components/display/podcasts/PodcastImage.vue +28 -7
- package/src/components/display/podcasts/PodcastItem.vue +4 -1
- package/src/components/display/podcasts/PodcastList.vue +9 -1
- package/src/components/display/podcasts/PodcastPlayButton.vue +92 -20
- package/src/components/form/ClassicSelect.vue +29 -29
- package/src/components/misc/ClassicAccordion.vue +2 -2
- package/src/components/misc/ClassicAlert.vue +98 -0
- package/src/components/misc/ClassicHelpButton.vue +9 -3
- package/src/components/pages/PodcastPage.vue +4 -0
- package/tsconfig.json +2 -6
package/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export const getClassicLazy = () => import("./src/components/misc/ClassicLazy.vu
|
|
|
39
39
|
export const getContractPreviewModal = () => import("./src/components/misc/modal/ContractPreviewModal.vue");
|
|
40
40
|
export const getClassicModalInBody = () => import("./src/components/misc/modal/ClassicModalInBody.vue");
|
|
41
41
|
export const getClassicHelpButton = () => import("./src/components/misc/ClassicHelpButton.vue");
|
|
42
|
+
export const getClassicAlert = () => import("./src/components/misc/ClassicAlert.vue");
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
//Display
|
|
@@ -152,6 +153,9 @@ export const getXIcon = () => import("./src/components/icons/XIcon.vue");
|
|
|
152
153
|
// Routing
|
|
153
154
|
import { setupRouter } from './src/router/utils';
|
|
154
155
|
|
|
156
|
+
// Types
|
|
157
|
+
import { type SelectOption } from "./src/components/form/ClassicSelect.vue";
|
|
158
|
+
|
|
155
159
|
export {
|
|
156
160
|
useResizePhone,
|
|
157
161
|
useTagOf,
|
|
@@ -183,5 +187,6 @@ export {
|
|
|
183
187
|
deepEqual,
|
|
184
188
|
downloadHelper,
|
|
185
189
|
displayHelper,
|
|
186
|
-
setupRouter
|
|
190
|
+
setupRouter,
|
|
191
|
+
SelectOption,
|
|
187
192
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saooti/octopus-sdk",
|
|
3
|
-
"version": "41.0.
|
|
3
|
+
"version": "41.0.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Javascript SDK for using octopus",
|
|
6
6
|
"author": "Saooti",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@types/sockjs-client": "^1.5.4",
|
|
68
|
-
"@types/webpack-env": "^1.18.8",
|
|
69
68
|
"@vitejs/plugin-vue": "^5.2.4",
|
|
70
69
|
"eslint": "^9.28.0",
|
|
71
70
|
"eslint-plugin-vue": "^9.33.0",
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Component displaying a list of podcasts IN A PLAYLIST
|
|
3
|
+
Do not confuse this with PodcastList from podcasts
|
|
4
|
+
-->
|
|
1
5
|
<template>
|
|
2
6
|
<div>
|
|
3
7
|
<h3 class="mb-3 align-self-baseline">
|
|
4
8
|
{{ titleList }}
|
|
5
9
|
</h3>
|
|
10
|
+
|
|
6
11
|
<ClassicSearch
|
|
7
12
|
v-if="!loading && notEmptyPlaylist"
|
|
8
13
|
v-model:text-init="searchPattern"
|
|
@@ -10,6 +15,7 @@
|
|
|
10
15
|
id-search="podcast-list-search"
|
|
11
16
|
:label="t('Search')"
|
|
12
17
|
/>
|
|
18
|
+
|
|
13
19
|
<ListPaginate
|
|
14
20
|
id="podcastPlaylistListPaginate"
|
|
15
21
|
v-model:first="dfirst"
|
|
@@ -38,7 +44,12 @@
|
|
|
38
44
|
:key="p.podcastId"
|
|
39
45
|
:min-height="410"
|
|
40
46
|
>
|
|
41
|
-
<PodcastItem
|
|
47
|
+
<PodcastItem
|
|
48
|
+
v-if="0 !== p.podcastId"
|
|
49
|
+
:podcast="p"
|
|
50
|
+
:in-list="true"
|
|
51
|
+
/>
|
|
52
|
+
|
|
42
53
|
<template #preview>
|
|
43
54
|
<router-link
|
|
44
55
|
:to="{
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Component to display the image of a podcast.
|
|
3
|
+
May also display additional information, for example when an error occured
|
|
4
|
+
when processing the file (using PodcastPlayButton).
|
|
5
|
+
-->
|
|
1
6
|
<template>
|
|
2
7
|
<div
|
|
3
8
|
v-if="podcast"
|
|
@@ -16,10 +21,9 @@
|
|
|
16
21
|
height="270"
|
|
17
22
|
aria-hidden="true"
|
|
18
23
|
alt=""
|
|
19
|
-
|
|
20
24
|
class="img-box img-box-podcast"
|
|
21
25
|
:title="t('Episode name image', { name: podcast.title })"
|
|
22
|
-
|
|
26
|
+
>
|
|
23
27
|
</router-link>
|
|
24
28
|
<div
|
|
25
29
|
v-if="state.generalParameters.podcastmaker"
|
|
@@ -43,6 +47,7 @@
|
|
|
43
47
|
:podcast="podcast"
|
|
44
48
|
:hide-play="hidePlay"
|
|
45
49
|
:fetch-conference="fetchConference"
|
|
50
|
+
:in-list="inList"
|
|
46
51
|
/>
|
|
47
52
|
<button
|
|
48
53
|
v-if="displayDescription && isMobile"
|
|
@@ -73,6 +78,8 @@ const props = defineProps({
|
|
|
73
78
|
arrowDirection: { default: "up", type: String },
|
|
74
79
|
isAnimatorLive: { default: false, type: Boolean },
|
|
75
80
|
fetchConference: { default: undefined, type: Object as () => Conference },
|
|
81
|
+
/** Indicates that the podcast is displayed in a list */
|
|
82
|
+
inList: { default: false, type: Boolean }
|
|
76
83
|
})
|
|
77
84
|
|
|
78
85
|
//Emits
|
|
@@ -104,23 +111,37 @@ const isRecordedInLive = computed(() => {
|
|
|
104
111
|
);
|
|
105
112
|
});
|
|
106
113
|
const statusText = computed(() => {
|
|
107
|
-
if (!props.fetchConference)
|
|
114
|
+
if (!props.fetchConference) {
|
|
115
|
+
return "";
|
|
116
|
+
}
|
|
117
|
+
|
|
108
118
|
switch (props.fetchConference.status) {
|
|
109
119
|
case "PLANNED":
|
|
110
120
|
return t("live in few time");
|
|
121
|
+
|
|
111
122
|
case "PENDING":
|
|
112
|
-
if (props.isAnimatorLive)
|
|
113
|
-
|
|
123
|
+
if (props.isAnimatorLive) {
|
|
124
|
+
return t("Open studio");
|
|
125
|
+
} else {
|
|
126
|
+
return t("live upcoming");
|
|
127
|
+
}
|
|
128
|
+
|
|
114
129
|
case "RECORDING":
|
|
115
130
|
return t("In live");
|
|
131
|
+
|
|
116
132
|
case "DEBRIEFING":
|
|
117
|
-
if ("READY_TO_RECORD" === props.podcast.processingStatus)
|
|
133
|
+
if ("READY_TO_RECORD" === props.podcast.processingStatus) {
|
|
118
134
|
return t("Not recording");
|
|
119
|
-
|
|
135
|
+
} else {
|
|
136
|
+
return t("Debriefing");
|
|
137
|
+
}
|
|
138
|
+
|
|
120
139
|
case "ERROR":
|
|
121
140
|
return t("In error");
|
|
141
|
+
|
|
122
142
|
case "PUBLISHING":
|
|
123
143
|
return t("Publishing");
|
|
144
|
+
|
|
124
145
|
default:
|
|
125
146
|
return "";
|
|
126
147
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
:display-description="0 !== description.length"
|
|
11
11
|
:arrow-direction="arrowDirection"
|
|
12
12
|
:fetch-conference="fetchConference"
|
|
13
|
+
:in-list="inList"
|
|
13
14
|
@hide-description="hideDescription"
|
|
14
15
|
@show-description="showDescription"
|
|
15
16
|
/>
|
|
@@ -50,7 +51,9 @@ import { Conference } from "@/stores/class/conference/conference";
|
|
|
50
51
|
const props = defineProps({
|
|
51
52
|
podcast: { default: () => ({}), type: Object as () => Podcast },
|
|
52
53
|
fetchConference: { default: undefined, type: Object as () => Conference },
|
|
53
|
-
|
|
54
|
+
/** Indicates that the podcast is displayed in a list */
|
|
55
|
+
inList: { default: false, type: Boolean }
|
|
56
|
+
});
|
|
54
57
|
|
|
55
58
|
//Data
|
|
56
59
|
const isMobile = ref(false);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Component displaying a list of podcast
|
|
3
|
+
DO NOT confuse this with PodcastList from playlist
|
|
4
|
+
-->
|
|
1
5
|
<template>
|
|
2
6
|
<ListPaginate
|
|
3
7
|
id="podcastListPaginate"
|
|
@@ -28,7 +32,11 @@
|
|
|
28
32
|
:key="p.podcastId"
|
|
29
33
|
:min-height="410"
|
|
30
34
|
>
|
|
31
|
-
<PodcastItem
|
|
35
|
+
<PodcastItem
|
|
36
|
+
v-if="0 !== p.podcastId"
|
|
37
|
+
:podcast="p"
|
|
38
|
+
in-list
|
|
39
|
+
/>
|
|
32
40
|
<template #preview>
|
|
33
41
|
<router-link
|
|
34
42
|
:to="{
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Component displaying the play button on a podcast.
|
|
3
|
+
If the podcast is not available, an overlay is displayed with a message.
|
|
4
|
+
-->
|
|
1
5
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
6
|
+
<div
|
|
7
|
+
v-if="!hidePlay || recordingLive"
|
|
8
|
+
:class="{ 'img-blur-background': displayBanner, 'allow-play': classicPodcastPlay }"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
v-if="displayBanner"
|
|
12
|
+
class="live-image-status bg-dark"
|
|
13
|
+
>
|
|
4
14
|
{{ textVisible }}
|
|
5
15
|
</div>
|
|
6
|
-
|
|
16
|
+
|
|
17
|
+
<div
|
|
18
|
+
class="multi-buttons-play"
|
|
19
|
+
:class="justButtons ? 'play-button-relative' : ''"
|
|
20
|
+
>
|
|
7
21
|
<template v-if="!isLiveToBeRecorded">
|
|
8
22
|
<button
|
|
9
23
|
class="d-flex"
|
|
@@ -16,8 +30,14 @@
|
|
|
16
30
|
v-if="!playingPodcast || (playingPodcast && playerStore.playerVideo)"
|
|
17
31
|
:size="'audio' === hoverType ? 50 : 40"
|
|
18
32
|
/>
|
|
19
|
-
<PodcastIsPlaying v-if="playingPodcast && !playerStore.playerVideo"/>
|
|
20
|
-
<time
|
|
33
|
+
<PodcastIsPlaying v-if="playingPodcast && !playerStore.playerVideo" />
|
|
34
|
+
<time
|
|
35
|
+
v-if="!isVideoPodcast"
|
|
36
|
+
class="ms-1"
|
|
37
|
+
:datetime="durationIso"
|
|
38
|
+
>
|
|
39
|
+
{{ durationString }}
|
|
40
|
+
</time>
|
|
21
41
|
</button>
|
|
22
42
|
<button
|
|
23
43
|
v-if="isVideoPodcast"
|
|
@@ -27,15 +47,35 @@
|
|
|
27
47
|
@mouseenter="hoverType = 'video'"
|
|
28
48
|
@mouseleave="hoverType = ''"
|
|
29
49
|
>
|
|
30
|
-
<PlayVideoIcon
|
|
31
|
-
|
|
32
|
-
|
|
50
|
+
<PlayVideoIcon
|
|
51
|
+
v-if="!playerStore.playerVideo"
|
|
52
|
+
:size="'video' === hoverType ? 50 : 40"
|
|
53
|
+
/>
|
|
54
|
+
<PodcastIsPlaying v-if="playingPodcast && playerStore.playerVideo" />
|
|
55
|
+
<time
|
|
56
|
+
class="ms-2"
|
|
57
|
+
:datetime="durationIso"
|
|
58
|
+
>
|
|
59
|
+
{{ durationString }}
|
|
60
|
+
</time>
|
|
33
61
|
</button>
|
|
34
|
-
|
|
35
|
-
|
|
62
|
+
|
|
63
|
+
<div
|
|
64
|
+
v-if="displayBanner"
|
|
65
|
+
class="special-icon-play-button"
|
|
66
|
+
>
|
|
67
|
+
<component
|
|
68
|
+
:is="iconName"
|
|
69
|
+
:size="16"
|
|
70
|
+
/>
|
|
36
71
|
</div>
|
|
37
72
|
</template>
|
|
38
|
-
<component
|
|
73
|
+
<component
|
|
74
|
+
:is="iconName"
|
|
75
|
+
v-else
|
|
76
|
+
:size="50"
|
|
77
|
+
:title="textVisible"
|
|
78
|
+
/>
|
|
39
79
|
</div>
|
|
40
80
|
</div>
|
|
41
81
|
</template>
|
|
@@ -70,6 +110,8 @@ const props = defineProps({
|
|
|
70
110
|
hidePlay: { default: false, type: Boolean },
|
|
71
111
|
fetchConference: { default: undefined, type: Object as () => Conference },
|
|
72
112
|
justButtons: { default: false, type: Boolean },
|
|
113
|
+
/** Indicates that the podcast is displayed in a list */
|
|
114
|
+
inList: { default: false, type: Boolean }
|
|
73
115
|
})
|
|
74
116
|
|
|
75
117
|
|
|
@@ -119,42 +161,65 @@ const isLiveValidAndVisible = computed(() => {
|
|
|
119
161
|
props.podcast.availability.visibility
|
|
120
162
|
);
|
|
121
163
|
});
|
|
164
|
+
|
|
165
|
+
/** Whether the podcast can be played */
|
|
122
166
|
const classicPodcastPlay = computed(() => {
|
|
123
167
|
return (
|
|
124
168
|
isLiveValidAndVisible.value &&
|
|
125
169
|
!isLiveToBeRecorded.value &&
|
|
126
170
|
("READY_TO_RECORD" === props.podcast.processingStatus ||
|
|
127
171
|
"READY" === props.podcast.processingStatus ||
|
|
128
|
-
|
|
129
|
-
undefined === authStore.authOrgaId))
|
|
172
|
+
"PROCESSING" === props.podcast.processingStatus)
|
|
130
173
|
);
|
|
131
174
|
});
|
|
175
|
+
|
|
176
|
+
const displayBanner = computed(() => {
|
|
177
|
+
return !classicPodcastPlay.value || ("PROCESSING" === props.podcast.processingStatus && !props.inList);
|
|
178
|
+
});
|
|
179
|
+
|
|
132
180
|
const iconName = computed(() => {
|
|
133
|
-
if (isLiveToBeRecorded.value)
|
|
181
|
+
if (isLiveToBeRecorded.value) {
|
|
182
|
+
return ClockOutlineIcon;
|
|
183
|
+
}
|
|
184
|
+
|
|
134
185
|
if ("READY" === props.podcast.processingStatus || props.fetchConference) {
|
|
135
|
-
if (!props.podcast.valid)
|
|
186
|
+
if (!props.podcast.valid) {
|
|
187
|
+
return CheckIcon;
|
|
188
|
+
}
|
|
189
|
+
|
|
136
190
|
if (
|
|
137
191
|
!props.podcast.availability.visibility &&
|
|
138
192
|
props.podcast.availability.date
|
|
139
|
-
)
|
|
193
|
+
) {
|
|
140
194
|
return ClockOutlineIcon;
|
|
195
|
+
}
|
|
196
|
+
|
|
141
197
|
return EyeOffOutlineIcon;
|
|
142
198
|
}
|
|
199
|
+
|
|
143
200
|
if (
|
|
144
201
|
"PLANNED" === props.podcast.processingStatus ||
|
|
145
202
|
"PROCESSING" === props.podcast.processingStatus
|
|
146
|
-
)
|
|
203
|
+
) {
|
|
147
204
|
return TimerSandEmptyIcon;
|
|
148
|
-
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if ("CANCELED" === props.podcast.processingStatus) {
|
|
208
|
+
return CancelIcon;
|
|
209
|
+
}
|
|
149
210
|
return AlertIcon;
|
|
150
211
|
});
|
|
212
|
+
|
|
213
|
+
/** The text to display when the podcast is not ready */
|
|
151
214
|
const textVisible = computed(() => {
|
|
152
215
|
if (isLiveToBeRecorded.value){
|
|
153
216
|
return t("Podcast linked to waiting live");
|
|
154
217
|
}
|
|
155
218
|
|
|
156
219
|
if ("READY" === props.podcast.processingStatus || props.fetchConference) {
|
|
157
|
-
if (!props.podcast.valid)
|
|
220
|
+
if (!props.podcast.valid) {
|
|
221
|
+
return t("Podcast to validate");
|
|
222
|
+
}
|
|
158
223
|
if (
|
|
159
224
|
!props.podcast.availability.visibility &&
|
|
160
225
|
props.podcast.availability.date
|
|
@@ -174,6 +239,7 @@ const textVisible = computed(() => {
|
|
|
174
239
|
}
|
|
175
240
|
return t("Podcast in error");
|
|
176
241
|
});
|
|
242
|
+
|
|
177
243
|
const recordingLive = computed(() => {
|
|
178
244
|
return (
|
|
179
245
|
undefined !== props.fetchConference &&
|
|
@@ -188,7 +254,9 @@ const durationString = computed(() => {
|
|
|
188
254
|
);
|
|
189
255
|
});
|
|
190
256
|
const durationIso = computed(() => {
|
|
191
|
-
if (!props.podcast || props.podcast.duration <= 1)
|
|
257
|
+
if (!props.podcast || props.podcast.duration <= 1) {
|
|
258
|
+
return "";
|
|
259
|
+
}
|
|
192
260
|
return dayjs.duration({ milliseconds: props.podcast.duration }).toISOString();
|
|
193
261
|
});
|
|
194
262
|
|
|
@@ -230,6 +298,10 @@ function play(isVideo: boolean): void {
|
|
|
230
298
|
background-color:var(--octopus-background-transparent);
|
|
231
299
|
// Allow pointer events to go through (allow click on image beneath blur)
|
|
232
300
|
pointer-events: none;
|
|
301
|
+
|
|
302
|
+
&.allow-play {
|
|
303
|
+
pointer-events: all;
|
|
304
|
+
}
|
|
233
305
|
}
|
|
234
306
|
|
|
235
307
|
.live-image-status {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="classic-select" :class="{ 'form-margin': displayLabel }">
|
|
3
|
-
<label v-show="displayLabel" :for="idSelect" :class="classLabel">
|
|
4
|
-
label
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<label v-show="displayLabel" :for="idSelect" :class="classLabel">
|
|
4
|
+
{{ label }}
|
|
5
|
+
<AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="t('Mandatory input')"/>
|
|
6
|
+
<slot name="after-label" />
|
|
7
|
+
</label>
|
|
8
|
+
|
|
7
9
|
<select
|
|
8
10
|
:id="idSelect"
|
|
9
11
|
:value="textInit"
|
|
@@ -28,37 +30,36 @@
|
|
|
28
30
|
</select>
|
|
29
31
|
</div>
|
|
30
32
|
</template>
|
|
33
|
+
|
|
31
34
|
<script setup lang="ts">
|
|
32
35
|
import AsteriskIcon from "vue-material-design-icons/Asterisk.vue";
|
|
33
36
|
import { computed } from "vue";
|
|
34
37
|
import { useI18n } from "vue-i18n";
|
|
35
38
|
|
|
39
|
+
export interface SelectOption<T = number|string|undefined> {
|
|
40
|
+
title: string;
|
|
41
|
+
value: T;
|
|
42
|
+
fontFamily?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
//Props
|
|
37
46
|
const props = defineProps({
|
|
38
47
|
idSelect: { default: "", type: String },
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
fontFamily?: string;
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
textInit: { default: undefined, type: [String, Number] },
|
|
58
|
-
classLabel: { default: "form-label", type: String },
|
|
59
|
-
orderOptions: { default: true, type: Boolean},
|
|
60
|
-
placeholder: { default: undefined, type: String},
|
|
61
|
-
displayRequired: { default: false, type: Boolean },
|
|
48
|
+
label: { default: "", type: String },
|
|
49
|
+
displayLabel: { default: true, type: Boolean },
|
|
50
|
+
transparent: { default: false, type: Boolean },
|
|
51
|
+
isDisabled: { default: false, type: Boolean },
|
|
52
|
+
options: {
|
|
53
|
+
default: () => [],
|
|
54
|
+
type: Array as () => Array<SelectOption>,
|
|
55
|
+
},
|
|
56
|
+
topOption: { default: undefined,type: Object as () => SelectOption,
|
|
57
|
+
},
|
|
58
|
+
textInit: { default: undefined, type: [String, Number] },
|
|
59
|
+
classLabel: { default: "form-label", type: String },
|
|
60
|
+
orderOptions: { default: true, type: Boolean},
|
|
61
|
+
placeholder: { default: undefined, type: String},
|
|
62
|
+
displayRequired: { default: false, type: Boolean },
|
|
62
63
|
})
|
|
63
64
|
|
|
64
65
|
|
|
@@ -100,9 +101,8 @@ function onChange(value:string){
|
|
|
100
101
|
emit('update:textInit', value)
|
|
101
102
|
}
|
|
102
103
|
</script>
|
|
103
|
-
<style lang="scss">
|
|
104
|
-
|
|
105
104
|
|
|
105
|
+
<style lang="scss">
|
|
106
106
|
.octopus-app {
|
|
107
107
|
select option:is(:checked, :hover){
|
|
108
108
|
box-shadow: 0 0 10px 100px var(--octopus-secondary) inset;
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
:src="imageUrl"
|
|
22
22
|
aria-hidden="true"
|
|
23
23
|
alt=""
|
|
24
|
-
|
|
24
|
+
>
|
|
25
25
|
<span>{{ title }}</span>
|
|
26
26
|
<slot name="afterTitle"/>
|
|
27
27
|
<ChevronDownIcon class="ms-auto" :class="{ 'arrow-transform': isOpen }" />
|
|
@@ -58,7 +58,7 @@ const emit = defineEmits(["open"]);
|
|
|
58
58
|
const isOpen = ref(false);
|
|
59
59
|
|
|
60
60
|
//Watch
|
|
61
|
-
watch(isOpen, () => emit("open"));
|
|
61
|
+
watch(isOpen, () => emit("open", isOpen.value));
|
|
62
62
|
|
|
63
63
|
onMounted(()=>{
|
|
64
64
|
isOpen.value = props.initOpen;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Simple component to display a message to the user.
|
|
3
|
+
Usage:
|
|
4
|
+
<ClassicAlert type='info'>This is an information</ClassicAlert>
|
|
5
|
+
<ClassicAlert type='success'>Your changes have been saved</ClassicAlert>
|
|
6
|
+
<ClassicAlert type='warning'>Some data will be lost</ClassicAlert>
|
|
7
|
+
<ClassicAlert type='error'>An error occured while saving</ClassicAlert>
|
|
8
|
+
-->
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
class="p-2 pe-4 my-2 rounded d-flex alert"
|
|
12
|
+
:class="cardClass"
|
|
13
|
+
>
|
|
14
|
+
<!-- The icon -->
|
|
15
|
+
<component
|
|
16
|
+
:is="iconComponent"
|
|
17
|
+
v-if="!noIcon"
|
|
18
|
+
class="icon"
|
|
19
|
+
:size="30"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
<!-- Main content -->
|
|
23
|
+
<span class="ms-2">
|
|
24
|
+
<strong v-if="title">
|
|
25
|
+
{{ title }}
|
|
26
|
+
<br>
|
|
27
|
+
</strong>
|
|
28
|
+
|
|
29
|
+
<slot />
|
|
30
|
+
</span>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { computed } from 'vue';
|
|
36
|
+
|
|
37
|
+
import Alert from 'vue-material-design-icons/Alert.vue';
|
|
38
|
+
import CheckCircle from 'vue-material-design-icons/CheckCircle.vue';
|
|
39
|
+
import CloseCircle from 'vue-material-design-icons/CloseCircle.vue';
|
|
40
|
+
import Information from 'vue-material-design-icons/Information.vue';
|
|
41
|
+
|
|
42
|
+
const { type } = defineProps<{
|
|
43
|
+
/** Disables the icon when true */
|
|
44
|
+
noIcon?: boolean;
|
|
45
|
+
/** An optional title for the alert */
|
|
46
|
+
title?: string;
|
|
47
|
+
/** The type of message */
|
|
48
|
+
type: 'info'|'success'|'warning'|'error';
|
|
49
|
+
}>();
|
|
50
|
+
|
|
51
|
+
/** The class applied to the alert */
|
|
52
|
+
const cardClass = computed(() => {
|
|
53
|
+
return 'alert-' + type;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const iconComponent = computed(() => {
|
|
57
|
+
if (type === 'info') {
|
|
58
|
+
return Information;
|
|
59
|
+
} else if (type === 'success') {
|
|
60
|
+
return CheckCircle;
|
|
61
|
+
} else if (type === 'warning') {
|
|
62
|
+
return Alert;
|
|
63
|
+
} else if (type === 'error') {
|
|
64
|
+
return CloseCircle;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<style lang="scss" scoped>
|
|
70
|
+
.alert {
|
|
71
|
+
//color: white;
|
|
72
|
+
border: 1px solid;
|
|
73
|
+
border-left: 8px solid;
|
|
74
|
+
|
|
75
|
+
.icon {
|
|
76
|
+
align-items: start !important;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
$types: (
|
|
80
|
+
'success': hsl(from var(--octopus-primary) h s 45),
|
|
81
|
+
'info': var(--octopus-primary),
|
|
82
|
+
'warning': var(--octopus-warning),
|
|
83
|
+
'error': var(--octopus-danger),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
&.alert {
|
|
87
|
+
@each $type, $color in $types {
|
|
88
|
+
&-#{$type} {
|
|
89
|
+
background-color: hsl(from #{$color} h s 95) !important;
|
|
90
|
+
border-color: #{$color} !important;
|
|
91
|
+
.icon {
|
|
92
|
+
color: #{$color};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
<!-- Tooltip -->
|
|
17
17
|
<ClassicPopover
|
|
18
18
|
:target="computedId"
|
|
19
|
-
popover-class="popover
|
|
19
|
+
popover-class="help-popover"
|
|
20
20
|
>
|
|
21
|
-
<div class="
|
|
21
|
+
<div class="content">
|
|
22
22
|
<slot />
|
|
23
23
|
</div>
|
|
24
24
|
</ClassicPopover>
|
|
@@ -38,7 +38,13 @@ const computedId = computed(() => {
|
|
|
38
38
|
</script>
|
|
39
39
|
|
|
40
40
|
<style lang="scss" scoped>
|
|
41
|
-
.
|
|
41
|
+
.content {
|
|
42
42
|
font: revert;
|
|
43
|
+
font-size: 18px !important;
|
|
44
|
+
text-align: start;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.help-popover {
|
|
48
|
+
background-color: var(--octopus-secondary);
|
|
43
49
|
}
|
|
44
50
|
</style>
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
:organisation-id="authOrgaId"
|
|
28
28
|
/>
|
|
29
29
|
<CommentSection :podcast="podcast" />
|
|
30
|
+
|
|
31
|
+
<!-- Suggestions -->
|
|
30
32
|
<PodcastInlineList
|
|
31
33
|
:emission-id="podcast.emission.emissionId"
|
|
32
34
|
:href="'/main/pub/emission/' + podcast.emission.emissionId"
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
<PodcastInlineList
|
|
40
42
|
class="mt-4"
|
|
41
43
|
title-tag="h3"
|
|
44
|
+
:organisation-id="[podcast.organisation.id]"
|
|
42
45
|
:podcast-id="podcastId"
|
|
43
46
|
:title="t('Suggested listening')"
|
|
44
47
|
/>
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
:href="'/main/pub/category/' + c.id"
|
|
52
55
|
:title="t('More episodes of this category : ', { name: c.name })"
|
|
53
56
|
:button-text="t('All podcast button', { name: c.name })"
|
|
57
|
+
:organisation-id="[podcast.organisation.id]"
|
|
54
58
|
/>
|
|
55
59
|
</ClassicLazy>
|
|
56
60
|
</section>
|
package/tsconfig.json
CHANGED
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
"sourceMap": true,
|
|
14
14
|
"baseUrl": ".",
|
|
15
15
|
"types": [
|
|
16
|
-
"webpack-env"
|
|
17
|
-
],
|
|
18
|
-
"typeRoots": [
|
|
19
|
-
"./typings",
|
|
20
|
-
"./node_modules/@types/"
|
|
16
|
+
"webpack-env"
|
|
21
17
|
],
|
|
22
18
|
"paths": {
|
|
23
19
|
"@/*": [
|
|
@@ -42,6 +38,6 @@
|
|
|
42
38
|
"node_modules"
|
|
43
39
|
],
|
|
44
40
|
"files": [
|
|
45
|
-
"src/shims-vue.d.ts"
|
|
41
|
+
"src/shims-vue.d.ts",
|
|
46
42
|
]
|
|
47
43
|
}
|