This commit is contained in:
@@ -5,8 +5,8 @@ import {
|
||||
GripVertical, Inbox, ListChecks, ListTodo, Menu, Pencil, Plus, Search,
|
||||
Settings, Trash2, X, Repeat2,
|
||||
} from 'lucide-vue-next'
|
||||
import { buildTaskRrule, filterTasks, fromDateTimeLocal, groupTaskTree, moveItemWithinScope, parseTaskRrule, renderMarkdown, toDateTimeLocal, type TaskRepeatConfig } from './lib/task-utils'
|
||||
import { defaultView, isTaskView, nextTotalAfterLocalTaskAdd, quickTaskFields, shouldToggleRowSwipe, writeCountdownCache } from './lib/mvp-utils'
|
||||
import { buildTaskRrule, defaultTaskDueAt, filterTasks, fromDateTimeLocal, groupTaskTree, moveItemWithinScope, parseTaskRrule, renderMarkdown, toDateTimeLocal, type TaskRepeatConfig } from './lib/task-utils'
|
||||
import { defaultView, isTaskView, nextTotalAfterLocalTaskAdd, shouldToggleRowSwipe, writeCountdownCache } from './lib/mvp-utils'
|
||||
import { csrfHeader } from './lib/csrf'
|
||||
import MvpPanel from './MvpPanel.vue'
|
||||
import CountdownPanel from './CountdownPanel.vue'
|
||||
@@ -80,7 +80,7 @@ function openTaskCompose() {
|
||||
const inboxId = lists.value.find((item) => item.is_inbox)?.id || activeList.value
|
||||
composeTitle.value = ''
|
||||
composeListId.value = activeView.value === 'tasks' && activeList.value ? activeList.value : inboxId
|
||||
composeDueAt.value = activeView.value === 'today' ? toDateTimeLocal(quickTaskFields('today', activeList.value, inboxId).due_at ?? null) : ''
|
||||
composeDueAt.value = defaultTaskDueAt()
|
||||
composePriority.value = 0
|
||||
composeDescription.value = ''
|
||||
composeRepeat.value = 'none'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { buildTaskRrule, filterTasks, groupTaskTree, moveItemWithinScope, parseTaskRrule, renderMarkdown, toDateTimeLocal } from './task-utils'
|
||||
import { buildTaskRrule, defaultTaskDueAt, filterTasks, groupTaskTree, moveItemWithinScope, parseTaskRrule, renderMarkdown, toDateTimeLocal } from './task-utils'
|
||||
|
||||
type SearchTask = {
|
||||
id: string
|
||||
@@ -63,6 +63,11 @@ describe('task utilities', () => {
|
||||
expect(filterTasks(searchable, '工作').map((task) => task.id)).toEqual(['4'])
|
||||
})
|
||||
|
||||
it('defaults new tasks to today at noon in local time', () => {
|
||||
const due = defaultTaskDueAt(new Date(2026, 8, 8, 21, 30))
|
||||
expect(due).toBe('2026-09-08T12:00')
|
||||
})
|
||||
|
||||
it('formats API dates in local wall-clock time', () => {
|
||||
const original = process.env.TZ
|
||||
process.env.TZ = 'Asia/Shanghai'
|
||||
|
||||
@@ -144,6 +144,13 @@ export function parseTaskRrule(rrule = ''): TaskRepeatConfig {
|
||||
}
|
||||
}
|
||||
|
||||
export function defaultTaskDueAt(now = new Date()) {
|
||||
const year = now.getFullYear()
|
||||
const month = `${now.getMonth() + 1}`.padStart(2, '0')
|
||||
const day = `${now.getDate()}`.padStart(2, '0')
|
||||
return `${year}-${month}-${day}T12:00`
|
||||
}
|
||||
|
||||
export function toDateTimeLocal(value: string | null | undefined) {
|
||||
if (!value) return ''
|
||||
const date = new Date(value)
|
||||
|
||||
@@ -183,6 +183,11 @@ describe('mobile touch targets', () => {
|
||||
})
|
||||
|
||||
describe('unified floating add interaction', () => {
|
||||
it('defaults every new-task composer to today', () => {
|
||||
expect(app).toContain('composeDueAt.value = defaultTaskDueAt()')
|
||||
expect(app).not.toContain("activeView.value === 'today' ? toDateTimeLocal(quickTaskFields")
|
||||
})
|
||||
|
||||
it('lets task create and detail forms configure a repeat rule', () => {
|
||||
expect(app).toContain('const composeRepeat = ref')
|
||||
expect(app).toContain('const selectedTaskRepeat = ref')
|
||||
|
||||
Reference in New Issue
Block a user