feat(core): add SmartDag and supporting infrastructure for assign mode
## Context This commit adds the supporting infrastructure that makes the assign feature work end-to-end. ## Components Added/Modified ### SmartDag - Main view component for graph-based task management - Integrates TaskCardGrid and WorkflowGraph - Has 'Assign' mode toggle button - Passes archetypes and assignMode to WorkflowGraph - Manages filter state (hideClosed, sortReadyFirst, etc.) ### useGraphAnalysis Hook - Extracted graph analysis logic for reuse - Returns: actionableNodeIds, cycleNodeIdSet, blockerTooltipMap, etc. - Used by both SmartDag and AssignmentPanel - Ensures consistent 'actionable' definition across components ### UnifiedShell - Added assignMode state - Added selectedAssignIssue state - Renders AssignmentPanel when in graph view + assign mode - Wires up onAssignModeChange and onSelectedIssueChange callbacks ## Design Philosophy - Shared hook means single source of truth for 'actionable' - Clean separation between view (SmartDag) and sidebar (AssignmentPanel) - URL state preserved for navigation ## Test Coverage - SmartDag tests: 12 tests covering buttons, callbacks, imports - useGraphAnalysis tests: 6 tests covering cycle detection, blockers - UnifiedShell tests: 9 tests covering state and rendering
This commit is contained in:
parent
308a7d9b31
commit
93b3c33976
6 changed files with 706 additions and 79 deletions
78
tests/components/graph/smart-dag.test.tsx
Normal file
78
tests/components/graph/smart-dag.test.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
// Test that the SmartDag component file exists and exports correctly
|
||||
test('SmartDag - file exists and exports', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('export function SmartDag'), 'Should export SmartDag function');
|
||||
assert.ok(fileContent.includes('export interface SmartDagProps'), 'Should export SmartDagProps interface');
|
||||
});
|
||||
|
||||
// Test that SmartDag has Filters toggle
|
||||
test('SmartDag - contains Filters toggle button', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('Filters'), 'Should contain Filters text');
|
||||
assert.ok(fileContent.includes('showFilters'), 'Should have showFilters state');
|
||||
});
|
||||
|
||||
// Test that SmartDag has Assign toggle
|
||||
test('SmartDag - contains Assign toggle button', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('Assign'), 'Should contain Assign text');
|
||||
assert.ok(fileContent.includes('assignMode'), 'Should have assignMode state');
|
||||
});
|
||||
|
||||
// Test that SmartDag has WorkflowTabs
|
||||
test('SmartDag - contains WorkflowTabs', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('WorkflowTabs'), 'Should import WorkflowTabs');
|
||||
assert.ok(fileContent.includes('activeTab'), 'Should have activeTab state');
|
||||
});
|
||||
|
||||
// Test that SmartDag has callback props
|
||||
test('SmartDag - supports onAssignModeChange callback', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('onAssignModeChange'), 'Should have onAssignModeChange prop');
|
||||
});
|
||||
|
||||
test('SmartDag - supports onSelectedIssueChange callback', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('onSelectedIssueChange'), 'Should have onSelectedIssueChange prop');
|
||||
});
|
||||
|
||||
// Test that SmartDag imports TaskCardGrid
|
||||
test('SmartDag - imports TaskCardGrid', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('TaskCardGrid'), 'Should import TaskCardGrid');
|
||||
});
|
||||
|
||||
// Test that SmartDag imports WorkflowGraph
|
||||
test('SmartDag - imports WorkflowGraph', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('WorkflowGraph'), 'Should import WorkflowGraph');
|
||||
});
|
||||
|
||||
// Test that SmartDag passes assignMode to WorkflowGraph
|
||||
test('SmartDag - passes assignMode to WorkflowGraph', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(/assignMode=\{assignMode\}/.test(fileContent), 'Should pass assignMode to WorkflowGraph');
|
||||
});
|
||||
|
||||
// Test that SmartDag has filter state management
|
||||
test('SmartDag - manages hideClosed filter', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('hideClosed'), 'Should manage hideClosed state');
|
||||
});
|
||||
|
||||
test('SmartDag - manages sortReadyFirst filter', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('sortReadyFirst'), 'Should manage sortReadyFirst state');
|
||||
});
|
||||
|
||||
// Test that SmartDag uses useGraphAnalysis hook
|
||||
test('SmartDag - uses useGraphAnalysis hook', async () => {
|
||||
const fileContent = await fs.readFile(path.join(process.cwd(), 'src/components/graph/smart-dag.tsx'), 'utf-8');
|
||||
assert.ok(fileContent.includes('useGraphAnalysis'), 'Should import and use useGraphAnalysis');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue