@saooti/octopus-sdk 41.1.15 → 41.2.1

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 (44) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/index.ts +29 -2
  3. package/package.json +1 -1
  4. package/src/api/groupsApi.ts +214 -0
  5. package/src/api/podcastApi.ts +47 -9
  6. package/src/components/buttons/ActionButton.vue +99 -0
  7. package/src/components/buttons/index.ts +5 -0
  8. package/src/components/composable/route/types.ts +11 -3
  9. package/src/components/composable/route/useAdvancedParamInit.ts +40 -13
  10. package/src/components/composable/useErrorHandler.ts +3 -2
  11. package/src/components/composable/useNotifications.ts +50 -0
  12. package/src/components/display/emission/EmissionGroupChooser.vue +56 -0
  13. package/src/components/display/emission/EmissionList.vue +8 -2
  14. package/src/components/display/filter/AdvancedSearch.vue +83 -23
  15. package/src/components/display/list/ListPaginate.vue +4 -1
  16. package/src/components/display/podcasts/PodcastList.vue +12 -5
  17. package/src/components/display/podcasts/PodcastPlayButton.vue +2 -2
  18. package/src/components/display/podcasts/TagList.vue +4 -1
  19. package/src/components/form/ClassicMultiselect.vue +43 -37
  20. package/src/components/icons.ts +13 -0
  21. package/src/components/misc/ClassicAlert.vue +8 -1
  22. package/src/components/misc/ClassicBigChip.vue +84 -0
  23. package/src/components/misc/ClassicDataTable.vue +98 -0
  24. package/src/components/misc/ClassicDataTable_Internal.vue +132 -0
  25. package/src/components/misc/ClassicHelpButton.vue +3 -3
  26. package/src/components/misc/ClassicNotifications.vue +23 -0
  27. package/src/components/misc/ClassicPopover.vue +1 -0
  28. package/src/components/pages/EmissionPage.vue +2 -2
  29. package/src/components/pages/EmissionsPage.vue +10 -15
  30. package/src/components/pages/PodcastPage.vue +1 -1
  31. package/src/components/pages/PodcastsPage.vue +8 -20
  32. package/src/helper/fetchHelper.ts +1 -0
  33. package/src/locale/de.ts +2 -0
  34. package/src/locale/en.ts +2 -0
  35. package/src/locale/es.ts +2 -0
  36. package/src/locale/fr.ts +5 -3
  37. package/src/locale/it.ts +2 -0
  38. package/src/locale/sl.ts +2 -0
  39. package/src/router/router.ts +14 -288
  40. package/src/router/routes.ts +236 -0
  41. package/src/router/utils.ts +43 -2
  42. package/src/stores/class/general/emission.ts +8 -2
  43. package/src/style/_variables.scss +3 -0
  44. package/src/style/bootstrap.scss +5 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 41.2.1 (05/01/2026)
4
+
5
+ **Fixes**
6
+
7
+ - Recherche avancées
8
+ - Correction chargements groupes & ayants-droits depuis routing
9
+ - Filtrage des groupes par organisation
10
+
11
+ **Misc**
12
+
13
+ - Export des routes principales pour réutilisation dans projets incluant le SDK
14
+
15
+ ## 41.2.0 (05/01/2026)
16
+
17
+ **Features**
18
+
19
+ - Ajout d'un système de notifications
20
+ - Intégrez `ClassicNotification` dans la vue principale pour afficher les
21
+ notifications
22
+ - Utilisez le composable `useNotifications` pour contrôler l'affichage des
23
+ notification depuis n'importe quel composant
24
+ - Ajout du composant `ClassicDataTable` pour afficher des tableaux de données
25
+ facilement
26
+ - Ajout du composant `ActionButton` pour faire un bouton déclenchant une action,
27
+ avec confirmation optionnelle
28
+ - Ajout du composant `ClassicBigChip` pour afficher des éléments simples
29
+ - Ajout du composant `EmissionGroupChooser` pour sélectionner un groupe
30
+ d'émissions parmis ceux définis
31
+ - Ajout de la bibliothèque d'icones `src/components/icons.ts` pour uniformiser
32
+ les icones au sein des différents projets
33
+ - Ajout de l'API groupes
34
+ - Ajout du filtrage par groupe sur les podcasts
35
+
36
+ **Fixes**
37
+
38
+ - Les mots-clés définis à la fois sur une émission et sur un épisode de cette
39
+ émissions ne s'affichent qu'une seule fois lors de la consultation de cet
40
+ épisode
41
+ - Le bouton de lecture vidéo ne disparait plus quand on lit une autre vidéo
42
+ - Correction des épisodes avec vidéos n'apparaissant plus lors de la
43
+ consultation des émissions
44
+ - `ClassicHelpButton` utilise le string `relative-class` au lieu du booléen
45
+ `relative` pour déterminer l'élément parent.
46
+
3
47
  ## 41.1.15 (19/12/2025)
4
48
 
5
49
  **Fixes**
package/index.ts CHANGED
@@ -40,11 +40,27 @@ export const getContractPreviewModal = () => import("./src/components/misc/modal
40
40
  export const getClassicModalInBody = () => import("./src/components/misc/modal/ClassicModalInBody.vue");
41
41
  export const getClassicHelpButton = () => import("./src/components/misc/ClassicHelpButton.vue");
42
42
  export const getClassicAlert = () => import("./src/components/misc/ClassicAlert.vue");
43
+ export const getClassicBigChip = () => import("./src/components/misc/ClassicBigChip.vue");
44
+
45
+ import ClassicDataTable, { type ClassicDataTableHeader } from "./src/components/misc/ClassicDataTable.vue";
46
+ import ClassicNotifications from "./src/components/misc/ClassicNotifications.vue";
47
+
48
+ export {
49
+ ClassicDataTable,
50
+ type ClassicDataTableHeader,
51
+ ClassicNotifications
52
+ }
53
+
54
+ // Buttons
55
+ import ActionButton from "./src/components/buttons/ActionButton.vue";
56
+ export { ActionButton };
57
+
43
58
  //Display
44
59
  export const getCategoryChooser = () => import("./src/components/display/categories/CategoryChooser.vue");
45
60
  export const getCategoryList = () => import("./src/components/display/categories/CategoryList.vue");
46
61
  export const getCategoryFilter = () => import("./src/components/display/categories/CategoryFilter.vue");
47
62
  export const getEmissionList = () => import("./src/components/display/emission/EmissionList.vue");
63
+ export const getEmissionGroupChooser = () => import("./src/components/display/emission/EmissionGroupChooser.vue");
48
64
  export const getOrganisationChooser = () => import("./src/components/display/organisation/OrganisationChooser.vue");
49
65
  export const getPodcastFilterList = () => import("./src/components/display/podcasts/PodcastFilterList.vue");
50
66
  export const getPodcastInlineList = () => import("./src/components/display/podcasts/PodcastInlineList.vue");
@@ -110,7 +126,7 @@ import {useOrganisationFilter} from "./src/components/composable/useOrganisation
110
126
  import {useInit} from "./src/components/composable/useInit.ts";
111
127
  import {useErrorHandler} from "./src/components/composable/useErrorHandler.ts";
112
128
  import { useSimplePageParam } from "./src/components/composable/route/useSimplePageParam";
113
-
129
+ import { useNotifications } from "./src/components/composable/useNotifications.ts";
114
130
 
115
131
  //helper
116
132
  import domHelper from "./src/helper/domHelper.ts";
@@ -135,11 +151,16 @@ import {useAuthStore} from "./src/stores/AuthStore.ts";
135
151
  import {getApiUrl, ModuleApi} from "./src/api/apiConnection.ts";
136
152
  import classicApi from "./src/api/classicApi.ts";
137
153
 
154
+ // API
138
155
  export { emissionApi } from "./src/api/emissionApi.ts";
156
+ export * from "./src/api/groupsApi.ts";
139
157
  export { organisationApi } from "./src/api/organisationApi.ts";
140
158
  export { playlistApi } from "./src/api/playlistApi.ts";
141
159
  export { podcastApi, PodcastSort, type PodcastSearchOptions } from "./src/api/podcastApi.ts";
142
160
 
161
+ // Types
162
+ export { type Emission, emptyEmissionData } from "./src/stores/class/general/emission.ts";
163
+
143
164
  //Icons
144
165
  export const getAmazonMusicIcon = () => import("./src/components/icons/AmazonMusicIcon.vue");
145
166
  export const getApplePodcastIcon = () => import("./src/components/icons/ApplePodcastIcon.vue");
@@ -155,12 +176,14 @@ export const getTuninIcon = () => import("./src/components/icons/TuninIcon.vue")
155
176
  export const getXIcon = () => import("./src/components/icons/XIcon.vue");
156
177
 
157
178
  // Routing
158
- import { setupRouter } from './src/router/utils';
179
+ import { setupRouter, getSimpleRouteProps, getRouteProps } from './src/router/utils';
180
+ import { routes as sdkRoutes } from './src/router/routes';
159
181
 
160
182
  // Types
161
183
  import { type SelectOption } from "./src/components/form/ClassicSelect.vue";
162
184
 
163
185
  import { ROUTE_PARAMS } from "./src/components/composable/route/types";
186
+ import { defineAsyncComponent } from "vue";
164
187
 
165
188
  export {
166
189
  useResizePhone,
@@ -173,6 +196,7 @@ export {
173
196
  useInit,
174
197
  useErrorHandler,
175
198
  useSimplePageParam,
199
+ useNotifications,
176
200
  debounce,
177
201
  useVastStore,
178
202
  useSaveFetchStore,
@@ -194,6 +218,9 @@ export {
194
218
  downloadHelper,
195
219
  displayHelper,
196
220
  setupRouter,
221
+ getSimpleRouteProps,
222
+ getRouteProps,
223
+ sdkRoutes,
197
224
  SelectOption,
198
225
  ROUTE_PARAMS
199
226
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "41.1.15",
3
+ "version": "41.2.1",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
@@ -0,0 +1,214 @@
1
+ import classicApi from "./classicApi";
2
+ import { ModuleApi } from "./apiConnection";
3
+ import { ListClassicReturn } from "../stores/class/general/listReturn";
4
+ import { Emission } from "@/stores/class/general/emission";
5
+ import { mapFromGetAll } from "./apiUtils";
6
+
7
+ const BASE_PATH = 'emission/groups/';
8
+
9
+ /** Group of emissions */
10
+ export interface EmissionGroup {
11
+ /** Name of the group */
12
+ name: string;
13
+ /** Id of the group */
14
+ groupId: number;
15
+ /** Simple description */
16
+ description?: string;
17
+ /** The id of the organisation this group belongs to */
18
+ organisationId: string;
19
+ /** The list of ids of emissions in this group */
20
+ emissionIds: Array<number>|null;
21
+ /** If set, defines this group as a "marque" group. */
22
+ acpmMarque: string|null;
23
+ }
24
+
25
+ interface Pagination {
26
+ /** Pagination */
27
+ first: number;
28
+ /** Number of elements */
29
+ size: number;
30
+ }
31
+
32
+ interface SearchParams {
33
+ /** Filter by acpm */
34
+ acpmMarque: string;
35
+ /** Filter by name */
36
+ search: string;
37
+ /** Filter by organisations */
38
+ organisationIds: Array<string>;
39
+ }
40
+
41
+ /**
42
+ * Add an emission to a list of groups
43
+ * @param emission The emission to add to the groups
44
+ * @param groups The list of groups to add the emission to
45
+ */
46
+ async function addToGroups(emission: Emission|number, groups: Array<EmissionGroup>|Array<number>): Promise<void> {
47
+ if (groups.length === 0) {
48
+ return;
49
+ }
50
+
51
+ let emissionId: number;
52
+ if (typeof emission === 'object') {
53
+ emissionId = emission.emissionId;
54
+ } else {
55
+ emissionId = emission;
56
+ }
57
+ let groupIds: Array<number>;
58
+ if (typeof groups[0] === 'object') {
59
+ groupIds = (groups as Array<EmissionGroup>).map(g => g.groupId);
60
+ } else {
61
+ groupIds = groups as Array<number>;
62
+ }
63
+
64
+ return classicApi.putData({
65
+ api: ModuleApi.DEFAULT,
66
+ path: BASE_PATH + 'add/' + emissionId,
67
+ dataToSend: groupIds
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Create a new group
73
+ */
74
+ async function create(group: Omit<EmissionGroup, 'groupId'|'emissionIds'>): Promise<EmissionGroup> {
75
+ return classicApi.postData<EmissionGroup>({
76
+ api: ModuleApi.DEFAULT,
77
+ path: BASE_PATH,
78
+ dataToSend: group
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Delete a group
84
+ */
85
+ async function remove(groupId: number): Promise<void> {
86
+ return classicApi.deleteData({
87
+ api: ModuleApi.DEFAULT,
88
+ path: BASE_PATH + groupId
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Retrieve a group by its ID
94
+ * @param groupId The ID of the group to retrieve
95
+ * @return The group
96
+ */
97
+ async function get(groupId: number): Promise<EmissionGroup> {
98
+ return classicApi.fetchData<EmissionGroup>({
99
+ api: ModuleApi.DEFAULT,
100
+ path: BASE_PATH + groupId
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Retrieve all groups specified by their IDs
106
+ * @param groupIds A list of group IDs. For better result, they
107
+ should be unique.
108
+ * @return The matching groups
109
+ */
110
+ async function getAllById(groupIds: Array<number>): Promise<Record<string, EmissionGroup>> {
111
+ return mapFromGetAll(groupIds, get, 'groupId');
112
+ }
113
+
114
+ /**
115
+ * Remove an emission from a list of groups
116
+ * @param emission The emission to remove from the groups
117
+ * @param groups The list of groups to remove the emission from
118
+ */
119
+ async function removeFromGroups(emission: Emission|number, groups: Array<EmissionGroup>|Array<number>): Promise<void> {
120
+ if (groups.length === 0) {
121
+ return;
122
+ }
123
+
124
+ let emissionId: number;
125
+ if (typeof emission === 'object') {
126
+ emissionId = emission.emissionId;
127
+ } else {
128
+ emissionId = emission;
129
+ }
130
+ let groupIds: Array<number>;
131
+ if (typeof groups[0] === 'object') {
132
+ groupIds = (groups as Array<EmissionGroup>).map(g => g.groupId);
133
+ } else {
134
+ groupIds = groups as Array<number>;
135
+ }
136
+
137
+ return classicApi.putData({
138
+ api: ModuleApi.DEFAULT,
139
+ path: BASE_PATH + 'remove/' + emissionId,
140
+ dataToSend: groupIds
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Update a group
146
+ */
147
+ async function update(group: Omit<EmissionGroup, 'emissionIds'>): Promise<EmissionGroup> {
148
+ return classicApi.putData({
149
+ api: ModuleApi.DEFAULT,
150
+ path: BASE_PATH,
151
+ dataToSend: group
152
+ });
153
+ }
154
+
155
+ /**
156
+ * Count number of groups
157
+ */
158
+ async function count(parameters: Partial<SearchParams>): Promise<number> {
159
+ const result = await search({
160
+ ...parameters,
161
+ size: 0
162
+ });
163
+
164
+ return result.count;
165
+ }
166
+
167
+ /**
168
+ * Search groups
169
+ */
170
+ async function search(parameters: Partial<SearchParams & Pagination>): Promise<ListClassicReturn<EmissionGroup>> {
171
+ return classicApi.fetchData<ListClassicReturn<EmissionGroup>>({
172
+ api: ModuleApi.DEFAULT,
173
+ path: BASE_PATH + 'search',
174
+ parameters
175
+ });
176
+ }
177
+
178
+ /**
179
+ * Search for all groups, without pagination
180
+ */
181
+ async function searchNoPagination(parameters: Partial<SearchParams>): Promise<Array<EmissionGroup>> {
182
+ const result: Array<EmissionGroup> = [];
183
+
184
+ let index = 0;
185
+ while (true) {
186
+ const response = await search({
187
+ ...parameters,
188
+ first: index,
189
+ size: 1
190
+ });
191
+
192
+ result.push(...response.result);
193
+ index += response.result.length;
194
+
195
+ if (index >= response.count || response.result.length === 0) {
196
+ break;
197
+ }
198
+ }
199
+
200
+ return result;
201
+ }
202
+
203
+ export const groupsApi = {
204
+ addToGroups,
205
+ count,
206
+ create,
207
+ remove,
208
+ get,
209
+ getAllById,
210
+ removeFromGroups,
211
+ update,
212
+ search,
213
+ searchNoPagination
214
+ };
@@ -6,6 +6,9 @@ import { ModuleApi } from './apiConnection';
6
6
  import { unique } from '../helper/arrayHelper';
7
7
  import { organisationApi } from './organisationApi';
8
8
  import { emissionApi } from './emissionApi';
9
+ import { EmissionGroup } from './groupsApi';
10
+ import { FetchParam } from '@/stores/class/general/fetchParam';
11
+ import { toRaw } from 'vue';
9
12
 
10
13
  export enum PodcastSort {
11
14
  DATE = 'DATE',
@@ -41,6 +44,8 @@ interface Paginable<S> {
41
44
  export interface PodcastSearchOptions extends Paginable<PodcastSort> {
42
45
  /** Filter by emission ID */
43
46
  emissionId?: number|number[];
47
+ /** Filter by emission groups */
48
+ emissionGroups?: EmissionGroup[];
44
49
  /** Filter by organisation ID */
45
50
  organisationId?: string[];
46
51
  /** Filter by title containing */
@@ -103,6 +108,47 @@ function get(podcastId: number): Promise<Podcast> {
103
108
  });
104
109
  }
105
110
 
111
+
112
+ /**
113
+ * Convert easy to use PodcastSearchOptions to the actual FetchParams used by
114
+ * the endpoint.
115
+ */
116
+ function processSearchParameters(search: PodcastSearchOptions): FetchParam {
117
+ const parameters: FetchParam = {};
118
+
119
+ Object.keys(search).forEach(key => {
120
+ const value = search[key];
121
+
122
+ if (value === undefined || value === null) {
123
+ return;
124
+ }
125
+
126
+ if (key === 'beneficiaries') {
127
+ parameters.beneficiary = value;
128
+ } else if (key === 'processingStatus') {
129
+ parameters.includeStatus = value;
130
+ } else if (key === 'tags') {
131
+ parameters.includeTags = value;
132
+ } else if (key === 'pubDateBefore') {
133
+ parameters.before = value;
134
+ } else if (key === 'pubDateAfter') {
135
+ parameters.after = value;
136
+ } else if (key === 'pageSize') {
137
+ parameters.size = value;
138
+ } else if (key === 'emissionGroups') {
139
+ const emissionIds = [search.emissionId ?? undefined].flat();
140
+ search.emissionGroups.forEach(group => {
141
+ emissionIds.push(...group.emissionIds);
142
+ });
143
+ parameters.emissionId = emissionIds;
144
+ } else {
145
+ parameters[key] = value;
146
+ }
147
+ });
148
+
149
+ return parameters;
150
+ }
151
+
106
152
  /**
107
153
  * Search for podcasts. Retrieved podcasts are 'incomplete', some of their
108
154
  * properties are only IDs.
@@ -115,15 +161,7 @@ function search(options: PodcastSearchOptions, adaptParameters?: boolean): Promi
115
161
  return classicApi.fetchData<ListClassicReturn<SimplifiedPodcast>>({
116
162
  api: ModuleApi.DEFAULT,
117
163
  path: 'v2/podcast/search',
118
- parameters: {
119
- ...options,
120
- beneficiary: options.beneficiaries,
121
- includeStatus: options.processingStatus,
122
- includeTags: options.tags,
123
- before: options.pubDateBefore,
124
- after: options.pubDateAfter,
125
- size: options.pageSize ?? 50
126
- },
164
+ parameters: processSearchParameters(options),
127
165
  specialTreatement: adaptParameters
128
166
  });
129
167
  }
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div>
3
+ <!-- The button with an icon to trigger the action -->
4
+ <button
5
+ class="btn btn-transparent"
6
+ :title="action"
7
+ @click="onClick"
8
+ >
9
+ <component :is="icon" />
10
+ </button>
11
+
12
+ <!-- Modal to ask for confirmation -->
13
+ <MessageModal
14
+ v-if="showModal"
15
+ :title="confirmModal.title"
16
+ :message="confirmModal.message"
17
+ :validatetext="$t('Yes')"
18
+ :canceltext="$t('No')"
19
+ @validate="onConfirmModal"
20
+ @cancel="showModal = false"
21
+ @close="showModal = false"
22
+ />
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { type Component, computed, ref } from 'vue';
28
+ import MessageModal from '../misc/modal/MessageModal.vue';
29
+ import Icons from '../icons';
30
+
31
+ /** Actions available to the button */
32
+ enum Action {
33
+ Edit = 'edit',
34
+ Delete = 'delete'
35
+ }
36
+
37
+ export interface ConfirmModalData {
38
+ title: string;
39
+ message: string;
40
+ }
41
+
42
+ const { action, confirmModal } = defineProps<{
43
+ /** The type of action provided by the button */
44
+ action: Action;
45
+ /** When set, clicking on the button will first open a confirm modal */
46
+ confirmModal?: ConfirmModalData;
47
+ }>();
48
+
49
+ const emit = defineEmits<{
50
+ /**
51
+ * Event trigger when the button is clicked, or after confirmation in the
52
+ * modal if `withConfirmModal` is true.
53
+ */
54
+ (e: 'click'): void
55
+ }>();
56
+
57
+ /************************
58
+ * Using button
59
+ ***********************/
60
+
61
+ /** Method called when clicking on button */
62
+ function onClick(): void {
63
+ if (confirmModal === undefined) {
64
+ emit('click');
65
+ } else {
66
+ showModal.value = true;
67
+ }
68
+ }
69
+
70
+ /***********************
71
+ * Modal
72
+ **********************/
73
+ /** Display modal when true */
74
+ const showModal = ref(false);
75
+
76
+ /** Method called when the modal is validated */
77
+ function onConfirmModal(): void {
78
+ showModal.value = false;
79
+ emit('click');
80
+ }
81
+
82
+ /***********************
83
+ * Button appearance
84
+ **********************/
85
+
86
+ /** The icon displayed by the button */
87
+ const icon = computed((): Component => {
88
+ switch (action) {
89
+ case Action.Edit:
90
+ return Icons.Edit;
91
+
92
+ case Action.Delete:
93
+ return Icons.Delete;
94
+
95
+ default:
96
+ return;
97
+ }
98
+ });
99
+ </script>
@@ -0,0 +1,5 @@
1
+ import ActionButton from "./ActionButton.vue";
2
+
3
+ export {
4
+ ActionButton
5
+ };
@@ -14,6 +14,8 @@ export interface RouteProps {
14
14
  routeRubriques?: string;
15
15
  /** The filter on beneficiaries defined on the route props */
16
16
  routeBeneficiaries?: string[];
17
+ /** The filter on emission groups defined on the route props */
18
+ routeEmissionGroups?: number[];
17
19
  }
18
20
 
19
21
  type DateStr = string;
@@ -32,16 +34,22 @@ export interface AdvancedRouteParams extends RouteParams {
32
34
  to?: DateStr;
33
35
  /** When set, filter on beneficiaries */
34
36
  b?: string[];
37
+ /** When set, filter on topics */
38
+ r?: string;
35
39
  q?: string;
40
+ /** When set, filter on groups */
41
+ gp?: number[];
36
42
  }
37
43
 
38
44
  type RouteParamEnum =
39
45
  'Beneficiaries' |
40
- 'Query'
46
+ 'Query' |
47
+ 'EmissionGroups'
41
48
  ;
42
49
 
43
50
  /** Utility to access route params by constants instead of undefined value */
44
51
  export const ROUTE_PARAMS: Record<RouteParamEnum, keyof AdvancedRouteParams> = {
45
52
  Beneficiaries: 'b',
46
- Query: 'q'
47
- };
53
+ Query: 'q',
54
+ EmissionGroups: 'gp'
55
+ };
@@ -8,6 +8,7 @@ import { computed, nextTick, onMounted, Ref, ref, watch } from "vue";
8
8
  import dayjs from "dayjs";
9
9
 
10
10
  import { RouteProps } from "./types";
11
+ import { EmissionGroup, groupsApi } from "../../../api/groupsApi";
11
12
 
12
13
  export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) => {
13
14
 
@@ -29,7 +30,7 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
29
30
  const iabId: Ref<number|undefined> = ref(undefined);
30
31
  const rubriqueFilter: Ref<Array<RubriquageFilter>> = ref([]);
31
32
  const beneficiaries = ref<string[]|null>(null);
32
-
33
+ const emissionGroups = ref<EmissionGroup[]|null>(null);
33
34
 
34
35
  const organisationRight = computed(() => isEditRights(organisationId.value));
35
36
  const organisation = computed(() => organisationId.value ?? filterStore.filterOrgaId);
@@ -53,17 +54,18 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
53
54
  }
54
55
  });
55
56
 
56
- watch(() => props.routeQuery, () => initSearchPattern());
57
- watch(() => props.routeMonetisable, () => initMonetisable());
58
- watch(() => props.routeSort, () => initSort());
59
- watch(() => props.routeIncludeHidden, () => initIncludeHidden());
60
- watch(() => props.routeValidity, () => initValidity());
61
- watch(() => props.routeFrom, () => initFromDate());
62
- watch(() => props.routeTo, () => initToDate());
57
+ watch(() => props.routeQuery, initSearchPattern);
58
+ watch(() => props.routeMonetisable, initMonetisable);
59
+ watch(() => props.routeSort, initSort);
60
+ watch(() => props.routeIncludeHidden, initIncludeHidden);
61
+ watch(() => props.routeValidity, initValidity);
62
+ watch(() => props.routeFrom, initFromDate);
63
+ watch(() => props.routeTo, initToDate);
63
64
  watch(() => props.routeIab, () => {iabId.value = props.routeIab;});
64
- watch(() => props.routeOrga, () => initOrga());
65
- watch(() => props.routeRubriques, () => initRubriquageFilter());
65
+ watch(() => props.routeOrga, initOrga);
66
+ watch(() => props.routeRubriques, initRubriquageFilter);
66
67
  watch(() => props.routeBeneficiaries, initBeneficiariesFilter);
68
+ watch(() => props.routeEmissionGroups, initEmissionGroups);
67
69
  watch(organisationId, () => {
68
70
  if (!isInit.value) {
69
71
  return;
@@ -84,6 +86,8 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
84
86
  initSort();
85
87
  initFromDate();
86
88
  initToDate();
89
+ initBeneficiariesFilter();
90
+ initEmissionGroups();
87
91
  nextTick(() => {
88
92
  isInit.value = true;
89
93
  });
@@ -135,7 +139,7 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
135
139
  return
136
140
  }
137
141
  const rubriqueFilterToUpdate = [];
138
- if(props.routeRubriques.trim().length){
142
+ if(props.routeRubriques?.trim().length){
139
143
  const arrayFilter = props.routeRubriques.split(",");
140
144
  for(const filter of arrayFilter){
141
145
  const rubriqueFilter = filter.split(":");
@@ -151,7 +155,7 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
151
155
  }
152
156
 
153
157
  function initBeneficiariesFilter() {
154
- const data = props.routeBeneficiaries as string[];
158
+ const data = props.routeBeneficiaries;
155
159
  // No beneficiaries
156
160
  if (
157
161
  data === undefined ||
@@ -170,6 +174,28 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
170
174
  beneficiaries.value = data;
171
175
  }
172
176
 
177
+ async function initEmissionGroups(): Promise<void> {
178
+ const data = props.routeEmissionGroups;
179
+ // No groups
180
+ if (
181
+ data === undefined ||
182
+ data === null ||
183
+ data.length === 0
184
+ ) {
185
+ emissionGroups.value = null;
186
+ return;
187
+ }
188
+
189
+ // No changes
190
+ if(emissionGroups.value && data === emissionGroups.value.map(g => g.groupId)){
191
+ return;
192
+ }
193
+
194
+ const groups = await groupsApi.getAllById(data);
195
+
196
+ emissionGroups.value = Object.values(groups);
197
+ }
198
+
173
199
  return {
174
200
  organisationId,
175
201
  searchPattern,
@@ -185,6 +211,7 @@ export const useAdvancedParamInit = (props: RouteProps, isEmission: boolean) =>
185
211
  validity,
186
212
  rubriquesFilterArrayIds,
187
213
  isInit,
188
- beneficiaries
214
+ beneficiaries,
215
+ emissionGroups
189
216
  };
190
217
  }