Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
840ec36
feat(files_reminders): integrate load scripts
Pytal Aug 3, 2023
a3abb0b
feat(files_reminders): add reminder service
Pytal Aug 3, 2023
c25ed87
fix: due date nullable
Pytal Aug 3, 2023
ec4d660
fix: frontend ocs
Pytal Aug 3, 2023
1d46632
feat(files_reminders): add datetime utils
Pytal Aug 3, 2023
5c6925d
feat(files_reminders): register file action
Pytal Aug 3, 2023
b57a884
feat(files_reminders): emit action menu opened
Pytal Aug 3, 2023
c2be544
fix: action icon color
Pytal Aug 3, 2023
1af7287
feat(files_reminders): add logger
Pytal Aug 3, 2023
b10a1a7
feat(files_reminders): add webpack module
Pytal Aug 3, 2023
dd36606
feat(files_reminders): add types
Pytal Aug 3, 2023
118ea83
feat(files_reminders): mount set reminder actions
Pytal Aug 3, 2023
103f2c6
fix: prevent sidebar from opening
Pytal Aug 3, 2023
33c4861
feat(files_reminders): add verbose date string util
Pytal Aug 3, 2023
ec8f8ce
feat(files_reminders): add set reminder actions
Pytal Aug 3, 2023
3248e3f
enh: later today 3 hours later
Pytal Aug 3, 2023
2139e33
enh: rename to saturday sunday
Pytal Aug 3, 2023
effc210
enh: shorten date string if same day
Pytal Aug 3, 2023
d13b8dd
fix: indent with tabs
Pytal Aug 3, 2023
d498414
enh: use vue-material-design-icons
Pytal Aug 3, 2023
64cd84b
fix: composer
Pytal Aug 3, 2023
68f4a13
feat(files_reminders): v1.0.0
Pytal Aug 4, 2023
6335282
enh: add clean up buffer
Pytal Aug 4, 2023
3bba555
fix: eslint
Pytal Aug 4, 2023
0131005
fix: load script
Pytal Aug 4, 2023
72bcafb
fix: remove non-existing reminder notification
Pytal Aug 4, 2023
e5e5c97
enh: use alarm icon
Pytal Aug 4, 2023
fa48409
refactor: format options
Pytal Aug 4, 2023
271122e
enh: remove icons
Pytal Aug 8, 2023
c71db8a
feat: custom date & time
Pytal Aug 8, 2023
f6a8441
enh: en dash
Pytal Aug 8, 2023
6c89550
enh: move to 8am
Pytal Aug 8, 2023
15ade72
chore: compile assets
Pytal Aug 8, 2023
0c0ed38
enh: pass params in subject
Pytal Aug 9, 2023
87f9700
enh: set later today to 6pm
Pytal Aug 9, 2023
a3c333c
chore: compile assets
Pytal Aug 9, 2023
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
Prev Previous commit
Next Next commit
feat(files_reminders): add set reminder actions
Signed-off-by: Christopher Ng <[email protected]>
(cherry picked from commit 5e4881b)
  • Loading branch information
Pytal authored and AndyScherzinger committed Aug 10, 2023
commit ec8f8ce2a07a0aa08af43205bcafa4e426393393
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 <[email protected]>
-
- @author Christopher Ng <[email protected]>
-
- @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>