mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
✨ feat: add dependency graph view for task visualization
Add a new interactive graph view alongside the kanban board for visualizing task dependencies. The graph view uses React Flow with dagre auto-layout to display tasks as nodes connected by dependency edges. Key features: - Toggle between kanban and graph view via new control buttons - Custom TaskNode component matching existing card styling/themes - Animated edges that flow when tasks are in progress - Status-aware node colors (backlog, in-progress, waiting, verified) - Blocked tasks show lock icon with dependency count tooltip - MiniMap for navigation in large graphs - Zoom, pan, fit-view, and lock controls - Horizontal/vertical layout options via dagre - Click node to view details, double-click to edit - Respects all 32 themes via CSS variables - Reduced motion support for animations New dependencies: @xyflow/react, dagre
This commit is contained in:
@@ -889,3 +889,162 @@
|
||||
.xterm-viewport::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--muted-foreground);
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
DEPENDENCY GRAPH STYLES
|
||||
Theme-aware styling for React Flow graph
|
||||
======================================== */
|
||||
|
||||
/* React Flow base theme overrides */
|
||||
.graph-canvas {
|
||||
--xy-background-color: transparent;
|
||||
--xy-node-background-color: var(--card);
|
||||
--xy-node-border-color: var(--border);
|
||||
--xy-node-border-radius: 0.75rem;
|
||||
--xy-edge-stroke-default: var(--border);
|
||||
--xy-edge-stroke-selected: var(--brand-500);
|
||||
--xy-minimap-background-color: var(--popover);
|
||||
--xy-minimap-mask-background-color: rgba(0, 0, 0, 0.2);
|
||||
--xy-controls-background-color: var(--popover);
|
||||
--xy-controls-border-color: var(--border);
|
||||
}
|
||||
|
||||
/* MiniMap styling */
|
||||
.graph-canvas .react-flow__minimap {
|
||||
background-color: var(--popover) !important;
|
||||
border: 1px solid var(--border) !important;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.graph-canvas .react-flow__minimap-mask {
|
||||
fill: var(--background);
|
||||
fill-opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Edge animations */
|
||||
@keyframes flow-dash {
|
||||
to {
|
||||
stroke-dashoffset: -20;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes edge-glow {
|
||||
0%, 100% {
|
||||
filter: drop-shadow(0 0 2px var(--status-in-progress));
|
||||
}
|
||||
50% {
|
||||
filter: drop-shadow(0 0 6px var(--status-in-progress));
|
||||
}
|
||||
}
|
||||
|
||||
.graph-canvas .animated-edge path {
|
||||
animation: flow-dash 0.5s linear infinite;
|
||||
}
|
||||
|
||||
.graph-canvas .edge-flowing path {
|
||||
animation:
|
||||
flow-dash 0.5s linear infinite,
|
||||
edge-glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Edge particle animation */
|
||||
.edge-particle {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Node animations */
|
||||
@keyframes pulse-subtle {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 0 0 var(--status-in-progress);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 15px 3px var(--status-in-progress);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-pulse-subtle {
|
||||
animation: pulse-subtle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Progress bar indeterminate animation */
|
||||
@keyframes progress-indeterminate {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
width: 50%;
|
||||
}
|
||||
50% {
|
||||
transform: translateX(50%);
|
||||
width: 30%;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(200%);
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-progress-indeterminate {
|
||||
animation: progress-indeterminate 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Handle styling */
|
||||
.graph-canvas .react-flow__handle {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--border);
|
||||
border: 2px solid var(--background);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.graph-canvas .react-flow__handle:hover {
|
||||
background-color: var(--brand-500);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.graph-canvas .react-flow__handle-left {
|
||||
left: -6px;
|
||||
}
|
||||
|
||||
.graph-canvas .react-flow__handle-right {
|
||||
right: -6px;
|
||||
}
|
||||
|
||||
/* Selection styles */
|
||||
.graph-canvas .react-flow__node.selected {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.graph-canvas .react-flow__edge.selected path {
|
||||
stroke: var(--brand-500);
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
/* Attribution removal (requires pro license) */
|
||||
.graph-canvas .react-flow__attribution {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Panel styling */
|
||||
.graph-canvas .react-flow__panel {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
/* Retro theme overrides */
|
||||
.retro .graph-canvas .react-flow__handle,
|
||||
.retro .graph-canvas .react-flow__minimap {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.retro .graph-canvas .react-flow__node {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* Reduce motion preference */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.graph-canvas .animated-edge path,
|
||||
.graph-canvas .edge-flowing path,
|
||||
.animate-pulse-subtle,
|
||||
.animate-progress-indeterminate {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user