diff --git a/frontend/src/stores/tasks.test.ts b/frontend/src/stores/tasks.test.ts new file mode 100644 index 000000000..4d7a60af6 --- /dev/null +++ b/frontend/src/stores/tasks.test.ts @@ -0,0 +1,44 @@ +import {describe, expect, it} from 'vitest' +import {buildDefaultRemindersForQuickAdd} from './tasks' +import {REMINDER_PERIOD_RELATIVE_TO_TYPES} from '@/types/IReminderPeriodRelativeTo' +import type {ITaskReminder} from '@/modelTypes/ITaskReminder' + +const aDefault: ITaskReminder = { + reminder: null, + relativePeriod: -3600, + relativeTo: REMINDER_PERIOD_RELATIVE_TO_TYPES.DUEDATE, +} as ITaskReminder + +describe('buildDefaultRemindersForQuickAdd', () => { + it('returns empty array when due date is null', () => { + expect(buildDefaultRemindersForQuickAdd([aDefault], null)).toEqual([]) + }) + + it('returns empty array when defaults are undefined', () => { + expect(buildDefaultRemindersForQuickAdd(undefined, '2026-05-01T00:00:00.000Z')).toEqual([]) + }) + + it('returns empty array when defaults are empty', () => { + expect(buildDefaultRemindersForQuickAdd([], '2026-05-01T00:00:00.000Z')).toEqual([]) + }) + + it('clones defaults with relativeTo locked to due_date', () => { + const result = buildDefaultRemindersForQuickAdd([aDefault], '2026-05-01T00:00:00.000Z') + expect(result).toHaveLength(1) + expect(result[0].relativePeriod).toBe(-3600) + expect(result[0].relativeTo).toBe(REMINDER_PERIOD_RELATIVE_TO_TYPES.DUEDATE) + expect(result[0].reminder).toBeNull() + }) + + it('does not share references with the input array', () => { + const defaults = [aDefault] + const result = buildDefaultRemindersForQuickAdd(defaults, '2026-05-01T00:00:00.000Z') + expect(result[0]).not.toBe(defaults[0]) + }) + + it('forces relativeTo to due_date even if a default somehow had another value', () => { + const weird = {...aDefault, relativeTo: REMINDER_PERIOD_RELATIVE_TO_TYPES.STARTDATE} as ITaskReminder + const result = buildDefaultRemindersForQuickAdd([weird], '2026-05-01T00:00:00.000Z') + expect(result[0].relativeTo).toBe(REMINDER_PERIOD_RELATIVE_TO_TYPES.DUEDATE) + }) +}) diff --git a/frontend/src/stores/tasks.ts b/frontend/src/stores/tasks.ts index 45b8ac58a..3eb99d1ef 100644 --- a/frontend/src/stores/tasks.ts +++ b/frontend/src/stores/tasks.ts @@ -15,13 +15,17 @@ import LabelTaskModel from '@/models/labelTask' import LabelTask from '@/models/labelTask' import TaskModel from '@/models/task' import LabelModel from '@/models/label' +import TaskReminderModel from '@/models/taskReminder' import type {ILabel} from '@/modelTypes/ILabel' import type {ITask} from '@/modelTypes/ITask' +import type {ITaskReminder} from '@/modelTypes/ITaskReminder' import type {IUser} from '@/modelTypes/IUser' import type {IAttachment} from '@/modelTypes/IAttachment' import type {IProject} from '@/modelTypes/IProject' +import {REMINDER_PERIOD_RELATIVE_TO_TYPES} from '@/types/IReminderPeriodRelativeTo' + import {setModuleLoading} from '@/stores/helper' import {useLabelStore} from '@/stores/labels' import {useProjectStore} from '@/stores/projects' @@ -38,6 +42,23 @@ interface MatchedAssignee extends IUser { match: string, } +export function buildDefaultRemindersForQuickAdd( + defaults: readonly ITaskReminder[] | undefined, + dueDate: string | null, +): ITaskReminder[] { + if (!dueDate) { + return [] + } + if (!defaults || defaults.length === 0) { + return [] + } + return defaults.map(d => new TaskReminderModel({ + reminder: null, + relativePeriod: d.relativePeriod, + relativeTo: REMINDER_PERIOD_RELATIVE_TO_TYPES.DUEDATE, + })) +} + // IDEA: maybe use a small fuzzy search here to prevent errors function findPropertyByValue(object, key, value, fuzzy = false) { return Object.values(object).find(l => { @@ -483,6 +504,10 @@ export const useTaskStore = defineStore('task', () => { index, }) task.repeatAfter = parsedTask.repeats + task.reminders = buildDefaultRemindersForQuickAdd( + authStore.settings.frontendSettings.quickAddDefaultReminders, + dueDate, + ) if (parsedTask.repeats?.type === REPEAT_TYPES.Months && parsedTask.repeats?.amount === 1) { task.repeatMode = TASK_REPEAT_MODES.REPEAT_MODE_MONTH