feat: unify task and habit pages with Today
ci / gitleaks (push) Successful in 8s
ci / docker (push) Successful in 6m49s

This commit is contained in:
2026-09-18 10:51:57 +08:00
parent 6d568273ef
commit 978c4b87ed
9 changed files with 204 additions and 20 deletions
+9 -6
View File
@@ -611,8 +611,8 @@ describe('task and habit row decoration', () => {
it('shows habit drag handles only in explicit available reorder mode and never changes Today habits', () => {
expect(mvpPanel).toContain('const habitReorderMode = ref(false)')
expect(mvpPanel).toContain("const habitReorderAvailable = computed(() => props.view === 'habits' && visibleHabits.value.length > 1)")
expect(mvpPanel).toContain('v-if="habitReorderAvailable" class="habit-reorder-toolbar"')
expect(mvpPanel).toContain('class="soft-button reorder-mode-toggle habit-reorder-toggle"')
expect(mvpPanel).toContain('v-if="habitReorderAvailable" class="list-section-action"')
expect(mvpPanel).toContain('class="list-section-heading habit-section-heading"')
expect(mvpPanel).toContain("{{ habitReorderMode ? '完成' : '调整顺序' }}")
expect(mvpPanel).toContain('v-if="habitReorderMode && habitReorderAvailable" class="drag-handle habit-drag-handle"')
const todayHabits = mvpPanel.slice(mvpPanel.indexOf('<!-- 今日习惯'), mvpPanel.indexOf('<!-- 完整习惯列表'))
@@ -782,10 +782,13 @@ describe('task and habit row decoration', () => {
it('uses one completed filter per supported view and keeps App as the only preference owner', () => {
expect(app).toContain("import CompletedFilterPill from './components/CompletedFilterPill.vue'")
expect(app.match(/<CompletedFilterPill/g)).toHaveLength(2)
const topbar = app.slice(app.indexOf('<header class="topbar"'), app.indexOf('</header>', app.indexOf('<header class="topbar"')))
expect(topbar.match(/<CompletedFilterPill/g)).toHaveLength(1)
expect(topbar).toContain('<CompletedFilterPill v-if="activeView===\'upcoming\'" v-model="showCompleted" class="topbar-filter" />')
expect(app).toContain("v-if=\"['today', 'tasks', 'upcoming', 'habits'].includes(activeView)\"")
expect(app).toContain('<CompletedFilterPill v-if="activeView!==\'today\'" v-model="showCompleted" class="topbar-filter" />')
expect(app).toContain('class="today-inline-filter"')
expect(app).toContain('class="list-inline-filter"')
expect(mvpPanel).toContain('class="completed-filter-pill habit-inline-filter"')
expect(app).toContain('v-model="showCompleted"')
expect(app).toContain('class="topbar-actions"')
expect(app).toContain('topbar-refresh')
@@ -799,9 +802,9 @@ describe('task and habit row decoration', () => {
expect(app).toContain("readStoredBoolean(window.localStorage, SHOW_COMPLETED_STORAGE_KEY, true)")
expect(app).toContain("writeStoredBoolean(window.localStorage, SHOW_COMPLETED_STORAGE_KEY, value)")
expect(app).toContain(':show-completed="showCompleted"')
expect(app).not.toContain('@update:show-completed')
expect(app).toContain('@update:show-completed="showCompleted=$event"')
expect(mvpPanel).toContain('showCompleted: boolean')
expect(mvpPanel).not.toContain("'update:showCompleted': [value: boolean]")
expect(mvpPanel).toContain("'update:showCompleted': [value: boolean]")
expect(completedFilterPill).not.toContain('localStorage')
})