@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.
Files changed (43) hide show
  1. package/package.json +3 -1
  2. package/plateform.conf +1 -1
  3. package/src/App.vue +3 -7
  4. package/src/api/classicApi.ts +1 -1
  5. package/src/components/composable/player/usePlayerLive.ts +2 -2
  6. package/src/components/composable/radio/usefetchRadioData.ts +29 -12
  7. package/src/components/display/categories/CategoryChooser.vue +4 -0
  8. package/src/components/display/comments/CommentList.vue +1 -1
  9. package/src/components/display/filter/DateFilter.vue +15 -2
  10. package/src/components/display/live/RadioCurrently.vue +2 -5
  11. package/src/components/display/podcasts/PodcastPlayButton.vue +4 -1
  12. package/src/components/display/sharing/PlayerParameters.vue +0 -8
  13. package/src/components/display/sharing/SharePlayer.vue +0 -5
  14. package/src/components/display/sharing/SubscribeButtons.vue +4 -2
  15. package/src/components/form/ClassicInputText.vue +3 -0
  16. package/src/components/form/ClassicMultiselect.vue +36 -8
  17. package/src/components/misc/ClassicAccordion.vue +4 -4
  18. package/src/components/misc/ClassicSpinner.vue +1 -1
  19. package/src/components/misc/HomeDropdown.vue +3 -110
  20. package/src/components/misc/MobileMenu.vue +59 -64
  21. package/src/components/misc/TopBar.vue +4 -11
  22. package/src/components/misc/TopBarMainContent.vue +0 -2
  23. package/src/components/misc/UserButtonContent.vue +159 -0
  24. package/src/components/misc/player/elements/PlayerImage.vue +0 -1
  25. package/src/components/misc/player/elements/PlayerTitle.vue +3 -3
  26. package/src/components/misc/player/radio/RadioHistory.vue +3 -2
  27. package/src/components/misc/player/video/PlayerVideo.vue +2 -2
  28. package/src/components/pages/PageLogout.vue +1 -6
  29. package/src/components/pages/PodcastPage.vue +0 -1
  30. package/src/components/pages/VideoPage.vue +5 -2
  31. package/src/locale/de.ts +3 -3
  32. package/src/locale/en.ts +3 -3
  33. package/src/locale/es.ts +3 -3
  34. package/src/locale/fr.ts +3 -3
  35. package/src/locale/it.ts +3 -3
  36. package/src/locale/sl.ts +3 -3
  37. package/src/stores/FilterStore.ts +1 -1
  38. package/src/stores/PlayerStore.ts +6 -1
  39. package/src/stores/class/conference/conference.ts +2 -0
  40. package/src/stores/class/general/player.ts +2 -2
  41. package/src/style/_variables.scss +6 -0
  42. package/src/style/general.scss +18 -1
  43. 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-SNAPSHOT",
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
- dev2.saooti.org
1
+ preprod.saooti.org
package/src/App.vue CHANGED
@@ -8,16 +8,14 @@
8
8
  <router-view />
9
9
  <PlayerComponent />
10
10
  </main>
11
- <ClassicLazy :min-height="123">
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
- const FooterOctopus = defineAsyncComponent(
29
- () => import("@/components/misc/FooterSection.vue"),
30
- );
26
+
31
27
  const CategoryFilter = defineAsyncComponent(
32
28
  () => import("@/components/display/categories/CategoryFilter.vue"),
33
29
  );
@@ -78,7 +78,7 @@ export default {
78
78
  params.catchFunction();
79
79
  }else{
80
80
  const axiosError= error as AxiosError;
81
- return Promise.reject(new Error(axiosError.message));
81
+ return Promise.reject(axiosError);
82
82
  }
83
83
  });
84
84
  return response?.data;
@@ -51,8 +51,8 @@ export const usePlayerLive = (hlsReady: Ref<boolean>)=>{
51
51
  }
52
52
 
53
53
  function playLive() {
54
- if (!playerStore.playerLive) return;
55
- playerStore.playerUpdatePlayerHlsUrl(`${apiStore.hlsUrl}live/dev.${playerStore.playerLive.conferenceId}/index.m3u8`);
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
- arrayMetadata.unshift(metadata.currently);
37
- for (let index = 0, len = arrayMetadata.length; index < len; index++) {
38
- if (
39
- dayjs().valueOf() - 18000 >
40
- dayjs(arrayMetadata[index].startDate).valueOf()
41
- ) {
42
- await useCallbackIfNewMetadata(previousTitle, arrayMetadata, index, len,callbackMetadata);
43
- return;
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
- return radioHelper.displayTitle(metadata);
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
- if (currentMetadata.value) {
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
- ...{ conferenceId: props.fetchConference?.conferenceId },
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(), {immediate: true});
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
- <label :class="displayLabel ? '' : 'd-none'" :for="id" class="form-label">{{
11
- label
12
- }}
13
- <AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="t('Mandatory input')"/>
14
- </label>
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
- class="h-100"
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
- alt=""
24
-
23
+ alt=""
25
24
  />
26
- <span class="flex-grow-1">{{ title }}</span>
27
- <ChevronDownIcon :class="{ 'arrow-transform': isOpen }" />
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 />
@@ -16,7 +16,7 @@ defineProps({
16
16
  --size-spinner: 3rem;
17
17
  --size-spinner-section: calc(var(--size-spinner) / 20);
18
18
  --half-size-spinner: calc(var(--size-spinner) / 2);
19
-
19
+
20
20
  color: #000000;
21
21
  display: inline-block;
22
22
  position: relative;
@@ -32,143 +32,36 @@
32
32
  :left-pos="true"
33
33
  :is-top-layer="true"
34
34
  >
35
- <nav :aria-label="t('User menu')">
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 OpenInNewIcon from "vue-material-design-icons/OpenInNew.vue";
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
- const props = defineProps({
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() {