diff --git a/src/components/AppNavigation/CalendarList.vue b/src/components/AppNavigation/CalendarList.vue index 7e32e374dc..ed37317380 100644 --- a/src/components/AppNavigation/CalendarList.vue +++ b/src/components/AppNavigation/CalendarList.vue @@ -101,6 +101,19 @@ :calendar="calendar" /> + + @@ -122,6 +135,9 @@ import CalendarListItemLoadingPlaceholder from './CalendarList/CalendarListItemL import CalendarListNew from './CalendarList/CalendarListNew.vue' import PublicCalendarListItem from './CalendarList/PublicCalendarListItem.vue' import useCalendarsStore from '../../store/calendars.js' +import useDelegationStore from '../../store/delegation.ts' +import usePrincipalsStore from '../../store/principals.js' +import { isAfterVersion } from '../../utils/nextcloudVersion.ts' const limit = pLimit(1) @@ -153,13 +169,14 @@ export default { return { calendars: [], /** - * Calendars sorted by personal, shared, deck, and tasks + * Calendars sorted by personal, shared, deck, and delegated */ sortedCalendars: { personal: [], shared: [], deck: [], tasks: [], + delegated: [], }, disableDragging: false, @@ -168,7 +185,7 @@ export default { }, computed: { - ...mapStores(useCalendarsStore), + ...mapStores(useCalendarsStore, useDelegationStore, usePrincipalsStore), ...mapState(useCalendarsStore, { serverCalendars: 'sortedCalendarsSubscriptions', }), @@ -176,6 +193,35 @@ export default { loadingKeyCalendars() { return this._uid + '-loading-placeholder-calendars' }, + + isDelegationSupported() { + return isAfterVersion(34) + }, + + /** + * Delegated calendars grouped by the delegator (the user who granted + * proxy access), which may differ from each calendar's owner when the + * delegator only has access via a regular share. + * + * @return {Array<{delegatorUrl: string, displayname: string, calendars: object[]}>} + */ + delegatedGroups() { + const groups = new Map() + for (const calendar of this.sortedCalendars.delegated) { + const delegatorUrl = calendar.delegatorUrl || calendar.owner || '' + if (!groups.has(delegatorUrl)) { + const principal = this.principalsStore.getPrincipalByUrl(delegatorUrl) + groups.set(delegatorUrl, { + delegatorUrl, + displayname: principal?.displayname || principal?.userId || '', + readOnly: !!calendar.readOnly, + calendars: [], + }) + } + groups.get(delegatorUrl).calendars.push(calendar) + } + return Array.from(groups.values()) + }, }, watch: { @@ -208,9 +254,15 @@ export default { shared: [], deck: [], tasks: [], + delegated: [], } this.calendars.forEach((calendar) => { + if (calendar.isDelegated) { + this.sortedCalendars.delegated.push(calendar) + return + } + if (calendar.isSharedWithMe) { this.sortedCalendars.shared.push(calendar) return diff --git a/src/components/AppNavigation/CalendarList/CalendarListItem.vue b/src/components/AppNavigation/CalendarList/CalendarListItem.vue index b8cc504872..c2501a76ea 100644 --- a/src/components/AppNavigation/CalendarList/CalendarListItem.vue +++ b/src/components/AppNavigation/CalendarList/CalendarListItem.vue @@ -26,16 +26,36 @@