diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2023-10-25 09:43:58 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2023-11-08 08:39:01 +0100 |
commit | cf6c921376effdf7e3682388237f675bb1520945 (patch) | |
tree | ded738bfb4bd0fe6cf3765f26b9ee24a8564d6d1 /apps/files_reminders | |
parent | 72ffd4999a82c242a7f82afd750372a8d49e517e (diff) | |
download | nextcloud-server-cf6c921376effdf7e3682388237f675bb1520945.tar.gz nextcloud-server-cf6c921376effdf7e3682388237f675bb1520945.zip |
chore(files_reminders): upgrade to 28 APIs
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files_reminders')
10 files changed, 506 insertions, 375 deletions
diff --git a/apps/files_reminders/lib/Listener/LoadAdditionalScriptsListener.php b/apps/files_reminders/lib/Listener/LoadAdditionalScriptsListener.php index 1e7f63d8e0d..bc3aa42ff6c 100644 --- a/apps/files_reminders/lib/Listener/LoadAdditionalScriptsListener.php +++ b/apps/files_reminders/lib/Listener/LoadAdditionalScriptsListener.php @@ -47,6 +47,6 @@ class LoadAdditionalScriptsListener implements IEventListener { return; } - Util::addScript(Application::APP_ID, 'main'); + Util::addInitScript(Application::APP_ID, 'init'); } } diff --git a/apps/files_reminders/src/actions/setReminderCustomAction.ts b/apps/files_reminders/src/actions/setReminderCustomAction.ts new file mode 100644 index 00000000000..efcf70dc311 --- /dev/null +++ b/apps/files_reminders/src/actions/setReminderCustomAction.ts @@ -0,0 +1,45 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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/>. + * + */ +import { FileAction, Node } from '@nextcloud/files' +import { translate as t } from '@nextcloud/l10n' +import CalendarClockSvg from '@mdi/svg/svg/calendar-clock.svg?raw' + +import { SET_REMINDER_MENU_ID } from './setReminderMenuAction' +import { pickCustomDate } from '../services/customPicker' + +export const action = new FileAction({ + id: 'set-reminder-custom', + displayName: () => t('files', 'Set custom reminder'), + title: () => t('files_reminders', 'Set reminder at custom date & time'), + iconSvgInline: () => CalendarClockSvg, + + enabled: () => true, + parent: SET_REMINDER_MENU_ID, + + async exec(file: Node) { + pickCustomDate(file) + return null + }, + + // After presets + order: 22, +}) diff --git a/apps/files_reminders/src/actions/setReminderMenuAction.ts b/apps/files_reminders/src/actions/setReminderMenuAction.ts new file mode 100644 index 00000000000..11810413db1 --- /dev/null +++ b/apps/files_reminders/src/actions/setReminderMenuAction.ts @@ -0,0 +1,40 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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/>. + * + */ +import { FileAction } from '@nextcloud/files' +import { translate as t } from '@nextcloud/l10n' +import AlarmSvg from '@mdi/svg/svg/alarm.svg?raw' + +export const SET_REMINDER_MENU_ID = 'set-reminder-menu' + +export const action = new FileAction({ + id: SET_REMINDER_MENU_ID, + displayName: () => t('files', 'Set reminder'), + iconSvgInline: () => AlarmSvg, + + enabled: () => true, + + async exec() { + return null + }, + + order: 20, +}) diff --git a/apps/files_reminders/src/actions/setReminderSuggestionActions.scss b/apps/files_reminders/src/actions/setReminderSuggestionActions.scss new file mode 100644 index 00000000000..16964e9ae2f --- /dev/null +++ b/apps/files_reminders/src/actions/setReminderSuggestionActions.scss @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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/>. + * + */ + // TODO: remove when/if the actions API supports a separator + // This the last preset action, so we need to add a separator +.files-list__row-action-set-reminder-3 { + margin-bottom: 13px; + + &::after { + content: ""; + margin: 3px 10px 3px 15px; + border-bottom: 1px solid var(--color-border-dark); + cursor: default; + display: flex; + height: 0; + position: absolute; + left: 0; + right: 0; + } +} diff --git a/apps/files_reminders/src/actions/setReminderSuggestionActions.ts b/apps/files_reminders/src/actions/setReminderSuggestionActions.ts new file mode 100644 index 00000000000..453bab4c5c1 --- /dev/null +++ b/apps/files_reminders/src/actions/setReminderSuggestionActions.ts @@ -0,0 +1,106 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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/>. + * + */ +import type { Node } from '@nextcloud/files' + +import { FileAction } from '@nextcloud/files' +import { showError, showSuccess } from '@nextcloud/dialogs' +import { translate as t } from '@nextcloud/l10n' + +import { DateTimePreset, getDateString, getDateTime, getVerboseDateString } from '../shared/utils' +import { logger } from '../shared/logger' +import { SET_REMINDER_MENU_ID } from './setReminderMenuAction' +import { setReminder } from '../services/reminderService' +import './setReminderSuggestionActions.scss' + +interface ReminderOption { + dateTimePreset: DateTimePreset + label: string + ariaLabel: string + dateString?: string + action?: () => Promise<void> +} + +const laterToday: ReminderOption = { + dateTimePreset: DateTimePreset.LaterToday, + label: t('files_reminders', 'Later today'), + ariaLabel: t('files_reminders', 'Set reminder for later today'), +} + +const tomorrow: ReminderOption = { + dateTimePreset: DateTimePreset.Tomorrow, + label: t('files_reminders', 'Tomorrow'), + ariaLabel: t('files_reminders', 'Set reminder for tomorrow'), +} + +const thisWeekend: ReminderOption = { + dateTimePreset: DateTimePreset.ThisWeekend, + label: t('files_reminders', 'This weekend'), + ariaLabel: t('files_reminders', 'Set reminder for this weekend'), +} + +const nextWeek: ReminderOption = { + dateTimePreset: DateTimePreset.NextWeek, + label: t('files_reminders', 'Next week'), + ariaLabel: t('files_reminders', 'Set reminder for next week'), +} + +// Generate the default preset actions +export const actions = [laterToday, tomorrow, thisWeekend, nextWeek].map((option): FileAction|null => { + const dateTime = getDateTime(option.dateTimePreset) + if (!dateTime) { + return null + } + + return new FileAction({ + id: `set-reminder-${option.dateTimePreset}`, + displayName: () => `${option.label} - ${getDateString(dateTime)}`, + title: () => `${option.ariaLabel} – ${getVerboseDateString(dateTime)}`, + + // Empty svg to hide the icon + iconSvgInline: () => '<svg></svg>', + + enabled: () => true, + parent: SET_REMINDER_MENU_ID, + + async exec(node: Node) { + // Can't really happen, but just in case™ + if (!node.fileid) { + logger.error('Failed to set reminder, missing file id') + showError(t('files_reminders', 'Failed to set reminder')) + return null + } + + // Set the reminder + try { + await setReminder(node.fileid, dateTime) + showSuccess(t('files_reminders', 'Reminder set for "{fileName}"', { fileName: node.basename })) + } catch (error) { + logger.error('Failed to set reminder', { error }) + showError(t('files_reminders', 'Failed to set reminder')) + } + // Silent success as we display our own notification + return null + }, + + order: 21, + }) +}).filter(Boolean) as FileAction[] diff --git a/apps/files_reminders/src/components/SetCustomReminderModal.vue b/apps/files_reminders/src/components/SetCustomReminderModal.vue new file mode 100644 index 00000000000..c4023d1c39b --- /dev/null +++ b/apps/files_reminders/src/components/SetCustomReminderModal.vue @@ -0,0 +1,199 @@ +<!-- + - @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> + <NcModal v-if="opened" + :out-transition="true" + size="small" + @close="onClose"> + <form class="custom-reminder-modal" @submit.prevent="setCustom"> + <h2 class="custom-reminder-modal__title"> + {{ title }} + </h2> + + <NcDateTimePickerNative id="set-custom-reminder" + v-model="customDueDate" + :label="label" + :min="nowDate" + :required="true" + type="datetime-local" + @input="onInput" /> + + <NcNoteCard v-if="isValid" type="info"> + {{ t('files_reminders', 'We will remind you of this file') }} + <NcDateTime :timestamp="customDueDate" /> + </NcNoteCard> + + <NcNoteCard v-else type="error"> + {{ t('files_reminders', 'Please choose a valid date & time') }} + </NcNoteCard> + + <!-- Buttons --> + <div class="custom-reminder-modal__buttons"> + <!-- Cancel pick --> + <NcButton @click="onClose"> + {{ t('files_reminders', 'Cancel') }} + </NcButton> + + <!-- Set reminder --> + <NcButton :disabled="!isValid" native-type="submit" type="primary"> + {{ t('files_reminders', 'Set reminder') }} + </NcButton> + </div> + </form> + </NcModal> +</template> + +<script lang="ts"> +import type { Node } from '@nextcloud/files' +import { showError, showSuccess } from '@nextcloud/dialogs' +import { translate as t } from '@nextcloud/l10n' +import Vue from 'vue' + +import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' +import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js' +import NcDateTimePickerNative from '@nextcloud/vue/dist/Components/NcDateTimePickerNative.js' +import NcModal from '@nextcloud/vue/dist/Components/NcModal.js' +import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js' + +import { getDateString, getInitialCustomDueDate } from '../shared/utils.ts' +import { logger } from '../shared/logger.ts' +import { setReminder } from '../services/reminderService.ts' + +export default Vue.extend({ + name: 'SetCustomReminderModal', + + components: { + NcButton, + NcDateTime, + NcDateTimePickerNative, + NcModal, + NcNoteCard, + }, + + data() { + return { + node: undefined as Node | undefined, + opened: false, + isValid: true, + + customDueDate: getInitialCustomDueDate() as '' | Date, + nowDate: new Date(), + } + }, + + computed: { + fileId(): number { + return this.node.fileid + }, + + fileName(): string { + return this.node.basename + }, + + title() { + return t('files_reminders', 'Set reminder for "{fileName}"', { fileName: this.fileName }) + }, + + label(): string { + return t('files_reminders', 'Set reminder at custom date & time') + }, + + clearAriaLabel(): string { + return t('files_reminders', 'Clear reminder') + }, + }, + + methods: { + t, + getDateString, + + /** + * Open the modal to set a custom reminder + * and reset the state. + * @param node The node to set a reminder for + */ + async open(node: Node): Promise<void> { + this.node = node + this.isValid = true + this.opened = true + this.customDueDate = getInitialCustomDueDate() + this.nowDate = new Date() + + // Focus the input and show the picker after the animation + setTimeout(() => { + const input = document.getElementById('set-custom-reminder') as HTMLInputElement + input.focus() + input.showPicker() + }, 300) + }, + + async setCustom(): Promise<void> { + // Handle input cleared + if (this.customDueDate === '') { + showError(t('files_reminders', 'Please choose a valid date & time')) + return + } + + try { + await setReminder(this.fileId, this.customDueDate) + showSuccess(t('files_reminders', 'Reminder set for "{fileName}"', { fileName: this.fileName })) + this.onClose() + } catch (error) { + logger.error('Failed to set reminder', { error }) + showError(t('files_reminders', 'Failed to set reminder')) + } + }, + + onClose(): void { + this.opened = false + this.$emit('close') + }, + + onInput(): void { + const input = document.getElementById('set-custom-reminder') as HTMLInputElement + this.isValid = input.checkValidity() + }, + }, +}) +</script> + +<style lang="scss" scoped> +.custom-reminder-modal { + margin: 30px; + + &__title { + font-size: 16px; + line-height: 2em; + } + + &__buttons { + display: flex; + justify-content: flex-end; + margin-top: 30px; + + button { + margin-left: 10px; + } + } +} +</style> diff --git a/apps/files_reminders/src/components/SetReminderActions.vue b/apps/files_reminders/src/components/SetReminderActions.vue deleted file mode 100644 index bf0b417a355..00000000000 --- a/apps/files_reminders/src/components/SetReminderActions.vue +++ /dev/null @@ -1,272 +0,0 @@ -<!-- - - @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> - <ArrowLeft :size="20" /> - </template> - {{ t('files_reminders', 'Back') }} - </NcActionButton> - - <NcActionButton v-if="Boolean(dueDate)" - :aria-label="clearAriaLabel" - @click="clear"> - <template #icon> - <CloseCircleOutline :size="20" /> - </template> - {{ t('files_reminders', 'Clear reminder') }} – {{ getDateString(dueDate) }} - </NcActionButton> - - <NcActionSeparator /> - - <NcActionButton v-for="({ label, ariaLabel, dateString, action }) in options" - :key="label" - :aria-label="ariaLabel" - @click="action"> - {{ label }} – {{ dateString }} - </NcActionButton> - - <NcActionSeparator /> - - <NcActionInput type="datetime-local" - is-native-picker - :min="now" - v-model="customDueDate"> - <template #icon> - <CalendarClock :size="20" /> - </template> - </NcActionInput> - - <NcActionButton :aria-label="customAriaLabel" - @click="setCustom"> - <template #icon> - <Check :size="20" /> - </template> - {{ t('files_reminders', 'Set custom reminder') }} - </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 NcActionInput from '@nextcloud/vue/dist/Components/NcActionInput.js' -import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' -import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js' - -import ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue' -import CalendarClock from 'vue-material-design-icons/CalendarClock.vue' -import Check from 'vue-material-design-icons/Check.vue' -import CloseCircleOutline from 'vue-material-design-icons/CloseCircleOutline.vue' - -import { clearReminder, setReminder } from '../services/reminderService.ts' -import { - DateTimePreset, - getDateString, - getDateTime, - getInitialCustomDueDate, - getVerboseDateString, -} from '../shared/utils.ts' -import { logger } from '../shared/logger.ts' - -import type { FileAttributes } from '../shared/types.ts' - -interface ReminderOption { - dateTimePreset: DateTimePreset - label: string - ariaLabel: string - dateString?: string - action?: () => Promise<void> -} - -const laterToday: ReminderOption = { - dateTimePreset: DateTimePreset.LaterToday, - label: t('files_reminders', 'Later today'), - ariaLabel: t('files_reminders', 'Set reminder for later today'), -} - -const tomorrow: ReminderOption = { - dateTimePreset: DateTimePreset.Tomorrow, - label: t('files_reminders', 'Tomorrow'), - ariaLabel: t('files_reminders', 'Set reminder for tomorrow'), -} - -const thisWeekend: ReminderOption = { - dateTimePreset: DateTimePreset.ThisWeekend, - label: t('files_reminders', 'This weekend'), - ariaLabel: t('files_reminders', 'Set reminder for this weekend'), -} - -const nextWeek: ReminderOption = { - dateTimePreset: DateTimePreset.NextWeek, - label: t('files_reminders', 'Next week'), - ariaLabel: t('files_reminders', 'Set reminder for next week'), -} - -export default Vue.extend({ - name: 'SetReminderActions', - - components: { - ArrowLeft, - CalendarClock, - Check, - CloseCircleOutline, - NcActionButton, - NcActionInput, - NcActions, - NcActionSeparator, - }, - - props: { - file: { - type: Object as PropType<FileAttributes>, - required: true, - }, - - dueDate: { - type: Date as PropType<null | Date>, - default: null, - }, - }, - - data() { - return { - open: true, - now: new Date(), - customDueDate: getInitialCustomDueDate() as '' | Date, - } - }, - - 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)}` - }, - - customAriaLabel(): null | string { - if (this.customDueDate === '') { - return null - } - return `${t('files_reminders', 'Set reminder at custom date & time')} – ${getVerboseDateString(this.customDueDate)}` - }, - - options(): ReminderOption[] { - const computeOption = (option: ReminderOption): null | ReminderOption => { - const dateTime = getDateTime(option.dateTimePreset) - if (!dateTime) { - return null - } - return { - ...option, - ariaLabel: `${option.ariaLabel} – ${getVerboseDateString(dateTime)}`, - dateString: getDateString(dateTime), - action: () => this.set(dateTime), - } - } - - const options = [ - laterToday, - tomorrow, - thisWeekend, - nextWeek, - ] - return options - .map(computeOption) - .filter(Boolean) as ReminderOption[] - }, - }, - - 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 setCustom(): Promise<void> { - // Handle input cleared - if (this.customDueDate === '') { - showError(t('files_reminders', 'Please choose a valid date & time')) - return - } - - try { - await setReminder(this.fileId, this.customDueDate) - 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> diff --git a/apps/files_reminders/src/init.ts b/apps/files_reminders/src/init.ts new file mode 100644 index 00000000000..59f5d23ebe3 --- /dev/null +++ b/apps/files_reminders/src/init.ts @@ -0,0 +1,29 @@ +/** + * @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/>. + * + */ +import { registerFileAction } from '@nextcloud/files' +import { action as menuAction } from './actions/setReminderMenuAction' +import { actions as suggestionActions } from './actions/setReminderSuggestionActions' +import { action as customAction } from './actions/setReminderCustomAction' + +registerFileAction(menuAction) +registerFileAction(customAction) +suggestionActions.forEach((action) => registerFileAction(action)) diff --git a/apps/files_reminders/src/main.ts b/apps/files_reminders/src/main.ts deleted file mode 100644 index b03f0b12ba6..00000000000 --- a/apps/files_reminders/src/main.ts +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @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/>. - * - */ - -import Vue, { type ComponentInstance } from 'vue' -import { subscribe } from '@nextcloud/event-bus' -import { showError } from '@nextcloud/dialogs' -import { translate as t } from '@nextcloud/l10n' - -import SetReminderActionsComponent from './components/SetReminderActions.vue' - -import { getReminder } from './services/reminderService.js' -import { logger } from './shared/logger.js' - -import type { FileAttributes } from './shared/types.js' - -interface FileContext { - [key: string]: any - $file: JQuery<HTMLTableRowElement> - fileInfoModel: { - [key: string]: any - attributes: FileAttributes - } -} - -interface EventPayload { - el: HTMLDivElement - context: FileContext -} - -const handleOpen = async (payload: EventPayload) => { - const fileId = payload.context.fileInfoModel.attributes.id - const menuEl = payload.context.$file[0].querySelector('.fileactions .action-menu') as HTMLLinkElement - const linkEl = payload.el.querySelector('.action-setreminder-container .action-setreminder') as HTMLLinkElement - - let dueDate: null | Date = null - let error: null | any = null - try { - dueDate = (await getReminder(fileId)).dueDate - } catch (e) { - error = e - logger.error(`Failed to load reminder for file with id: ${fileId}`, { error }) - } - - linkEl.addEventListener('click', (_event) => { - if (error) { - showError(t('files_reminders', 'Failed to load reminder')) - throw Error() - } - - const mountPoint = document.createElement('div') - const SetReminderActions = Vue.extend(SetReminderActionsComponent) - - const origDisplay = menuEl.style.display - menuEl.style.display = 'none' - menuEl.insertAdjacentElement('afterend', mountPoint) - - const propsData = { - file: payload.context.fileInfoModel.attributes, - dueDate, - } - const actions = (new SetReminderActions({ propsData }) as ComponentInstance) - .$mount(mountPoint) - - const cleanUp = () => { - actions.$destroy() // destroy popper - actions.$el.remove() // remove action menu button - menuEl.style.display = origDisplay - } - - actions.$once('back', () => { - cleanUp() - menuEl.click() // reopen original actions menu - }) - - actions.$once('close', () => { - cleanUp() - }) - }, { - once: true, - }) -} - -subscribe('files:action-menu:opened', handleOpen) diff --git a/apps/files_reminders/src/services/customPicker.ts b/apps/files_reminders/src/services/customPicker.ts new file mode 100644 index 00000000000..3a15cd514f8 --- /dev/null +++ b/apps/files_reminders/src/services/customPicker.ts @@ -0,0 +1,48 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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/>. + * + */ + +import type { Node } from '@nextcloud/files' +import Vue from 'vue' + +import SetCustomReminderModal from '../components/SetCustomReminderModal.vue' + +const View = Vue.extend(SetCustomReminderModal) +const mount = document.createElement('div') +mount.id = 'set-custom-reminder-modal' +document.body.appendChild(mount) + +// Create a new Vue instance and mount it to our modal container +const CustomReminderModal = new View({ + name: 'SetCustomReminderModal', + el: mount, +}) + +export const pickCustomDate = async (node: Node): Promise<void> => { + console.debug('CustomReminderModal', mount, CustomReminderModal) + + CustomReminderModal.open(node) + + // Wait for the modal to close + return new Promise((resolve) => { + CustomReminderModal.$on('close', resolve) + }) +} |