Merge pull request #59228 from nextcloud/fix/reminder-past

fix(files_reminder): passed reminder handling
pull/63036/merge
John Molakvoæ 22 hours ago committed by GitHub
commit 1c3dfbe85d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 9
      apps/files_reminders/lib/Service/ReminderService.php
  2. 17
      apps/files_reminders/src/components/SetCustomReminderModal.vue
  3. 15
      apps/files_reminders/src/files_actions/reminderStatusAction.spec.ts
  4. 5
      apps/files_reminders/src/files_actions/reminderStatusAction.ts
  5. 6
      apps/files_reminders/src/services/reminderService.ts
  6. 2
      dist/files_reminders-files_reminders-init-CjUvwokK.chunk.css
  7. 2
      dist/files_reminders-init.css
  8. 2
      dist/files_reminders-init.mjs
  9. 2
      dist/files_reminders-init.mjs.map

@ -74,11 +74,20 @@ class ReminderService {
return null;
}
if ($cachedReminder instanceof Reminder) {
if ($cachedReminder->getDueDate() < new DateTime()) {
$this->cache->remove("{$user->getUID()}-$fileId");
return null;
}
return new RichReminder($cachedReminder, $this->root);
}
try {
$reminder = $this->reminderMapper->findDueForUser($user, $fileId);
// If reminder is in the past, do not return it and do not cache it.
if ($reminder->getDueDate() < new DateTime()) {
return null;
}
$this->cache->set("{$user->getUID()}-$fileId", $reminder);
return new RichReminder($reminder, $this->root);
} catch (DoesNotExistException $e) {

@ -8,10 +8,9 @@ import type { INode } from '@nextcloud/files'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { emit as emitEventBus } from '@nextcloud/event-bus'
import { t } from '@nextcloud/l10n'
import { onBeforeMount, onMounted, ref } from 'vue'
import { formatRelativeTime, t } from '@nextcloud/l10n'
import { computed, onBeforeMount, onMounted, ref } from 'vue'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcDateTime from '@nextcloud/vue/components/NcDateTime'
import NcDateTimePickerNative from '@nextcloud/vue/components/NcDateTimePickerNative'
import NcDialog from '@nextcloud/vue/components/NcDialog'
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
@ -33,6 +32,15 @@ const isValid = ref(true)
const customDueDate = ref<Date>()
const nowDate = ref(new Date())
const informationText = computed(() => {
const relativeDueDate = formatRelativeTime(customDueDate.value ?? 0)
return (nowDate.value.getTime() >= (customDueDate.value?.getTime() ?? 0))
// TRANSLATORS: {relativeDueDate} will be replaced with a relative time, e.g. "2 hours ago" or "in 3 days".
? t('files_reminders', 'We reminded you of this file {relativeDueDate}', { relativeDueDate })
// TRANSLATORS: {relativeDueDate} will be replaced with a relative time, e.g. "2 hours ago" or "in 3 days".
: t('files_reminders', 'We will remind you of this file {relativeDueDate}', { relativeDueDate })
})
onBeforeMount(() => {
const dueDate = props.node.attributes['reminder-due-date']
? new Date(props.node.attributes['reminder-due-date'])
@ -132,8 +140,7 @@ function onInput(): void {
@input="onInput" />
<NcNoteCard v-if="isValid && customDueDate" type="info">
{{ t('files_reminders', 'We will remind you of this file') }}
<NcDateTime :timestamp="customDueDate" />
{{ informationText }}
</NcNoteCard>
<NcNoteCard v-else type="error">

@ -22,7 +22,7 @@ describe('reminderStatusAction', () => {
owner: 'user',
source: 'https://example.com/remote.php/dav/files/user/folder',
attributes: {
'reminder-due-date': '2024-12-25T10:00:00Z',
'reminder-due-date': '2099-12-25T10:00:00Z',
},
root: '/files/user',
})
@ -38,6 +38,17 @@ describe('reminderStatusAction', () => {
})).toBe(true)
})
it('should be disabled for one node with past due date', () => {
const node = folder.clone()
node.attributes['reminder-due-date'] = '2000-01-01T00:00:00Z'
expect(action.enabled!({
nodes: [node],
view,
folder: root,
contents: [],
})).toBe(false)
})
it('should be disabled with more than one node', () => {
expect(action.enabled!({
nodes: [folder, folder],
@ -64,6 +75,6 @@ describe('reminderStatusAction', () => {
view,
folder: root,
contents: [],
})).toMatchInlineSnapshot('"Reminder set – Wednesday, December 25, 2024 at 10:00 AM"')
})).toMatchInlineSnapshot('"Reminder set – Friday, December 25, 2099 at 10:00 AM"')
})
})

@ -33,7 +33,10 @@ export const action: IFileAction = {
const node = nodes.at(0)!
const dueDate = node.attributes['reminder-due-date']
return Boolean(dueDate)
const now = new Date()
// Do not show if the reminder is in the past
return Boolean(dueDate) && new Date(dueDate) > now
},
async exec({ nodes }) {

@ -48,7 +48,11 @@ export async function setReminder(fileId: number, dueDate: Date): Promise<[]> {
*/
export async function clearReminder(fileId: number): Promise<[]> {
const url = generateOcsUrl('/apps/files_reminders/api/v1/{fileId}', { fileId })
const response = await axios.delete(url)
const response = await axios.delete(url, {
// We allow 404 as it means there is no reminder to delete,
// which is the desired state after this function is called anyway
validateStatus: (status) => status === 200 || status === 404,
})
return response.data.ocs.data
}

@ -1 +1 @@
.custom-reminder-modal[data-v-1cc1857f]{margin:0 12px}.files-list__row-action-set-reminder-custom{margin-top:13px;position:relative}.files-list__row-action-set-reminder-custom:before{content:"";margin-block:3px;margin-inline:15px 10px;border-bottom:1px solid var(--color-border-dark);cursor:default;display:flex;height:0;position:absolute;inset-inline:0;top:-10px}
.custom-reminder-modal[data-v-d7127154]{margin:0 12px}.files-list__row-action-set-reminder-custom{margin-top:13px;position:relative}.files-list__row-action-set-reminder-custom:before{content:"";margin-block:3px;margin-inline:15px 10px;border-bottom:1px solid var(--color-border-dark);cursor:default;display:flex;height:0;position:absolute;inset-inline:0;top:-10px}

@ -1,5 +1,5 @@
/* extracted by css-entry-points-plugin */
@import './files_reminders-files_reminders-init-AoQhTI1A.chunk.css';
@import './files_reminders-files_reminders-init-CjUvwokK.chunk.css';
@import './common-createElementId-DhjFt1I9-C_oBIsvc.chunk.css';
@import './common-logger-D3RVzcfQ-Ks0gkIDB.chunk.css';
@import './common-NcModal-DiDvgcU8-B-yi1OwC.chunk.css';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save