feat(board): rework quick-peek modal (Linear-style) + board toolbar
CI - Build & Test / Backend (.NET) (push) Successful in 33s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 17s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Has been skipped

Modal redesign — compact summary instead of two long cards:
- Topbar: breadcrumb + state pill + copyable task-id/link chip; review
  actions (approve / request changes) live in the modal header too
- Main column: title, meta chips (ball, created, last update), compact
  description, then square summary tiles (done/total with progress,
  active, open, blocked) + per-agent pills — details stay in Vollansicht
- Right sidebar: properties as slim Linear-style rows (status, priority,
  assignee, due, source) with hover-reveal controls; activity moved next
  to properties as a compact timeline with a new comment composer
  (POST tasks/{id}/activity via new store action postTaskActivity)
- Unified button system (32px: primary/ghost/approve/changes/icon)
- flattenBoard includes nested children again so quick-peek works for
  child rows inside master cards

Board (issue-tracker basics):
- Toolbar with search (title/detail/id/child titles) and ball filters:
  Alle / Du bist dran / Bei Iris / Haengt

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 12:10:51 +02:00
parent 50d95fa7a9
commit 2ee1fe973f
19 changed files with 402 additions and 922 deletions
-72
View File
@@ -1,72 +0,0 @@
<script setup lang="ts">
/**
* StatusDot — Nexus V2 animierter Status-Indikator
*
* Kapselt die pulse-keyframes aus nexus-tokens.css.
* Status-Farben und Pulse-Animationen stammen ausschließlich aus Tokens.
*
* Props:
* status 'work' | 'think' | 'idle' | 'block' | 'queue'
* size 'sm' (8px) | 'md' (9px) | 'lg' (12px), default 'md'
* pulse Animation aktiv (default: true für work/think/block)
* label Text-Label rechts neben dem Dot (optional)
*/
withDefaults(defineProps<{
status: 'work' | 'think' | 'idle' | 'block' | 'queue'
size?: 'sm' | 'md' | 'lg'
pulse?: boolean
label?: string
}>(), {
size: 'md',
})
</script>
<template>
<span class="status-dot-wrapper">
<span
class="dot"
:class="[status, size, { pulse: pulse !== false }]"
:aria-label="label || status"
role="status"
></span>
<span v-if="label" class="dot-label">{{ label }}</span>
</span>
</template>
<style scoped>
.status-dot-wrapper {
display: inline-flex;
align-items: center;
gap: 6px;
}
.dot {
display: inline-block;
border-radius: 50%;
flex: 0 0 auto;
}
.dot.sm { width: 7px; height: 7px; }
.dot.md { width: 9px; height: 9px; }
.dot.lg { width: 12px; height: 12px; }
/* Farben aus nexus-tokens.css — Single Source of Truth */
.dot.work { background: var(--st-work); }
.dot.think { background: var(--st-think); }
.dot.idle { background: var(--st-idle); }
.dot.block { background: var(--st-block); }
.dot.queue { background: var(--st-queue); }
/* Pulse-Animationen (Keyframes in tokens.css definiert) */
.dot.work.pulse { animation: pulse-work 1.8s infinite; box-shadow: 0 0 0 0 rgba(61,220,151,.55); }
.dot.think.pulse { animation: pulse-think 1.8s infinite; box-shadow: 0 0 0 0 rgba(52,214,245,.55); }
.dot.block.pulse { animation: pulse-block 1.4s infinite; box-shadow: 0 0 0 0 rgba(251,113,133,.55); }
.dot-label {
font-size: 12.5px;
font-weight: 600;
color: var(--tx-2);
white-space: nowrap;
}
</style>