Skip to content

Commit

Permalink
feat(files_reminders): add set reminder actions
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Ng <chrng8@gmail.com>
  • Loading branch information
Pytal committed Aug 9, 2023
1 parent 419bea6 commit 5e4881b
Showing 1 changed file with 225 additions and 0 deletions.
225 changes: 225 additions & 0 deletions apps/files_reminders/src/components/SetReminderActions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<!--
- @copyright 2023 Christopher Ng <chrng8@gmail.com>
-
- @author Christopher Ng <chrng8@gmail.com>
-
- @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<NcActions class="actions-secondary-vue"
:open.sync="open">
<NcActionButton @click="$emit('back')">
<template #icon>
<NcIconSvgWrapper :svg="arrowLeftSvg" />
</template>
{{ t('files_reminders', 'Back') }}
</NcActionButton>
<NcActionButton v-if="Boolean(dueDate)"
:aria-label="clearAriaLabel"
@click="clear">
<template #icon>
<NcIconSvgWrapper :svg="clearSvg" />
</template>
{{ t('files_reminders', 'Clear reminder') }} — {{ getDateString(dueDate) }}
</NcActionButton>
<NcActionSeparator />
<NcActionButton v-for="({ icon, label, ariaLabel, dateString, action }) in options"
:key="label"
:aria-label="ariaLabel"
@click="action">
<template #icon>
<NcIconSvgWrapper :svg="icon" />
</template>
{{ label }} — {{ dateString }}
</NcActionButton>
</NcActions>
</template>

<script lang="ts">
import Vue, { type PropType } from 'vue'
import { translate as t } from '@nextcloud/l10n'
import { showError, showSuccess } from '@nextcloud/dialogs'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import arrowLeftSvg from '@mdi/svg/svg/arrow-left.svg?raw'
import clearSvg from '@mdi/svg/svg/close-circle-outline.svg?raw'
import laterTodaySvg from '@mdi/svg/svg/update.svg?raw'
import tomorrowSvg from '@mdi/svg/svg/chevron-right.svg?raw'
import thisWeekendSvg from '@mdi/svg/svg/calendar-weekend.svg?raw'
import nextWeekSvg from '@mdi/svg/svg/chevron-double-right.svg?raw'
import { clearReminder, setReminder } from '../services/reminderService.js'
import {
DateTimePreset,
getDateString,
getDateTime,
getVerboseDateString,
} from '../shared/utils.js'
import { logger } from '../shared/logger.js'
import type { FileAttributes } from '../shared/types.js'
interface ReminderOption {
dateTimePreset: DateTimePreset
icon: string
label: string
ariaLabel: string
dateString?: string
action?: () => Promise<void>
}
const laterToday: ReminderOption = {
dateTimePreset: DateTimePreset.LaterToday,
icon: laterTodaySvg,
label: t('files_reminders', 'Later today'),
ariaLabel: t('files_reminders', 'Set reminder for later today'),
}
const tomorrow: ReminderOption = {
dateTimePreset: DateTimePreset.Tomorrow,
icon: tomorrowSvg,
label: t('files_reminders', 'Tomorrow'),
ariaLabel: t('files_reminders', 'Set reminder for tomorrow'),
}
const thisWeekend: ReminderOption = {
dateTimePreset: DateTimePreset.ThisWeekend,
icon: thisWeekendSvg,
label: t('files_reminders', 'This weekend'),
ariaLabel: t('files_reminders', 'Set reminder for this weekend'),
}
const nextWeek: ReminderOption = {
dateTimePreset: DateTimePreset.NextWeek,
icon: nextWeekSvg,
label: t('files_reminders', 'Next week'),
ariaLabel: t('files_reminders', 'Set reminder for next week'),
}
export default Vue.extend({
name: 'SetReminderActions',
components: {
NcActionButton,
NcActions,
NcActionSeparator,
NcIconSvgWrapper,
},
props: {
file: {
type: Object as PropType<FileAttributes>,
required: true,
},
dueDate: {
type: Date as PropType<null | Date>,
default: null,
},
},
data() {
return {
arrowLeftSvg,
clearSvg,
open: true,
}
},
watch: {
open(isOpen) {
if (!isOpen) {
this.$emit('close')
}
},
},
computed: {
fileId(): number {
return this.file.id
},
fileName(): string {
return this.file.name
},
clearAriaLabel(): string {
return `${t('files_reminders', 'Clear reminder')} — ${getVerboseDateString(this.dueDate as Date)}`
},
options(): ReminderOption[] {
const computeOption = (option: ReminderOption) => {
const dateTime = getDateTime(option.dateTimePreset)
return {
...option,
ariaLabel: `${option.ariaLabel} — ${getVerboseDateString(dateTime)}`,
dateString: getDateString(dateTime),
action: () => this.set(dateTime),
}
}
return [
laterToday,
tomorrow,
thisWeekend,
nextWeek,
].map(computeOption)
},
},
methods: {
t,
getDateString,
async set(dueDate: Date): Promise<void> {
try {
await setReminder(this.fileId, dueDate)
showSuccess(t('files_reminders', 'Reminder set for "{fileName}"', { fileName: this.fileName }))
this.open = false
} catch (error) {
logger.error('Failed to set reminder', { error })
showError(t('files_reminders', 'Failed to set reminder'))
}
},
async clear(): Promise<void> {
try {
await clearReminder(this.fileId)
showSuccess(t('files_reminders', 'Reminder cleared'))
this.open = false
} catch (error) {
logger.error('Failed to clear reminder', { error })
showError(t('files_reminders', 'Failed to clear reminder'))
}
},
},
})
</script>

<style lang="scss" scoped>
.actions-secondary-vue {
display: block !important;
float: right !important;
padding: 5px 0 0 4px !important;
pointer-events: none !important; // prevent activation of file row
}
</style>

0 comments on commit 5e4881b

Please sign in to comment.