重构: 跨模块样式DRY收口+审批列表增强+灵感模块优化
- 全局样式收口: page-header/btn/modal/filter-bar/back-link/empty-state 等通用类从12个视图的scoped重复定义提取到global.css/components.css - 审批列表增强: 筛选栏(状态/风险/工具搜索)+行展开查看完整参数结果 +审批耗时显示+刷新spinner+硬编码颜色全部改用CSS变量 - 灵感模块: scoreTier统一评分阈值+score-bar/assessment-badge提取全局 +statusLabelKey消除重复+i18n状态文案对齐+eval-report--muted统一空态 - Dashboard: df-panel/df-link提取全局(修scoped不渗透)+统计卡可点击跳转 +活跃项目面板只显示active状态+灵感列表按分数排序+刷新spinner - 修复: intent.rs tool_type类型对齐(newtype)+ToolCardList补ai-btn定义 +SkillMention/ImageInput样式不渗透修复(提取全局)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<router-link to="/projects" class="df-link">{{ $t('dashboard.viewAll') }}</router-link>
|
||||
</div>
|
||||
<div class="project-list">
|
||||
<div v-for="(p, i) in displayProjects" :key="p.id" class="project-row" :style="{ animationDelay: `${300 + i * 50}ms` }">
|
||||
<div v-for="(p, i) in displayProjects" :key="p.id" class="project-row clickable" :style="{ animationDelay: `${300 + i * 50}ms` }" @click="goDetail(p.id)" :title="t('dashboard.goProjectDetail')">
|
||||
<div class="project-row-top">
|
||||
<div class="project-identity">
|
||||
<span class="project-dot" :class="'dot-' + p.stage"></span>
|
||||
@@ -34,57 +34,67 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
// 活跃项目面板 — 从 Dashboard.vue 抽出(项目列表 + 进度条 + 阶段 chip + 空态)。
|
||||
// 共享 project store(全局单例),displayProjects computed 直读 store.projects/tasks,无需父传 props。
|
||||
// getProjectStage 死键语义对齐 constants/project.ts 的 PROJECT_STAGE_INFO。
|
||||
// 共享 project store(全局单例),displayProjects computed 过滤 active 状态按更新时间倒序取前 6 条。
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useProjectStore } from '@/stores/project'
|
||||
import { projectStageInfo } from '@/constants/project'
|
||||
import { formatRelative } from '@/utils/time'
|
||||
|
||||
const store = useProjectStore()
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
|
||||
function getProjectStage(status: string): { stage: string; stageLabelKey: string; progress: number } {
|
||||
// F-09 对齐:project status 死键(in_progress/paused/cancelled)已从后端映射移除,
|
||||
// 此处 switch 同步收敛,与 constants/project.ts 的 PROJECT_STAGE_INFO 语义一致。
|
||||
switch (status) {
|
||||
case 'planning': return { stage: 'planning', stageLabelKey: 'planning', progress: 20 }
|
||||
case 'active': return { stage: 'coding', stageLabelKey: 'coding', progress: 55 }
|
||||
case 'completed': return { stage: 'release', stageLabelKey: 'done', progress: 100 }
|
||||
default: return { stage: 'planning', stageLabelKey: 'planning', progress: 20 }
|
||||
}
|
||||
// 点击项目行跳转详情(治本:列表项可进详情,与其他列表页交互一致)
|
||||
function goDetail(projectId: string) {
|
||||
router.push(`/projects/${projectId}`)
|
||||
}
|
||||
|
||||
function getProjectTaskCount(projectId: string): number {
|
||||
return store.tasks.filter(t => t.project_id === projectId && t.status === 'in_progress').length
|
||||
}
|
||||
|
||||
// 相对时间复用 utils/time.formatRelative(与 Tasks/AuditLog/MessageList 等同源,根治 NaN)
|
||||
// 原 formatLastActivity 是其逐行复制,提取为单一来源。
|
||||
const formatLastActivity = formatRelative
|
||||
|
||||
// 阶段 label key:projectStageInfo 返回的 stage 值(coding/testing/release/planning)
|
||||
// 直接拼接 i18n key dashboard.stage.<stage>,与 constants/project.ts PROJECT_STAGE_INFO 单一来源。
|
||||
// 面板名为"活跃项目",只显示 active 状态(DB 实际默认值,ProjectStatus union 历史遗留未含
|
||||
// 'active',此处断言绕过;DB 实际无 planning/in_progress 等值产生,详见功能决策记录)。
|
||||
// 按更新时间倒序取前 6 条(completed 归档项目不混入)。
|
||||
const displayProjects = computed(() =>
|
||||
store.projects.map(p => {
|
||||
const stageInfo = getProjectStage(p.status)
|
||||
return {
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
...stageInfo,
|
||||
activeTasks: getProjectTaskCount(p.id),
|
||||
lastActivity: formatLastActivity(p.updated_at),
|
||||
}
|
||||
})
|
||||
store.projects
|
||||
.filter(p => (p.status as string) === 'active')
|
||||
.sort((a, b) => b.updated_at.localeCompare(a.updated_at))
|
||||
.slice(0, 6)
|
||||
.map(p => {
|
||||
const info = projectStageInfo(p.status)
|
||||
return {
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
stage: info.stage,
|
||||
stageLabelKey: info.stage,
|
||||
progress: info.progress,
|
||||
activeTasks: getProjectTaskCount(p.id),
|
||||
lastActivity: formatRelative(p.updated_at),
|
||||
}
|
||||
})
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 仅迁入项目行自身样式;df-panel/df-link 等通用面板类留 Dashboard.vue(多面板共享) */
|
||||
/* df-panel/df-link 通用面板类已提取到 styles/components.css 全局 */
|
||||
.project-list { display: flex; flex-direction: column; }
|
||||
.project-row {
|
||||
padding: 10px 0;
|
||||
border-bottom: 0.5px solid var(--df-border);
|
||||
animation: fadeInUp 0.4s var(--df-ease) both;
|
||||
}
|
||||
.project-row.clickable {
|
||||
cursor: pointer;
|
||||
transition: background 0.15s var(--df-ease);
|
||||
}
|
||||
.project-row.clickable:hover {
|
||||
background: var(--df-bg);
|
||||
}
|
||||
.project-row:last-child { border-bottom: none; }
|
||||
|
||||
.project-row-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
|
||||
|
||||
Reference in New Issue
Block a user