@saooti/octopus-sdk 41.0.18 → 41.0.20

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 (37) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/index.ts +4 -0
  3. package/package.json +31 -31
  4. package/src/components/composable/route/types.ts +47 -0
  5. package/src/components/composable/route/useAdvancedParamInit.ts +29 -4
  6. package/src/components/composable/route/useRouteUpdateParams.ts +9 -19
  7. package/src/components/composable/route/useSimplePageParam.ts +6 -4
  8. package/src/components/display/emission/EmissionList.vue +6 -2
  9. package/src/components/display/filter/AdvancedSearch.vue +237 -170
  10. package/src/components/display/list/SwiperList.vue +15 -2
  11. package/src/components/display/playlist/PodcastList.vue +0 -1
  12. package/src/components/display/podcasts/PodcastImage.vue +4 -4
  13. package/src/components/display/podcasts/PodcastItem.vue +1 -4
  14. package/src/components/display/podcasts/PodcastList.vue +4 -2
  15. package/src/components/display/podcasts/PodcastModuleBox.vue +24 -6
  16. package/src/components/display/podcasts/PodcastPlayButton.vue +3 -5
  17. package/src/components/display/podcasts/TagList.vue +2 -2
  18. package/src/components/form/ClassicInputText.vue +1 -0
  19. package/src/components/form/ClassicMultiselect.vue +1 -0
  20. package/src/components/form/ClassicRadio.vue +29 -6
  21. package/src/components/form/ClassicTagInput.vue +155 -0
  22. package/src/components/misc/ClassicPopover.vue +1 -1
  23. package/src/components/pages/EmissionPage.vue +10 -0
  24. package/src/components/pages/EmissionsPage.vue +66 -61
  25. package/src/components/pages/PodcastsPage.vue +71 -66
  26. package/src/helper/durationHelper.ts +37 -19
  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 +2 -1
  31. package/src/locale/it.ts +1 -0
  32. package/src/locale/sl.ts +1 -0
  33. package/src/router/router.ts +4 -0
  34. package/src/stores/AuthStore.ts +4 -0
  35. package/src/stores/class/general/emission.ts +2 -0
  36. package/src/stores/class/general/podcast.ts +2 -0
  37. package/src/style/general.scss +18 -14
@@ -1,84 +1,113 @@
1
1
  <template>
2
- <div id="advanced-search" class="d-flex flex-column justify-content-center align-items-center">
3
- <button
4
- class="d-flex justify-content-center align-items-center mb-3 text-secondary btn-transparent"
5
- @click="clickShowFilters"
6
- >
7
- <div>{{ t("Advanced filters") }}</div>
8
- <ChevronDownIcon :class="{ 'arrow-transform': showFilters }" />
9
- </button>
10
- <Transition name="advanced-search">
11
- <div
12
- v-if="firstLoaded"
13
- v-show="showFilters"
14
- class="advanced-search-container"
15
- >
16
- <fieldset class="d-flex flex-column flex-grow-3">
17
- <legend class="text-primary mb-2">
18
- {{ t("Filter") }}
19
- </legend>
20
- <MonetizableFilter
21
- v-if="!isPodcastmaker && !generalStore.platformEducation"
22
- :is-emission="isEmission"
23
- :monetisable="monetisable"
24
- @update:monetisable="updateMonetisable"
25
- />
26
- <CategorySearchFilter :iab-id="iabId" @update:iab-id="updateIab" />
27
- <RubriqueFilter
28
- :rubrique-filter="rubriqueFilter"
29
- @update:rubrique-filter="updateRubriquageFilter"
30
- />
31
- <DateFilter
32
- :is-emission="isEmission"
33
- :from-date="fromDate"
34
- :to-date="toDate"
35
- @update-dates="updateDates($event)"
36
- />
37
- <div
38
- v-if="organisation && organisationRight && !isPodcastmaker"
39
- class="d-flex flex-column mt-3"
2
+ <div id="advanced-search" class="d-flex flex-column justify-content-center align-items-center">
3
+ <!-- Button to open the advanced filters -->
4
+ <button
5
+ class="d-flex justify-content-center align-items-center mb-3 text-secondary btn-transparent"
6
+ @click="clickShowFilters"
40
7
  >
41
- <ClassicCheckbox
42
- :text-init="includeHidden"
43
- class="flex-shrink-0"
44
- id-checkbox="search-future-checkbox"
45
- :label="textNotVisible"
46
- :is-disabled="isSelectValidity && 'true'!==validity"
47
- @update:text-init="updateIncludeHidden"
48
- />
49
- </div>
50
- <ClassicSelect
51
- v-if="isSelectValidity"
52
- :text-init="validity"
53
- id-select="valid-episodes-select"
54
- :label="t('Episodes to validate')+' :'"
55
- :display-label="true"
56
- class-label="flex-shrink-0 me-1"
57
- class="d-flex align-items-center mt-3 mb-0"
58
- :options="[
59
- { title: t('Display only episodes to validate'), value: 'false' },
60
- { title: t('Display episodes to validate'), value: '' },
61
- { title: t('Do not display episodes to validate'), value: 'true' },
62
- ]"
63
- @update:text-init="updateValidity"
64
- />
65
- <ClassicCheckbox
66
- v-if="!isEmission"
67
- :text-init="onlyVideo"
68
- class="flex-shrink-0 mt-3"
69
- id-checkbox="only-video-checkbox"
70
- :label="t('Show only episodes with video')"
71
- @update:text-init="updateOnlyVideo"
72
- />
73
- </fieldset>
74
- <SearchOrder
75
- :is-emission="isEmission"
76
- :sort="sort"
77
- @update:sort="updateSort"
78
- />
8
+ <div>{{ t("Advanced filters") }}</div>
9
+ <ChevronDownIcon :class="{ 'arrow-transform': showFilters }" />
10
+ </button>
11
+
12
+ <!-- Filters -->
13
+ <Transition name="advanced-search">
14
+ <div
15
+ v-if="firstLoaded"
16
+ v-show="showFilters"
17
+ class="advanced-search-container"
18
+ >
19
+ <fieldset class="d-flex flex-column flex-grow-3">
20
+ <legend class="text-primary mb-2">
21
+ {{ t("Filter") }}
22
+ </legend>
23
+ <MonetizableFilter
24
+ v-if="!isPodcastmaker && !generalStore.platformEducation"
25
+ :is-emission="isEmission"
26
+ :monetisable="monetisable"
27
+ @update:monetisable="updateMonetisable"
28
+ />
29
+ <CategorySearchFilter :iab-id="iabId" @update:iab-id="updateIab" />
30
+ <RubriqueFilter
31
+ :rubrique-filter="rubriqueFilter"
32
+ @update:rubrique-filter="updateRubriquageFilter"
33
+ />
34
+
35
+ <!-- Date -->
36
+ <DateFilter
37
+ :is-emission="isEmission"
38
+ :from-date="fromDate"
39
+ :to-date="toDate"
40
+ @update-dates="updateDates($event)"
41
+ />
42
+
43
+ <!-- Rights holders/beneficiaries -->
44
+ <div v-if="beneficiariesEnabled" class="mt-3 d-flex">
45
+ <ClassicCheckbox
46
+ :text-init="beneficiaries !== null && beneficiaries !== undefined"
47
+ class="flex-shrink-0"
48
+ id-checkbox="search-beneficiaries-checkbox"
49
+ :label="t('Filters - Beneficiaries')"
50
+ @update:text-init="updateBeneficiariesCheckbox"
51
+ />
52
+
53
+ <ClassicTagInput
54
+ v-if="beneficiaries !== null && beneficiaries !== undefined"
55
+ class="ms-4 flex-grow-1"
56
+ :tags="beneficiaries"
57
+ @update:tags="updateBeneficiaries"
58
+ />
59
+ </div>
60
+
61
+ <div
62
+ v-if="organisation && organisationRight && !isPodcastmaker"
63
+ class="d-flex flex-column mt-3"
64
+ >
65
+ <ClassicCheckbox
66
+ :text-init="includeHidden"
67
+ class="flex-shrink-0"
68
+ id-checkbox="search-future-checkbox"
69
+ :label="textNotVisible"
70
+ :is-disabled="isSelectValidity && 'true'!==validity"
71
+ @update:text-init="updateIncludeHidden"
72
+ />
73
+ </div>
74
+
75
+ <ClassicSelect
76
+ v-if="isSelectValidity"
77
+ :text-init="validity"
78
+ id-select="valid-episodes-select"
79
+ :label="t('Episodes to validate')+' :'"
80
+ :display-label="true"
81
+ class-label="flex-shrink-0 me-1"
82
+ class="d-flex align-items-center mt-3 mb-0"
83
+ :options="[
84
+ { title: t('Display only episodes to validate'), value: 'false' },
85
+ { title: t('Display episodes to validate'), value: '' },
86
+ { title: t('Do not display episodes to validate'), value: 'true' },
87
+ ]"
88
+ @update:text-init="updateValidity"
89
+ />
90
+
91
+ <!-- Only with video -->
92
+ <ClassicCheckbox
93
+ v-if="!isEmission"
94
+ :text-init="onlyVideo"
95
+ class="flex-shrink-0 mt-3"
96
+ id-checkbox="only-video-checkbox"
97
+ :label="t('Show only episodes with video')"
98
+ @update:text-init="updateOnlyVideo"
99
+ />
100
+ </fieldset>
101
+
102
+ <!-- Sort -->
103
+ <SearchOrder
104
+ :is-emission="isEmission"
105
+ :sort="sort"
106
+ @update:sort="updateSort"
107
+ />
108
+ </div>
109
+ </Transition>
79
110
  </div>
80
- </Transition>
81
- </div>
82
111
  </template>
83
112
 
84
113
  <script setup lang="ts">
@@ -92,53 +121,60 @@ import { defineAsyncComponent, ref, computed, watch } from "vue";
92
121
  import { useGeneralStore } from "../../../stores/GeneralStore";
93
122
  import { useI18n } from "vue-i18n";
94
123
  const MonetizableFilter = defineAsyncComponent(
95
- () => import("./MonetizableFilter.vue"),
124
+ () => import("./MonetizableFilter.vue"),
96
125
  );
97
126
  const CategorySearchFilter = defineAsyncComponent(
98
- () => import("./CategorySearchFilter.vue"),
127
+ () => import("./CategorySearchFilter.vue"),
99
128
  );
100
129
  const RubriqueFilter = defineAsyncComponent(
101
- () => import("./RubriqueFilter.vue"),
130
+ () => import("./RubriqueFilter.vue"),
102
131
  );
103
132
  const ClassicSelect = defineAsyncComponent(
104
- () => import("../../form/ClassicSelect.vue"),
133
+ () => import("../../form/ClassicSelect.vue"),
134
+ );
135
+ const ClassicTagInput = defineAsyncComponent(
136
+ () => import("../../form/ClassicTagInput.vue"),
105
137
  );
106
138
  const ClassicCheckbox = defineAsyncComponent(
107
- () => import("../../form/ClassicCheckbox.vue"),
139
+ () => import("../../form/ClassicCheckbox.vue"),
108
140
  );
109
141
  const DateFilter = defineAsyncComponent(() => import("./DateFilter.vue"));
110
142
  const SearchOrder = defineAsyncComponent(() => import("./SearchOrder.vue"));
143
+ import { ROUTE_PARAMS } from '../../composable/route/types';
111
144
 
112
145
  //Props
113
146
  const props = defineProps({
114
- organisationId: { default: undefined, type: String },
115
- isEmission: { default: false, type: Boolean },
116
- includeHidden: { default: false, type: Boolean },
117
- sort: { default: "DATE", type: String },
118
- onlyVideo: { default: false, type: Boolean },
119
- monetisable: { default: "UNDEFINED", type: String },
120
- iabId: { default: undefined, type: Number },
121
- searchPattern: { default: "", type: String },
122
- fromDate: { default: undefined, type: String },
123
- toDate: { default: undefined, type: String },
124
- validity: { default: 'true', type: String },
125
- rubriqueFilter: {
126
- default: () => [],
127
- type: Array as () => Array<RubriquageFilter>,
128
- },
147
+ organisationId: { default: undefined, type: String },
148
+ isEmission: { default: false, type: Boolean },
149
+ includeHidden: { default: false, type: Boolean },
150
+ sort: { default: "DATE", type: String },
151
+ onlyVideo: { default: false, type: Boolean },
152
+ monetisable: { default: "UNDEFINED", type: String },
153
+ iabId: { default: undefined, type: Number },
154
+ searchPattern: { default: "", type: String },
155
+ fromDate: { default: undefined, type: String },
156
+ toDate: { default: undefined, type: String },
157
+ validity: { default: 'true', type: String },
158
+ /** The filter on beneficiaries */
159
+ beneficiaries: { default: null, type: Array as () => Array<string> },
160
+ rubriqueFilter: {
161
+ default: () => [],
162
+ type: Array as () => Array<RubriquageFilter>,
163
+ },
129
164
  })
130
165
 
131
166
  //Emits
132
167
  const emit = defineEmits([
133
- "update:toDate",
134
- "update:fromDate",
135
- "update:monetisable",
136
- "update:iabId",
137
- "update:sort",
138
- "update:includeHidden",
139
- "update:validity",
140
- "update:rubriqueFilter",
141
- "update:onlyVideo",
168
+ "update:toDate",
169
+ "update:fromDate",
170
+ "update:monetisable",
171
+ "update:iabId",
172
+ "update:sort",
173
+ "update:includeHidden",
174
+ "update:validity",
175
+ "update:rubriqueFilter",
176
+ "update:onlyVideo",
177
+ "update:beneficiaries"
142
178
  ]);
143
179
 
144
180
  //Data
@@ -160,96 +196,127 @@ const organisationRight = computed(() => isEditRights(props.organisationId));
160
196
  const organisation = computed(() => props.organisationId ?? filterStore.filterOrgaId);
161
197
  const textNotVisible = computed(() => props.isEmission ? t("Consider podcasts no visible"): t("See podcasts no visible"));
162
198
  const isSelectValidity = computed(() => {
163
- return (
164
- undefined !== organisation.value &&
165
- organisationRight.value &&
166
- authStore.isRoleContribution &&
167
- !isPodcastmaker &&
168
- !props.isEmission &&
169
- props.includeHidden
170
- );
199
+ return (
200
+ undefined !== organisation.value &&
201
+ organisationRight.value &&
202
+ authStore.isRoleContribution &&
203
+ !isPodcastmaker &&
204
+ !props.isEmission &&
205
+ props.includeHidden
206
+ );
207
+ });
208
+ /** The beneficiaries filter is only displayed if beneficiaries are enabled */
209
+ const beneficiariesEnabled = computed(() => {
210
+ return authStore.authOrganisation.attributes['beneficiaries.enabled'] === 'true';
171
211
  });
172
-
173
212
 
174
213
  //Watch
175
214
  watch(organisation, async () => {
176
- const hidden = undefined !== organisation.value && organisationRight.value && !props.isEmission;
177
- if (hidden !== props.includeHidden) {
178
- updateIncludeHidden(hidden);
179
- }
215
+ const hidden = undefined !== organisation.value && organisationRight.value && !props.isEmission;
216
+ if (hidden !== props.includeHidden) {
217
+ updateIncludeHidden(hidden);
218
+ }
180
219
  });
220
+
181
221
  watch(()=>props.searchPattern, (value: string) => {
182
- const search = value.trim();
183
- let valSort = "SCORE"
184
- if(search.length <= 3){
185
- valSort = props.isEmission? "LAST_PODCAST_DESC" : "DATE";
186
- }
187
- updateRouteParamAdvanced({
188
- q: search.length ? search : undefined,
189
- s: valSort,
190
- });
222
+ const search = value.trim();
223
+ let valSort = "SCORE"
224
+ if(search.length <= 3){
225
+ valSort = props.isEmission? "LAST_PODCAST_DESC" : "DATE";
226
+ }
227
+ updateRouteParamAdvanced({
228
+ q: search.length ? search : undefined,
229
+ s: valSort,
230
+ });
191
231
  });
192
232
 
193
233
  //Methods
194
234
  function updateMonetisable(value: string): void {
195
- emit("update:monetisable", value);
196
- updateRouteParamAdvanced({ m: "UNDEFINED" !== value ? value : undefined });
235
+ emit("update:monetisable", value);
236
+ updateRouteParamAdvanced({ m: "UNDEFINED" !== value ? value : undefined });
197
237
  }
238
+
198
239
  function updateIab(value: number | undefined) {
199
- emit("update:iabId", 0 !== value ? value : undefined);
200
- let filterIab = {};
201
- if (filterStore.filterIab && filterStore.filterIab.id !== value) {
202
- filterIab = { iabId: undefined };
203
- }
204
- updateRouteParamAdvanced({
205
- ...{ i: value ? value.toString() : undefined },
206
- ...filterIab,
207
- });
240
+ emit("update:iabId", 0 !== value ? value : undefined);
241
+ let filterIab = {};
242
+ if (filterStore.filterIab && filterStore.filterIab.id !== value) {
243
+ filterIab = { iabId: undefined };
244
+ }
245
+ updateRouteParamAdvanced({
246
+ ...{ i: value ? value.toString() : undefined },
247
+ ...filterIab,
248
+ });
208
249
  }
250
+
209
251
  function updateSort(value: string) {
210
- emit("update:sort", value);
211
- updateRouteParamAdvanced({ s: value });
252
+ emit("update:sort", value);
253
+ updateRouteParamAdvanced({ s: value });
212
254
  }
255
+
213
256
  function updateIncludeHidden(value: boolean) {
214
- emit("update:includeHidden", value);
215
- updateRouteParamAdvanced({ h: value.toString() });
257
+ emit("update:includeHidden", value);
258
+ updateRouteParamAdvanced({ h: value.toString() });
216
259
  }
260
+
217
261
  function updateValidity(value: boolean) {
218
- emit("update:validity", value);
219
- updateRouteParamAdvanced({ vl: value.toString() });
262
+ emit("update:validity", value);
263
+ updateRouteParamAdvanced({ vl: value.toString() });
220
264
  }
265
+
221
266
  function updateOnlyVideo(value: boolean) {
222
- emit("update:onlyVideo", value);
223
- updateRouteParamAdvanced({ v: value ? "true" : undefined });
267
+ emit("update:onlyVideo", value);
268
+ updateRouteParamAdvanced({ v: value ? "true" : undefined });
224
269
  }
270
+
225
271
  function updateDates(value: {
226
- from: string | undefined;
227
- to: string | undefined;
272
+ from: string | undefined;
273
+ to: string | undefined;
228
274
  }): void {
229
- emit("update:fromDate", value.from);
230
- emit("update:toDate", value.to);
231
- updateRouteParamAdvanced({ from: value.from, to: value.to });
275
+ emit("update:fromDate", value.from);
276
+ emit("update:toDate", value.to);
277
+ updateRouteParamAdvanced({ from: value.from, to: value.to });
232
278
  }
279
+
233
280
  function updateRubriquageFilter(value: Array<RubriquageFilter>) {
234
- emit("update:rubriqueFilter", value);
235
- let filterRubriques = {};
236
- const valueString = stringifyRubriquesFilter(value);
237
- if (
238
- filterStore.filterRubrique.length &&
239
- stringifyRubriquesFilter(filterStore.filterRubrique) !== valueString
240
- ) {
241
- filterRubriques = { rubriquesId: undefined };
242
- }
243
- updateRouteParamAdvanced({
244
- ...{ r: valueString.length ? valueString : undefined },
245
- ...filterRubriques,
246
- });
281
+ emit("update:rubriqueFilter", value);
282
+ let filterRubriques = {};
283
+ const valueString = stringifyRubriquesFilter(value);
284
+ if (
285
+ filterStore.filterRubrique.length &&
286
+ stringifyRubriquesFilter(filterStore.filterRubrique) !== valueString
287
+ ) {
288
+ filterRubriques = { rubriquesId: undefined };
289
+ }
290
+ updateRouteParamAdvanced({
291
+ ...{ r: valueString.length ? valueString : undefined },
292
+ ...filterRubriques,
293
+ });
247
294
  }
295
+
296
+ /** Update the beneficiaries filter */
297
+ function updateBeneficiaries(value: string[]|undefined): void {
298
+ emit('update:beneficiaries', value);
299
+ if (value === undefined) {
300
+ updateRouteParamAdvanced({ [ROUTE_PARAMS.Beneficiaries]: undefined });
301
+ } else {
302
+ updateRouteParamAdvanced({ [ROUTE_PARAMS.Beneficiaries]: value });
303
+ }
304
+ }
305
+
306
+ /** Update the value of the beneficiaries checkbox */
307
+ function updateBeneficiariesCheckbox(value: boolean): void {
308
+ if (value === true) {
309
+ emit('update:beneficiaries', []);
310
+ } else {
311
+ updateBeneficiaries(undefined);
312
+ }
313
+ }
314
+
248
315
  function clickShowFilters(): void {
249
- if (!firstLoaded.value) {
250
- firstLoaded.value = true;
251
- }
252
- showFilters.value = !showFilters.value;
316
+ if (!firstLoaded.value) {
317
+ firstLoaded.value = true;
318
+ }
319
+ showFilters.value = !showFilters.value;
253
320
  }
254
321
  </script>
255
322
 
@@ -5,9 +5,11 @@
5
5
  :key="manualReload"
6
6
  :slides-per-view="numberItem"
7
7
  :space-between="0"
8
- :loop="true"
8
+ :loop="loop"
9
9
  :slides-offset-before="offsetSwiper"
10
10
  :slides-offset-after="offsetSwiper"
11
+ :allow-slide-next="loop"
12
+ :allow-slide-prev="loop"
11
13
  :navigation="true"
12
14
  :modules="modules"
13
15
  @slides-updated="slidesUpdated"
@@ -44,7 +46,6 @@ const props = defineProps({
44
46
 
45
47
  //Data
46
48
  const manualReload = ref(0);
47
- const modules = ref([Navigation]);
48
49
  const numberItem = ref(5);
49
50
  const offsetSwiper = ref(40);
50
51
  const widthSwiperUsable = ref(0);
@@ -71,6 +72,18 @@ const sizeItem = computed(() => {
71
72
  });
72
73
  const itemRecalculizedSize = computed(() => widthSwiperUsable.value / numberItem.value);
73
74
 
75
+ /** Indicates that the swiper should loop */
76
+ const loop = computed((): boolean => {
77
+ return (props.listObject.length > numberItem.value);
78
+ });
79
+
80
+ const modules = computed(() => {
81
+ if (loop.value === true) {
82
+ return [Navigation];
83
+ } else {
84
+ return [];
85
+ }
86
+ });
74
87
 
75
88
  //Watch
76
89
  watch(windowWidth, () => onWindowResize());
@@ -47,7 +47,6 @@
47
47
  <PodcastItem
48
48
  v-if="0 !== p.podcastId"
49
49
  :podcast="p"
50
- :in-list="true"
51
50
  />
52
51
 
53
52
  <template #preview>
@@ -47,7 +47,7 @@
47
47
  :podcast="podcast"
48
48
  :hide-play="hidePlay"
49
49
  :fetch-conference="fetchConference"
50
- :in-list="inList"
50
+ :show-processing="isAuthenticated"
51
51
  />
52
52
  <button
53
53
  v-if="displayDescription && isMobile"
@@ -69,6 +69,7 @@ import { Conference } from "@/stores/class/conference/conference";
69
69
  import {useImageProxy} from "../../composable/useImageProxy";
70
70
  import { computed, onBeforeMount, ref, watch } from "vue";
71
71
  import { useI18n } from "vue-i18n";
72
+ import { useAuthStore } from "../../../stores/AuthStore";
72
73
 
73
74
  //Props
74
75
  const props = defineProps({
@@ -77,9 +78,7 @@ const props = defineProps({
77
78
  displayDescription: { default: false, type: Boolean },
78
79
  arrowDirection: { default: "up", type: String },
79
80
  isAnimatorLive: { default: false, type: Boolean },
80
- fetchConference: { default: undefined, type: Object as () => Conference },
81
- /** Indicates that the podcast is displayed in a list */
82
- inList: { default: false, type: Boolean }
81
+ fetchConference: { default: undefined, type: Object as () => Conference }
83
82
  })
84
83
 
85
84
  //Emits
@@ -92,6 +91,7 @@ const isMobile = ref(false);
92
91
  //Composables
93
92
  const { t } = useI18n();
94
93
  const { useProxyImageUrl } = useImageProxy();
94
+ const { isAuthenticated } = useAuthStore();
95
95
 
96
96
  //Computed
97
97
  const mainRubrique = computed(() => {
@@ -10,7 +10,6 @@
10
10
  :display-description="0 !== description.length"
11
11
  :arrow-direction="arrowDirection"
12
12
  :fetch-conference="fetchConference"
13
- :in-list="inList"
14
13
  @hide-description="hideDescription"
15
14
  @show-description="showDescription"
16
15
  />
@@ -50,9 +49,7 @@ import { Conference } from "@/stores/class/conference/conference";
50
49
  //Props
51
50
  const props = defineProps({
52
51
  podcast: { default: () => ({}), type: Object as () => Podcast },
53
- fetchConference: { default: undefined, type: Object as () => Conference },
54
- /** Indicates that the podcast is displayed in a list */
55
- inList: { default: false, type: Boolean }
52
+ fetchConference: { default: undefined, type: Object as () => Conference }
56
53
  });
57
54
 
58
55
  //Data
@@ -35,7 +35,6 @@
35
35
  <PodcastItem
36
36
  v-if="0 !== p.podcastId"
37
37
  :podcast="p"
38
- in-list
39
38
  />
40
39
  <template #preview>
41
40
  <router-link
@@ -95,6 +94,8 @@ const props = defineProps({
95
94
  withVideo: { default: undefined, type: Boolean },
96
95
  includeTag:{ default: () => [], type: Array as () => Array<string> },
97
96
  forceUpdateParameters: { default: false, type: Boolean },
97
+ /** The beneficiaries to filter on */
98
+ beneficiaries: { default: null, type: Array as () => Array<string> }
98
99
  })
99
100
 
100
101
  //Emits
@@ -128,7 +129,7 @@ const changed = computed(() => {
128
129
  return `${organisation.value}|${props.emissionId}|${props.sortCriteria}|${sort.value}
129
130
  ${props.iabId}|${props.participantId}|${props.query}|${props.monetisable}|${props.popularSort}|
130
131
  ${props.rubriqueId}|${props.rubriquageId}|${props.before}|${props.after}|${props.includeHidden}|${props.noRubriquageId}|${props.validity}|
131
- ${props.withVideo}|${props.includeTag}`;
132
+ ${props.withVideo}|${props.includeTag}|${props.beneficiaries}`;
132
133
  });
133
134
  const organisation = computed(() => {
134
135
  if (props.organisationId) {
@@ -201,6 +202,7 @@ async function fetchContent(reset: boolean): Promise<void> {
201
202
  includeStatus: ["READY", "PROCESSING"],
202
203
  withVideo: props.withVideo,
203
204
  includeTag: props.includeTag.length ? props.includeTag : undefined,
205
+ beneficiary: props.beneficiaries ?? undefined
204
206
  };
205
207
  try {
206
208
  const data = await classicApi.fetchData<ListClassicReturn<Podcast>>({
@@ -25,6 +25,7 @@
25
25
  : '',
26
26
  ]"
27
27
  class="me-3"
28
+ show-processing
28
29
  :hide-play="isLiveReadyToRecord"
29
30
  :podcast="podcast"
30
31
  :playing-podcast="playingPodcast"
@@ -129,8 +130,8 @@
129
130
  </div>
130
131
  </div>
131
132
  <TagList
132
- v-if="undefined !== podcast.tags && 0 !== podcast.tags.length"
133
- :tag-list="podcast.tags"
133
+ v-if="undefined !== tags && 0 !== tags.length"
134
+ :tag-list="tags"
134
135
  :orga-id="podcast.organisation.id"
135
136
  :podcast-annotations="podcast.annotations"
136
137
  />
@@ -260,13 +261,30 @@ const podcastNotValid = computed(() => {
260
261
  false === props.podcast?.valid
261
262
  );
262
263
  });
263
- const photoCredit = computed(() => (props.podcast?.annotations?.photoCredit as string) ?? "");
264
- const audioCredit = computed(() => (props.podcast?.annotations?.audioCredit as string) ?? "");
265
- const authorCredit = computed(() => (props.podcast?.annotations?.authorCredit as string) ?? "");
264
+ const photoCredit = computed(() => formatCredits(props.podcast?.annotations?.photoCredit as string|undefined));
265
+ const audioCredit = computed(() => formatCredits(props.podcast?.annotations?.audioCredit as string|undefined));
266
+ const authorCredit = computed(() => formatCredits(props.podcast?.annotations?.authorCredit as string|undefined));
266
267
  const isEditBox = computed(() => !((state.generalParameters.podcastmaker as boolean) ?? false));
267
-
268
+ /** The tags to display */
269
+ const tags = computed(() => {
270
+ const tags = [];
271
+ if(props.podcast.tags) {
272
+ tags.push(...props.podcast.tags);
273
+ }
274
+ // Also display tags defined on emission
275
+ if(props.podcast.emission.tags) {
276
+ tags.push(...props.podcast.emission.tags);
277
+ }
278
+ return tags;
279
+ });
268
280
 
269
281
  //Methods
282
+ function formatCredits(credits: string|undefined): string {
283
+ if (credits === undefined) {
284
+ return '';
285
+ }
286
+ return credits.split(',').map(s => s.trim()).join(', ');
287
+ }
270
288
  function urlify(text:string|undefined){
271
289
  return displayHelper.urlify(text);
272
290
  }