@saooti/octopus-sdk 36.0.5 → 36.0.6

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 (36) hide show
  1. package/index.ts +1 -2
  2. package/package.json +3 -2
  3. package/src/assets/bootstrap.scss +11 -1
  4. package/src/components/display/categories/CategoryChooser.vue +79 -171
  5. package/src/components/display/categories/CategoryFilter.vue +10 -4
  6. package/src/components/display/emission/EmissionPlayerItem.vue +4 -1
  7. package/src/components/display/filter/CategorySearchFilter.vue +1 -1
  8. package/src/components/display/filter/ProductorSearch.vue +6 -16
  9. package/src/components/display/filter/RubriqueChoice.vue +1 -1
  10. package/src/components/display/filter/RubriqueFilter.vue +2 -1
  11. package/src/components/display/list/Paginate.vue +4 -1
  12. package/src/components/display/organisation/OrganisationChooser.vue +72 -200
  13. package/src/components/display/podcasts/PodcastFilterList.vue +5 -3
  14. package/src/components/display/podcasts/PodcastImage.vue +3 -1
  15. package/src/components/display/podcasts/PodcastModuleBox.vue +17 -5
  16. package/src/components/display/podcasts/TagList.vue +2 -2
  17. package/src/components/display/rubriques/RubriqueChooser.vue +87 -181
  18. package/src/components/display/rubriques/RubriqueList.vue +8 -5
  19. package/src/components/display/sharing/PlayerParameters.vue +3 -1
  20. package/src/components/display/sharing/ShareButtons.vue +5 -3
  21. package/src/components/display/sharing/ShareButtonsIntern.vue +24 -8
  22. package/src/components/display/sharing/ShareDistribution.vue +3 -1
  23. package/src/components/display/sharing/SharePlayer.vue +3 -1
  24. package/src/components/display/sharing/SharePlayerColors.vue +6 -2
  25. package/src/components/form/ClassicCheckbox.vue +1 -1
  26. package/src/components/form/ClassicMultiselect.vue +155 -0
  27. package/src/components/misc/TopBar.vue +8 -4
  28. package/src/components/misc/modal/NewsletterModal.vue +1 -1
  29. package/src/components/pages/Emission.vue +5 -2
  30. package/src/components/pages/Home.vue +3 -3
  31. package/src/components/pages/Playlist.vue +4 -1
  32. package/src/components/pages/Podcast.vue +4 -1
  33. package/src/stores/ParamSdkStore.ts +13 -13
  34. package/src/stores/class/general/organisation.ts +8 -0
  35. package/src/assets/multiselect.scss +0 -518
  36. package/src/components/display/emission/EmissionChooser.vue +0 -187
@@ -1,264 +1,136 @@
1
1
  <template>
2
- <div
3
- v-if="!value || init"
4
- class="default-multiselect-width"
5
- :style="{ width: width }"
2
+ <ClassicMultiselect
3
+ v-if="!orgaIdSelected || initLoaded"
4
+ id="organisation-chooser"
5
+ ref="selectOrganisation"
6
+ option-label="name"
7
+ :label="$t('select productor')"
8
+ :max-element="maxElement"
9
+ :width="width"
10
+ :in-modal="inModal"
11
+ :option-chosen="organisationChosen"
12
+ :option-custom-templating="isImage"
13
+ @onSearch="onSearchOrganisation"
14
+ @selected="$emit('selected', $event)"
6
15
  >
7
- <label
8
- for="organisationChooser"
9
- class="d-inline"
10
- title="select productor"
11
- />
12
- <VueMultiselect
13
- id="organisationChooser"
14
- ref="multiselectRef"
15
- v-model="organisation"
16
- label="name"
17
- track-by="id"
18
- :aria-expanded="false"
19
- :placeholder="$t('Type string to filter by organisation')"
20
- :options="organisations"
21
- :multiple="false"
22
- :searchable="true"
23
- :loading="isLoading"
24
- :internal-search="false"
25
- :clear-on-select="false"
26
- :close-on-select="true"
27
- :options-limit="200"
28
- :max-height="600"
29
- :show-no-results="true"
30
- :hide-selected="true"
31
- :show-labels="false"
32
- :class="{ 'multiselect-transparent': light }"
33
- @search-change="onSearchOrganisation"
34
- @open="onOpen"
35
- @select="onOrganisationSelected"
16
+ <template
17
+ v-if="isImage"
18
+ #optionTemplating="{option}"
36
19
  >
37
- <template #clear="{ props }">
38
- <div
39
- v-if="organisation"
40
- class="multiselect__clear"
41
- @mousedown.prevent.stop="clearAll(props.search)"
42
- />
43
- </template>
44
- <template #singleLabel="{ option }">
45
- <div class="multiselect-octopus-proposition">
46
- <img
47
- v-if="!light"
48
- v-lazy="proxyImageUrl(option.imageUrl, '32')"
49
- width="32"
50
- height="32"
51
- class="option__image"
52
- :alt="option.name"
53
- >
54
- <span
55
- class="option__title"
56
- >
57
- {{ option.name }}
58
- </span>
59
- </div>
60
- </template>
61
- <template #option="{ option }">
62
- <div
63
- class="multiselect-octopus-proposition"
64
- :data-selenium="
65
- 'organisation-chooser-' + seleniumFormat(option.name)
66
- "
20
+ <div
21
+ class="d-flex align-items-center"
22
+ :data-selenium="'organisation-chooser-' + seleniumFormat(option.name)"
23
+ >
24
+ <img
25
+ v-lazy="proxyImageUrl(option.imageUrl, '32')"
26
+ width="32"
27
+ height="32"
28
+ class="me-2"
29
+ :alt="option.name"
67
30
  >
68
- <img
69
- v-if="!light"
70
- v-lazy="proxyImageUrl(option.imageUrl, '32')"
71
- width="32"
72
- height="32"
73
- class="option__image"
74
- :alt="option.name"
75
- >
76
- <span
77
- class="option__title"
78
- >
79
- {{ option.name }}
80
- </span>
81
- </div>
82
- </template>
83
- <template #noResult="">
84
- <span>{{ $t('No elements found. Consider changing the search query.') }}</span>
85
- </template>
86
- <template #afterList="">
87
- <div
88
- v-if="remainingElements"
89
- class="multiselect-remaining-elements"
90
- >
91
- {{
92
- $t(
93
- 'Count more elements matched your query, please make a more specific search.',
94
- { count: remainingElements }
95
- )
96
- }}
97
- </div>
98
- </template>
99
- <template #noOptions="">
100
- {{ $t('List is empty') }}
101
- </template>
102
- <template #caret="">
103
- <div
104
- class="position-relative"
105
- >
106
- <span
107
- class="saooti-down octopus-arrow-down-absolute"
108
- />
109
- </div>
110
- </template>
111
- </VueMultiselect>
112
- </div>
31
+ <span>
32
+ {{ option.name }}
33
+ </span>
34
+ </div>
35
+ </template>
36
+ </ClassicMultiselect>
113
37
  </template>
114
38
 
115
39
  <script lang="ts">
40
+ import { useAuthStore } from '@/stores/AuthStore';
41
+ import { mapState } from 'pinia';
116
42
  import imageProxy from '../../mixins/imageProxy';
117
43
  import selenium from '../../mixins/selenium';
118
44
  import { orgaComputed } from '../../mixins/orgaComputed';
119
- //@ts-ignore
120
- import VueMultiselect from 'vue-multiselect';
121
45
  import octopusApi from '@saooti/octopus-api';
122
- import { state } from '../../../stores/ParamSdkStore';
123
- import { Organisation } from '@/stores/class/general/organisation';
124
- import { useAuthStore } from '@/stores/AuthStore';
125
- import { mapState } from 'pinia';
126
- const ELEMENTS_COUNT = 50;
127
- const DEFAULT_ORGANISATION_ID = "";
128
- const DEFAULT_ORGANISATION_IMAGE = '/img/emptypodcast.webp';
129
-
130
- const getDefaultOrganistion = (defaultName: string) => {
131
- if(''===defaultName){
132
- return undefined;
133
- }
134
- return {
135
- name: defaultName,
136
- id: DEFAULT_ORGANISATION_ID,
137
- imageUrl: DEFAULT_ORGANISATION_IMAGE,
138
- };
139
- };
140
-
46
+ import ClassicMultiselect from '../../form/ClassicMultiselect.vue';
141
47
  import { defineComponent } from 'vue';
48
+ import { emptyOrgaData, Organisation } from '@/stores/class/general/organisation';
142
49
  export default defineComponent({
143
50
  components: {
144
- VueMultiselect,
51
+ ClassicMultiselect,
145
52
  },
146
53
  mixins:[selenium, orgaComputed, imageProxy],
147
54
  props: {
148
- width: { default: '100%', type: String },
149
55
  defaultanswer: { default: '', type: String},
150
- value: { default: undefined, type: String},
151
- light: { default: false, type: Boolean},
56
+ orgaIdSelected: { default: undefined, type: String},
152
57
  reset: { default: false, type: Boolean},
58
+ width: { default: '100%', type: String },
59
+ isImage: { default: true, type: Boolean },
60
+ inModal:{default: false, type: Boolean},
153
61
  },
154
62
  emits: ['selected'],
155
63
  data() {
156
64
  return {
157
- organisations: [] as Array<Organisation>,
158
- remainingElements: 0 as number,
159
- isLoading: false as boolean,
160
- init: false as boolean,
161
- myImage: state.organisation.imageUrl as string,
162
- organisation: getDefaultOrganistion(this.defaultanswer) as Organisation | undefined
65
+ maxElement: 50 as number,
66
+ organisationChosen: undefined as Organisation | undefined,
67
+ initLoaded: false as boolean
163
68
  };
164
69
  },
165
70
 
166
71
  computed: {
167
72
  ...mapState(useAuthStore, ['authOrganisation']),
73
+ getDefaultOrganisation(): Organisation|undefined{
74
+ if(''===this.defaultanswer){
75
+ return undefined;
76
+ }
77
+ return emptyOrgaData(this.defaultanswer);
78
+ },
168
79
  myOrganisation(): Organisation|undefined {
169
80
  if (!this.authenticated) return undefined;
170
- return {
171
- id: this.myOrganisationId??"",
172
- imageUrl: this.myImage,
173
- name: `${this.$t('Edit my organisation')} (${state.organisation.name})`
174
- };
175
- },
81
+ return {...this.authOrganisation, ...{name: `${this.$t('Edit my organisation')} (${this.authOrganisation.name})`}};
82
+ }
176
83
  },
177
84
  watch: {
178
- value(): void {
179
- if (!this.init || this.value) {
180
- this.fetchOrganisation();
85
+ orgaIdSelected: {
86
+ immediate:true,
87
+ handler(){
88
+ if (!this.initLoaded && this.orgaIdSelected) {
89
+ this.fetchOrganisation();
90
+ }
181
91
  }
182
92
  },
183
93
  reset(): void {
184
- this.organisation = this.defaultanswer
185
- ? getDefaultOrganistion(this.defaultanswer)
186
- : undefined;
94
+ this.organisationChosen = this.getDefaultOrganisation;
187
95
  },
188
96
  },
189
97
 
190
98
  async created() {
191
- if (
192
- this.authenticated &&
193
- (undefined === this.authOrganisation.imageUrl ||'' === this.authOrganisation.imageUrl)
194
- ) {
195
- const data = await octopusApi.fetchData<Organisation>(0,`organisation/${this.myOrganisationId ?this.myOrganisationId:""}`);
196
- this.myImage = data.imageUrl;
197
- }
198
- if (this.value) {
199
- this.fetchOrganisation();
200
- }
99
+ this.organisationChosen = this.getDefaultOrganisation;
201
100
  },
202
101
  methods: {
203
- onOpen(): void {
204
- (this.$refs.multiselectRef as VueMultiselect).$refs.search.setAttribute(
205
- 'autocomplete',
206
- 'off'
207
- );
208
- this.onSearchOrganisation();
209
- },
210
- onOrganisationSelected(organisation: Organisation|undefined): void {
211
- this.$emit('selected', organisation);
212
- },
213
102
  async onSearchOrganisation(query?: string): Promise<void> {
214
- this.isLoading = true;
215
- const response = await octopusApi.fetchDataWithParams<{count: number;result: Array<Organisation>;sort: string;}>(0, 'organisation/search',{
103
+ const response = await octopusApi.fetchDataWithParams<{count: number;result:Array<Organisation>;sort: string;}>(0, 'organisation/search',{
216
104
  query: query,
217
105
  first: 0,
218
- size: ELEMENTS_COUNT,
106
+ size: this.maxElement
219
107
  });
220
- const orga = response.result;
221
- const notNull = orga.filter((o: Organisation|null) => {
108
+ let notNullOrga = response.result.filter((o: Organisation|null) => {
222
109
  return null !== o;
223
110
  });
224
- if (this.defaultanswer) {
225
- const defaultOrganisation = getDefaultOrganistion(this.defaultanswer);
226
- if(defaultOrganisation){
227
- this.organisations =[defaultOrganisation].concat(notNull);
228
- }
229
- } else {
230
- this.organisations = notNull;
111
+ if (this.getDefaultOrganisation) {
112
+ notNullOrga.unshift(this.getDefaultOrganisation);
231
113
  }
232
114
  if (this.myOrganisation) {
233
115
  if (undefined === query) {
234
- this.organisations = this.organisations.filter((obj: Organisation) => {
116
+ notNullOrga = notNullOrga.filter((obj: Organisation) => {
235
117
  return obj.id !== this.myOrganisationId;
236
118
  });
237
- this.organisations.splice(1, 0, this.myOrganisation);
119
+ notNullOrga.splice(1, 0, this.myOrganisation);
238
120
  } else {
239
- const foundIndex = this.organisations.findIndex(
121
+ const foundIndex = notNullOrga.findIndex(
240
122
  (obj: Organisation) => obj.id === this.myOrganisationId
241
123
  );
242
124
  if (foundIndex) {
243
- this.organisations[foundIndex] = this.myOrganisation;
125
+ notNullOrga[foundIndex] = this.myOrganisation;
244
126
  }
245
127
  }
246
128
  }
247
- this.isLoading = false;
248
- this.remainingElements = Math.max(0, response.count - orga.length);
129
+ (this.$refs.selectOrganisation as InstanceType<typeof ClassicMultiselect>).afterSearch(notNullOrga,response.count);
249
130
  },
250
131
  async fetchOrganisation(): Promise<void> {
251
- if (0 === this.organisations.length) {
252
- this.onSearchOrganisation();
253
- }
254
- if(!this.value){return;}
255
- const data = await octopusApi.fetchData<Organisation>(0,`organisation/${this.value}`);
256
- this.organisation = data;
257
- this.init = true;
258
- },
259
- clearAll(): void {
260
- this.organisation = undefined;
261
- this.organisations.length = 0;
132
+ this.organisationChosen = await octopusApi.fetchData<Organisation>(0,`organisation/${this.orgaIdSelected}`);
133
+ this.initLoaded = true;
262
134
  },
263
135
  },
264
136
  })
@@ -1,9 +1,11 @@
1
1
  <template>
2
2
  <div class="py-3">
3
- <h2 class="big-h2 mb-2">{{ titleFilter }}</h2>
3
+ <h2 class="big-h2 mb-2">
4
+ {{ titleFilter }}
5
+ </h2>
4
6
  <div class="d-flex align-items-center flex-wrap mb-2">
5
7
  <div
6
- class="d-flex align-items-center flex-grow-1 me-3"
8
+ class="w-50-responsive pe-3"
7
9
  >
8
10
  <CategoryChooser
9
11
  :defaultanswer="$t('No category filter')"
@@ -12,7 +14,7 @@
12
14
  </div>
13
15
  <ClassicSearch
14
16
  v-model:textInit="searchPattern"
15
- class="flex-small-grow"
17
+ class="w-50-responsive"
16
18
  id-search="podcast-filter-search"
17
19
  :label="$t('Search')"
18
20
  />
@@ -59,7 +59,9 @@
59
59
  <span class="paddle2" />
60
60
  <span class="paddle3" />
61
61
  </div>
62
- <div class="ms-2">{{durationString}}</div>
62
+ <div class="ms-2">
63
+ {{ durationString }}
64
+ </div>
63
65
  </div>
64
66
  <div
65
67
  v-else
@@ -29,7 +29,7 @@
29
29
  {{ date }}
30
30
  </div>
31
31
  <div>
32
- {{ duration}}
32
+ {{ duration }}
33
33
  </div>
34
34
  <div
35
35
  v-if="isLiveReady"
@@ -50,7 +50,10 @@
50
50
  />
51
51
  <!-- eslint-enable -->
52
52
  <div class="my-3">
53
- <ParticipantDescription class="mb-1" :participants="podcast.animators" />
53
+ <ParticipantDescription
54
+ class="mb-1"
55
+ :participants="podcast.animators"
56
+ />
54
57
  <div class="mb-1">
55
58
  {{ $t('Emission') + ' : ' }}
56
59
  <router-link
@@ -65,7 +68,10 @@
65
68
  {{ podcast.emission.name }}
66
69
  </router-link>
67
70
  </div>
68
- <div class="mb-1" v-if="!isPodcastmaker">
71
+ <div
72
+ v-if="!isPodcastmaker"
73
+ class="mb-1"
74
+ >
69
75
  {{ $t('Producted by : ') }}
70
76
  <router-link
71
77
  :to="{
@@ -79,10 +85,16 @@
79
85
  {{ podcast.organisation.name }}
80
86
  </router-link>
81
87
  </div>
82
- <div class="mb-1" v-if="''!==photoCredit">
88
+ <div
89
+ v-if="''!==photoCredit"
90
+ class="mb-1"
91
+ >
83
92
  {{ $t('Photo credits') + " : "+ photoCredit }}
84
93
  </div>
85
- <div class="mb-1" v-if="''!==audioCredit">
94
+ <div
95
+ v-if="''!==audioCredit"
96
+ class="mb-1"
97
+ >
86
98
  {{ $t('Audio credits') + " : "+ audioCredit }}
87
99
  </div>
88
100
  <a
@@ -30,8 +30,8 @@
30
30
  v-if="isOuestFranceTag(tag)"
31
31
  :target="'tag-list-from-podcast-page'+index"
32
32
  :content="tag.substring(4,tag.length)"
33
- relativeClass="page-element"
34
- :isFixed="true"
33
+ relative-class="page-element"
34
+ :is-fixed="true"
35
35
  />
36
36
  </div>
37
37
  </div>