@saooti/octopus-sdk 41.0.18 → 41.0.19

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.
@@ -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
 
@@ -95,6 +95,8 @@ const props = defineProps({
95
95
  withVideo: { default: undefined, type: Boolean },
96
96
  includeTag:{ default: () => [], type: Array as () => Array<string> },
97
97
  forceUpdateParameters: { default: false, type: Boolean },
98
+ /** The beneficiaries to filter on */
99
+ beneficiaries: { default: null, type: Array as () => Array<string> }
98
100
  })
99
101
 
100
102
  //Emits
@@ -128,7 +130,7 @@ const changed = computed(() => {
128
130
  return `${organisation.value}|${props.emissionId}|${props.sortCriteria}|${sort.value}
129
131
  ${props.iabId}|${props.participantId}|${props.query}|${props.monetisable}|${props.popularSort}|
130
132
  ${props.rubriqueId}|${props.rubriquageId}|${props.before}|${props.after}|${props.includeHidden}|${props.noRubriquageId}|${props.validity}|
131
- ${props.withVideo}|${props.includeTag}`;
133
+ ${props.withVideo}|${props.includeTag}|${props.beneficiaries}`;
132
134
  });
133
135
  const organisation = computed(() => {
134
136
  if (props.organisationId) {
@@ -201,6 +203,7 @@ async function fetchContent(reset: boolean): Promise<void> {
201
203
  includeStatus: ["READY", "PROCESSING"],
202
204
  withVideo: props.withVideo,
203
205
  includeTag: props.includeTag.length ? props.includeTag : undefined,
206
+ beneficiary: props.beneficiaries ?? undefined
204
207
  };
205
208
  try {
206
209
  const data = await classicApi.fetchData<ListClassicReturn<Podcast>>({
@@ -129,8 +129,8 @@
129
129
  </div>
130
130
  </div>
131
131
  <TagList
132
- v-if="undefined !== podcast.tags && 0 !== podcast.tags.length"
133
- :tag-list="podcast.tags"
132
+ v-if="undefined !== tags && 0 !== tags.length"
133
+ :tag-list="tags"
134
134
  :orga-id="podcast.organisation.id"
135
135
  :podcast-annotations="podcast.annotations"
136
136
  />
@@ -260,13 +260,30 @@ const podcastNotValid = computed(() => {
260
260
  false === props.podcast?.valid
261
261
  );
262
262
  });
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) ?? "");
263
+ const photoCredit = computed(() => formatCredits(props.podcast?.annotations?.photoCredit as string|undefined));
264
+ const audioCredit = computed(() => formatCredits(props.podcast?.annotations?.audioCredit as string|undefined));
265
+ const authorCredit = computed(() => formatCredits(props.podcast?.annotations?.authorCredit as string|undefined));
266
266
  const isEditBox = computed(() => !((state.generalParameters.podcastmaker as boolean) ?? false));
267
-
267
+ /** The tags to display */
268
+ const tags = computed(() => {
269
+ const tags = [];
270
+ if(props.podcast.tags) {
271
+ tags.push(...props.podcast.tags);
272
+ }
273
+ // Also display tags defined on emission
274
+ if(props.podcast.emission.tags) {
275
+ tags.push(...props.podcast.emission.tags);
276
+ }
277
+ return tags;
278
+ });
268
279
 
269
280
  //Methods
281
+ function formatCredits(credits: string|undefined): string {
282
+ if (credits === undefined) {
283
+ return '';
284
+ }
285
+ return credits.split(',').map(s => s.trim()).join(', ');
286
+ }
270
287
  function urlify(text:string|undefined){
271
288
  return displayHelper.urlify(text);
272
289
  }
@@ -12,7 +12,7 @@
12
12
  class="d-flex align-items-center border p-1 m-1 text-dark"
13
13
  :to="{
14
14
  name: 'tag',
15
- params: { tag: tag},
15
+ params: { tag },
16
16
  query: organisationQuery
17
17
  }"
18
18
  >
@@ -82,7 +82,7 @@ const organisationQuery = computed(() => {
82
82
  if(filterStore.filterOrgaId){
83
83
  return undefined;
84
84
  }
85
- return { o: props.orgaId};
85
+ return { o: props.orgaId };
86
86
  });
87
87
  /* const ouestFranceMainTag = computed(() => {
88
88
  if (props.podcastAnnotations?.["mainOfTag"]) {
@@ -212,6 +212,7 @@ defineExpose({
212
212
  afterSearch
213
213
  });
214
214
  </script>
215
+
215
216
  <style lang="scss">
216
217
  @use "vue-select/dist/vue-select.css";
217
218
  /* stylelint-disable */