Epics table: barra de progreso (% HUs completadas) + removida columna Asignado

- epicProgress computed: agrupa HUs por _epicCode, calcula % completadas
- getEpicProgress(epic): resuelve progreso para cada épica
- Barra visual con colores: verde=100%, azul=>0%, gris=0%
This commit is contained in:
2026-05-29 22:38:52 -05:00
parent 3035351e6f
commit 2073d936e2
+38 -5
View File
@@ -539,6 +539,32 @@ watch(
{ immediate: true }
)
// ─── Epic progress bar ───────────────────────────────
const epicProgress = computed(() => {
const map = new Map<string, { total: number; done: number }>()
for (const hu of workItems.userStories) {
const epicCode = hu._epicCode || ''
if (!epicCode) continue
if (!map.has(epicCode)) map.set(epicCode, { total: 0, done: 0 })
const entry = map.get(epicCode)!
entry.total++
const s = String(hu.status ?? '').toLowerCase()
if (['done', 'completed', 'closed', 'finalizado', '5', 'true'].includes(s)) {
entry.done++
}
}
const result: Record<string, number> = {}
for (const [code, { total, done }] of map) {
result[code] = total > 0 ? Math.round((done / total) * 100) : 0
}
return result
})
function getEpicProgress(epic: any): number {
const code = epic._epicCode
return code ? epicProgress.value[code] ?? 0 : 0
}
const statusVariant = (status: unknown) => {
const s = String(status ?? '').toLowerCase()
if (['done', 'completed', 'closed', 'finalizado'].includes(s)) return 'secondary'
@@ -771,8 +797,7 @@ const statusLabel = (status: unknown) => {
<TableHead class="w-[60px]">{{ t('users.role') }}</TableHead>
<TableHead>{{ t('dashboard.title') }}</TableHead>
<TableHead class="w-[60px] text-center">Desc</TableHead>
<TableHead class="w-[90px] text-center">{{ t('dashboard.assignedTo') }}</TableHead>
<TableHead class="w-[100px]">{{ t('dashboard.status') }}</TableHead>
<TableHead class="w-[140px]">Progreso</TableHead>
</TableRow>
</TableHeader>
<TableBody>
@@ -792,9 +817,17 @@ const statusLabel = (status: unknown) => {
</Dialog>
<span v-else class="text-xs text-muted-foreground/40"></span>
</TableCell>
<TableCell class="text-center text-xs text-muted-foreground"></TableCell>
<TableCell>
<Badge :variant="statusVariant(epic.status || '')" class="text-xs">{{ statusLabel(epic.status || '') }}</Badge>
<TableCell class="text-xs">
<div class="flex items-center gap-2">
<div class="flex-1 h-2 rounded-full bg-muted overflow-hidden">
<div
class="h-full rounded-full transition-all duration-300"
:class="getEpicProgress(epic) >= 100 ? 'bg-green-500' : getEpicProgress(epic) > 0 ? 'bg-primary' : ''"
:style="{ width: getEpicProgress(epic) + '%' }"
/>
</div>
<span class="font-mono text-[10px] text-muted-foreground w-8 text-right">{{ getEpicProgress(epic) }}%</span>
</div>
</TableCell>
</TableRow>
</TableBody>