@saooti/octopus-sdk 31.0.35 → 31.0.36

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 (84) hide show
  1. package/README.md +4 -1
  2. package/index.ts +5 -2
  3. package/package.json +1 -1
  4. package/public/img/403.jpeg +0 -0
  5. package/public/img/404.svg +242 -0
  6. package/src/assets/bootstrap-diff.scss +25 -24
  7. package/src/assets/general.scss +57 -2
  8. package/src/assets/modal.scss +5 -4
  9. package/src/assets/share.scss +2 -0
  10. package/src/components/display/categories/CategoryFilter.vue +12 -26
  11. package/src/components/display/categories/CategoryList.vue +14 -20
  12. package/src/components/display/comments/AddCommentModal.vue +19 -36
  13. package/src/components/display/comments/CommentBasicView.vue +2 -5
  14. package/src/components/display/comments/CommentInput.vue +8 -21
  15. package/src/components/display/comments/CommentList.vue +10 -21
  16. package/src/components/display/comments/CommentPlayer.vue +0 -3
  17. package/src/components/display/comments/CommentSection.vue +6 -14
  18. package/src/components/display/emission/EmissionInlineList.vue +5 -10
  19. package/src/components/display/emission/EmissionItem.vue +5 -10
  20. package/src/components/display/emission/EmissionList.vue +66 -68
  21. package/src/components/display/filter/AdvancedSearch.vue +19 -45
  22. package/src/components/display/filter/CategoryFilter.vue +11 -20
  23. package/src/components/display/filter/MonetizableFilter.vue +7 -14
  24. package/src/components/display/filter/ProductorSearch.vue +69 -78
  25. package/src/components/display/filter/RubriqueChoice.vue +1 -4
  26. package/src/components/display/filter/RubriqueFilter.vue +1 -5
  27. package/src/components/display/list/ListPaginate.vue +150 -0
  28. package/src/components/display/list/Paginate.vue +219 -0
  29. package/src/components/display/live/LiveHorizontalList.vue +56 -40
  30. package/src/components/display/organisation/OrganisationChooser.vue +7 -12
  31. package/src/components/display/participant/ParticipantItem.vue +6 -17
  32. package/src/components/display/participant/ParticipantList.vue +53 -46
  33. package/src/components/display/playlist/PlaylistItem.vue +1 -4
  34. package/src/components/display/playlist/PlaylistList.vue +60 -63
  35. package/src/components/display/playlist/PodcastList.vue +74 -101
  36. package/src/components/display/podcasts/AnimatorsItem.vue +17 -28
  37. package/src/components/display/podcasts/ParticipantDescription.vue +3 -11
  38. package/src/components/display/podcasts/PodcastFilterList.vue +8 -16
  39. package/src/components/display/podcasts/PodcastImage.vue +86 -92
  40. package/src/components/display/podcasts/PodcastItem.vue +1 -2
  41. package/src/components/display/podcasts/PodcastItemInfo.vue +10 -10
  42. package/src/components/display/podcasts/PodcastList.vue +61 -81
  43. package/src/components/display/podcasts/PodcastModuleBox.vue +19 -25
  44. package/src/components/display/podcasts/PodcastSwiperList.vue +2 -3
  45. package/src/components/display/podcasts/TagList.vue +0 -2
  46. package/src/components/display/sharing/QrCode.vue +2 -11
  47. package/src/components/display/sharing/ShareButtons.vue +44 -329
  48. package/src/components/display/sharing/ShareButtonsIntern.vue +209 -0
  49. package/src/components/display/sharing/SharePlayer.vue +21 -53
  50. package/src/components/display/sharing/SplitButton.vue +42 -0
  51. package/src/components/display/sharing/SubscribeButtons.vue +46 -39
  52. package/src/components/misc/Footer.vue +1 -4
  53. package/src/components/misc/HomeDropdown.vue +26 -24
  54. package/src/components/misc/LeftMenu.vue +3 -7
  55. package/src/components/misc/TopBar.vue +9 -16
  56. package/src/components/misc/modal/ClipboardModal.vue +1 -1
  57. package/src/components/misc/modal/MessageModal.vue +1 -1
  58. package/src/components/misc/modal/QrCodeModal.vue +1 -1
  59. package/src/components/misc/modal/ShareModalPlayer.vue +1 -1
  60. package/src/components/mixins/organisationFilter.ts +6 -0
  61. package/src/components/mixins/player/playerLive.ts +1 -1
  62. package/src/components/pages/Category.vue +1 -1
  63. package/src/components/pages/Emission.vue +0 -6
  64. package/src/components/pages/Emissions.vue +1 -1
  65. package/src/components/pages/Error403Page.vue +44 -8
  66. package/src/components/pages/PageNotFound.vue +55 -0
  67. package/src/components/pages/Participant.vue +0 -15
  68. package/src/components/pages/Participants.vue +1 -1
  69. package/src/components/pages/Playlist.vue +2 -2
  70. package/src/components/pages/Playlists.vue +1 -1
  71. package/src/components/pages/Podcast.vue +1 -3
  72. package/src/components/pages/Podcasts.vue +11 -8
  73. package/src/components/pages/Rubrique.vue +1 -1
  74. package/src/locale/de.ts +3 -0
  75. package/src/locale/en.ts +9 -0
  76. package/src/locale/es.ts +3 -0
  77. package/src/locale/fr.ts +10 -1
  78. package/src/locale/it.ts +3 -0
  79. package/src/locale/sl.ts +3 -0
  80. package/src/router/router.ts +2 -0
  81. package/src/sass/_variables.scss +0 -1
  82. package/src/store/class/general/playlist.ts +1 -1
  83. package/src/store/paramStore.ts +7 -11
  84. package/src/store/typeAppStore.ts +20 -2
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <div
3
+ v-if="totalCount > 0"
4
+ class="paginate"
5
+ >
6
+ <div class="d-flex align-items-center justify-content-center">
7
+ <label for="rows-per-page-select">{{ $t('Items per page :') }}</label>
8
+ <select
9
+ id="rows-per-page-select"
10
+ v-model="rowsPerPageIntern"
11
+ class="c-hand p-1 mx-2"
12
+ >
13
+ <option
14
+ v-for="option in optionsRowsPerPage"
15
+ :key="option"
16
+ :value="option"
17
+ >
18
+ {{ option }}
19
+ </option>
20
+ </select>
21
+ <div class="mx-2">
22
+ {{ $t('Showing items number', {page: (page+1), totalPage: totalPage}) }}
23
+ </div>
24
+ <div class="d-flex flex-nowrap">
25
+ <button
26
+ v-for="paginateButton in buttonsLeft"
27
+ :key="paginateButton.title"
28
+ class="btn"
29
+ :title="paginateButton.title"
30
+ :disabled="paginateButton.disabled"
31
+ @click="paginateButton.action"
32
+ >
33
+ <svg
34
+ xmlns="http://www.w3.org/2000/svg"
35
+ width="16"
36
+ height="16"
37
+ fill="currentColor"
38
+ viewBox="0 0 16 16"
39
+ >
40
+ <path
41
+ fill-rule="evenodd"
42
+ :d="paginateButton.path"
43
+ />
44
+ </svg>
45
+ </button>
46
+ <div
47
+ v-for="pageNumber in pagination"
48
+ :key="pageNumber"
49
+ >
50
+ <span
51
+ v-if="null === pageNumber"
52
+ class="btn"
53
+ >
54
+ ...
55
+ </span>
56
+ <button
57
+ v-else
58
+ class="btn"
59
+ :class="{ 'active': page === (pageNumber-1) }"
60
+ @click="changeFirst((pageNumber-1)*rowsPerPageIntern)"
61
+ >
62
+ {{ pageNumber }}
63
+ </button>
64
+ </div>
65
+ <button
66
+ v-for="paginateButton in buttonsRight"
67
+ :key="paginateButton.title"
68
+ class="btn"
69
+ :title="paginateButton.title"
70
+ :disabled="paginateButton.disabled"
71
+ @click="paginateButton.action"
72
+ >
73
+ <svg
74
+ xmlns="http://www.w3.org/2000/svg"
75
+ width="16"
76
+ height="16"
77
+ fill="currentColor"
78
+ viewBox="0 0 16 16"
79
+ >
80
+ <path
81
+ fill-rule="evenodd"
82
+ :d="paginateButton.path"
83
+ />
84
+ </svg>
85
+ </button>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ </template>
90
+
91
+ <script lang="ts">
92
+ import { defineComponent } from 'vue';
93
+ export default defineComponent({
94
+ name: "Paginate",
95
+ components: {
96
+ },
97
+ props: {
98
+ totalCount: { default: 0, type: Number },
99
+ first: { default: 0, type: Number },
100
+ rowsPerPage:{ default:0, type:Number},
101
+ rangeSize:{default:1, type: Number}
102
+ },
103
+ emits:['update:first', 'update:rowsPerPage'],
104
+ data() {
105
+ return {
106
+ rowsPerPageIntern: 30 as number,
107
+ optionsRowsPerPage: [5, 10, 15, 20, 25 , 30, 50] as Array<number>,
108
+ };
109
+ },
110
+ computed:{
111
+ buttonsLeft(){
112
+ return [{
113
+ title: this.$t('Go to first page'), disabled: 0===this.first, action: ()=>{this.changeFirst(0)}, path:"M11.854 3.646a.5.5 0 0 1 0 .708L8.207 8l3.647 3.646a.5.5 0 0 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 0 1 .708 0zM4.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5z"},
114
+ {title: this.$t('Go to previous page'), disabled: 0===this.first, action: ()=>{this.changeFirst(this.first - this.rowsPerPage)}, path:"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"},]
115
+ },
116
+ buttonsRight(){
117
+ return [
118
+ {title: this.$t('Go to next page'), disabled: this.lastFirst===this.first, action: ()=>{this.changeFirst(this.first + this.rowsPerPage)}, path:"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"},
119
+ {title: this.$t('Go to last page'), disabled: this.lastFirst===this.first, action: ()=>{this.changeFirst(this.lastFirst)}, path:"M4.146 3.646a.5.5 0 0 0 0 .708L7.793 8l-3.647 3.646a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708 0zM11.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5z"}]
120
+ },
121
+ page(){
122
+ return Math.floor(this.first/this.rowsPerPage);
123
+ },
124
+ totalPage(){
125
+ return Math.ceil(this.totalCount/this.rowsPerPage);
126
+ },
127
+ pagination(): (number | null)[] {
128
+ if(-1===this.rangeSize){return[];}
129
+ const res = [];
130
+ const minPaginationElems = 5 + this.rangeSize * 2;
131
+ let rangeStart = this.totalPage <= minPaginationElems ? 1 : (this.page + 1) - this.rangeSize;
132
+ let rangeEnd =this.totalPage <= minPaginationElems ? this.totalPage : (this.page + 1)+ this.rangeSize;
133
+ rangeEnd = rangeEnd > this.totalPage ? this.totalPage : rangeEnd;
134
+ rangeStart = rangeStart < 1 ? 1 : rangeStart;
135
+ if (this.totalPage > minPaginationElems) {
136
+ const isStartBoundaryReached = rangeStart - 1 < 3;
137
+ const isEndBoundaryReached = this.totalPage - rangeEnd < 3;
138
+ if (isStartBoundaryReached) {
139
+ rangeEnd = minPaginationElems - 2;
140
+ for (let i = 1; i < rangeStart; i++) {
141
+ res.push(i);
142
+ }
143
+ } else {
144
+ res.push(1);
145
+ res.push(null);
146
+ }
147
+ if (isEndBoundaryReached) {
148
+ rangeStart = this.totalPage - (minPaginationElems - 3);
149
+ for (let i = rangeStart; i <= this.totalPage; i++) {
150
+ res.push(i);
151
+ }
152
+ } else {
153
+ for (let i = rangeStart; i <= rangeEnd; i++) {
154
+ res.push(i);
155
+ }
156
+ res.push(null);
157
+ res.push(this.totalPage);
158
+ }
159
+ } else {
160
+ for (let i = rangeStart; i <= rangeEnd; i++) {
161
+ res.push(i);
162
+ }
163
+ }
164
+ return res;
165
+ },
166
+ lastFirst(): number{
167
+ return (this.totalPage-1)*this.rowsPerPage;
168
+ }
169
+ },
170
+ watch: {
171
+ rowsPerPageIntern(){
172
+ if(this.rowsPerPage !== this.rowsPerPageIntern){
173
+ this.$emit('update:rowsPerPage', this.rowsPerPageIntern);
174
+ }
175
+ },
176
+ rowsPerPage(){
177
+ if(this.rowsPerPage !== this.rowsPerPageIntern){
178
+ this.rowsPerPageIntern =this.rowsPerPage;
179
+ }
180
+ }
181
+ },
182
+ created(){
183
+ this.initRowsPerPage();
184
+ },
185
+
186
+ methods:{
187
+ initRowsPerPage(){
188
+ if(!this.optionsRowsPerPage.includes(this.rowsPerPage)){
189
+ this.optionsRowsPerPage.push(this.rowsPerPage);
190
+ this.optionsRowsPerPage.sort((a,b)=>a-b);
191
+ }
192
+ this.rowsPerPageIntern = this.rowsPerPage;
193
+ },
194
+ changeFirst(newFirst: number){
195
+ this.$emit('update:first', newFirst);
196
+ },
197
+ }
198
+ });
199
+ </script>
200
+ <style lang="scss">
201
+ @import '../../../sass/_variables.scss';
202
+ .octopus-app .paginate{
203
+ display: flex;
204
+ justify-content: flex-end;
205
+ select{
206
+ border-top: 0;
207
+ border-right: 0;
208
+ border-left: 0;
209
+ background: transparent !important;
210
+ outline-width: 0;
211
+ }
212
+ .btn{
213
+ border-radius: 0;
214
+ &.active{
215
+ background: rgba($octopus-primary-color, 0.3) ;
216
+ }
217
+ }
218
+ }
219
+ </style>
@@ -1,54 +1,56 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="notEmpty"
4
- class="d-flex flex-column"
4
+ class="p-3"
5
5
  >
6
- <h2 class="mb-4 mt-3">
6
+ <h2 class="mb-0 mt-3">
7
7
  {{ $t('All live emission button') }}
8
8
  </h2>
9
- <ul class="podcast-list">
10
- <PodcastItem
11
- v-for="l in lives"
12
- :key="l.podcastId"
13
- :podcast="l"
14
- />
15
- </ul>
16
- <button
17
- v-show="!allFetched"
18
- class="btn"
19
- :class="buttonPlus ? 'btn-primary align-self-center width-fit-content m-4 mt-3' : 'btn-more'"
20
- :disabled="inFetching"
21
- :title="$t('See more')"
22
- @click="displayMore"
9
+ <ListPaginate
10
+ id="liveListPaginate"
11
+ v-model:first="dfirst"
12
+ v-model:rowsPerPage="dsize"
13
+ v-model:isMobile="isMobile"
14
+ :total-count="totalCount"
15
+ :loading="false"
23
16
  >
24
- <template v-if="buttonPlus">
25
- {{ $t('See more') }}
17
+ <template #list>
18
+ <ul
19
+ class="podcast-list"
20
+ >
21
+ <template
22
+ v-for="p in displayArray"
23
+ :key="p.podcastId"
24
+ >
25
+ <PodcastItem
26
+ v-if="-1!==p.podcastId"
27
+ :podcast="p"
28
+ />
29
+ </template>
30
+ </ul>
26
31
  </template>
27
- <div
28
- :class="buttonPlus?'ms-1':''"
29
- class="saooti-more"
30
- />
31
- </button>
32
+ </ListPaginate>
32
33
  </div>
33
34
  </template>
34
35
 
35
36
  <script lang="ts">
37
+ import ListPaginate from '../list/ListPaginate.vue';
36
38
  import octopusApi from '@saooti/octopus-api';
37
39
  import PodcastItem from '../podcasts/PodcastItem.vue';
38
- import { state } from '../../../store/paramStore';
39
-
40
40
  import { Podcast } from '@/store/class/general/podcast';
41
41
  import { defineComponent } from 'vue'
42
+ import { emptyPodcastData } from '@/store/typeAppStore';
42
43
  export default defineComponent({
43
44
  name: 'LiveHorizontalList',
44
45
 
45
46
  components: {
46
47
  PodcastItem,
48
+ ListPaginate
47
49
  },
48
50
 
49
51
  props: {
50
52
  first: { default: 0, type: Number },
51
- size: { default: 12, type: Number },
53
+ size: { default: 30, type: Number },
52
54
  emissionId: { default: undefined, type: Number},
53
55
  },
54
56
 
@@ -60,27 +62,41 @@ export default defineComponent({
60
62
  lives: [] as Array<Podcast>,
61
63
  notEmpty: false as boolean,
62
64
  inFetching: false as boolean,
65
+ isMobile: false as boolean,
63
66
  };
64
67
  },
65
68
 
66
69
 
67
70
  computed: {
68
- allFetched(): boolean {
69
- return this.dfirst >= this.totalCount;
70
- },
71
- buttonPlus(): boolean {
72
- return (state.generalParameters.buttonPlus as boolean);
73
- },
71
+ displayArray(): Array<Podcast>{
72
+ if(this.isMobile){
73
+ return this.lives;
74
+ }
75
+ return this.lives.slice(this.dfirst, Math.min(this.dfirst + this.dsize,this.totalCount));
76
+ },
77
+ },
78
+ watch: {
79
+ dsize():void{
80
+ this.reloadList();
81
+ },
82
+ dfirst(): void{
83
+ if(!this.lives[this.dfirst] || -1===this.lives[this.dfirst].podcastId){
84
+ this.fetchContent(false);
85
+ }
86
+ },
74
87
  },
75
88
 
76
89
  created() {
77
90
  this.fetchContent(true);
78
91
  },
79
92
  methods: {
93
+ reloadList(){
94
+ this.dfirst = 0;
95
+ this.fetchContent(true);
96
+ },
80
97
  async fetchContent(reset: boolean): Promise<void> {
81
98
  this.inFetching = true;
82
99
  if (reset) {
83
- this.dfirst = 0;
84
100
  this.notEmpty = false;
85
101
  }
86
102
  const param = {
@@ -95,22 +111,22 @@ export default defineComponent({
95
111
  afterFetching(reset: boolean, data: {count: number, result: Array<Podcast>, sort: string}): void {
96
112
  if (reset) {
97
113
  this.lives.length = 0;
98
- this.dfirst = 0;
99
114
  }
100
- this.lives = this.lives.concat(data.result).filter((l: Podcast | null) => {
115
+ if(this.dfirst > this.lives.length){
116
+ for (let i = this.lives.length-1, len = this.dfirst + this.dsize; i < len; i++) {
117
+ this.lives.push(emptyPodcastData());
118
+ }
119
+ }
120
+ const responseLives = data.result.filter((l: Podcast | null) => {
101
121
  return null !== l;
102
122
  });
103
- this.dfirst += this.dsize;
123
+ this.lives = this.lives.slice(0, this.dfirst).concat(responseLives).concat(this.lives.slice(this.dfirst+this.dsize, this.lives.length));
104
124
  this.totalCount = data.count;
105
125
  if (0 !== this.lives.length) {
106
126
  this.notEmpty = true;
107
127
  }
108
128
  this.inFetching = false;
109
129
  },
110
- displayMore(event: { preventDefault: () => void }): void {
111
- event.preventDefault();
112
- this.fetchContent(false);
113
- },
114
130
  },
115
131
  })
116
132
  </script>
@@ -110,6 +110,7 @@
110
110
 
111
111
  <script lang="ts">
112
112
  import { selenium } from '../../mixins/functions';
113
+ import { orgaComputed } from '../../mixins/orgaComputed';
113
114
  //@ts-ignore
114
115
  import VueMultiselect from 'vue-multiselect';
115
116
  import octopusApi from '@saooti/octopus-api';
@@ -131,12 +132,12 @@ const getDefaultOrganistion = (defaultName: string) => {
131
132
  };
132
133
  };
133
134
 
134
- import { defineComponent } from 'vue'
135
+ import { defineComponent } from 'vue';
135
136
  export default defineComponent({
136
137
  components: {
137
138
  VueMultiselect,
138
139
  },
139
- mixins:[selenium],
140
+ mixins:[selenium, orgaComputed],
140
141
  props: {
141
142
  width: { default: '100%', type: String },
142
143
  defaultanswer: { default: '', type: String},
@@ -157,16 +158,10 @@ export default defineComponent({
157
158
  },
158
159
 
159
160
  computed: {
160
- organisationId(): string|undefined {
161
- return state.generalParameters.organisationId;
162
- },
163
- authenticated(): boolean {
164
- return (state.generalParameters.authenticated as boolean);
165
- },
166
161
  myOrganisation(): Organisation|undefined {
167
162
  if (!this.authenticated) return undefined;
168
163
  return {
169
- id: this.organisationId ? this.organisationId : "",
164
+ id: this.myOrganisationId ? this.myOrganisationId : "",
170
165
  imageUrl: this.myImage,
171
166
  name:
172
167
  this.$t('Edit my organisation') +
@@ -194,7 +189,7 @@ export default defineComponent({
194
189
  this.authenticated &&
195
190
  undefined === this.$store.state.organisation.imageUrl
196
191
  ) {
197
- const data = await octopusApi.fetchOrganisation(this.organisationId ?this.organisationId:"");
192
+ const data = await octopusApi.fetchOrganisation(this.myOrganisationId ?this.myOrganisationId:"");
198
193
  this.myImage = data.imageUrl;
199
194
  }
200
195
  if (this.value) {
@@ -234,12 +229,12 @@ export default defineComponent({
234
229
  if (this.myOrganisation) {
235
230
  if (undefined === query) {
236
231
  this.organisations = this.organisations.filter((obj: Organisation) => {
237
- return obj.id !== this.organisationId;
232
+ return obj.id !== this.myOrganisationId;
238
233
  });
239
234
  this.organisations.splice(1, 0, this.myOrganisation);
240
235
  } else {
241
236
  const foundIndex = this.organisations.findIndex(
242
- (obj: Organisation) => obj.id === this.organisationId
237
+ (obj: Organisation) => obj.id === this.myOrganisationId
243
238
  );
244
239
  if (foundIndex) {
245
240
  this.organisations[foundIndex] = this.myOrganisation;
@@ -7,7 +7,7 @@
7
7
  :to="{
8
8
  name: 'participant',
9
9
  params: { participantId: participant.participantId },
10
- query: { productor: $store.state.filter.organisationId },
10
+ query: { productor: filterOrga },
11
11
  }"
12
12
  class="mt-3 text-dark"
13
13
  :title="$t('Participant')"
@@ -42,7 +42,7 @@
42
42
  :to="{
43
43
  name: 'productor',
44
44
  params: { productorId: participant.orga.id },
45
- query: { productor: $store.state.filter.organisationId },
45
+ query: { productor: filterOrga },
46
46
  }"
47
47
  class="participant-producer"
48
48
  >
@@ -56,36 +56,25 @@ import octopusApi from '@saooti/octopus-api';
56
56
  import { Participant } from '@/store/class/general/participant';
57
57
  import { state } from '../../../store/paramStore';
58
58
  import { displayMethods } from '../../mixins/functions';
59
+ import { orgaComputed } from '../../mixins/orgaComputed';
59
60
  import { defineComponent } from 'vue'
60
61
  export default defineComponent({
61
62
  name: 'ParticpantItem',
62
- mixins: [displayMethods],
63
+ mixins: [displayMethods, orgaComputed],
63
64
  props: {
64
65
  participant: { default: ()=>({}), type: Object as ()=> Participant},
65
66
  },
66
-
67
67
  data() {
68
68
  return {
69
69
  activeParticipant: true as boolean,
70
70
  };
71
71
  },
72
-
73
72
  computed: {
74
73
  isPodcastmaker(): boolean {
75
74
  return (state.generalParameters.podcastmaker as boolean);
76
75
  },
77
76
  name(): string {
78
- return (
79
- (this.participant.firstName || '') +
80
- ' ' +
81
- (this.participant.lastName || '')
82
- ).trim();
83
- },
84
- organisationId(): string|undefined {
85
- return state.generalParameters.organisationId;
86
- },
87
- authenticated(): boolean {
88
- return (state.generalParameters.authenticated as boolean);
77
+ return (`${this.participant.firstName||''} ${this.participant.lastName||''}`).trim();
89
78
  },
90
79
  editRight(): boolean {
91
80
  if(!this.participant || !this.participant.orga){
@@ -93,7 +82,7 @@ export default defineComponent({
93
82
  }
94
83
  if (
95
84
  (this.authenticated &&
96
- this.organisationId === this.participant.orga.id) ||
85
+ this.myOrganisationId === this.participant.orga.id) ||
97
86
  state.generalParameters.isAdmin
98
87
  ){
99
88
  return true;
@@ -1,43 +1,39 @@
1
1
  <template>
2
- <div class="d-flex flex-column align-items-center">
3
- <ClassicLoading
4
- :loading-text="loading?$t('Loading participants ...'):undefined"
5
- />
6
- <template v-if="isLoadingMoreOrFinished">
7
- <div
8
- v-if="showCount"
9
- class="text-secondary mb-2"
10
- >
11
- {{
12
- $t('Number participants', { nb: displayCount }) +" "+ $t('sort by score')
13
- }}
14
- </div>
2
+ <ListPaginate
3
+ id="participantListPaginate"
4
+ v-model:first="dfirst"
5
+ v-model:rowsPerPage="dsize"
6
+ v-model:isMobile="isMobile"
7
+ :text-count="showCount && displayCount > 1 ? `${$t('Number participants', { nb: displayCount })} ${$t('sort by score')}`: undefined"
8
+ :total-count="totalCount"
9
+ :loading="loading"
10
+ :loading-text="loading?$t('Loading participants ...'):undefined"
11
+ >
12
+ <template #list>
15
13
  <ul
16
14
  class="participant-list"
17
15
  >
18
- <ParticipantItem
19
- v-for="p in participants"
16
+ <template
17
+ v-for="p in displayArray"
20
18
  :key="p.participantId"
21
- :participant="p"
22
- />
19
+ >
20
+ <ParticipantItem
21
+ v-if="-1!==p.participantId"
22
+ :participant="p"
23
+ />
24
+ </template>
23
25
  </ul>
24
- <button
25
- v-show="!allFetched"
26
- class="btn btn-more saooti-more"
27
- :title="$t('See more')"
28
- :disabled="loading"
29
- @click="fetchContent(false)"
30
- />
31
26
  </template>
32
- </div>
27
+ </ListPaginate>
33
28
  </template>
34
29
 
35
30
  <script lang="ts">
31
+ import ListPaginate from '../list/ListPaginate.vue';
36
32
  import { handle403 } from '../../mixins/handle403';
37
33
  import octopusApi from '@saooti/octopus-api';
38
34
  import ParticipantItem from './ParticipantItem.vue';
39
- import ClassicLoading from '../../form/ClassicLoading.vue';
40
35
  import { Participant } from '@/store/class/general/participant';
36
+ import { emptyParticipantData } from '@/store/typeAppStore';
41
37
  import { defineComponent } from 'vue'
42
38
  import { AxiosError } from 'axios';
43
39
  export default defineComponent({
@@ -45,14 +41,14 @@ export default defineComponent({
45
41
 
46
42
  components: {
47
43
  ParticipantItem,
48
- ClassicLoading
44
+ ListPaginate
49
45
  },
50
46
 
51
47
  mixins: [handle403],
52
48
 
53
49
  props: {
54
50
  first: { default: 0, type: Number },
55
- size: { default: 12, type: Number },
51
+ size: { default: 30, type: Number },
56
52
  query: { default: undefined, type: String},
57
53
  organisationId: { default: undefined, type: String},
58
54
  showCount: { default: false, type: Boolean },
@@ -66,44 +62,51 @@ export default defineComponent({
66
62
  totalCount: 0 as number,
67
63
  displayCount: 0 as number,
68
64
  participants: [] as Array<Participant>,
65
+ isMobile: false as boolean,
69
66
  };
70
67
  },
71
68
 
72
69
 
73
70
  computed: {
74
- isLoadingMoreOrFinished():boolean{
75
- return !this.loading || this.participants.length > 1;
76
- },
77
- allFetched(): boolean {
78
- return this.dfirst >= this.totalCount;
79
- },
80
- filterOrga(): string {
81
- return this.$store.state.filter.organisationId;
82
- },
71
+ displayArray(): Array<Participant>{
72
+ if(this.isMobile){
73
+ return this.participants;
74
+ }
75
+ return this.participants.slice(this.dfirst, Math.min(this.dfirst + this.dsize,this.totalCount));
76
+ },
83
77
  organisation(): string|undefined {
84
78
  if (this.organisationId) return this.organisationId;
85
- if (this.filterOrga) return this.filterOrga;
79
+ if (this.$store.state.filter.organisationId) return this.$store.state.filter.organisationId;
86
80
  return undefined;
87
81
  },
88
82
  },
89
83
  watch: {
90
84
  query(): void {
91
- this.fetchContent(true);
85
+ this.reloadList();
92
86
  },
93
87
  organisation(): void {
94
- this.fetchContent(true);
88
+ this.reloadList();
95
89
  },
90
+ dsize():void{
91
+ this.reloadList();
92
+ },
93
+ dfirst(): void{
94
+ if(!this.participants[this.dfirst] || -1===this.participants[this.dfirst].participantId){
95
+ this.fetchContent(false);
96
+ }
97
+ },
96
98
  },
97
99
 
98
100
  created() {
99
101
  this.fetchContent(true);
100
102
  },
101
103
  methods: {
104
+ reloadList(){
105
+ this.dfirst = 0;
106
+ this.fetchContent(true);
107
+ },
102
108
  async fetchContent(reset: boolean): Promise<void> {
103
109
  this.loading = true;
104
- if (reset) {
105
- this.dfirst = 0;
106
- }
107
110
  try {
108
111
  const data = await octopusApi.fetchParticipants({
109
112
  first: this.dfirst,
@@ -113,16 +116,20 @@ export default defineComponent({
113
116
  });
114
117
  if (reset) {
115
118
  this.participants.length = 0;
116
- this.dfirst = 0;
117
119
  }
118
120
  this.displayCount = data.count;
119
- this.participants = this.participants.concat(data.result).filter((p: Participant | null) => {
121
+ if(this.dfirst > this.participants.length){
122
+ for (let i = this.participants.length-1, len = this.dfirst + this.dsize; i < len; i++) {
123
+ this.participants.push(emptyParticipantData());
124
+ }
125
+ }
126
+ const responseParticipants = data.result.filter((p: Participant | null) => {
120
127
  if (null === p) {
121
128
  this.displayCount--;
122
129
  }
123
130
  return null !== p;
124
131
  });
125
- this.dfirst += this.dsize;
132
+ this.participants = this.participants.slice(0, this.dfirst).concat(responseParticipants).concat(this.participants.slice(this.dfirst+this.dsize, this.participants.length));
126
133
  this.totalCount = data.count;
127
134
  } catch (error) {
128
135
  this.handle403((error as AxiosError));