diff --git a/src/components/AppNavigation/CalendarList/Trashbin.vue b/src/components/AppNavigation/CalendarList/Trashbin.vue
index 8df203f3e0..d77d06297c 100644
--- a/src/components/AppNavigation/CalendarList/Trashbin.vue
+++ b/src/components/AppNavigation/CalendarList/Trashbin.vue
@@ -70,11 +70,11 @@
-
+
{{ t('calendar', 'Restore') }}
-
+
@@ -164,6 +164,7 @@ export default {
url: calendar._url,
deletedAt: calendar._props['{http://nextcloud.com/ns}deleted-at'],
color: calendar.color ?? uidToHexColor(calendar.displayname),
+ readonly: false,
}))
const formattedCalendarObjects = this.objects.map((vobject) => {
let eventSummary = t('calendar', 'Untitled item')
@@ -185,6 +186,8 @@ export default {
const color = vobject.calendarComponent.getComponentIterator().next().value?.color
?? vobject.calendar?.color
?? uidToHexColor(subline)
+ const canDelete = vobject.calendar?.canDeleteObject
+ const canRestore = vobject.calendar?.canCreateObject && vobject.calendar?.canModifyObject
return {
vobject,
type: 'object',
@@ -194,6 +197,8 @@ export default {
url: vobject.uri,
deletedAt: vobject.dav._props['{http://nextcloud.com/ns}deleted-at'],
color,
+ canDelete,
+ canRestore,
}
})
@@ -281,6 +286,9 @@ export default {
return
}
this.items.forEach((item) => {
+ if (!this.canModify(item)) {
+ return
+ }
this.onDeletePermanently(item)
})
},
diff --git a/src/store/calendars.js b/src/store/calendars.js
index 3892c9da5b..6bd28cb29c 100644
--- a/src/store/calendars.js
+++ b/src/store/calendars.js
@@ -126,17 +126,40 @@ export default defineStore('calendars', {
* @return {Array}
*/
allDeletedCalendarObjects(state) {
- const calendarUriMap = {}
+ const lastSegment = (uri) => (uri ?? '').split('/').filter(Boolean).at(-1) ?? ''
+
+ const sourceUriOf = (calendar) => {
+ const tail = lastSegment(calendar.url)
+ const at = tail.lastIndexOf('_shared_by_')
+ if (at > 0) {
+ return tail.slice(0, at)
+ }
+ return tail
+ }
+
+ // Key calendars by `${ownerUserId}|${sourceUri}` so deleted objects
+ // match their origin calendar across owned/shared/delegated views.
+ const calendarBySource = new Map()
state.calendars.forEach((calendar) => {
- const withoutTrail = calendar.url.replace(/\/$/, '')
- const uri = withoutTrail.slice(withoutTrail.lastIndexOf('/') + 1)
- calendarUriMap[uri] = calendar
+ let key = `${lastSegment(calendar.owner)}|${sourceUriOf(calendar)}`
+ if (calendar.isDelegated) {
+ key += lastSegment(calendar.delegatorUrl)
+ }
+ calendarBySource.set(key, calendar)
})
- return state.deletedCalendarObjects.map((obj) => ({
- calendar: calendarUriMap[obj.dav._props['{http://nextcloud.com/ns}calendar-uri']],
- ...obj,
- }))
+ return state.deletedCalendarObjects.map((obj) => {
+ const owner = obj.dav.calendarOwnerPrincipalUri
+ const sourceUri = obj.dav.sourceCalendarUri
+ let key = `${lastSegment(owner)}|${sourceUri}`
+ if (obj.dav.delegator) {
+ key += lastSegment(obj.dav.delegator)
+ }
+ return {
+ calendar: calendarBySource.get(key),
+ ...obj,
+ }
+ })
},
/**
|