feat: unify completed filters in topbar
This commit is contained in:
+32
-20
@@ -7,6 +7,7 @@ const app = readFileSync('src/App.vue', 'utf8')
|
||||
const mvpPanel = readFileSync('src/MvpPanel.vue', 'utf8')
|
||||
const countdownPanel = readFileSync('src/CountdownPanel.vue', 'utf8')
|
||||
const floatingAdd = readFileSync('src/components/FloatingAddButton.vue', 'utf8')
|
||||
const completedFilterPill = readFileSync('src/components/CompletedFilterPill.vue', 'utf8')
|
||||
|
||||
describe('mobile navigation styles', () => {
|
||||
it('renames the bottom More tab to a direct Settings tab', () => {
|
||||
@@ -419,35 +420,46 @@ describe('task and habit row decoration', () => {
|
||||
expect(app).toContain('if (restoredNavigation.view === \'tasks\' && restoredNavigation.listId)')
|
||||
})
|
||||
|
||||
it('uses one positive completed-item preference across task and habit views', () => {
|
||||
it('uses one topbar pill and keeps App as the only preference owner', () => {
|
||||
expect(app).toContain("import CompletedFilterPill from './components/CompletedFilterPill.vue'")
|
||||
expect(app.match(/<CompletedFilterPill/g)).toHaveLength(1)
|
||||
expect(app).toContain("v-if=\"['today', 'tasks', 'upcoming', 'habits'].includes(activeView)\"")
|
||||
expect(app).toContain('v-model="showCompleted"')
|
||||
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).toContain('@update:show-completed="showCompleted = $event"')
|
||||
expect(app).not.toContain('@update:show-completed')
|
||||
expect(mvpPanel).toContain('showCompleted: boolean')
|
||||
expect(mvpPanel).toContain("'update:showCompleted': [value: boolean]")
|
||||
expect(mvpPanel).not.toContain('HIDE_COMPLETED_HABITS_STORAGE_KEY')
|
||||
expect(mvpPanel).not.toContain('dodo.hide-completed-habits')
|
||||
expect(mvpPanel).not.toContain("'update:showCompleted': [value: boolean]")
|
||||
expect(completedFilterPill).not.toContain('localStorage')
|
||||
})
|
||||
|
||||
it('shows one positive switch before Today content and no switch inside today habits', () => {
|
||||
expect(app).toContain('class="list-toolbar today-completed-toolbar"')
|
||||
expect(app.indexOf('class="list-toolbar today-completed-toolbar"')).toBeLessThan(app.indexOf('class="today-board"'))
|
||||
expect(app).toContain('<input v-model="showCompleted" type="checkbox"> 显示已完成')
|
||||
it('removes duplicate completed filters while preserving habit completion buttons', () => {
|
||||
expect(app).not.toContain('today-completed-toolbar')
|
||||
expect(app).not.toContain('<input v-model="showCompleted" type="checkbox"> 显示已完成')
|
||||
expect(mvpPanel).not.toContain('class="habit-toolbar"')
|
||||
expect(mvpPanel).not.toMatch(/type="checkbox"[^>]*显示已完成/)
|
||||
expect(mvpPanel.match(/class="task-check habit-check"/g)?.length).toBe(2)
|
||||
const todayHabits = mvpPanel.slice(mvpPanel.indexOf('<!-- 今日习惯'), mvpPanel.indexOf('<!-- 完整习惯列表'))
|
||||
expect(todayHabits).not.toContain('type="checkbox"')
|
||||
expect(todayHabits).not.toContain('completed-filter-pill')
|
||||
expect(todayHabits).not.toContain('显示已完成')
|
||||
expect(todayHabits).not.toContain('隐藏已完成')
|
||||
})
|
||||
|
||||
it('adds top spacing only to the Today completed toolbar before mobile overrides', () => {
|
||||
const todayToolbarRule = '.today-completed-toolbar{margin-top:8px}'
|
||||
const todayToolbarIndex = css.indexOf(todayToolbarRule)
|
||||
const mobileBreakpointIndex = css.indexOf('@media(max-width:930px)')
|
||||
expect(css.match(/\.today-completed-toolbar\{/g)).toHaveLength(1)
|
||||
expect(todayToolbarIndex).toBeGreaterThan(css.indexOf('.list-toolbar{'))
|
||||
expect(todayToolbarIndex).toBeLessThan(mobileBreakpointIndex)
|
||||
expect(css.slice(mobileBreakpointIndex)).not.toContain('.today-completed-toolbar{')
|
||||
it('keeps the pill at the topbar right and wraps only search when space is narrow', () => {
|
||||
expect(css).toContain('main{container-type:inline-size;')
|
||||
expect(css).toContain('.topbar{display:grid;grid-template-columns:44px minmax(0,1fr) auto;grid-template-areas:"menu title filter";')
|
||||
expect(css).toContain('.topbar:has(.search):has(.topbar-filter){grid-template-columns:44px minmax(0,1fr) minmax(180px,260px) auto;grid-template-areas:"menu title search filter"}')
|
||||
expect(css).toContain('.topbar-title{grid-area:title;min-width:0;width:100%}')
|
||||
expect(css).toContain('.topbar h1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;')
|
||||
expect(css).toContain('.topbar-filter{grid-area:filter;justify-self:end;')
|
||||
expect(app.indexOf('class="topbar-filter"')).toBeLessThan(app.indexOf('class="search"'))
|
||||
expect(css).toContain('@container(max-width:640px){.topbar:has(.search):has(.topbar-filter){grid-template-columns:44px minmax(0,1fr) auto;grid-template-areas:"menu title filter" ". search search";grid-template-rows:auto auto;')
|
||||
expect(css).toContain('.topbar>.icon{grid-area:menu}.topbar-title{grid-area:title}.topbar-filter{grid-area:filter}.topbar .search{grid-area:search;grid-row:2;justify-self:end;width:min(260px,100%);')
|
||||
expect(css).toContain('@media(max-width:930px){.topbar:has(.search):has(.topbar-filter){grid-template-columns:44px minmax(0,1fr) auto;grid-template-areas:"menu title filter" ". search search";grid-template-rows:auto auto;')
|
||||
const mobileLayout = css.slice(css.indexOf('@media(max-width:930px){.shell'))
|
||||
expect(mobileLayout).toContain('.completed-filter-pill{min-width:138px;height:44px')
|
||||
expect(css).not.toContain('.today-completed-toolbar{margin-top:8px}')
|
||||
expect(css).not.toContain('.habit-toolbar{')
|
||||
})
|
||||
|
||||
it('filters habits with the shared preference and disables sorting while completed items are hidden', () => {
|
||||
@@ -457,7 +469,7 @@ describe('task and habit row decoration', () => {
|
||||
expect(mvpPanel).toContain('v-for="h in visibleHabits"')
|
||||
expect(mvpPanel).toContain(':disabled="!showCompleted"')
|
||||
expect(mvpPanel).toContain('if (busy.value || !props.showCompleted) return')
|
||||
expect(css).toContain('.habit-toolbar{')
|
||||
expect(css).not.toContain('.habit-toolbar{')
|
||||
})
|
||||
|
||||
it('distinguishes hidden completed items from true and search empty states', () => {
|
||||
|
||||
Reference in New Issue
Block a user