@saooti/octopus-sdk 41.10.9 → 41.11.0-beta2

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.
@@ -0,0 +1,215 @@
1
+ <template>
2
+ <div v-if="displayIndicator">
3
+ <div v-if="!text">
4
+ <LockIcon
5
+ :id="iconId"
6
+ :class="{ invisible: hasAccess }"
7
+ aria-hidden="true"
8
+ fill-color="var(--octopus-primary)"
9
+ />
10
+ <ClassicPopover
11
+ v-if="!hasAccess"
12
+ :target="iconId"
13
+ only-mouse
14
+ >
15
+ {{ message }}
16
+ </ClassicPopover>
17
+ </div>
18
+ <ClassicAlert
19
+ v-else-if="!hasAccess"
20
+ type="info"
21
+ >
22
+ <template #icon>
23
+ <LockIcon
24
+ aria-hidden="true"
25
+ fill-color="var(--octopus-primary)"
26
+ />
27
+ </template>
28
+ {{ message }}
29
+ </ClassicAlert>
30
+ </div>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { Mix } from '../../stores/class/radio/mix';
35
+ import { PlaylistMedia } from '../../stores/class/radio/playlistMedia';
36
+ import { Podcast } from '../../stores/class/general/podcast';
37
+ import { Cartouchier } from '../../stores/class/cartouchier/cartouchier';
38
+ import { Media } from "../../stores/class/general/media";
39
+ import { computed, getCurrentInstance } from 'vue';
40
+ import { useI18n } from 'vue-i18n';
41
+ import LockIcon from 'vue-material-design-icons/Lock.vue';
42
+ import { ActionRight, useRights } from '../composable/useRights';
43
+ import ClassicAlert from '../misc/ClassicAlert.vue';
44
+ import ClassicPopover from '../misc/ClassicPopover.vue';
45
+ import { state } from '../../stores/ParamSdkStore';
46
+ import { useAuthStore } from '../../stores/AuthStore';
47
+ import { storeToRefs } from 'pinia';
48
+
49
+ const rights = useRights();
50
+ const { t, te } = useI18n();
51
+ const { isAuthenticated } = storeToRefs(useAuthStore());
52
+
53
+ type Action = 'create'|'edit'|'delete'|'any';
54
+
55
+ interface PropsBase {
56
+ /** Type of action to check */
57
+ action: Action;
58
+ /** Display reason as text instead of only tooltip */
59
+ text?: boolean;
60
+ }
61
+
62
+ type NeverEntities = {
63
+ podcast?: never;
64
+ cartouchier?: never;
65
+ mix?: never;
66
+ playlistMedia?: never;
67
+ media?: never;
68
+ };
69
+
70
+ interface PropsPodcast extends PropsBase, Omit<NeverEntities, 'podcast'> {
71
+ podcast: Podcast|boolean;
72
+ }
73
+ interface PropsCartouchier extends PropsBase, Omit<NeverEntities, 'cartouchier'> {
74
+ cartouchier: Cartouchier|boolean;
75
+ }
76
+ interface PropsMix extends PropsBase, Omit<NeverEntities, 'mix'> {
77
+ mix: Mix|boolean;
78
+ }
79
+ interface PropsPlaylistMedia extends PropsBase, Omit<NeverEntities, 'playlistMedia'> {
80
+ playlistMedia: PlaylistMedia|boolean;
81
+ }
82
+ interface PropsMedia extends PropsBase, Omit<NeverEntities, 'media'> {
83
+ media: Media|boolean;
84
+ }
85
+
86
+ const props = defineProps<PropsPodcast|PropsCartouchier|PropsMix|PropsPlaylistMedia|PropsMedia>();
87
+
88
+ type Rights = ReturnType<typeof useRights>;
89
+ type ActionSegment = 'Create'|'Edit'|'Delete';
90
+ type EntitySegment = 'Podcast'|'Cartouchier'|'Mix'|'PlaylistMedia'|'Media';
91
+ type RightMethodKey = `get${ActionSegment}${EntitySegment}Right` & keyof Rights;
92
+ type RightEntity = Podcast|Cartouchier|Mix|PlaylistMedia|Media|boolean|undefined;
93
+
94
+ const actionSegmentMap: Record<Exclude<Action, 'any'>, ActionSegment> = {
95
+ create: 'Create',
96
+ edit: 'Edit',
97
+ delete: 'Delete',
98
+ };
99
+
100
+ /**
101
+ * Whether to display the indicator
102
+ * It is not shown on podcastmaker, or for unidentified users
103
+ */
104
+ const displayIndicator = computed((): boolean => {
105
+ return !state.generalParameters.podcastmaker && isAuthenticated.value;
106
+ });
107
+
108
+ /**
109
+ * The entity on which rights are checked
110
+ */
111
+ const entity = computed((): [EntitySegment, RightEntity]|null => {
112
+ let arg: RightEntity;
113
+ let entitySegment: EntitySegment|undefined;
114
+
115
+ if ('podcast' in props && props.podcast) {
116
+ entitySegment = 'Podcast';
117
+ arg = props.podcast;
118
+ } else if ('cartouchier' in props && props.cartouchier) {
119
+ entitySegment = 'Cartouchier';
120
+ arg = props.cartouchier;
121
+ } else if ('mix' in props && props.mix) {
122
+ entitySegment = 'Mix';
123
+ arg = props.mix;
124
+ } else if ('playlistMedia' in props && props.playlistMedia) {
125
+ entitySegment = 'PlaylistMedia';
126
+ arg = props.playlistMedia;
127
+ } else if ('media' in props && props.media) {
128
+ entitySegment = 'Media';
129
+ arg = props.media;
130
+ } else {
131
+ return null;
132
+ }
133
+
134
+ return [entitySegment, arg];
135
+ });
136
+
137
+ /**
138
+ * The current rights for the given entity
139
+ */
140
+ const actionRight = computed((): ActionRight => {
141
+ const data = entity.value;
142
+ if (!data) {
143
+ return ActionRight.DeniedNoRight;
144
+ }
145
+
146
+ const [entitySegment, arg] = data;
147
+
148
+ if (props.action === 'any') {
149
+ const checks: ActionSegment[] = typeof arg === 'object' && arg !== null
150
+ ? ['Create', 'Edit', 'Delete']
151
+ : ['Create'];
152
+
153
+ let best = ActionRight.DeniedNoRight;
154
+ for (const a of checks) {
155
+ const key = `get${a}${entitySegment}Right` as RightMethodKey;
156
+ const r = callRightMethod(key, arg);
157
+ if (r === ActionRight.Allowed) {
158
+ return ActionRight.Allowed;
159
+ }
160
+ if (r === ActionRight.DeniedNotOwner) {
161
+ best = ActionRight.DeniedNotOwner;
162
+ }
163
+ }
164
+ return best;
165
+ }
166
+
167
+ if ((props.action === 'edit' || props.action === 'delete') && typeof arg !== 'object') {
168
+ return ActionRight.DeniedNoRight;
169
+ }
170
+
171
+ const methodName = `get${actionSegmentMap[props.action]}${entitySegment}Right` as RightMethodKey;
172
+ return callRightMethod(methodName, arg);
173
+ });
174
+
175
+ /** Helper for calling the method on useRights */
176
+ function callRightMethod(key: RightMethodKey, arg: unknown): ActionRight {
177
+ return (rights[key] as (arg?: unknown) => ActionRight)(arg);
178
+ }
179
+
180
+ const hasAccess = computed((): boolean => {
181
+ return actionRight.value === ActionRight.Allowed;
182
+ });
183
+
184
+ const message = computed((): string => {
185
+ const entitySegment = entity.value?.[0];
186
+ let key: string;
187
+ let genericKey: string;
188
+
189
+ switch (actionRight.value) {
190
+ case ActionRight.Allowed:
191
+ return '';
192
+
193
+ case ActionRight.DeniedNotOwner:
194
+ key = `RightsIndicator - ${entitySegment} - Not owner`;
195
+ genericKey = 'Generic - Action disabled - Not owner';
196
+ break;
197
+
198
+ case ActionRight.DeniedNoRight:
199
+ return 'insufficient rights';
200
+
201
+ default:
202
+ return 'Cannot process rights';
203
+ }
204
+
205
+ if (te(key)) {
206
+ return t(key);
207
+ } else {
208
+ return t(genericKey);
209
+ }
210
+ });
211
+
212
+ const uid = getCurrentInstance()?.uid;
213
+ /** ID of the icon for reference by the popover */
214
+ const iconId = computed((): string => 'rights-indicator-' + uid);
215
+ </script>
@@ -10,16 +10,21 @@
10
10
  <div
11
11
  class="p-2 pe-4 rounded d-flex alert"
12
12
  :class="cardClass"
13
+ :role="type === 'error' || type === 'warning' ? 'alert' : 'status'"
14
+ :aria-live="type === 'error' || type === 'warning' ? 'assertive' : 'polite'"
15
+ aria-atomic="true"
13
16
  >
14
- <!-- The icon -->
15
- <component
16
- :is="iconComponent"
17
- v-if="!noIcon"
18
- aria-hidden="true"
19
- focusable="false"
20
- class="icon"
21
- :size="text ? 22 : 30"
22
- />
17
+ <span aria-hidden="true">
18
+ <slot name="icon">
19
+ <!-- The icon -->
20
+ <component
21
+ :is="iconComponent"
22
+ v-if="!noIcon"
23
+ class="icon"
24
+ :size="text ? 22 : 30"
25
+ />
26
+ </slot>
27
+ </span>
23
28
 
24
29
  <!-- Main content -->
25
30
  <span class="ms-2 content">
@@ -41,7 +46,7 @@ import CheckCircle from 'vue-material-design-icons/CheckCircle.vue';
41
46
  import CloseCircle from 'vue-material-design-icons/CloseCircle.vue';
42
47
  import Information from 'vue-material-design-icons/Information.vue';
43
48
 
44
- const { type, text } = defineProps<{
49
+ const { type, title = undefined, text } = defineProps<{
45
50
  /** Disables the icon when true */
46
51
  noIcon?: boolean;
47
52
  /** An optional title for the alert */
@@ -1,5 +1,6 @@
1
1
  <!--
2
2
  Component to make a tab-based navigation
3
+ @deprecated Use ClassicTabs instead
3
4
  -->
4
5
  <template>
5
6
  <ul class="octopus-nav" :class="light ? 'light' : ''">
@@ -41,9 +42,13 @@
41
42
 
42
43
  //Props
43
44
  defineProps({
45
+ /** Number of tabs to display */
44
46
  tabNumber: { default: 0, type: Number },
47
+ /** Currently active tab */
45
48
  activeTab: { default: 0, type: Number },
49
+ /** Alternative css */
46
50
  transparent: { default: false, type: Boolean },
51
+ /** Alternative css */
47
52
  light: { default: false, type: Boolean },
48
53
  })
49
54
 
@@ -1,30 +1,31 @@
1
1
  <template>
2
- <div
3
- v-show="displayPopover"
4
- :id="'popover' + target"
5
- ref="popover"
6
- popover
7
- tabindex="0"
8
- class="octopus-popover border"
9
- :class="[
10
- displayPopover ? 'd-block': '',
11
- onlyClick ? 'octopus-dropdown' : '',
12
- isFixed && isTopLayerPopover ? 'position-fixed':'position-absolute',
13
- popoverClass]"
14
- :style="positionInlineStyle"
15
- @mouseenter="overPopover = true"
16
- @mouseleave="
17
- overPopover = false;
18
- clearData();
19
- "
20
- >
21
- <div v-if="title" class="bg-secondary-light p-2">
22
- {{ title }}
23
- </div>
24
- <div class="p-2">
25
- <slot>{{ content }}</slot>
2
+ <Teleport to="#app">
3
+ <div
4
+ v-show="displayPopover"
5
+ :id="'popover' + target"
6
+ ref="popover"
7
+ popover
8
+ tabindex="0"
9
+ class="octopus-popover border position-fixed"
10
+ :class="[
11
+ displayPopover ? 'd-block': '',
12
+ onlyClick ? 'octopus-dropdown' : '',
13
+ popoverClass]"
14
+ :style="positionInlineStyle"
15
+ @mouseenter="overPopover = true"
16
+ @mouseleave="
17
+ overPopover = false;
18
+ clearData();
19
+ "
20
+ >
21
+ <div v-if="title" class="bg-secondary-light p-2">
22
+ {{ title }}
23
+ </div>
24
+ <div class="p-2">
25
+ <slot>{{ content }}</slot>
26
+ </div>
26
27
  </div>
27
- </div>
28
+ </Teleport>
28
29
  </template>
29
30
 
30
31
  <script setup lang="ts">
@@ -40,13 +41,13 @@ const props = defineProps({
40
41
  onlyClick: { type: Boolean, default: false },
41
42
  onlyMouse: { type: Boolean, default: false },
42
43
  isFixed: { type: Boolean, default: false },
43
- /** Class(????) of the parent with relative positionning, must be set for proper positionning */
44
+ /** @deprecated No longer needed. The popover is teleported to body and always uses position:fixed. */
44
45
  relativeClass: { type: String, default: undefined },
45
46
  leftPos: { type: Boolean, default: false },
46
47
  topPos: { type: Boolean, default: false },
47
48
  popoverClass: { type: String, default: undefined },
48
49
  isTopLayer: { type: Boolean, default: false },
49
- /** If set to true, max height of popover will not overflow from parent */
50
+ /** @deprecated No longer needed. If set to true, max height of popover will not overflow from parent */
50
51
  constrainHeight: { type: Boolean, default: true }
51
52
  })
52
53
 
@@ -214,56 +215,24 @@ function setPopoverData(e: MouseEvent | PointerEvent) {
214
215
  openedByHover.value = true;
215
216
  }
216
217
  show.value = true;
217
- let parentLeft = 0;
218
- let parentTop = 0;
219
- let parentScrollTop = 0;
220
- let parentBottom = 0;
221
- let parentWidth=0;
222
218
  const popover = popoverRef?.value as HTMLElement;
223
- if (!isTopLayerPopover.value && props.relativeClass) {
224
- const modalBody = document.getElementsByClassName(props.relativeClass,)[0];
225
- if (undefined === modalBody) {
226
- popover.style.display = "block";
227
- posX.value = 0;
228
- posY.value = 0;
229
- return;
230
- }
231
- const modalBodyRect = modalBody.getBoundingClientRect();
232
- parentLeft = modalBodyRect.left;
233
- parentTop = modalBodyRect.top;
234
- parentScrollTop = modalBody.scrollTop;
235
- parentBottom=modalBodyRect.bottom;
236
- parentWidth = modalBodyRect.width;
237
- }
219
+ // The popover is teleported to <body> and uses position:fixed, so
220
+ // getBoundingClientRect() coordinates map directly to viewport coordinates.
238
221
  const rectElement = (e.target as HTMLElement).getBoundingClientRect();
239
222
  popover.style.display = "block";
240
223
  const sizePopover = popover.clientWidth;
241
- const sizeAvailable = parentWidth || window.innerWidth;
242
224
  if (props.leftPos) {
243
- handleLeftPos(rectElement, parentLeft, sizeAvailable, sizePopover);
225
+ handleLeftPos(rectElement, 0, window.innerWidth, sizePopover);
244
226
  } else {
245
- handleRightPos(rectElement, parentLeft, sizeAvailable, sizePopover);
227
+ handleRightPos(rectElement, 0, window.innerWidth, sizePopover);
246
228
  }
247
229
  posX.value = Math.max(0, posX.value);
248
230
  const yPosParent = props.topPos ? rectElement.top : rectElement.bottom;
249
231
  const yGap = props.topPos
250
232
  ? -5 - popover.clientHeight
251
233
  : 5;
252
-
253
- posY.value =
254
- yPosParent +
255
- parentScrollTop -
256
- parentTop +
257
- (props.isFixed ? 0 : window.scrollY) +
258
- yGap;
259
- if(isTopLayerPopover.value){
260
- posY.value = Math.max(0, posY.value);
261
- maxHeight.value = (window.innerHeight - posY.value) + "px";
262
- }else if(props.relativeClass && props.constrainHeight !== false) {
263
- maxHeight.value = (parentBottom- posY.value -parentTop) + "px";
264
- }else{
265
- maxHeight.value = '80dvh';
266
- }
234
+ posY.value = Math.max(0, yPosParent + yGap);
235
+ maxHeight.value = (window.innerHeight - posY.value) + "px";
267
236
  }
268
237
 
269
238
  function clearDataBlur(e: FocusEvent) {
@@ -0,0 +1,57 @@
1
+ <!--
2
+ Replacement component for ClassicNav
3
+ It is easier to use, and rely on user-defined ids to identify the slots,
4
+ instead of indices.
5
+ -->
6
+ <template>
7
+ <ClassicNav
8
+ v-model:active-tab="activeTab"
9
+ :tab-number="tabs.length"
10
+ >
11
+ <template v-for="(tab, index) in tabs" #[index]>
12
+ {{ tab.label }}
13
+ </template>
14
+
15
+ <template v-for="(tab, index) in tabs" #[tabSlotName(index)]>
16
+ <slot :name="'tab-' + tab.id" />
17
+ </template>
18
+ </ClassicNav>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { computed } from 'vue';
23
+ import ClassicNav from './ClassicNav.vue';
24
+
25
+ /** Type for the ID of tabs */
26
+ type TabId = string|number;
27
+
28
+ export interface Tab {
29
+ /** ID of the tab, used for slots */
30
+ id: TabId;
31
+ /** Label displayed for the tab */
32
+ label: string;
33
+ };
34
+
35
+ const props = defineProps<{
36
+ /** Tabs definition */
37
+ tabs: Array<Tab>;
38
+ /** Currently active tab */
39
+ activeTab: TabId;
40
+ }>();
41
+
42
+ const emit = defineEmits<{
43
+ /** Emitted when the tab changes */
44
+ (e: 'update:active-tab', tab: string|number): void;
45
+ }>();
46
+
47
+ /** Currently active tab, just a proxy */
48
+ const activeTab = computed({
49
+ get: () => props.tabs.findIndex(t => t.id === props.activeTab),
50
+ set: (index: number) => emit('update:active-tab', props.tabs[index].id)
51
+ });
52
+
53
+ /** Get the tab content slot name */
54
+ function tabSlotName(index: number): string {
55
+ return 'tab' + index;
56
+ }
57
+ </script>
@@ -425,5 +425,10 @@
425
425
  "Podcast - Season": "Jahreszeit",
426
426
  "Podcast - Episode number": "Episodennummer",
427
427
  "Player - Generating subtitles": "Generierung von Untertiteln in {language}…",
428
- "Transcript - Available languages": "Verfügbare Sprachen"
428
+ "Transcript - Available languages": "Verfügbare Sprachen",
429
+ "Generic - Action disabled - Not owner": "Diese Aktion ist nicht verfügbar, da Ihre Rechte es Ihnen nicht erlauben, Elemente zu ändern oder zu löschen, deren Eigentümer Sie nicht sind",
430
+ "RightsIndicator - Podcast - Not owner": "Dieser Podcast wurde von einem anderen Benutzer erstellt. Sie können ihn ansehen, aber nicht bearbeiten.",
431
+ "RightsIndicator - Cartouchier - Not owner": "Diese Patronenhülse wurde von einem anderen Benutzer erstellt. Sie können sie anzeigen, aber nicht ändern.",
432
+ "RightsIndicator - PlaylistMedia - Not owner": "Dieser Behälter wurde von einem anderen Benutzer erstellt. Sie können ihn anzeigen, aber nicht ändern.",
433
+ "RightsIndicator - Mix - Not owner": "Dieser Mix wurde von einem anderen Benutzer erstellt. Sie können ihn anzeigen, aber nicht bearbeiten."
429
434
  }
@@ -425,5 +425,10 @@
425
425
  "Podcast - Season": "Season",
426
426
  "Podcast - Episode number": "Episode number",
427
427
  "Player - Generating subtitles": "Generation of subtitles in {language}…",
428
- "Transcript - Available languages": "Languages ​​available"
428
+ "Transcript - Available languages": "Languages ​​available",
429
+ "Generic - Action disabled - Not owner": "This action is not available because your rights do not allow you to modify or delete elements of which you are not the owner",
430
+ "RightsIndicator - Podcast - Not owner": "This podcast was created by another user, you can view it, but you cannot edit it.",
431
+ "RightsIndicator - Cartouchier - Not owner": "This cartridge case was created by another user, you can view it, but you cannot modify it.",
432
+ "RightsIndicator - PlaylistMedia - Not owner": "This bin was created by another user, you can view it, but you cannot modify it.",
433
+ "RightsIndicator - Mix - Not owner": "This mix was created by another user, you can view it, but you cannot edit it."
429
434
  }
@@ -425,5 +425,10 @@
425
425
  "Podcast - Season": "Estación",
426
426
  "Podcast - Episode number": "Número de episodio",
427
427
  "Player - Generating subtitles": "Generación de subtítulos en {language}…",
428
- "Transcript - Available languages": "Idiomas disponibles"
428
+ "Transcript - Available languages": "Idiomas disponibles",
429
+ "Generic - Action disabled - Not owner": "Esta acción no está disponible porque tus derechos no te permiten modificar o eliminar elementos de los que no eres propietario",
430
+ "RightsIndicator - Podcast - Not owner": "Este podcast fue creado por otro usuario, puedes verlo, pero no puedes editarlo.",
431
+ "RightsIndicator - Cartouchier - Not owner": "Esta cartuchera fue creada por otro usuario, puedes verla, pero no puedes modificarla.",
432
+ "RightsIndicator - PlaylistMedia - Not owner": "Este contenedor fue creado por otro usuario, puedes verlo, pero no puedes modificarlo.",
433
+ "RightsIndicator - Mix - Not owner": "Esta mezcla fue creada por otro usuario, puedes verla, pero no puedes editarla."
429
434
  }
@@ -449,5 +449,11 @@
449
449
  "Podcast - Episode number": "Numéro d'épisode",
450
450
  "Player - Generating subtitles": "Génération des sous-titres en {language}…",
451
451
 
452
- "Transcript - Available languages": "Langues disponibles"
452
+ "Transcript - Available languages": "Langues disponibles",
453
+
454
+ "Generic - Action disabled - Not owner": "Cette action n'est pas disponible car vos droits ne vous permettent pas de modifier ou supprimer des éléments dont vous n'êtes pas propriétaire",
455
+ "RightsIndicator - Podcast - Not owner": "Ce podcast a été créé par un autre utilisateur, vous pouvez le consulter, mais vous ne pouvez pas le modifier.",
456
+ "RightsIndicator - Cartouchier - Not owner": "Ce cartouchier a été créé par un autre utilisateur, vous pouvez le consulter, mais vous ne pouvez pas le modifier.",
457
+ "RightsIndicator - PlaylistMedia - Not owner": "Ce bac a été créé par un autre utilisateur, vous pouvez le consulter, mais vous ne pouvez pas le modifier.",
458
+ "RightsIndicator - Mix - Not owner": "Ce mix a été créé par un autre utilisateur, vous pouvez le consulter, mais vous ne pouvez pas le modifier."
453
459
  }
@@ -426,5 +426,10 @@
426
426
  "Podcast - Season": "Stagione",
427
427
  "Podcast - Episode number": "Numero dell'episodio",
428
428
  "Player - Generating subtitles": "Generazione di sottotitoli in {language}…",
429
- "Transcript - Available languages": "Lingue disponibili"
429
+ "Transcript - Available languages": "Lingue disponibili",
430
+ "Generic - Action disabled - Not owner": "Questa azione non è disponibile perché i tuoi diritti non ti consentono di modificare o eliminare elementi di cui non sei proprietario",
431
+ "RightsIndicator - Podcast - Not owner": "Questo podcast è stato creato da un altro utente, puoi visualizzarlo, ma non puoi modificarlo.",
432
+ "RightsIndicator - Cartouchier - Not owner": "Questo bossolo è stato creato da un altro utente, puoi visualizzarlo, ma non puoi modificarlo.",
433
+ "RightsIndicator - PlaylistMedia - Not owner": "Questo contenitore è stato creato da un altro utente, puoi visualizzarlo, ma non puoi modificarlo.",
434
+ "RightsIndicator - Mix - Not owner": "Questo mix è stato creato da un altro utente, puoi visualizzarlo, ma non puoi modificarlo."
430
435
  }
@@ -424,5 +424,10 @@
424
424
  "Podcast - Season": "Sezona",
425
425
  "Podcast - Episode number": "Številka epizode",
426
426
  "Player - Generating subtitles": "Generiranje podnapisov v {language}…",
427
- "Transcript - Available languages": "Razpoložljivi jeziki"
427
+ "Transcript - Available languages": "Razpoložljivi jeziki",
428
+ "Generic - Action disabled - Not owner": "To dejanje ni na voljo, ker vam vaše pravice ne dovoljujejo spreminjanja ali brisanja elementov, katerih lastnik niste",
429
+ "RightsIndicator - Podcast - Not owner": "Ta podcast je ustvaril drug uporabnik, lahko si ga ogledate, ne morete pa ga urejati.",
430
+ "RightsIndicator - Cartouchier - Not owner": "Ta tulec je ustvaril drug uporabnik, lahko si ga ogledate, ne morete pa ga spreminjati.",
431
+ "RightsIndicator - PlaylistMedia - Not owner": "Ta koš je ustvaril drug uporabnik, lahko si ga ogledate, ne morete pa ga spreminjati.",
432
+ "RightsIndicator - Mix - Not owner": "Ta miks je ustvaril drug uporabnik, lahko si ga ogledate, ne morete pa ga urejati."
428
433
  }
@@ -21,9 +21,6 @@ export const useFilterStore = defineStore("FilterStore", () => {
21
21
  const filterRubriquage = ref<Array<Rubriquage>>([]);
22
22
  const filterRubrique = ref<Array<RubriquageFilter>>([]);
23
23
  const filterRubriqueDisplay = ref<Array<Rubrique>>([]);
24
- const filterTypeMedia = ref<string>();
25
- const filterSortOrder = ref<string>();
26
- const filterSortField = ref<string>();
27
24
  const filterLive = ref<boolean>(false);
28
25
  const filterIab = ref<Category>();
29
26
 
@@ -101,22 +98,6 @@ export const useFilterStore = defineStore("FilterStore", () => {
101
98
  filterRubriqueDisplay.value = rubriques.filter(rubrique=> rubrique);
102
99
  }
103
100
 
104
- function filterUpdateMedia(filter: {
105
- type?: string;
106
- order?: string;
107
- field?: string;
108
- }) {
109
- if (filter.type) {
110
- filterTypeMedia.value = filter.type;
111
- }
112
- if (filter.order) {
113
- filterSortOrder.value = filter.order;
114
- }
115
- if (filter.field) {
116
- filterSortField.value = filter.field;
117
- }
118
- }
119
-
120
101
  return {
121
102
  filterOrgaId,
122
103
  realOrgaId,
@@ -127,16 +108,12 @@ export const useFilterStore = defineStore("FilterStore", () => {
127
108
  filterUpdateIab,
128
109
  filterUpdateRubrique,
129
110
  filterUpdateRubriqueDisplay,
130
- filterUpdateMedia,
131
111
 
132
112
  filterImgUrl,
133
113
  filterName,
134
114
  filterRubriquage,
135
115
  filterRubrique,
136
116
  filterRubriqueDisplay,
137
- filterTypeMedia,
138
- filterSortOrder,
139
- filterSortField,
140
117
  filterLive,
141
118
  filterIab
142
119
  };
@@ -5,4 +5,6 @@ export interface Cartouchier {
5
5
  title: string;
6
6
  organisationId: string;
7
7
  cartouches: { [key: string]: Cartouche };
8
+ /** ID of the user that created this cartouchier */
9
+ ownerId?: string;
8
10
  }
@@ -14,6 +14,8 @@ export interface Media {
14
14
  cueIn?: number;
15
15
  cueOut?: number;
16
16
  bpm?: number;
17
+ /** ID of the user that created this cartouchier */
18
+ ownerId?: string;
17
19
  }
18
20
 
19
21
  export function emptyMediaData(): Media {
@@ -5,6 +5,8 @@ export interface Mix {
5
5
  name: string;
6
6
  organisationId: string;
7
7
  samplings: Array<MediaSampling>;
8
+ /** ID of the user that created this mix */
9
+ ownerId?: string;
8
10
  }
9
11
 
10
12
  export interface MediaSampling {
@@ -7,4 +7,6 @@ export interface PlaylistMedia {
7
7
  name: string;
8
8
  organisationId: string;
9
9
  medias: Array<Media>;
10
+ /** ID of the user that created this playlist media */
11
+ ownerId?: string;
10
12
  }