refactor(frontend): deduplicate CSS keyframes, unify types, extract format utils, add UI states, trim mock data
- Remove duplicate @keyframes pulse-* from 3 component files (already in nexus-tokens.css) - Rename AgentDetail → AgentDetailData in dashboard types to avoid collision with types/agent.ts - Extract shared formatNumber/initials/formatTime to utils/format.ts - Simplify FlowBoard: use agentStore modal/selection getters instead of duplicating local state - Add error banner + empty state to IrisChat; add loading skeleton + error/empty states to TaskStrip - Remove 105-line unused mockAgents array from useFlowLayout - Reduce operations store fallbacks from hardcoded preview data to minimal safe defaults - Update operations store tests to match lean fallback structure - Net: -73 lines, cleaner imports, fewer magic strings
This commit is contained in:
@@ -10,11 +10,29 @@ import type { TaskItem } from './types'
|
||||
|
||||
defineProps<{
|
||||
tasks: TaskItem[]
|
||||
loading?: boolean
|
||||
error?: string | null
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="taskstrip v2-scroll">
|
||||
<!-- Loading skeleton -->
|
||||
<template v-if="loading">
|
||||
<div v-for="n in 3" :key="'sk-' + n" class="taskcard skeleton" />
|
||||
</template>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="task-error">
|
||||
<span class="error-icon">⚠</span> {{ error }}
|
||||
</div>
|
||||
|
||||
<!-- Empty -->
|
||||
<div v-else-if="!tasks.length" class="task-empty">
|
||||
No active tasks
|
||||
</div>
|
||||
|
||||
<!-- Tasks -->
|
||||
<div
|
||||
v-for="task in tasks"
|
||||
:key="task.id"
|
||||
@@ -169,4 +187,40 @@ defineProps<{
|
||||
background: var(--st-block);
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
/* ── Skeleton ─────────────────────────────────── */
|
||||
.taskcard.skeleton {
|
||||
height: 98px;
|
||||
background: var(--glass);
|
||||
animation: skeleton-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes skeleton-pulse {
|
||||
0%, 100% { opacity: 0.5; }
|
||||
50% { opacity: 0.8; }
|
||||
}
|
||||
|
||||
/* ── Error ────────────────────────────────────── */
|
||||
.task-error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-family: 'Manrope', sans-serif;
|
||||
font-size: 11px;
|
||||
color: #fda4b0;
|
||||
padding: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.error-icon { flex: 0 0 auto; font-size: 14px; }
|
||||
|
||||
/* ── Empty ────────────────────────────────────── */
|
||||
.task-empty {
|
||||
font-family: 'Manrope', sans-serif;
|
||||
font-size: 11px;
|
||||
color: var(--tx-3);
|
||||
font-style: italic;
|
||||
padding: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user