@saooti/octopus-sdk 39.4.8 → 39.4.10

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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/App.vue +1 -1
  3. package/src/components/display/categories/CategoryChooser.vue +2 -0
  4. package/src/components/display/comments/CommentName.vue +16 -26
  5. package/src/components/display/emission/EmissionItem.vue +2 -2
  6. package/src/components/display/emission/EmissionPresentationItem.vue +2 -2
  7. package/src/components/display/filter/AdvancedSearch.vue +4 -4
  8. package/src/components/display/filter/SearchOrder.vue +3 -1
  9. package/src/components/display/list/PaginateSection.vue +2 -2
  10. package/src/components/display/participant/ParticipantItem.vue +2 -2
  11. package/src/components/display/playlist/PlaylistItem.vue +2 -2
  12. package/src/components/display/podcasts/PodcastItem.vue +2 -2
  13. package/src/components/display/podcasts/PodcastPlayButton.vue +9 -2
  14. package/src/components/display/sharing/ChooseEpisodesNumber.vue +59 -0
  15. package/src/components/display/sharing/PlayerParameters.vue +98 -115
  16. package/src/components/display/sharing/SharePlayer.vue +11 -16
  17. package/src/components/form/ClassicInputText.vue +13 -13
  18. package/src/components/form/ClassicMultiselect.vue +6 -1
  19. package/src/components/form/ClassicRadio.vue +1 -1
  20. package/src/components/form/ClassicRadioLabel.vue +4 -3
  21. package/src/components/form/ClassicSelect.vue +8 -1
  22. package/src/components/misc/ClassicPopover.vue +0 -2
  23. package/src/components/misc/FooterSection.vue +3 -2
  24. package/src/components/misc/HomeDropdown.vue +1 -1
  25. package/src/components/misc/TopBarMainContent.vue +31 -30
  26. package/src/components/pages/MapPage.vue +1 -1
  27. package/src/locale/de.ts +1 -0
  28. package/src/locale/en.ts +1 -0
  29. package/src/locale/es.ts +1 -0
  30. package/src/locale/fr.ts +1 -0
  31. package/src/locale/it.ts +1 -0
  32. package/src/locale/sl.ts +1 -0
  33. package/src/style/_utilities.scss +2 -0
  34. package/src/style/form.scss +6 -1
  35. package/src/style/share.scss +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "39.4.8",
3
+ "version": "39.4.10",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
package/src/App.vue CHANGED
@@ -2,7 +2,7 @@
2
2
  <div class="d-flex flex-column h-100 octopus-app">
3
3
  <template v-if="pageFullyLoad">
4
4
  <TopBar/>
5
- <main>
5
+ <main role="main">
6
6
  <CategoryFilter v-if="firstDisplayCategoryFilter" />
7
7
  <div v-else class="category-filter-no-filter" />
8
8
  <router-view />
@@ -15,6 +15,7 @@
15
15
  :width="width"
16
16
  :is-disabled="isDisabled"
17
17
  :no-deselect="noDeselect"
18
+ :display-required="displayRequired"
18
19
  @on-search="onSearchCategory"
19
20
  @selected="onCategorySelected"
20
21
  />
@@ -50,6 +51,7 @@ export default defineComponent({
50
51
  label:{default: undefined, type: String },
51
52
  displayLabel: { default: false, type: Boolean },
52
53
  textDanger :{ default: undefined, type: String },
54
+ displayRequired: { default: false, type: Boolean },
53
55
  },
54
56
  emits: [
55
57
  "update:categorySelected",
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <div class="d-flex align-items-center mb-2">
2
+ <div
3
+ class="d-flex align-items-center mb-2">
3
4
  <component
4
5
  :is="canEditName ? 'button' : 'div'"
5
6
  v-if="!isEditing"
@@ -9,27 +10,20 @@
9
10
  >{{ commentUser.name }}</component
10
11
  >
11
12
  <template v-else>
12
- <div class="d-flex flex-column">
13
- <input
14
- v-model="temporaryName"
15
- :title="$t('Your name')"
16
- class="h6"
17
- type="text"
18
- :class="{ 'border border-danger': nameNotValid }"
19
- />
20
- <p
21
- class="d-flex justify-content-end h6 mb-0"
22
- :class="{ 'text-danger': !validName }"
23
- >
24
- {{ countName + " / " + maxName }}
25
- </p>
26
- </div>
13
+ <ClassicInputText
14
+ v-model:text-init="temporaryName"
15
+ v-model:error-variable="errorName"
16
+ input-id="comment-name-input"
17
+ :label="$t('Your name')"
18
+ :max-length="maxName"
19
+ class="me-3"
20
+ />
27
21
  <button class="btn m-1" @click="isEditing = false">
28
22
  {{ $t("Cancel") }}
29
23
  </button>
30
24
  <button
31
25
  class="btn btn-primary m-1"
32
- :disabled="nameNotValid"
26
+ :disabled="errorName"
33
27
  @click="validEdit"
34
28
  >
35
29
  {{ $t("Yes") }}
@@ -39,6 +33,7 @@
39
33
  </template>
40
34
 
41
35
  <script lang="ts">
36
+ import ClassicInputText from "../../form/ClassicInputText.vue";
42
37
  import Constants from "../../../../public/config";
43
38
  import { useAuthStore } from "../../../stores/AuthStore";
44
39
  import { mapActions, mapState } from "pinia";
@@ -46,11 +41,15 @@ import { defineComponent } from "vue";
46
41
  import { useCommentStore } from "../../../stores/CommentStore";
47
42
  export default defineComponent({
48
43
  name: "CommentName",
44
+ components:{
45
+ ClassicInputText
46
+ },
49
47
  emits: [],
50
48
  data() {
51
49
  return {
52
50
  isEditing: false as boolean,
53
51
  temporaryName: "" as string,
52
+ errorName: true as boolean,
54
53
  maxName: Constants.MAX_COMMENT_NAME as number,
55
54
  };
56
55
  },
@@ -61,15 +60,6 @@ export default defineComponent({
61
60
  canEditName(): boolean {
62
61
  return undefined !== this.authProfile;
63
62
  },
64
- nameNotValid(): boolean {
65
- return 0 === this.countName || !this.validName;
66
- },
67
- validName(): boolean {
68
- return this.countName <= this.maxName;
69
- },
70
- countName(): number {
71
- return this.temporaryName.length;
72
- },
73
63
  },
74
64
  methods: {
75
65
  ...mapActions(useCommentStore, ["setCommentUser"]),
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="mt-3 emission-item-container">
2
+ <article class="mt-3 emission-item-container">
3
3
  <router-link
4
4
  :to="{
5
5
  name: 'emission',
@@ -50,7 +50,7 @@
50
50
  </router-link>
51
51
  </div>
52
52
  </router-link>
53
- </div>
53
+ </article>
54
54
  </template>
55
55
 
56
56
  <script lang="ts">
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div
2
+ <article
3
3
  class="emission-item-container emission-presentation-container mt-3"
4
4
  :class="isVertical ? 'emission-vertical-item' : ''"
5
5
  >
@@ -40,7 +40,7 @@
40
40
  </div>
41
41
  </div>
42
42
  </router-link>
43
- </div>
43
+ </article>
44
44
  </template>
45
45
 
46
46
  <script lang="ts">
@@ -12,10 +12,10 @@
12
12
  v-show="showFilters"
13
13
  class="advanced-search-container"
14
14
  >
15
- <div class="d-flex flex-column">
16
- <div class="text-primary mb-2">
15
+ <fieldset class="d-flex flex-column flex-grow-3">
16
+ <legend class="text-primary mb-2">
17
17
  {{ $t("Filter") }}
18
- </div>
18
+ </legend>
19
19
  <MonetizableFilter
20
20
  v-if="!isPodcastmaker && !platformEducation"
21
21
  :is-emission="isEmission"
@@ -63,7 +63,7 @@
63
63
  :label="$t('Show only episodes with video')"
64
64
  @update:text-init="updateOnlyVideo"
65
65
  />
66
- </div>
66
+ </fieldset>
67
67
  <SearchOrder
68
68
  :is-emission="isEmission"
69
69
  :sort="sort"
@@ -5,10 +5,11 @@
5
5
  :options="optionsArray"
6
6
  :radio-label="$t('Sort')"
7
7
  class-label="text-primary mb-2"
8
+ :type-tag="typeTag"
9
+ class="flex-grow-1"
8
10
  @update:text-init="$emit('update:sort', $event)"
9
11
  />
10
12
  </template>
11
-
12
13
  <script lang="ts">
13
14
  import ClassicRadioLabel from "../../form/ClassicRadioLabel.vue";
14
15
  import { defineComponent } from "vue";
@@ -19,6 +20,7 @@ export default defineComponent({
19
20
  props: {
20
21
  isEmission: { default: false, type: Boolean },
21
22
  sort: { default: "DATE", type: String },
23
+ typeTag: { default: "fieldset", type: String },
22
24
  },
23
25
 
24
26
  emits: ["update:sort"],
@@ -22,7 +22,7 @@
22
22
  <path fill-rule="evenodd" :d="paginateButton.path" />
23
23
  </svg>
24
24
  </button>
25
- <div v-for="pageNumber in pagination" :key="pageNumber">
25
+ <template v-for="pageNumber in pagination" :key="pageNumber">
26
26
  <span v-if="null === pageNumber" class="btn btn-min-width"> ... </span>
27
27
  <button
28
28
  v-else
@@ -32,7 +32,7 @@
32
32
  >
33
33
  {{ pageNumber }}
34
34
  </button>
35
- </div>
35
+ </template>
36
36
  <button
37
37
  v-for="paginateButton in buttonsRight"
38
38
  :key="paginateButton.title"
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-if="participant" class="participant-item-container">
2
+ <article v-if="participant" class="participant-item-container">
3
3
  <router-link
4
4
  :to="{
5
5
  name: 'participant',
@@ -48,7 +48,7 @@
48
48
  >
49
49
  © {{ participant.orga.name }}
50
50
  </router-link>
51
- </div>
51
+ </article>
52
52
  </template>
53
53
 
54
54
  <script lang="ts">
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="emission-item-container">
2
+ <article class="emission-item-container">
3
3
  <router-link
4
4
  :to="{
5
5
  name: 'playlist',
@@ -44,7 +44,7 @@
44
44
  class="img-box"
45
45
  />
46
46
  </router-link>
47
- </div>
47
+ </article>
48
48
  </template>
49
49
 
50
50
  <script lang="ts">
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div
2
+ <article
3
3
  class="podcast-item-container"
4
4
  :data-pubdate="displayDate"
5
5
  :data-count="podcast.downloadCount"
@@ -41,7 +41,7 @@
41
41
  :animators="podcast.animators"
42
42
  />
43
43
  </div>
44
- </div>
44
+ </article>
45
45
  </template>
46
46
 
47
47
  <script lang="ts">
@@ -17,7 +17,7 @@
17
17
  :size="'audio' === hoverType ? 50 : 40"
18
18
  />
19
19
  <PodcastIsPlaying v-if="playingPodcast && !playerVideo"/>
20
- <span v-if="!isVideoPodcast" class="ms-1">{{ durationString }}</span>
20
+ <time v-if="!isVideoPodcast" class="ms-1" :datetime="durationIso">{{ durationString }}</time>
21
21
  </button>
22
22
  <button
23
23
  v-if="isVideoPodcast"
@@ -29,7 +29,7 @@
29
29
  >
30
30
  <PlayVideoIcon v-if="!playerVideo" :size="'video' === hoverType ? 50 : 40" />
31
31
  <PodcastIsPlaying v-if="playingPodcast && playerVideo"/>
32
- <span class="ms-2">{{ durationString }}</span>
32
+ <time class="ms-2" :datetime="durationIso">{{ durationString }}</time>
33
33
  </button>
34
34
  <div v-if="!classicPodcastPlay" class="special-icon-play-button">
35
35
  <component :is="iconName" :size="16" />
@@ -58,6 +58,9 @@ import { useAuthStore } from "../../../stores/AuthStore";
58
58
  import { usePlayerStore } from "../../../stores/PlayerStore";
59
59
  import { mapState, mapActions } from "pinia";
60
60
  import { defineAsyncComponent, defineComponent } from "vue";
61
+ import dayjs from "dayjs";
62
+ import duration from "dayjs/plugin/duration";
63
+ dayjs.extend(duration);
61
64
  const PodcastIsPlaying = defineAsyncComponent(() => import("./PodcastIsPlaying.vue"));
62
65
  export default defineComponent({
63
66
  name: "PodcastPlayButton",
@@ -193,6 +196,10 @@ export default defineComponent({
193
196
  Math.round(this.podcast.duration / 1000),
194
197
  );
195
198
  },
199
+ durationIso(): string {
200
+ if (!this.podcast || this.podcast.duration <= 1) return "";
201
+ return dayjs.duration({ milliseconds: this.podcast.duration }).toISOString();
202
+ },
196
203
  },
197
204
 
198
205
  methods: {
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <div class="d-flex align-items-center flex-wrap">
3
+ <span class="flex-shrink-0">{{ $t("Show") }}</span>
4
+ <input
5
+ id="number-input"
6
+ v-model="internNumber"
7
+ type="number"
8
+ min="1"
9
+ max="50"
10
+ class="input-share-player text-center m-2"
11
+ :title="$t('Number of player podcasts')"
12
+ />
13
+ <span class="flex-shrink-0">{{ $t("Last podcasts") }}</span>
14
+ </div>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ import { defineComponent } from "vue";
19
+ export default defineComponent({
20
+ props: {
21
+ episodesNumber: { default: 3, type: Number },
22
+ },
23
+ emits: [
24
+ "updateNumber",
25
+ ],
26
+
27
+ data() {
28
+ return {
29
+ internNumber: 3 as number
30
+ };
31
+ },
32
+ watch:{
33
+ internNumber(){
34
+ if (this.internNumber < 1) {
35
+ this.$emit("updateNumber", 1);
36
+ }else if(this.internNumber > 50){
37
+ this.$emit("updateNumber", 50);
38
+ }else{
39
+ this.$emit("updateNumber", this.internNumber);
40
+ }
41
+ }
42
+ },
43
+
44
+ created(){
45
+ this.internNumber = this.episodesNumber;
46
+ }
47
+
48
+ });
49
+ </script>
50
+
51
+ <style lang="scss">
52
+ .octopus-app {
53
+ .input-share-player {
54
+ border: 1px solid var(--octopus-border-default);
55
+ border-radius: 50px;
56
+ width: 60px;
57
+ }
58
+ }
59
+ </style>
@@ -1,98 +1,102 @@
1
1
  <template>
2
- <div class="h4 mb-2 mt-3">
3
- {{ $t("player parameters") }}
4
- </div>
5
- <template v-if="choseNumberEpisode">
6
- <div
7
- v-if="displayChoiceAllEpisodes"
8
- class="d-flex align-items-center flex-wrap mt-1"
9
- >
10
- <input
11
- id="radio-all-episodes"
12
- v-model="episodeNumbers"
13
- class="form-check-input"
14
- type="radio"
15
- name="episodeNumbers"
16
- value="all"
2
+ <fieldset class="mt-3">
3
+ <legend class="h4 mb-2 mt-3">
4
+ {{ $t("player parameters") }}
5
+ </legend>
6
+ <template v-if="choseNumberEpisode">
7
+ <div v-if="displayChoiceAllEpisodes" role="radiogroup">
8
+ <div
9
+ class="d-flex align-items-center flex-wrap mt-1"
10
+ >
11
+ <input
12
+ id="radio-all-episodes"
13
+ v-model="episodeChoiceDisplay"
14
+ class="form-check-input"
15
+ type="radio"
16
+ name="episodeNumbers"
17
+ value="all"
18
+ />
19
+ <label for="radio-all-episodes" class="flex-shrink-0">{{
20
+ $t("Show every episode")
21
+ }}</label>
22
+ </div>
23
+ <div
24
+ class="d-flex align-items-center flex-wrap"
25
+ >
26
+ <input
27
+ v-if="displayChoiceAllEpisodes"
28
+ v-model="episodeChoiceDisplay"
29
+ class="form-check-input"
30
+ type="radio"
31
+ name="episodeNumbers"
32
+ value="number"
33
+ :title="$t('Show') + ' ' + $t('Last podcasts')"
34
+ />
35
+ <ChooseEpisodesNumber :episodes-number="episodesNumber" @update-number="$emit('update:episodesNumber', $event)"/>
36
+ </div>
37
+ </div>
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)"
17
44
  />
18
- <label for="radio-all-episodes" class="flex-shrink-0">{{
19
- $t("Show every episode")
20
- }}</label>
21
- </div>
22
- <div
23
- class="d-flex align-items-center flex-wrap"
24
- :class="displayChoiceAllEpisodes ? '' : 'mt-3'"
25
- >
26
- <input
27
- v-if="displayChoiceAllEpisodes"
28
- v-model="episodeNumbers"
29
- class="form-check-input"
30
- type="radio"
31
- name="episodeNumbers"
32
- value="number"
33
- :title="$t('Show') + ' ' + $t('Last podcasts')"
34
- />
35
- <span class="flex-shrink-0">{{ $t("Show") }}</span>
36
- <input
37
- id="number-input"
38
- v-model="iFrameNumber"
39
- type="number"
40
- min="1"
41
- max="50"
42
- class="input-share-player text-center m-2"
43
- :title="$t('Number of player podcasts')"
44
- />
45
- <span class="flex-shrink-0">{{ $t("Last podcasts") }}</span>
46
- </div>
45
+ </template>
46
+ <ClassicCheckbox
47
+ v-if="displayIsVisible"
48
+ :text-init="isVisible"
49
+ id-checkbox="is-visible-checkbox"
50
+ :label="titleStillAvailable"
51
+ @update:text-init="$emit('update:isVisible', $event)"
52
+ />
53
+ <ClassicCheckbox
54
+ v-if="displayArticleParam"
55
+ :text-init="displayArticle"
56
+ id-checkbox="display-article-checkbox"
57
+ :label="$t('Display associated article')"
58
+ @update:text-init="$emit('update:displayArticle', $event)"
59
+ />
60
+ <ClassicCheckbox
61
+ v-if="displayTranscriptParam"
62
+ :text-init="displayTranscript"
63
+ id-checkbox="display-transcript-checkbox"
64
+ :label="$t('If the transcript is available, show it')"
65
+ @update:text-init="$emit('update:displayTranscript', $event)"
66
+ />
67
+ <ClassicCheckbox
68
+ v-if="displayWaveParam"
69
+ :text-init="displayWave"
70
+ id-checkbox="display-wave-checkbox"
71
+ :label="$t('Show animated wave')"
72
+ @update:text-init="$emit('update:displayWave', $event)"
73
+ />
47
74
  <ClassicCheckbox
48
- :text-init="proceedReading"
49
- id-checkbox="proceed-reading-checkbox"
50
- :label="$t('Proceed reading')"
51
- @update:text-init="$emit('update:proceedReading', $event)"
75
+ :text-init="playerAutoPlay"
76
+ id-checkbox="player-autoplay-checkbox"
77
+ :label="$t('Trigger automatic reading if this is possible')"
78
+ @update:text-init="$emit('update:playerAutoPlay', $event)"
79
+ />
80
+ <PlayerCommonParameters
81
+ v-if="displayInsertCode"
82
+ :insert-code="insertCode"
83
+ @update:insert-code="$emit('update:insertCode', $event)"
52
84
  />
53
- </template>
54
- <ClassicCheckbox
55
- v-if="displayIsVisible"
56
- :text-init="isVisible"
57
- id-checkbox="is-visible-checkbox"
58
- :label="titleStillAvailable"
59
- @update:text-init="$emit('update:isVisible', $event)"
60
- />
61
- <ClassicCheckbox
62
- v-if="displayArticleParam"
63
- :text-init="displayArticle"
64
- id-checkbox="display-article-checkbox"
65
- :label="$t('Display associated article')"
66
- @update:text-init="$emit('update:displayArticle', $event)"
67
- />
68
- <ClassicCheckbox
69
- v-if="displayTranscriptParam"
70
- :text-init="displayTranscript"
71
- id-checkbox="display-transcript-checkbox"
72
- :label="$t('If the transcript is available, show it')"
73
- @update:text-init="$emit('update:displayTranscript', $event)"
74
- />
75
- <ClassicCheckbox
76
- v-if="displayWaveParam"
77
- :text-init="displayWave"
78
- id-checkbox="display-wave-checkbox"
79
- :label="$t('Show animated wave')"
80
- @update:text-init="$emit('update:displayWave', $event)"
81
- />
82
- <ClassicCheckbox
83
- :text-init="playerAutoPlay"
84
- id-checkbox="player-autoplay-checkbox"
85
- :label="$t('Trigger automatic reading if this is possible')"
86
- @update:text-init="$emit('update:playerAutoPlay', $event)"
87
- />
85
+ </fieldset>
88
86
  </template>
89
87
 
90
88
  <script lang="ts">
91
89
  import ClassicCheckbox from "../../form/ClassicCheckbox.vue";
92
- import { defineComponent } from "vue";
90
+ import { defineAsyncComponent, defineComponent } from "vue";
91
+ const ChooseEpisodesNumber = defineAsyncComponent(() => import("./ChooseEpisodesNumber.vue"));
92
+ const PlayerCommonParameters = defineAsyncComponent(
93
+ () => import("./PlayerCommonParameters.vue"),
94
+ );
93
95
  export default defineComponent({
94
96
  components: {
95
97
  ClassicCheckbox,
98
+ ChooseEpisodesNumber,
99
+ PlayerCommonParameters
96
100
  },
97
101
  props: {
98
102
  isVisible: { default: false, type: Boolean },
@@ -102,28 +106,31 @@ export default defineComponent({
102
106
  displayTranscriptParam: { default: false, type: Boolean },
103
107
  displayArticleParam: { default: false, type: Boolean },
104
108
  displayIsVisible: { default: false, type: Boolean },
109
+ displayInsertCode: { default: false, type: Boolean },
105
110
  proceedReading: { default: true, type: Boolean },
106
111
  displayArticle: { default: true, type: Boolean },
107
112
  displayTranscript: { default: true, type: Boolean },
108
113
  displayWave: { default: true, type: Boolean },
109
114
  playerAutoPlay: { default: false, type: Boolean },
110
115
  isPodcastNotVisible: { default: false, type: Boolean },
116
+ episodesNumber: { default: 3, type: Number },
117
+ insertCode: { default: false, type: Boolean },
111
118
  },
112
119
  emits: [
113
- "episodeNumbers",
120
+ "episodeChoiceDisplay",
114
121
  "update:proceedReading",
115
122
  "update:isVisible",
116
- "iFrameNumber",
123
+ "update:episodesNumber",
117
124
  "update:displayArticle",
118
125
  "update:displayTranscript",
119
126
  "update:displayWave",
120
127
  "update:playerAutoPlay",
128
+ "update:insertCode"
121
129
  ],
122
130
 
123
131
  data() {
124
132
  return {
125
- episodeNumbers: "number" as string,
126
- iFrameNumberPriv: "3" as string,
133
+ episodeChoiceDisplay: "number" as string,
127
134
  };
128
135
  },
129
136
  computed: {
@@ -132,35 +139,11 @@ export default defineComponent({
132
139
  ? this.$t("Podcast still available")
133
140
  : this.$t("Podcasts still available");
134
141
  },
135
- iFrameNumber: {
136
- get(): string {
137
- return this.iFrameNumberPriv;
138
- },
139
- set(value: string) {
140
- const val = parseInt(value, 10);
141
- if (!isNaN(val) && val >= 1 && val <= 50) {
142
- this.iFrameNumberPriv = value;
143
- }
144
- },
145
- },
146
142
  },
147
143
  watch: {
148
- episodeNumbers(): void {
149
- this.$emit("episodeNumbers", this.episodeNumbers);
150
- },
151
- iFrameNumberPriv(): void {
152
- this.$emit("iFrameNumber", this.iFrameNumberPriv);
144
+ episodeChoiceDisplay(): void {
145
+ this.$emit("episodeChoiceDisplay", this.episodeChoiceDisplay);
153
146
  },
154
147
  },
155
148
  });
156
- </script>
157
-
158
- <style lang="scss">
159
- .octopus-app {
160
- .input-share-player {
161
- border: 1px solid var(--octopus-border-default);
162
- border-radius: 50px;
163
- width: 60px;
164
- }
165
- }
166
- </style>
149
+ </script>
@@ -47,6 +47,8 @@
47
47
  v-model:proceed-reading="proceedReading"
48
48
  v-model:is-visible="isVisible"
49
49
  v-model:player-auto-play="playerAutoPlay"
50
+ v-model:episodes-number="episodesNumber"
51
+ v-model:insert-code="insertCode"
50
52
  :display-is-visible="displayIsVisible"
51
53
  :is-podcast-not-visible="isPodcastNotVisible"
52
54
  :chose-number-episode="choseNumberEpisodes"
@@ -54,13 +56,10 @@
54
56
  :display-transcript-param="displayTranscriptParam"
55
57
  :display-article-param="displayArticleParam"
56
58
  :display-wave-param="displayWaveParam"
57
- @i-frame-number="iFrameNumber = $event"
58
- @episode-numbers="episodeNumbers = $event"
59
- />
60
- <PlayerCommonParameters
61
- v-if="displayInsertCode"
62
- v-model:insert-code="insertCode"
59
+ :display-insert-code="displayInsertCode"
60
+ @episode-choice-display="episodeChoiceDisplay = $event"
63
61
  />
62
+
64
63
  <ShareModalPlayer
65
64
  v-if="isShareModal"
66
65
  :embed-link="iFrame"
@@ -102,9 +101,6 @@ const ShareModalPlayer = defineAsyncComponent(
102
101
  const PlayerParameters = defineAsyncComponent(
103
102
  () => import("./PlayerParameters.vue"),
104
103
  );
105
- const PlayerCommonParameters = defineAsyncComponent(
106
- () => import("./PlayerCommonParameters.vue"),
107
- );
108
104
  const SharePlayerTypes = defineAsyncComponent(
109
105
  () => import("./SharePlayerTypes.vue"),
110
106
  );
@@ -117,7 +113,6 @@ export default defineComponent({
117
113
  SharePlayerColors,
118
114
  PlayerParameters,
119
115
  SharePlayerTypes,
120
- PlayerCommonParameters,
121
116
  },
122
117
  props: {
123
118
  podcast: { default: undefined, type: Object as () => Podcast },
@@ -136,8 +131,8 @@ export default defineComponent({
136
131
  color: "#40a372" as string,
137
132
  theme: "#000000" as string,
138
133
  proceedReading: true as boolean,
139
- episodeNumbers: "number" as string,
140
- iFrameNumber: "3" as string,
134
+ episodeChoiceDisplay: "number" as string,
135
+ episodesNumber: 3 as number,
141
136
  isVisible: false as boolean,
142
137
  displayArticle: true as boolean,
143
138
  displayTranscript: true as boolean,
@@ -263,9 +258,9 @@ export default defineComponent({
263
258
  }
264
259
  let url = [""];
265
260
  const iFrameNumber =
266
- this.displayChoiceAllEpisodes && "all" === this.episodeNumbers
261
+ this.displayChoiceAllEpisodes && "all" === this.episodeChoiceDisplay
267
262
  ? "/0"
268
- : "/" + this.iFrameNumber;
263
+ : "/" + this.episodesNumber;
269
264
  url.push(`${this.miniplayerUrl}miniplayer/`);
270
265
  if (!this.podcast && !this.playlist && this.emission) {
271
266
  url = this.constructEmissionUrl(url);
@@ -334,9 +329,9 @@ export default defineComponent({
334
329
  }
335
330
  },
336
331
  getIframeNumber(): string {
337
- return this.displayChoiceAllEpisodes && "all" === this.episodeNumbers
332
+ return this.displayChoiceAllEpisodes && "all" === this.episodeChoiceDisplay
338
333
  ? "/0"
339
- : "/" + this.iFrameNumber;
334
+ : "/" + this.episodesNumber;
340
335
  },
341
336
  constructEmissionUrl(url: Array<string>) {
342
337
  if (!this.emission) {
@@ -4,19 +4,13 @@
4
4
  :class="{ 'form-margin': displayLabel }"
5
5
  >
6
6
  <div class="d-flex align-items-center">
7
- <label
8
- v-if="!isWysiwyg"
9
- class="form-label"
10
- :for="inputId"
11
- :class="displayLabel ? '' : 'd-none'"
12
- >{{ label }}</label
13
- >
14
- <div
15
- v-else
16
- class="form-label"
17
- :class="displayLabel ? '' : 'd-none'"
18
- >{{ label }}</div
19
- >
7
+ <component
8
+ :is="isWysiwyg? 'div': 'label'"
9
+ :class="[classLabel, displayLabel ? '' : 'd-none']"
10
+ :for="isWysiwyg ? '': inputId"
11
+ >{{ label }}
12
+ <AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="$t('Mandatory input')"/>
13
+ </component>
20
14
  <template v-if="popover">
21
15
  <button
22
16
  :id="'popover' + inputId"
@@ -54,6 +48,7 @@
54
48
  forceError || (isError && (undefined !== textValue || canBeNull)),
55
49
  }"
56
50
  :disabled="isDisable"
51
+ :required="!canBeNull"
57
52
  />
58
53
  <textarea
59
54
  v-else-if="isTextarea"
@@ -69,6 +64,7 @@
69
64
  forceError || (isError && (undefined !== textValue || canBeNull)),
70
65
  }"
71
66
  :disabled="isDisable"
67
+ :required="!canBeNull"
72
68
  />
73
69
  <ClassicWysiwyg
74
70
  v-else
@@ -110,6 +106,7 @@
110
106
  </div>
111
107
  </template>
112
108
  <script lang="ts">
109
+ import AsteriskIcon from "vue-material-design-icons/Asterisk.vue";
113
110
  import HelpCircleIcon from "vue-material-design-icons/HelpCircle.vue";
114
111
  import { defineAsyncComponent, defineComponent } from "vue";
115
112
  const ClassicPopover = defineAsyncComponent(
@@ -127,6 +124,7 @@ export default defineComponent({
127
124
  ClassicPopover,
128
125
  ClassicEmojiPicker,
129
126
  HelpCircleIcon,
127
+ AsteriskIcon
130
128
  },
131
129
  props: {
132
130
  inputId: { default: "", type: String },
@@ -153,6 +151,8 @@ export default defineComponent({
153
151
  popoverRelativeClass: { default: undefined, type: String },
154
152
  forceReload: { default: false, type: Boolean },
155
153
  typeInput: { default: "text", type: String },
154
+ displayRequired: { default: false, type: Boolean },
155
+ classLabel: { default: "form-label", type: String },
156
156
  },
157
157
  emits: ["update:textInit", "update:errorVariable"],
158
158
  data() {
@@ -9,7 +9,9 @@
9
9
  >
10
10
  <label :class="displayLabel ? '' : 'd-none'" :for="id" class="form-label">{{
11
11
  label
12
- }}</label>
12
+ }}
13
+ <AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="$t('Mandatory input')"/>
14
+ </label>
13
15
  <vSelect
14
16
  v-model="optionSelected"
15
17
  :input-id="id"
@@ -74,12 +76,14 @@
74
76
  </template>
75
77
 
76
78
  <script lang="ts">
79
+ import AsteriskIcon from "vue-material-design-icons/Asterisk.vue";
77
80
  import ChevronDownIcon from "vue-material-design-icons/ChevronDown.vue";
78
81
  import vSelect from "vue-select";
79
82
  export default {
80
83
  components: {
81
84
  vSelect,
82
85
  ChevronDownIcon,
86
+ AsteriskIcon
83
87
  },
84
88
  props: {
85
89
  id: { default: "", type: String },
@@ -100,6 +104,7 @@ export default {
100
104
  maxOptions: { default: null, type: Number },
101
105
  allowEmpty: { default: true, type: Boolean },
102
106
  textDanger :{ default: undefined, type: String },
107
+ displayRequired: { default: false, type: Boolean },
103
108
  },
104
109
 
105
110
  emits: ["onSearch", "selected", "onClose"],
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="d-flex" :class="isColumn ? 'flex-column' : ''">
2
+ <div role="radiogroup" class="d-flex" :class="isColumn ? 'flex-column' : ''">
3
3
  <div
4
4
  v-for="option in options"
5
5
  :key="option.title"
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div class="d-flex flex-column">
3
- <div v-if="radioLabel" :class="classLabel">{{ radioLabel }}</div>
2
+ <component :is="typeTag" class="d-flex flex-column">
3
+ <component :is="'fieldset'===typeTag ? 'legend': 'div'" v-if="radioLabel" :class="classLabel">{{ radioLabel }}</component>
4
4
  <ClassicRadio
5
5
  :id-radio="idRadio"
6
6
  :is-disabled="isDisabled"
@@ -9,7 +9,7 @@
9
9
  :is-column="isColumn"
10
10
  @update:text-init="$emit('update:textInit', $event)"
11
11
  />
12
- </div>
12
+ </component>
13
13
  </template>
14
14
 
15
15
  <script lang="ts">
@@ -32,6 +32,7 @@ export default defineComponent({
32
32
  isColumn: { default: true, type: Boolean },
33
33
  radioLabel: { default: undefined, type: String },
34
34
  classLabel: { default: "form-label", type: String },
35
+ typeTag: { default: "div", type: String },
35
36
  },
36
37
  emits: ["update:textInit"]
37
38
  });
@@ -2,7 +2,8 @@
2
2
  <div class="classic-select" :class="{ 'form-margin': displayLabel }">
3
3
  <label v-show="displayLabel" :for="idSelect" :class="classLabel">{{
4
4
  label
5
- }}</label>
5
+ }}
6
+ <AsteriskIcon v-if="displayRequired" :size="10" class="ms-1 mb-2" :title="$t('Mandatory input')"/></label>
6
7
  <select
7
8
  :id="idSelect"
8
9
  :value="textInit"
@@ -11,6 +12,7 @@
11
12
  :class="transparent ? 'transparent' : ''"
12
13
  :style="getFontFamily"
13
14
  :aria-label="label"
15
+ :required="displayRequired"
14
16
  @change="$emit('update:textInit', $event.target.value)"
15
17
  >
16
18
  <option v-if="placeholder" value="" disabled selected>{{ placeholder }}</option>
@@ -27,9 +29,13 @@
27
29
  </div>
28
30
  </template>
29
31
  <script lang="ts">
32
+ import AsteriskIcon from "vue-material-design-icons/Asterisk.vue";
30
33
  import { defineComponent } from "vue";
31
34
  export default defineComponent({
32
35
  name: "ClassicSelect",
36
+ components:{
37
+ AsteriskIcon
38
+ },
33
39
  props: {
34
40
  idSelect: { default: "", type: String },
35
41
  label: { default: "", type: String },
@@ -54,6 +60,7 @@ export default defineComponent({
54
60
  classLabel: { default: "form-label", type: String },
55
61
  orderOptions: { default: true, type: Boolean},
56
62
  placeholder: { default: undefined, type: String},
63
+ displayRequired: { default: false, type: Boolean },
57
64
  },
58
65
  emits: ["update:textInit"],
59
66
  computed: {
@@ -173,7 +173,6 @@ export default defineComponent({
173
173
  }
174
174
  this.show = true;
175
175
  let parentLeft = 0;
176
- let parentRight = 0;
177
176
  let parentTop = 0;
178
177
  let parentScrollTop = 0;
179
178
  let parentBottom = 0;
@@ -190,7 +189,6 @@ export default defineComponent({
190
189
  }
191
190
  const modalBodyRect = modalBody.getBoundingClientRect();
192
191
  parentLeft = modalBodyRect.left;
193
- parentRight = modalBodyRect.right;
194
192
  parentTop = modalBodyRect.top;
195
193
  parentScrollTop = modalBody.scrollTop;
196
194
  parentBottom=modalBodyRect.bottom;
@@ -2,6 +2,7 @@
2
2
  <footer
3
3
  id="footer"
4
4
  ref="footer"
5
+ role="contentinfo"
5
6
  class="d-flex align-items-center justify-content-between border-top mt-auto"
6
7
  >
7
8
  <div v-if="!isPodcastmaker" class="d-flex flex-column px-1">
@@ -9,7 +10,7 @@
9
10
  &copy; Saooti 2025
10
11
  </div>
11
12
  <FooterGarSection v-if="isGarRole" :auth-orga-id="authOrgaId" />
12
- <nav :aria-label="$t('Site menu')">
13
+ <nav role="navigation" :aria-label="$t('Site menu')">
13
14
  <ul class="p-0 m-0">
14
15
  <li
15
16
  v-for="link in routerLinkSecondArray"
@@ -211,7 +212,7 @@ export default defineComponent({
211
212
  <style lang="scss">
212
213
  .octopus-app {
213
214
  #footer {
214
- font-size: 0.6rem;
215
+ font-size: max(0.6rem, 12px);
215
216
  bottom: 0;
216
217
  z-index: 10;
217
218
  background: white;
@@ -32,7 +32,7 @@
32
32
  :left-pos="true"
33
33
  :is-top-layer="true"
34
34
  >
35
- <nav :aria-label="$t('User menu')">
35
+ <nav role="navigation" :aria-label="$t('User menu')">
36
36
  <ul class="p-0 m-0">
37
37
  <template v-if="!isAuthenticated">
38
38
  <li class="li-style-none">
@@ -70,22 +70,23 @@
70
70
  </a>
71
71
  </template>
72
72
  <div class="d-flex align-items-center justify-content-end flex-grow-1">
73
- <nav :aria-label="$t('Site menu')">
73
+ <nav role="navigation" :aria-label="$t('Site menu')">
74
74
  <ul class="d-flex">
75
- <li v-for="link in routerLinkArray" :key="link.routeName" class="li-style-none">
76
- <router-link
77
- v-show="!isPhone"
78
- v-if="link.condition"
79
- :to="{
80
- name: link.routeName,
81
- query: getQueriesRouter(link.routeName),
82
- }"
83
- class="link-hover py-2 px-3"
84
- >
85
- {{ link.title }}
86
- </router-link>
87
- </li>
88
- </ul>
75
+ <template v-for="link in routerLinkArray" :key="link.routeName">
76
+ <li v-if="link.condition" class="li-style-none">
77
+ <router-link
78
+ v-show="!isPhone"
79
+ :to="{
80
+ name: link.routeName,
81
+ query: getQueriesRouter(link.routeName),
82
+ }"
83
+ class="link-hover py-2 px-3"
84
+ >
85
+ {{ link.title }}
86
+ </router-link>
87
+ </li>
88
+ </template>
89
+ </ul>
89
90
  </nav>
90
91
  <button
91
92
  v-show="!isPhone && !inContentDisplayPage"
@@ -105,24 +106,24 @@
105
106
  :left-pos="true"
106
107
  :is-top-layer="true"
107
108
  >
108
- <nav class="d-flex flex-column" :aria-label="$t('Site menu')">
109
+ <nav role="navigation" class="d-flex flex-column" :aria-label="$t('Site menu')">
109
110
  <ul class="p-0 m-0">
110
- <li
111
- v-for="link in routerLinkInsideArray"
112
- :key="link.routeName"
113
- class="li-style-none"
114
- >
115
- <router-link
111
+ <template v-for="link in routerLinkInsideArray" :key="link.routeName">
112
+ <li
116
113
  v-if="link.condition"
117
- :to="{
118
- name: link.routeName,
119
- query: getQueriesRouter(link.routeName),
120
- }"
121
- class="p-1 octopus-dropdown-item"
114
+ class="li-style-none"
122
115
  >
123
- {{ link.title }}
124
- </router-link>
125
- </li>
116
+ <router-link
117
+ :to="{
118
+ name: link.routeName,
119
+ query: getQueriesRouter(link.routeName),
120
+ }"
121
+ class="p-1 octopus-dropdown-item"
122
+ >
123
+ {{ link.title }}
124
+ </router-link>
125
+ </li>
126
+ </template>
126
127
  </ul>
127
128
  </nav>
128
129
  </ClassicPopover>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <section class="page-box map-page">
3
3
  <component :is="titleTag">{{ $t("Site map") }}</component>
4
- <nav :aria-label="$t('Site menu')" class="d-flex flex-column align-items-center">
4
+ <nav role="navigation" :aria-label="$t('Site menu')" class="d-flex flex-column align-items-center">
5
5
  <ul class="my-1">
6
6
  <template v-for="linkItem in siteMap" :key="linkItem.id">
7
7
  <li v-if="linkItem.condition" :id="linkItem.id" class="my-1">
package/src/locale/de.ts CHANGED
@@ -406,4 +406,5 @@ export default {
406
406
  "The episode is being processed":"Die Episode wird bearbeitet",
407
407
  Rubrics: "Rubriken",
408
408
  "New window":"{text} - Neues Fenster",
409
+ "Mandatory input":"Pflichteingabe",
409
410
  }
package/src/locale/en.ts CHANGED
@@ -407,4 +407,5 @@ export default {
407
407
  "The episode is being processed":"The episode is being processed",
408
408
  Rubrics: "Rubrics",
409
409
  "New window":"{text} - New window",
410
+ "Mandatory input":"Mandatory input",
410
411
  };
package/src/locale/es.ts CHANGED
@@ -407,4 +407,5 @@ export default {
407
407
  "The episode is being processed":"El episodio está siendo procesado",
408
408
  Rubrics: "Secciones",
409
409
  "New window":"{text} - Nueva ventana",
410
+ "Mandatory input":"Entrada obligatoria",
410
411
  }
package/src/locale/fr.ts CHANGED
@@ -414,4 +414,5 @@ export default {
414
414
  "The episode is being processed":"L'épisode est en cours de traitement",
415
415
  Rubrics: "Rubriques",
416
416
  "New window":"{text} - Nouvelle fenêtre",
417
+ "Mandatory input":"Saisie obligatoire",
417
418
  };
package/src/locale/it.ts CHANGED
@@ -401,4 +401,5 @@ export default{
401
401
  "The episode is being processed":"L'episodio è in fase di elaborazione",
402
402
  Rubrics: "Rubriche",
403
403
  "New window":"{text} - Nuova finestra",
404
+ "Mandatory input":"Ingresso obbligatorio",
404
405
  };
package/src/locale/sl.ts CHANGED
@@ -397,4 +397,5 @@ export default {
397
397
  "The episode is being processed":"Epizoda je v obdelavi",
398
398
  Rubrics: "Rubrike",
399
399
  "New window":"{text} - Novo okno",
400
+ "Mandatory input":"Obvezen vnos",
400
401
  }
@@ -179,6 +179,8 @@ $utilities: map.merge(
179
179
  values: (
180
180
  grow-0: 0,
181
181
  grow-1: 1,
182
+ grow-2: 2,
183
+ grow-3: 3,
182
184
  )
183
185
  ),
184
186
  "flex-shrink": (
@@ -1,6 +1,11 @@
1
1
 
2
2
 
3
3
  .octopus-app{
4
+ fieldset{
5
+ border-color: var(--octopus-secondary-lighter);
6
+ border-style: solid;
7
+ padding: 1rem;
8
+ }
4
9
  .octopus-form-item{
5
10
  min-height: 1.44rem;
6
11
  padding: 0.4rem 0;
@@ -11,7 +16,7 @@
11
16
  }
12
17
 
13
18
  .form-label {
14
- display: block;
19
+ display: flex;
15
20
  line-height: 1.2rem;
16
21
  padding: 0.5rem 0 0;
17
22
  color: black;
@@ -234,7 +234,6 @@
234
234
  border-radius:var(--octopus-border-radius);
235
235
  display: flex;
236
236
  width: 100%;
237
- padding: 1rem 2rem;
238
237
  margin-bottom: 1rem;
239
238
  justify-content: space-around;
240
239