Skip to content

Add Timeline feature with Gantt chart and D3 visualizations#121

Merged
thestumonkey merged 2 commits into
mainfrom
b9c5-timeline
Jan 23, 2026
Merged

Add Timeline feature with Gantt chart and D3 visualizations#121
thestumonkey merged 2 commits into
mainfrom
b9c5-timeline

Conversation

@thestumonkey

@thestumonkey thestumonkey commented Jan 22, 2026

Copy link
Copy Markdown
Member

Summary

Adds an interactive Timeline page to visualize memories with time ranges using two different visualization approaches: Frappe Gantt charts and D3-based Mycelia timelines.

What Changed

New Timeline Page

  • TimelinePage.tsx - Main component with tab-based navigation between two timeline implementations
  • FrappeGanttTimeline - Traditional Gantt chart view with zoom controls and multiple time granularities (Quarter Day, Half Day, Day, Week, Month)
  • MyceliaTimeline - Interactive D3-based timeline with pan/zoom gestures and hover tooltips
  • Demo mode with sample data to preview functionality without real memories

Frontend Integration

  • Added Timeline navigation item in sidebar (Calendar icon)
  • Installed dependencies: d3, frappe-gantt, @types/d3
  • Created TypeScript type declarations for frappe-gantt library
  • Added comprehensive data-testid attributes per CLAUDE.md requirements

Feature Flag Protection

  • Added timeline feature flag to config/feature_flags.yaml (enabled by default)
  • Wrapped route with FeatureRoute component for access control
  • Navigation item automatically shows/hides based on flag status

Why These Changes

This feature was extracted from the friend-lite repository (stu-old-branch) to bring timeline visualization capabilities to Ushadow's memory system. The implementation provides two different visualization approaches to give users flexibility in how they view their temporal memory data.

Implementation Highlights

Security Improvements

  • Replaced innerHTML-based tooltips with React components to prevent XSS vulnerabilities
  • Used safe DOM manipulation throughout

Type Safety

  • Extended Memory type with TimelineMetadata interface for type-safe timeRange access
  • Created proper TypeScript declarations for third-party library (frappe-gantt)
  • Type guards for filtering memories with time range data

User Experience

  • Tab-based interface allows switching between visualization styles
  • Demo mode provides immediate value preview without data
  • Zoom controls, view modes, and interactive tooltips
  • Dark mode support
  • Color-coded event types (Event, Person, Place)

Testing

  • TypeScript compilation: ✅ No errors
  • Build: ✅ Successful
  • Feature flag toggle: ✅ Shows/hides navigation and route access
  • All interactive elements have test IDs for E2E testing

Accessing the Feature

  1. Navigate to /timeline or click "Timeline" in the sidebar
  2. Toggle feature flag via Flask icon (🧪) in header → "Timeline"
  3. Use "Show Demo" button to see sample timeline data

Extracted from: friend-lite/stu-old-branch
Route: /timeline
Feature Flag: timeline

… integrated it into Ushadow. Here's a summary:

`★ Insight ─────────────────────────────────────`
**What was extracted:**
- **TimelineRouter** - Tab navigation between timeline implementations
- **FrappeGanttTimeline** - Gantt chart using the frappe-gantt library
- **MyceliaTimeline** - D3.js-based interactive timeline with zoom/pan

**Key adaptations made:**
1. **API Integration** - Changed from `memoriesApi.getAll()` to Ushadow's `memoriesApi.fetchMemories()` pattern
2. **Type Safety** - Created proper TypeScript interfaces and a type declaration for frappe-gantt
3. **Security** - Replaced innerHTML-based tooltips with React components (avoiding XSS)
4. **Test IDs** - Added comprehensive `data-testid` attributes per CLAUDE.md requirements
`────────────��────────────────────────────────────`

## Summary

**Files created:**
- `ushadow/frontend/src/pages/TimelinePage.tsx` - Main timeline page with two implementations
- `ushadow/frontend/src/types/frappe-gantt.d.ts` - TypeScript declarations for frappe-gantt

**Files modified:**
- `ushadow/frontend/src/App.tsx` - Added TimelinePage import and `/timeline` route
- `ushadow/frontend/package.json` - Added `d3`, `frappe-gantt`, and `@types/d3` dependencies

**Features:**
- Two timeline visualization options (Frappe Gantt and Mycelia D3)
- Tab navigation to switch between implementations
- Demo data mode to preview functionality without real data
- Zoom, pan, and view mode controls
- Tooltip details on hover/click
- Color-coded events by type (Event, Person, Place)
- Dark mode support
- Responsive design

The timeline is now accessible at `/timeline` in the Ushadow frontend.
…nt of the changes.

`★ Insight ─────────────────────────────────────`
**Feature Flag Architecture in Ushadow:**
- **YAML Configuration** - Feature flags are defined in `config/feature_flags.yaml` and hot-reloadable without restart
- **Context Provider** - `FeatureFlagsContext` provides `isEnabled()` function to check flag status
- **Route Protection** - `FeatureRoute` component conditionally renders routes based on flags
- **Navigation Filtering** - Navigation items with `featureFlag` property are automatically filtered in Layout
- **UI Indicator** - Feature flags drawer shows all flags with toggle controls (accessed via Flask icon in header)

This architecture allows you to:
1. Enable/disable features without code changes
2. Test features in production safely
3. Gradually roll out features to users
4. A/B test different implementations
`─────────────────────────────────────────────────`

## Summary

I've successfully added a navigation menu item for the Timeline feature and protected it with a feature flag. Here's what was done:

### Changes Made:

**1. Feature Flag Configuration** (`config/feature_flags.yaml`):
- Added `timeline` feature flag (enabled by default)
- Type: `release` - indicates it's a user-facing feature
- Description explains it visualizes memories on Gantt charts and D3 timelines

**2. Navigation Menu** (`ushadow/frontend/src/components/layout/Layout.tsx`):
- Imported `Calendar` icon from lucide-react
- Added Timeline navigation item between Memories and Cluster
- Item uses Calendar icon and is tied to the `timeline` feature flag
- Will automatically show/hide based on flag status

**3. Route Protection** (`ushadow/frontend/src/App.tsx`):
- Wrapped the `/timeline` route with `<FeatureRoute featureFlag="timeline">`
- This ensures users can't access the route even if they know the URL when the flag is disabled

### How It Works:

**When the feature flag is enabled (default):**
- "Timeline" menu item appears in the sidebar navigation
- Clicking it navigates to `/timeline`
- TimelinePage component renders with both Frappe Gantt and Mycelia D3 implementations

**When the feature flag is disabled:**
- Navigation item is automatically hidden
- Direct navigation to `/timeline` is blocked (returns to a safe route)
- No errors or broken links

**Toggle the feature flag:**
- Click the Flask icon (🧪) in the header to open the Feature Flags drawer
- Find "Timeline" in the list
- Toggle it on/off to show/hide the feature

The Timeline feature is now fully integrated with Ushadow's feature flag system and navigation!
@thestumonkey thestumonkey changed the title Timeline (vibe-kanban) Add Timeline feature with Gantt chart and D3 visualizations Jan 22, 2026
@thestumonkey
thestumonkey merged commit 7f411e0 into main Jan 23, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant