Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 44 additions & 16 deletions src/components/Editor/InvitationResponseButtons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@
class="invitation-response-buttons__button"
:disabled="loading"
@click="accept">
{{ t('calendar', 'Accept') }}
{{ acceptLabel }}
</NcButton>
<NcButton
v-if="!isDeclined"
variant="error"
class="invitation-response-buttons__button"
:disabled="loading"
@click="decline">
{{ t('calendar', 'Decline') }}
{{ declineLabel }}
</NcButton>
<template v-if="!isTentative">
<NcButton
v-if="!narrow"
class="invitation-response-buttons__button"
:disabled="loading"
@click="tentative">
{{ t('calendar', 'Tentative') }}
{{ tentativeLabel }}
</NcButton>
<Actions v-else>
<ActionButton
Expand All @@ -38,7 +38,7 @@
<template #icon>
<CalendarQuestionIcon :size="20" />
</template>
{{ t('calendar', 'Tentative') }}
{{ tentativeLabel }}
</ActionButton>
</Actions>
</template>
Expand Down Expand Up @@ -72,11 +72,6 @@ export default {
required: true,
},

calendarId: {
type: String,
required: true,
},

narrow: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -109,6 +104,45 @@ export default {
isTentative() {
return this.attendee.participationStatus === 'TENTATIVE'
},

responseScope() {
const eventComponent = this.calendarObjectInstanceStore.calendarObjectInstance?.eventComponent
if (!eventComponent?.isPartOfRecurrenceSet()) {
return null
}

return eventComponent.isRecurrenceException() ? 'occurrence' : 'series'
},

acceptLabel() {
if (this.responseScope === 'occurrence') {
return this.t('calendar', 'Accept this occurrence')
}
if (this.responseScope === 'series') {
return this.t('calendar', 'Accept entire series')
}
return this.t('calendar', 'Accept')
},

declineLabel() {
if (this.responseScope === 'occurrence') {
return this.t('calendar', 'Decline this occurrence')
}
if (this.responseScope === 'series') {
return this.t('calendar', 'Decline entire series')
}
return this.t('calendar', 'Decline')
},

tentativeLabel() {
if (this.responseScope === 'occurrence') {
return this.t('calendar', 'Tentative for this occurrence')
}
if (this.responseScope === 'series') {
return this.t('calendar', 'Tentative for entire series')
}
return this.t('calendar', 'Tentative')
},
},

methods: {
Expand Down Expand Up @@ -154,16 +188,10 @@ export default {
async setParticipationStatus(participationStatus) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit(non-blocking): changeAttendeesParticipationStatus is not unused.

this.loading = true
try {
this.calendarObjectInstanceStore.changeAttendeesParticipationStatus({
await this.calendarObjectInstanceStore.saveAttendeeParticipationResponse({
attendee: this.attendee,
participationStatus,
})
// TODO: What about recurring events? Add new buttons like "Accept this and all future"?
// Currently, this will only accept a single occurrence.
await this.calendarObjectInstanceStore.saveCalendarObjectInstance({
thisAndAllFuture: false,
calendarId: this.calendarId,
})
} catch (error) {
logger.error('Failed to set participation status', { error, participationStatus })
throw error
Expand Down
33 changes: 16 additions & 17 deletions src/components/Editor/Repeat/Repeat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@
<div class="property-repeat__options">
<h2>{{ $t('calendar', 'Repeat event') }}</h2>
<RepeatFreqInterval
v-if="!isRecurrenceException && !isReadOnly"
v-if="!isEditingExceptionInstance && !isReadOnly"
:frequency="recurrenceRule.frequency"
:interval="recurrenceRule.interval"
@changeInterval="changeInterval"
@changeFrequency="changeFrequency" />
<RepeatFreqWeeklyOptions
v-if="isFreqWeekly && !isRecurrenceException && !isReadOnly"
v-if="isFreqWeekly && !isEditingExceptionInstance && !isReadOnly"
:byDay="recurrenceRule.byDay"
@addByDay="addByDay"
@removeByDay="removeByDay" />
<RepeatFreqMonthlyOptions
v-if="isFreqMonthly && !isRecurrenceException && !isReadOnly"
v-if="isFreqMonthly && !isEditingExceptionInstance && !isReadOnly"
:byDay="recurrenceRule.byDay"
:byMonthDay="recurrenceRule.byMonthDay"
:bySetPosition="recurrenceRule.bySetPosition"
Expand All @@ -55,7 +55,7 @@
@changeToBySetPosition="changeToBySetPositionMonthly"
@changeToByMonthDay="changeToByDayMonthly" />
<RepeatFreqYearlyOptions
v-if="isFreqYearly && !isRecurrenceException && !isReadOnly"
v-if="isFreqYearly && !isEditingExceptionInstance && !isReadOnly"
:byDay="recurrenceRule.byDay"
:byMonth="recurrenceRule.byMonth"
:byMonthDay="recurrenceRule.byMonthDay"
Expand All @@ -69,19 +69,19 @@
@changeToBySetPosition="changeToBySetPositionYearly"
@changeToByMonthDay="changeToByDayYearly" />
<RepeatEndRepeat
v-if="isRepeating && !isRecurrenceException && !isReadOnly"
v-if="isRepeating && !isEditingExceptionInstance && !isReadOnly"
:until="recurrenceRule.until"
:count="recurrenceRule.count"
@setInfinite="setInfinite"
@setUntil="setUntil"
@setCount="setCount"
@changeToCount="changeToCount"
@changeToUntil="changeToUntil" />
<RepeatUnsupportedWarning v-if="recurrenceRule.isUnsupported && !isRecurrenceException" />
<RepeatExceptionWarning v-if="isRecurrenceException" />
<RepeatUnsupportedWarning v-if="recurrenceRule.isUnsupported && !isEditingExceptionInstance" />
<RepeatExceptionWarning v-if="isEditingExceptionInstance" />
</div>
<div
v-if="!isRecurrenceException && !isReadOnly"
v-if="!isEditingExceptionInstance && !isReadOnly"
class="property-repeat__options__footer">
<NcButton variant="primary" @click="saveAndClose">
{{ $t('calendar', 'Set repetition') }}
Expand Down Expand Up @@ -137,26 +137,25 @@ export default {
},

/**
* Whether or not the user is editing the master-item
* If so, we are enforcing "This and all future" and
* don't allow to just save this occurrence
* Whether or not the user is editing the base instance.
* Recurrence-rule changes on a non-base instance require a future update.
*/
isEditingMasterItem: {
isEditingBaseInstance: {
type: Boolean,
required: true,
},

/**
* Whether or not this instance of the event is a recurrence-exception.
* Whether or not the user is editing a recurrence-exception.
* If yes, you can't modify the recurrence-rule
*/
isRecurrenceException: {
isEditingExceptionInstance: {
type: Boolean,
required: true,
},
},

emits: ['forceThisAndAllFuture'],
emits: ['requireFutureUpdate'],

data() {
return {
Expand Down Expand Up @@ -468,8 +467,8 @@ export default {
})
}

if (!this.isEditingMasterItem) {
this.$emit('forceThisAndAllFuture')
if (!this.isEditingBaseInstance) {
this.$emit('requireFutureUpdate')
}

this.calendarObjectInstanceStore.calendarObjectInstance.canModifyAllDay = this.calendarObjectInstanceStore.calendarObjectInstance.eventComponent.canModifyAllDay()
Expand Down
78 changes: 50 additions & 28 deletions src/components/Editor/SaveButtons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
v-if="showSaveButton"
variant="primary"
:disabled="disabled"
@click="saveThisOnly">
@click="saveOccurrence">
<template #icon>
<CheckIcon :size="20" />
</template>
Expand All @@ -26,38 +26,43 @@
v-if="showUpdateButton"
variant="primary"
:disabled="disabled"
@click="saveThisOnly">
@click="saveOccurrence">
<template #icon>
<CheckIcon :size="20" />
</template>
{{ $t('calendar', 'Update') }}
</NcButton>
<NcButton
v-if="showUpdateThisAndFutureButton && !showUpdateOnlyThisButton"
v-if="showUpdateSeriesButton"
variant="primary"
:disabled="disabled"
@click="saveThisAndAllFuture">
{{ $t('calendar', 'Update this and all future') }}
@click="saveSeries">
{{ $t('calendar', 'Update entire series') }}
</NcButton>
<NcButton
v-if="showUpdateOnlyThisButton && !showUpdateThisAndFutureButton"
v-if="showUpdateFutureButton"
variant="primary"
:disabled="disabled"
@click="saveThisOnly">
{{ $t('calendar', 'Update this occurrence') }}
@click="saveFuture">
{{ $t('calendar', 'Update this and future occurrences') }}
</NcButton>

<NcActions v-if="showUpdateThisAndFutureButton && showUpdateOnlyThisButton" :primary="true" :menuName="t('calendar', 'Update')">
<NcActions v-if="showUpdateMenu" :primary="true" :menuName="t('calendar', 'Update')">
<template #icon>
<CheckIcon :size="20" />
</template>
<NcActionButton @click="saveThisAndAllFuture">
<NcActionButton v-if="canUpdateSeries" @click="saveSeries">
<template #icon>
<CheckIcon :size="20" />
</template>
{{ $t('calendar', 'Update entire series') }}
</NcActionButton>
<NcActionButton v-if="canUpdateFuture" @click="saveFuture">
<template #icon>
<CheckAllIcon :size="20" />
</template>
{{ $t('calendar', 'Update this and all future') }}
{{ $t('calendar', 'Update this and future occurrences') }}
</NcActionButton>
<NcActionButton @click="saveThisOnly">
<NcActionButton v-if="canUpdateOccurrence" @click="saveOccurrence">
<template #icon>
<CheckIcon :size="20" />
</template>
Expand Down Expand Up @@ -86,22 +91,27 @@ export default {
},

props: {
canCreateRecurrenceException: {
canUpdateOccurrence: {
type: Boolean,
required: true,
},

isNew: {
canUpdateFuture: {
type: Boolean,
required: true,
},

isReadOnly: {
canUpdateSeries: {
type: Boolean,
required: true,
},

forceThisAndAllFuture: {
isNew: {
type: Boolean,
required: true,
},

isReadOnly: {
type: Boolean,
required: true,
},
Expand All @@ -122,33 +132,45 @@ export default {
},
},

emits: ['saveThisOnly', 'saveThisAndAllFuture', 'showMore'],
emits: ['saveOccurrence', 'saveFuture', 'saveSeries', 'showMore'],

computed: {
showSaveButton() {
return !this.isReadOnly && this.isNew && !this.canCreateRecurrenceException
return !this.isReadOnly && this.isNew
},

showUpdateButton() {
return !this.isReadOnly && !this.isNew && !this.canCreateRecurrenceException
return !this.isReadOnly && !this.isNew && this.allowedUpdateScopeCount === 1 && this.canUpdateOccurrence
},

allowedUpdateScopeCount() {
return [this.canUpdateOccurrence, this.canUpdateFuture, this.canUpdateSeries].filter(Boolean).length
},

showUpdateOnlyThisButton() {
return !this.isReadOnly && this.canCreateRecurrenceException && !this.forceThisAndAllFuture
showUpdateFutureButton() {
return !this.isReadOnly && !this.isNew && this.allowedUpdateScopeCount === 1 && this.canUpdateFuture
},

showUpdateThisAndFutureButton() {
return !this.isReadOnly && this.canCreateRecurrenceException
showUpdateSeriesButton() {
return !this.isReadOnly && !this.isNew && this.allowedUpdateScopeCount === 1 && this.canUpdateSeries
},

showUpdateMenu() {
return !this.isReadOnly && !this.isNew && this.allowedUpdateScopeCount > 1
},
},

methods: {
saveThisOnly() {
this.$emit('saveThisOnly')
saveOccurrence() {
this.$emit('saveOccurrence')
},

saveFuture() {
this.$emit('saveFuture')
},

saveThisAndAllFuture() {
this.$emit('saveThisAndAllFuture')
saveSeries() {
this.$emit('saveSeries')
},

showMore() {
Expand Down
Loading
Loading