feat: 任务卡片展示创建时间
- 元信息行右侧新增「创建于 M月D日」,与「完成于」互斥:已完成卡片仍只显示 完成日期,避免两个时间挤占同一行把标签推到第二行 - 精确到分钟的时刻保留在 span 的 title 与卡片 title 中 - 「完成于」补 whitespace-nowrap,窄列下不再拆行 - 补充单元测试:待办/进行中显示创建日期、已完成不叠加、createdAt 非法时不渲染
This commit is contained in:
@@ -173,6 +173,40 @@ describe('时间信息', () => {
|
|||||||
expect(mountCard({ completedAt: null }).text()).not.toContain('完成于')
|
expect(mountCard({ completedAt: null }).text()).not.toContain('完成于')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('未完成卡片显示创建日期', () => {
|
||||||
|
const createdAt = new Date(2026, 9, 8, 9, 30).toISOString()
|
||||||
|
const wrapper = mountCard({ status: 'todo', createdAt })
|
||||||
|
|
||||||
|
const badge = wrapper.find('[data-role="created-at"]')
|
||||||
|
expect(badge.exists()).toBe(true)
|
||||||
|
expect(badge.text()).toBe('创建于 10月8日')
|
||||||
|
// 精确时刻放在 title,悬停即可看到
|
||||||
|
expect(badge.attributes('title')).toBe('创建于 2026-10-08 09:30')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('进行中的卡片同样显示创建日期', () => {
|
||||||
|
const createdAt = new Date(2026, 9, 20, 14, 0).toISOString()
|
||||||
|
const badge = mountCard({ status: 'doing', createdAt }).find('[data-role="created-at"]')
|
||||||
|
|
||||||
|
expect(badge.exists()).toBe(true)
|
||||||
|
expect(badge.text()).toBe('创建于 10月20日')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('已完成卡片只显示完成日期,不叠加创建日期', () => {
|
||||||
|
const createdAt = new Date(2026, 9, 8, 9, 30).toISOString()
|
||||||
|
const completedAt = new Date(2026, 9, 18, 10, 20).toISOString()
|
||||||
|
const wrapper = mountCard({ status: 'done', createdAt, completedAt })
|
||||||
|
|
||||||
|
expect(wrapper.text()).toContain('完成于')
|
||||||
|
expect(wrapper.find('[data-role="created-at"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('创建时间无效时不渲染创建日期', () => {
|
||||||
|
expect(mountCard({ createdAt: 'not-a-date' }).find('[data-role="created-at"]').exists()).toBe(
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it('卡片 title 暴露完整创建与完成时间', () => {
|
it('卡片 title 暴露完整创建与完成时间', () => {
|
||||||
const createdAt = new Date(2026, 9, 18, 10, 8).toISOString()
|
const createdAt = new Date(2026, 9, 18, 10, 8).toISOString()
|
||||||
const completedAt = new Date(2026, 9, 18, 10, 20).toISOString()
|
const completedAt = new Date(2026, 9, 18, 10, 20).toISOString()
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ const hiddenTagCount = computed(() => Math.max(0, props.task.tags.length - MAX_V
|
|||||||
const completedAtFull = computed(() => formatDateTime(props.task.completedAt))
|
const completedAtFull = computed(() => formatDateTime(props.task.completedAt))
|
||||||
const completedAtShort = computed(() => formatCompactDate(props.task.completedAt))
|
const completedAtShort = computed(() => formatCompactDate(props.task.completedAt))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间:未完成卡片在元信息行右侧补一行短日期,用来判断这条待办躺了多久。
|
||||||
|
* 与「完成于」互斥 —— 已完成卡片右侧已被完成日期占用,再叠一个会把标签挤到第二行,
|
||||||
|
* 而且回顾已完成任务时更关心「什么时候做完的」。精确到分钟的时刻仍在 `title` 里。
|
||||||
|
*/
|
||||||
|
const createdAtShort = computed(() => formatCompactDate(props.task.createdAt))
|
||||||
|
const showCreatedAt = computed(() => !isDone.value && createdAtShort.value !== null)
|
||||||
|
|
||||||
/** 悬停卡片即可看到完整时间,不必先打开详情抽屉 */
|
/** 悬停卡片即可看到完整时间,不必先打开详情抽屉 */
|
||||||
const timeTitle = computed(() => {
|
const timeTitle = computed(() => {
|
||||||
const lines = [`创建于 ${formatDateTime(props.task.createdAt) ?? '—'}`]
|
const lines = [`创建于 ${formatDateTime(props.task.createdAt) ?? '—'}`]
|
||||||
@@ -269,10 +277,19 @@ const priorityTextClass = computed(() => {
|
|||||||
v-if="completedAtShort"
|
v-if="completedAtShort"
|
||||||
data-role="completed-at"
|
data-role="completed-at"
|
||||||
:title="`完成于 ${completedAtFull}`"
|
:title="`完成于 ${completedAtFull}`"
|
||||||
class="ml-auto text-emerald-700 dark:text-emerald-400"
|
class="ml-auto whitespace-nowrap text-emerald-700 dark:text-emerald-400"
|
||||||
>
|
>
|
||||||
完成于 {{ completedAtShort }}
|
完成于 {{ completedAtShort }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else-if="showCreatedAt"
|
||||||
|
data-role="created-at"
|
||||||
|
:title="`创建于 ${formatDateTime(task.createdAt) ?? '—'}`"
|
||||||
|
class="ml-auto whitespace-nowrap text-slate-500 dark:text-zinc-400"
|
||||||
|
>
|
||||||
|
创建于 {{ createdAtShort }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
Reference in New Issue
Block a user