@saooti/octopus-sdk 41.0.12-SNAPSHOT → 41.0.12
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 +3 -1
- package/plateform.conf +1 -1
- package/src/App.vue +3 -7
- package/src/api/classicApi.ts +1 -1
- package/src/components/composable/player/usePlayerLive.ts +2 -2
- package/src/components/composable/radio/usefetchRadioData.ts +29 -12
- package/src/components/display/categories/CategoryChooser.vue +4 -0
- package/src/components/display/comments/CommentList.vue +1 -1
- package/src/components/display/filter/DateFilter.vue +15 -2
- package/src/components/display/live/RadioCurrently.vue +2 -5
- package/src/components/display/podcasts/PodcastPlayButton.vue +4 -1
- package/src/components/display/sharing/PlayerParameters.vue +0 -8
- package/src/components/display/sharing/SharePlayer.vue +0 -5
- package/src/components/display/sharing/SubscribeButtons.vue +4 -2
- package/src/components/form/ClassicInputText.vue +3 -0
- package/src/components/form/ClassicMultiselect.vue +36 -8
- package/src/components/misc/ClassicAccordion.vue +4 -4
- package/src/components/misc/ClassicSpinner.vue +1 -1
- package/src/components/misc/HomeDropdown.vue +3 -110
- package/src/components/misc/MobileMenu.vue +59 -64
- package/src/components/misc/TopBar.vue +4 -11
- package/src/components/misc/TopBarMainContent.vue +0 -2
- package/src/components/misc/UserButtonContent.vue +159 -0
- package/src/components/misc/player/elements/PlayerImage.vue +0 -1
- package/src/components/misc/player/elements/PlayerTitle.vue +3 -3
- package/src/components/misc/player/radio/RadioHistory.vue +3 -2
- package/src/components/misc/player/video/PlayerVideo.vue +2 -2
- package/src/components/pages/PageLogout.vue +1 -6
- package/src/components/pages/PodcastPage.vue +0 -1
- package/src/components/pages/VideoPage.vue +5 -2
- package/src/locale/de.ts +3 -3
- package/src/locale/en.ts +3 -3
- package/src/locale/es.ts +3 -3
- package/src/locale/fr.ts +3 -3
- package/src/locale/it.ts +3 -3
- package/src/locale/sl.ts +3 -3
- package/src/stores/FilterStore.ts +1 -1
- package/src/stores/PlayerStore.ts +6 -1
- package/src/stores/class/conference/conference.ts +2 -0
- package/src/stores/class/general/player.ts +2 -2
- package/src/style/_variables.scss +6 -0
- package/src/style/general.scss +18 -1
- package/src/helper/radio/radioHelper.ts +0 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saooti/octopus-sdk",
|
|
3
|
-
"version": "41.0.12
|
|
3
|
+
"version": "41.0.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Javascript SDK for using octopus",
|
|
6
6
|
"author": "Saooti",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"serve": "vite preview",
|
|
9
9
|
"build": "vite build",
|
|
10
10
|
"dev": "vite",
|
|
11
|
+
"bundle": "vite-bundle-visualizer",
|
|
11
12
|
"proxy_authentifié": "node proxy.ts",
|
|
12
13
|
"proxy_non_authentifié": "node proxy.ts false",
|
|
13
14
|
"lint": "eslint --fix src",
|
|
@@ -53,6 +54,7 @@
|
|
|
53
54
|
"video.js": "^8.23.3",
|
|
54
55
|
"videojs-quality-selector-hls": "^1.1.1",
|
|
55
56
|
"vite": "^6.3.5",
|
|
57
|
+
"vite-bundle-visualizer": "^1.2.1",
|
|
56
58
|
"vue": "^3.5.16",
|
|
57
59
|
"vue-i18n": "^11.1.5",
|
|
58
60
|
"vue-material-design-icons": "^5.3.1",
|
package/plateform.conf
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
preprod.saooti.org
|
package/src/App.vue
CHANGED
|
@@ -8,16 +8,14 @@
|
|
|
8
8
|
<router-view />
|
|
9
9
|
<PlayerComponent />
|
|
10
10
|
</main>
|
|
11
|
-
<
|
|
12
|
-
<FooterOctopus />
|
|
13
|
-
</ClassicLazy>
|
|
11
|
+
<FooterOctopus />
|
|
14
12
|
</template>
|
|
15
13
|
</div>
|
|
16
14
|
</template>
|
|
17
15
|
<script setup lang="ts">
|
|
18
16
|
import TopBar from "@/components/misc/TopBar.vue";
|
|
17
|
+
import FooterOctopus from "@/components/misc/FooterSection.vue";
|
|
19
18
|
import PlayerComponent from "@/components/misc/player/PlayerComponent.vue";
|
|
20
|
-
import ClassicLazy from "@/components/misc/ClassicLazy.vue";
|
|
21
19
|
import {useInit} from "./components/composable/useInit";
|
|
22
20
|
import {useMetaTitle} from "./components/composable/useMetaTitle";
|
|
23
21
|
import {useOrganisationFilter} from "./components/composable/useOrganisationFilter";
|
|
@@ -25,9 +23,7 @@ import { useAuthStore } from "./stores/AuthStore";
|
|
|
25
23
|
import { defineAsyncComponent, getCurrentInstance, onBeforeMount, ref, watch } from "vue";
|
|
26
24
|
import { useRoute } from "vue-router";
|
|
27
25
|
import { useI18n } from "vue-i18n";
|
|
28
|
-
|
|
29
|
-
() => import("@/components/misc/FooterSection.vue"),
|
|
30
|
-
);
|
|
26
|
+
|
|
31
27
|
const CategoryFilter = defineAsyncComponent(
|
|
32
28
|
() => import("@/components/display/categories/CategoryFilter.vue"),
|
|
33
29
|
);
|
package/src/api/classicApi.ts
CHANGED
|
@@ -51,8 +51,8 @@ export const usePlayerLive = (hlsReady: Ref<boolean>)=>{
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function playLive() {
|
|
54
|
-
if (!playerStore.
|
|
55
|
-
playerStore.playerUpdatePlayerHlsUrl(`${apiStore.hlsUrl}live
|
|
54
|
+
if (!playerStore.playerHlsIdentifier) return;
|
|
55
|
+
playerStore.playerUpdatePlayerHlsUrl(`${apiStore.hlsUrl}live/${playerStore.playerHlsIdentifier}/index.m3u8`);
|
|
56
56
|
playHls();
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -2,17 +2,19 @@ import classicApi from "../../../api/classicApi";
|
|
|
2
2
|
import { MediaRadio, MetadataRadio, NextAdvertising } from '@/stores/class/general/player';
|
|
3
3
|
import { Podcast } from '@/stores/class/general/podcast';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
|
-
import radioHelper from "../../../helper/radio/radioHelper";
|
|
6
5
|
import {onBeforeUnmount, Ref, ref} from 'vue';
|
|
6
|
+
import { useI18n } from "vue-i18n";
|
|
7
7
|
export const useFetchRadio = ()=>{
|
|
8
8
|
|
|
9
9
|
const radioInterval : Ref<ReturnType<typeof setTimeout> | undefined> = ref(undefined);
|
|
10
|
+
|
|
11
|
+
const {t} = useI18n();
|
|
10
12
|
|
|
11
13
|
async function fetchRadioMetadata(
|
|
12
14
|
canalId: number,
|
|
13
15
|
previousTitle: string,
|
|
14
16
|
callbackMetadata: (
|
|
15
|
-
metadata: MediaRadio,
|
|
17
|
+
metadata: MediaRadio|undefined,
|
|
16
18
|
podcast: Podcast | undefined,
|
|
17
19
|
history: Array<MediaRadio>
|
|
18
20
|
) => void,
|
|
@@ -33,15 +35,19 @@ export const useFetchRadio = ()=>{
|
|
|
33
35
|
callbackAdvertising(metadata.nextAdvertising);
|
|
34
36
|
}
|
|
35
37
|
const arrayMetadata = metadata.previously;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
if(null!==metadata.currently){
|
|
39
|
+
arrayMetadata.unshift(metadata.currently);
|
|
40
|
+
for (let index = 0, len = arrayMetadata.length; index < len; index++) {
|
|
41
|
+
if (
|
|
42
|
+
dayjs().valueOf() - 18000 >
|
|
43
|
+
dayjs(arrayMetadata[index].startDate).valueOf()
|
|
44
|
+
) {
|
|
45
|
+
await useCallbackIfNewMetadata(previousTitle, arrayMetadata, index, len,callbackMetadata);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
44
48
|
}
|
|
49
|
+
}else{
|
|
50
|
+
callbackMetadata(undefined, undefined, arrayMetadata);
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
async function useCallbackIfNewMetadata(previousTitle: string, arrayMetadata: Array<MediaRadio>, index:number, len: number, callbackMetadata: (
|
|
@@ -63,11 +69,22 @@ export const useFetchRadio = ()=>{
|
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
|
-
function displayTitle(metadata: MediaRadio): string {
|
|
67
|
-
|
|
72
|
+
function displayTitle(metadata: MediaRadio|undefined): string {
|
|
73
|
+
if(!metadata){
|
|
74
|
+
return t("Silent stream");
|
|
75
|
+
}
|
|
76
|
+
let title = "";
|
|
77
|
+
if (metadata?.title) {
|
|
78
|
+
title += metadata.title;
|
|
79
|
+
}
|
|
80
|
+
if (metadata?.artist) {
|
|
81
|
+
title += " - " + metadata.artist;
|
|
82
|
+
}
|
|
83
|
+
return title;
|
|
68
84
|
}
|
|
69
85
|
|
|
70
86
|
|
|
87
|
+
|
|
71
88
|
onBeforeUnmount(() => {
|
|
72
89
|
clearInterval(radioInterval.value as unknown as number);
|
|
73
90
|
})
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
:is-disabled="isDisabled"
|
|
18
18
|
:no-deselect="noDeselect"
|
|
19
19
|
:display-required="displayRequired"
|
|
20
|
+
:popover="popover"
|
|
21
|
+
:popover-relative-class="popoverRelativeClass"
|
|
20
22
|
@on-search="onSearchCategory"
|
|
21
23
|
@selected="onCategorySelected"
|
|
22
24
|
/>
|
|
@@ -52,6 +54,8 @@ const props = defineProps({
|
|
|
52
54
|
displayLabel: { default: false, type: Boolean },
|
|
53
55
|
textDanger :{ default: undefined, type: String },
|
|
54
56
|
displayRequired: { default: false, type: Boolean },
|
|
57
|
+
popover: { default: undefined, type: String },
|
|
58
|
+
popoverRelativeClass: { default: undefined, type: String },
|
|
55
59
|
})
|
|
56
60
|
|
|
57
61
|
//Emits
|
|
@@ -116,8 +116,8 @@ const { t } = useI18n();
|
|
|
116
116
|
const {handle403} = useErrorHandler();
|
|
117
117
|
|
|
118
118
|
//Computed
|
|
119
|
-
const changed = computed(() => `${props.size}|${props.reload}|${dsize.value}|${props.stateFilter}|${props.podcast?.podcastId}|${props.organisationId}`);
|
|
120
119
|
const isNotAnAnswerList = computed(() => undefined === props.answerToComment);
|
|
120
|
+
const changed = computed(() => `${props.size}|${props.reload}|${dsize.value}|${props.stateFilter}|${props.podcast?.podcastId}|${props.organisationId}`);
|
|
121
121
|
const sortChoice = computed(() =>{
|
|
122
122
|
return [
|
|
123
123
|
{ title: t("The most recent"), value: "DATE_DESC" },
|
|
@@ -28,7 +28,7 @@ import ClassicDatePicker from "../../form/ClassicDatePicker.vue";
|
|
|
28
28
|
import { ref, watch } from "vue";
|
|
29
29
|
import { useI18n } from "vue-i18n";
|
|
30
30
|
|
|
31
|
-
//Props
|
|
31
|
+
//Props
|
|
32
32
|
const props = defineProps({
|
|
33
33
|
isEmission: { default: false, type: Boolean },
|
|
34
34
|
fromDate: { default: undefined, type: String },
|
|
@@ -38,7 +38,7 @@ const props = defineProps({
|
|
|
38
38
|
//Emits
|
|
39
39
|
const emit = defineEmits(["updateDates"]);
|
|
40
40
|
|
|
41
|
-
//Data
|
|
41
|
+
//Data
|
|
42
42
|
const isActive = ref([false, false]);
|
|
43
43
|
const internDates = ref([
|
|
44
44
|
dayjs().subtract(10, "days").startOf("day").toDate(),
|
|
@@ -50,6 +50,17 @@ const { t } = useI18n();
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
//Watch
|
|
53
|
+
watch(isActive, () => {
|
|
54
|
+
emit("updateDates", {
|
|
55
|
+
from: isActive.value[0]
|
|
56
|
+
? dayjs(internDates.value[0]).toISOString()
|
|
57
|
+
: undefined,
|
|
58
|
+
to: isActive.value[1]
|
|
59
|
+
? dayjs(internDates.value[1]).toISOString()
|
|
60
|
+
: undefined,
|
|
61
|
+
});
|
|
62
|
+
}, { deep: true });
|
|
63
|
+
|
|
53
64
|
watch(()=>props.toDate, () => {
|
|
54
65
|
isActive.value[1] = undefined !== props.toDate;
|
|
55
66
|
if (props.toDate && props.toDate !== internDates.value[1].toISOString()) {
|
|
@@ -75,6 +86,8 @@ watch(()=>props.fromDate, () => {
|
|
|
75
86
|
|
|
76
87
|
|
|
77
88
|
//Methods
|
|
89
|
+
|
|
90
|
+
|
|
78
91
|
function updateDate(index: number, value: Date): void {
|
|
79
92
|
internDates.value[index] = value;
|
|
80
93
|
if (
|
|
@@ -72,10 +72,7 @@ const currentlyPlayingString = computed(() => {
|
|
|
72
72
|
if (playingRadio.value && playerStore.playerRadio) {
|
|
73
73
|
return displayTitle(playerStore.playerRadio.metadata);
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
return displayTitle(currentMetadata.value);
|
|
77
|
-
}
|
|
78
|
-
return "";
|
|
75
|
+
return displayTitle(currentMetadata.value);
|
|
79
76
|
});
|
|
80
77
|
|
|
81
78
|
onMounted(()=>{
|
|
@@ -102,7 +99,7 @@ async function fetchCurrentlyPlaying(): Promise<void> {
|
|
|
102
99
|
updateMetadata,
|
|
103
100
|
);
|
|
104
101
|
}
|
|
105
|
-
function updateMetadata(metadata: MediaRadio, podcast?: Podcast): void {
|
|
102
|
+
function updateMetadata(metadata: MediaRadio|undefined, podcast?: Podcast): void {
|
|
106
103
|
currentMetadata.value = metadata;
|
|
107
104
|
currentPodcast.value = podcast;
|
|
108
105
|
}
|
|
@@ -211,7 +211,10 @@ function play(isVideo: boolean): void {
|
|
|
211
211
|
playerStore.playerPlay(
|
|
212
212
|
{
|
|
213
213
|
...props.podcast,
|
|
214
|
-
...{
|
|
214
|
+
...{
|
|
215
|
+
conferenceId: props.fetchConference?.conferenceId,
|
|
216
|
+
hlsIdentifier: props.fetchConference?.hlsIdentifier,
|
|
217
|
+
},
|
|
215
218
|
},
|
|
216
219
|
isVideo,
|
|
217
220
|
);
|
|
@@ -36,12 +36,6 @@
|
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
38
38
|
<ChooseEpisodesNumber v-else :episodes-number="episodesNumber" @update-number="emit('update:episodesNumber', $event)"/>
|
|
39
|
-
<ClassicCheckbox
|
|
40
|
-
:text-init="proceedReading"
|
|
41
|
-
id-checkbox="proceed-reading-checkbox"
|
|
42
|
-
:label="t('Proceed reading')"
|
|
43
|
-
@update:text-init="emit('update:proceedReading', $event)"
|
|
44
|
-
/>
|
|
45
39
|
</template>
|
|
46
40
|
<ClassicCheckbox
|
|
47
41
|
v-if="displayIsVisible"
|
|
@@ -104,7 +98,6 @@ const props = defineProps({
|
|
|
104
98
|
displayArticleParam: { default: false, type: Boolean },
|
|
105
99
|
displayIsVisible: { default: false, type: Boolean },
|
|
106
100
|
displayInsertCode: { default: false, type: Boolean },
|
|
107
|
-
proceedReading: { default: true, type: Boolean },
|
|
108
101
|
displayArticle: { default: true, type: Boolean },
|
|
109
102
|
displayTranscript: { default: true, type: Boolean },
|
|
110
103
|
displayWave: { default: true, type: Boolean },
|
|
@@ -118,7 +111,6 @@ const props = defineProps({
|
|
|
118
111
|
//Emits
|
|
119
112
|
const emit = defineEmits([
|
|
120
113
|
"episodeChoiceDisplay",
|
|
121
|
-
"update:proceedReading",
|
|
122
114
|
"update:isVisible",
|
|
123
115
|
"update:episodesNumber",
|
|
124
116
|
"update:displayArticle",
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
v-model:display-article="displayArticle"
|
|
45
45
|
v-model:display-transcript="displayTranscript"
|
|
46
46
|
v-model:display-wave="displayWave"
|
|
47
|
-
v-model:proceed-reading="proceedReading"
|
|
48
47
|
v-model:is-visible="isVisible"
|
|
49
48
|
v-model:player-auto-play="playerAutoPlay"
|
|
50
49
|
v-model:episodes-number="episodesNumber"
|
|
@@ -125,7 +124,6 @@ const iFrameModel = ref("default");
|
|
|
125
124
|
const isShareModal = ref(false);
|
|
126
125
|
const color = ref("#40a372");
|
|
127
126
|
const theme = ref("#000000");
|
|
128
|
-
const proceedReading = ref(true);
|
|
129
127
|
const episodeChoiceDisplay = ref("number");
|
|
130
128
|
const episodesNumber = ref(3);
|
|
131
129
|
const isVisible = ref(false);
|
|
@@ -341,9 +339,6 @@ function addUrlParameters(url: Array<string>) {
|
|
|
341
339
|
url.push(
|
|
342
340
|
`&color=${color.value.substring(1)}&theme=${theme.value.substring(1)}`,
|
|
343
341
|
);
|
|
344
|
-
if (!proceedReading.value) {
|
|
345
|
-
url.push("&proceed=false");
|
|
346
|
-
}
|
|
347
342
|
if (!displayArticle.value && displayArticleParam.value) {
|
|
348
343
|
url.push("&article=false");
|
|
349
344
|
}
|
|
@@ -78,7 +78,7 @@ import RssIcon from "vue-material-design-icons/Rss.vue";
|
|
|
78
78
|
import { useApiStore } from "../../../stores/ApiStore";
|
|
79
79
|
import ClassicPopover from "../../misc/ClassicPopover.vue";
|
|
80
80
|
import { Emission } from "@/stores/class/general/emission";
|
|
81
|
-
import { computed, Ref, ref, useTemplateRef, watch } from "vue";
|
|
81
|
+
import { computed, onMounted, Ref, ref, useTemplateRef, watch } from "vue";
|
|
82
82
|
import { useI18n } from "vue-i18n";
|
|
83
83
|
type Link = {
|
|
84
84
|
name: string;
|
|
@@ -204,7 +204,9 @@ const rssUrl = computed(() => {
|
|
|
204
204
|
|
|
205
205
|
|
|
206
206
|
//Watch
|
|
207
|
-
watch(()=>props.windowWidth, () =>resizeWindow()
|
|
207
|
+
watch(()=>props.windowWidth, () =>resizeWindow());
|
|
208
|
+
|
|
209
|
+
onMounted(()=>resizeWindow());
|
|
208
210
|
|
|
209
211
|
|
|
210
212
|
//Methods
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
>{{ label }}
|
|
13
13
|
<AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="t('Mandatory input')"/>
|
|
14
14
|
</component>
|
|
15
|
+
<slot name="afterTitle"/>
|
|
15
16
|
<template v-if="popover">
|
|
16
17
|
<button
|
|
17
18
|
:id="'popover' + inputId"
|
|
@@ -31,7 +32,9 @@
|
|
|
31
32
|
<!-- eslint-enable -->
|
|
32
33
|
</ClassicPopover>
|
|
33
34
|
</template>
|
|
35
|
+
<slot name="afterHelp"/>
|
|
34
36
|
</div>
|
|
37
|
+
<slot name="betweenTitleInput"/>
|
|
35
38
|
<input
|
|
36
39
|
v-if="!isWysiwyg && !isTextarea"
|
|
37
40
|
v-show="showField"
|
|
@@ -7,11 +7,31 @@
|
|
|
7
7
|
}"
|
|
8
8
|
:style="{ width: width, height: height }"
|
|
9
9
|
>
|
|
10
|
-
<
|
|
11
|
-
label
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
<div class="d-flex align-items-center">
|
|
11
|
+
<label :class="displayLabel ? '' : 'd-none'" :for="id" class="form-label">{{
|
|
12
|
+
label
|
|
13
|
+
}}
|
|
14
|
+
<AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="t('Mandatory input')"/>
|
|
15
|
+
</label>
|
|
16
|
+
<template v-if="popover">
|
|
17
|
+
<button
|
|
18
|
+
:id="'popover' + id"
|
|
19
|
+
:title="t('Help')"
|
|
20
|
+
class="btn-transparent"
|
|
21
|
+
>
|
|
22
|
+
<HelpCircleIcon :size="30" />
|
|
23
|
+
</button>
|
|
24
|
+
<ClassicPopover
|
|
25
|
+
:target="'popover' + id"
|
|
26
|
+
popover-class="popover-z-index"
|
|
27
|
+
:relative-class="popoverRelativeClass"
|
|
28
|
+
>
|
|
29
|
+
<!-- eslint-disable vue/no-v-html -->
|
|
30
|
+
<div v-html="popover" />
|
|
31
|
+
<!-- eslint-enable -->
|
|
32
|
+
</ClassicPopover>
|
|
33
|
+
</template>
|
|
34
|
+
</div>
|
|
15
35
|
<vSelect
|
|
16
36
|
v-model="optionSelected"
|
|
17
37
|
:input-id="id"
|
|
@@ -28,7 +48,7 @@
|
|
|
28
48
|
"
|
|
29
49
|
:filter="fakeSearch"
|
|
30
50
|
:selectable="() => !maxOptionsSelected"
|
|
31
|
-
|
|
51
|
+
:style="{height: height }"
|
|
32
52
|
:class="{ 'border border-danger': textDanger?.length }"
|
|
33
53
|
@open="onSearch"
|
|
34
54
|
@search="onSearch"
|
|
@@ -77,12 +97,15 @@
|
|
|
77
97
|
</template>
|
|
78
98
|
|
|
79
99
|
<script setup lang="ts">
|
|
80
|
-
import { computed, ref, Ref, watch } from "vue";
|
|
100
|
+
import { computed, defineAsyncComponent, ref, Ref, watch } from "vue";
|
|
81
101
|
import { useI18n } from "vue-i18n";
|
|
82
102
|
import AsteriskIcon from "vue-material-design-icons/Asterisk.vue";
|
|
83
103
|
import ChevronDownIcon from "vue-material-design-icons/ChevronDown.vue";
|
|
84
104
|
import vSelect from "vue-select";
|
|
85
|
-
|
|
105
|
+
import HelpCircleIcon from "vue-material-design-icons/HelpCircle.vue";
|
|
106
|
+
const ClassicPopover = defineAsyncComponent(
|
|
107
|
+
() => import("../misc/ClassicPopover.vue"),
|
|
108
|
+
);
|
|
86
109
|
|
|
87
110
|
//Props
|
|
88
111
|
const props = defineProps({
|
|
@@ -106,6 +129,8 @@ const props = defineProps({
|
|
|
106
129
|
allowEmpty: { default: true, type: Boolean },
|
|
107
130
|
textDanger :{ default: undefined, type: String },
|
|
108
131
|
displayRequired: { default: false, type: Boolean },
|
|
132
|
+
popover: { default: undefined, type: String },
|
|
133
|
+
popoverRelativeClass: { default: undefined, type: String },
|
|
109
134
|
})
|
|
110
135
|
|
|
111
136
|
//Emits
|
|
@@ -214,6 +239,9 @@ defineExpose({
|
|
|
214
239
|
height: 100%;
|
|
215
240
|
}
|
|
216
241
|
|
|
242
|
+
.vs__search, .vs__search:focus{
|
|
243
|
+
border: var(--vs-selected-border-width) solid transparent;
|
|
244
|
+
}
|
|
217
245
|
.vs__search:focus {
|
|
218
246
|
min-width: 150px;
|
|
219
247
|
}
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
class="img-accordion"
|
|
21
21
|
:src="imageUrl"
|
|
22
22
|
aria-hidden="true"
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
alt=""
|
|
25
24
|
/>
|
|
26
|
-
<span
|
|
27
|
-
<
|
|
25
|
+
<span>{{ title }}</span>
|
|
26
|
+
<slot name="afterTitle"/>
|
|
27
|
+
<ChevronDownIcon class="ms-auto" :class="{ 'arrow-transform': isOpen }" />
|
|
28
28
|
</button>
|
|
29
29
|
<div v-show="isOpen" class="body p-2">
|
|
30
30
|
<slot />
|
|
@@ -32,143 +32,36 @@
|
|
|
32
32
|
:left-pos="true"
|
|
33
33
|
:is-top-layer="true"
|
|
34
34
|
>
|
|
35
|
-
<
|
|
36
|
-
<ul class="p-0 m-0">
|
|
37
|
-
<template v-if="!isAuthenticated">
|
|
38
|
-
<li class="li-style-none">
|
|
39
|
-
<a class="octopus-dropdown-item realLink" :href="pathLogin">
|
|
40
|
-
{{ t("Login") }}
|
|
41
|
-
</a>
|
|
42
|
-
</li>
|
|
43
|
-
<li class="li-style-none">
|
|
44
|
-
<router-link
|
|
45
|
-
v-if="!state.generalParameters.podcastmaker"
|
|
46
|
-
class="octopus-dropdown-item"
|
|
47
|
-
to="/main/pub/create"
|
|
48
|
-
>
|
|
49
|
-
{{ t("Create an account") }}
|
|
50
|
-
</router-link>
|
|
51
|
-
</li>
|
|
52
|
-
</template>
|
|
53
|
-
<template v-else>
|
|
54
|
-
<li v-for="routerBack in routerBackoffice" :key="routerBack.path" class="li-style-none">
|
|
55
|
-
<router-link
|
|
56
|
-
v-if="!state.generalParameters.podcastmaker && routerBack.condition"
|
|
57
|
-
:class="routerBack.class"
|
|
58
|
-
:to="routerBack.path"
|
|
59
|
-
>
|
|
60
|
-
{{ routerBack.title }}
|
|
61
|
-
</router-link>
|
|
62
|
-
</li>
|
|
63
|
-
<template v-if="helpLinks.length">
|
|
64
|
-
<hr />
|
|
65
|
-
<li v-for="helpLink in helpLinks" :key="helpLink.title" class="li-style-none">
|
|
66
|
-
<a
|
|
67
|
-
:href="helpLink.href"
|
|
68
|
-
class="octopus-dropdown-item realLink"
|
|
69
|
-
rel="noreferrer noopener"
|
|
70
|
-
target="_blank"
|
|
71
|
-
:title="t('New window', {text: helpLink.title})"
|
|
72
|
-
>
|
|
73
|
-
{{ helpLink.title }}
|
|
74
|
-
<OpenInNewIcon class="ms-1" :size="15"/>
|
|
75
|
-
</a>
|
|
76
|
-
</li>
|
|
77
|
-
</template>
|
|
78
|
-
<hr />
|
|
79
|
-
<li class="li-style-none">
|
|
80
|
-
<a class="octopus-dropdown-item c-hand" href="/logout">
|
|
81
|
-
{{ t("Logout") }}
|
|
82
|
-
</a>
|
|
83
|
-
</li>
|
|
84
|
-
</template>
|
|
85
|
-
<li class="li-style-none">
|
|
86
|
-
<router-link
|
|
87
|
-
v-if="!authStore.isGarRole"
|
|
88
|
-
class="octopus-dropdown-item"
|
|
89
|
-
to="/main/pub/contact"
|
|
90
|
-
>
|
|
91
|
-
{{ t("Contact") }}
|
|
92
|
-
</router-link>
|
|
93
|
-
</li>
|
|
94
|
-
</ul>
|
|
95
|
-
</nav>
|
|
35
|
+
<UserButtonContent :isEducation="isEducation" :navLabel="t('User menu')"/>
|
|
96
36
|
</ClassicPopover>
|
|
97
37
|
</div>
|
|
98
38
|
</template>
|
|
99
39
|
|
|
100
40
|
<script setup lang="ts">
|
|
101
|
-
import
|
|
41
|
+
import UserButtonContent from "./UserButtonContent.vue";
|
|
102
42
|
import AppsIcon from "vue-material-design-icons/Apps.vue";
|
|
103
43
|
import AccountIcon from "vue-material-design-icons/Account.vue";
|
|
104
44
|
import DownloadIcon from "vue-material-design-icons/Download.vue";
|
|
105
|
-
import { state } from "../../stores/ParamSdkStore";
|
|
106
45
|
import ClassicPopover from "../misc/ClassicPopover.vue";
|
|
107
46
|
import { useAuthStore } from "../../stores/AuthStore";
|
|
108
47
|
import { computed } from "vue";
|
|
109
|
-
import { useApiStore } from "../../stores/ApiStore";
|
|
110
48
|
import { useI18n } from "vue-i18n";
|
|
111
49
|
import { useRoute, useRouter } from "vue-router";
|
|
112
50
|
|
|
113
51
|
//Props
|
|
114
|
-
|
|
52
|
+
defineProps({
|
|
115
53
|
isEducation: { default: false, type: Boolean },
|
|
116
54
|
mobileMenuDisplay: { default: false, type: Boolean },
|
|
117
|
-
scrolled: { default: false, type: Boolean },
|
|
118
55
|
})
|
|
119
56
|
|
|
120
57
|
//Composables
|
|
121
58
|
const { t } = useI18n();
|
|
122
59
|
const authStore = useAuthStore();
|
|
123
|
-
const apiStore = useApiStore();
|
|
124
60
|
const route = useRoute();
|
|
125
61
|
const router = useRouter();
|
|
126
62
|
|
|
127
63
|
//Computed
|
|
128
|
-
const isAuthenticated = computed(() => undefined !== authStore.authProfile?.userId);
|
|
129
64
|
const isAuthenticatedWithOrga = computed(() => undefined !== authStore.authOrgaId);
|
|
130
|
-
const pathLogin = computed(() => "/sso/login?redirect_url="+encodeURI(apiStore.frontendUrl + route.fullPath));
|
|
131
|
-
const organisationsAvailable = computed(() => authStore.authProfile?.organisations ?? []);
|
|
132
|
-
const helpLinks = computed(() => {
|
|
133
|
-
if (authStore.isGarRole || props.isEducation) {
|
|
134
|
-
return [];
|
|
135
|
-
}
|
|
136
|
-
return [
|
|
137
|
-
{ title:t("Help"), href: "https://help.octopus.saooti.com/Aide/"},
|
|
138
|
-
{ title: t("TutoMag"), href: "https://help.octopus.saooti.com/" },
|
|
139
|
-
];
|
|
140
|
-
});
|
|
141
|
-
const routerBackoffice = computed(() => {
|
|
142
|
-
return [
|
|
143
|
-
{
|
|
144
|
-
title: t("My space"),
|
|
145
|
-
class: "octopus-dropdown-item show-small-phone-flex",
|
|
146
|
-
path: "/main/priv/backoffice",
|
|
147
|
-
condition: isAuthenticatedWithOrga.value,
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
title: t("Upload"),
|
|
151
|
-
class: "octopus-dropdown-item show-small-phone-flex",
|
|
152
|
-
path: "/main/priv/upload",
|
|
153
|
-
condition: isAuthenticatedWithOrga.value && authStore.isRoleContribution,
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
title: t("Edit my profile"),
|
|
157
|
-
class: "octopus-dropdown-item",
|
|
158
|
-
path: "/main/priv/edit/profile",
|
|
159
|
-
condition: true,
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
title: t("Edit my organisation"),
|
|
163
|
-
class: "octopus-dropdown-item",
|
|
164
|
-
path: "/main/priv/edit/organisation",
|
|
165
|
-
condition:
|
|
166
|
-
isAuthenticatedWithOrga.value &&
|
|
167
|
-
(authStore.isRoleOrganisation || 1 < organisationsAvailable.value.length),
|
|
168
|
-
},
|
|
169
|
-
];
|
|
170
|
-
});
|
|
171
|
-
|
|
172
65
|
|
|
173
66
|
//Methods
|
|
174
67
|
function goToAdministration() {
|