Refine dashboard scheduler task layout

This commit is contained in:
jxxghp
2026-06-29 08:49:52 +08:00
parent 82ab594e0c
commit 248984261e
2 changed files with 88 additions and 42 deletions

35
design-qa.md Normal file
View File

@@ -0,0 +1,35 @@
# Dashboard 后台任务组件 Design QA
- source visual truth path: `/var/folders/bg/whrysxz97c18y269rvshw3n00000gn/T/codex-clipboard-0ce83b91-83e5-4235-b128-a01f7c9fed84.png`
- implementation screenshot path: `/tmp/moviepilot-dashboard-scheduler-card-after.png`
- viewport: 1280 × 720组件卡片 500 × 350
- state: 浅色主题1 个运行任务、4 个等待任务
## Full-view comparison evidence
实现保持了原卡片的字体层级、任务头像、标题/副标题结构和卡片尺寸。标题前图标已移除,列表的纵向留白增大,原有任务分隔线不再显示。
## Focused region comparison evidence
卡片区域单独对比后确认:运行任务进度条与任务内容区同宽,右边界均为 868px运行时钟为主题主色 `rgb(145, 85, 253)`4 个等待时钟均为中性灰 `rgba(58, 53, 65, 0.6)`;标题区图标数量和分隔线数量均为 0。关键文字、任务头像和图标均清晰无新增图片资产。
## Findings
- 字体与排版:沿用项目现有字体、字号、字重和截断规则,无可执行偏差。
- 间距与布局:任务间距已增至 0.45rem;状态区并入内容布局,进度条可延伸到最右侧,无重叠。
- 颜色与视觉令牌:等待态使用中性灰,运行态使用主题主色;任务头像和进度条原有任务色保持不变。
- 图片与资产:本组件仅使用既有 Material Design Icons无图片质量问题或占位资产。
- 文案与内容:沿用后端状态与现有国际化文案,无变更。
## Patches made since previous QA pass
- 移除卡片标题图标。
- 增加任务间距并删除分隔线。
- 重排任务状态区,使进度条铺满剩余内容宽度。
- 统一等待/运行时钟的图标和语义色。
## Follow-up polish
无遗留 P0/P1/P2 问题。
final result: passed

View File

@@ -3,7 +3,6 @@ import api from '@/api'
import type { ScheduleInfo, TransferQueue } from '@/api/types'
import { useI18n } from 'vue-i18n'
import { useBackground } from '@/composables/useBackground'
import { SCHEDULER_SHORTCUT_ICON } from '@/composables/useShortcutTools'
import { isScheduleRunning, useScheduleProgress } from '@/composables/useScheduleProgress'
import { getSchedulerVisual } from '@/utils/schedulerVisual'
@@ -105,7 +104,6 @@ useDataRefresh(
<template>
<VCard class="dashboard-work-card dashboard-grid-fill">
<VCardItem>
<template #prepend><VIcon :icon="SCHEDULER_SHORTCUT_ICON" size="20" class="me-2" /></template>
<VCardTitle>{{ t('dashboard.scheduler') }}</VCardTitle>
</VCardItem>
@@ -118,35 +116,37 @@ useDataRefresh(
</VAvatar>
</template>
<VListItemTitle class="background-task-title">
{{ item.title }}
</VListItemTitle>
<VListItemSubtitle class="background-task-subtitle">
{{ item.subtitle }}
</VListItemSubtitle>
<VProgressLinear
v-if="item.progress !== undefined"
:model-value="item.progress"
:color="item.color"
height="2"
rounded
class="mt-2"
/>
<div class="background-task-body">
<div class="background-task-summary">
<div class="background-task-copy">
<VListItemTitle class="background-task-title">
{{ item.title }}
</VListItemTitle>
<VListItemSubtitle class="background-task-subtitle">
{{ item.subtitle }}
</VListItemSubtitle>
</div>
<template #append>
<span class="background-task-status">{{ item.status }}</span>
<VIcon
:icon="
item.progress === undefined
? 'mdi-clock-outline'
: item.progress === 100
? 'mdi-check-circle'
: 'mdi-progress-clock'
"
:color="item.progress === 100 ? 'success' : item.color"
size="15"
<div class="background-task-state">
<span class="background-task-status">{{ item.status }}</span>
<VIcon
:icon="item.progress === undefined ? 'mdi-clock-outline' : 'mdi-progress-clock'"
:color="item.progress === undefined ? undefined : 'primary'"
:class="{ 'text-medium-emphasis': item.progress === undefined }"
size="15"
/>
</div>
</div>
<VProgressLinear
v-if="item.progress !== undefined"
:model-value="item.progress"
:color="item.color"
height="2"
rounded
class="background-task-progress"
/>
</template>
</div>
</VListItem>
<VListItem v-if="backgroundTasks.length === 0">
<VListItemTitle class="text-center"> {{ t('dashboard.noSchedulers') }} </VListItemTitle>
@@ -166,7 +166,7 @@ useDataRefresh(
}
.card-list {
--v-card-list-gap: 0;
--v-card-list-gap: 0.45rem;
flex: 1 1 auto;
min-block-size: 0;
@@ -176,21 +176,28 @@ useDataRefresh(
}
.background-task-item {
position: relative;
min-block-size: 68px;
padding-block: 0.35rem;
border-radius: 0;
}
.background-task-item + .background-task-item::before {
position: absolute;
z-index: 1;
block-size: 1px;
background: rgba(var(--v-border-color), calc(var(--v-border-opacity) * 0.7));
content: '';
inset-block-start: 0;
inset-inline: 0.75rem;
pointer-events: none;
.background-task-body,
.background-task-copy {
min-inline-size: 0;
}
.background-task-body {
inline-size: 100%;
}
.background-task-summary {
display: grid;
align-items: center;
gap: 0.75rem;
grid-template-columns: minmax(0, 1fr) auto;
}
.background-task-state {
display: flex;
align-items: center;
}
.background-task-title {
@@ -209,6 +216,10 @@ useDataRefresh(
white-space: nowrap;
}
.background-task-progress {
margin-block-start: 0.4rem;
}
.dashboard-work-content {
display: flex;
flex: 1 1 auto;