diff --git a/src/mixins/EditorMixin.js b/src/mixins/EditorMixin.js index a25a3a85c1..5235afbc03 100644 --- a/src/mixins/EditorMixin.js +++ b/src/mixins/EditorMixin.js @@ -425,6 +425,14 @@ export default { isCreateTalkRoomButtonVisible() { return this.talkEnabled && this.isViewedByOrganizer !== false && this.isReadOnly !== true }, + /** + * Returns true if at least one writable calendar exists + * + * @return {boolean} + */ + hasWritableCalendars() { + return this.calendarsStore.sortedCalendarsAllowingCreate.length > 0 + }, }, async created() { @@ -666,6 +674,8 @@ export default { */ async duplicateEvent() { await this.calendarObjectInstanceStore.duplicateCalendarObjectInstance() + // Update the local calendarId to match the new calendar object + this.calendarId = this.calendarObject.calendarId }, /** diff --git a/src/store/calendarObjectInstance.js b/src/store/calendarObjectInstance.js index 9f14636764..3b5d859e04 100644 --- a/src/store/calendarObjectInstance.js +++ b/src/store/calendarObjectInstance.js @@ -1546,17 +1546,31 @@ export default defineStore('calendarObjectInstance', { */ async duplicateCalendarObjectInstance() { const calendarObjectsStore = useCalendarObjectsStore() + const calendarsStore = useCalendarsStore() const oldCalendarObjectInstance = this.calendarObjectInstance const oldEventComponent = oldCalendarObjectInstance.eventComponent const startDate = oldEventComponent.startDate.getInUTC() const endDate = oldEventComponent.endDate.getInUTC() + + // Determine the target calendar ID + let targetCalendarId = this.calendarObject?.calendarId ?? null + const currentCalendar = targetCalendarId ? calendarsStore.getCalendarById(targetCalendarId) : null + + // If the source calendar is read-only, use the first writable calendar + if (currentCalendar?.readOnly) { + const writableCalendars = calendarsStore.sortedCalendarsAllowingCreate + if (writableCalendars.length > 0) { + targetCalendarId = writableCalendars[0].id + } + } + const calendarObject = await calendarObjectsStore.createNewEvent({ start: startDate.unixTime, end: endDate.unixTime, timezoneId: oldEventComponent.startDate.timezoneId, isAllDay: oldEventComponent.isAllDay(), - calendarId: this.calendarObject?.calendarId ?? null, + calendarId: targetCalendarId, }) const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate.jsDate) copyCalendarObjectInstanceIntoEventComponent(oldCalendarObjectInstance, eventComponent, true) diff --git a/src/store/calendars.js b/src/store/calendars.js index 3892c9da5b..6f5fed98ab 100644 --- a/src/store/calendars.js +++ b/src/store/calendars.js @@ -78,6 +78,20 @@ export default defineStore('calendars', { .sort((a, b) => a.order - b.order) }, + /** + * List of sorted calendars that allow creating objects + * + * @param {object} state the store data + * @return {Array} + */ + sortedCalendarsAllowingCreate(state) { + return state.calendars + .filter((calendar) => calendar.supportsEvents) + .filter((calendar) => calendar.canCreateObject) + .filter((calendar) => !calendar.readOnly) + .sort((a, b) => a.order - b.order) + }, + /** * List of sorted all calendars * diff --git a/src/views/EditFull.vue b/src/views/EditFull.vue index 2a08cc0e91..d2b5dba58b 100644 --- a/src/views/EditFull.vue +++ b/src/views/EditFull.vue @@ -70,7 +70,7 @@ {{ $t('calendar', 'Export') }} - + diff --git a/src/views/EditSimple.vue b/src/views/EditSimple.vue index 61102d50f2..55fb09bd9f 100644 --- a/src/views/EditSimple.vue +++ b/src/views/EditSimple.vue @@ -84,7 +84,7 @@ {{ $t('calendar', 'Export') }} - +