Skip to main content

Blogging Mechanism - Link Management

· One min read

Blog Technique - Link Manipulation

  • I should have guidance on noteplan links / local vscode links / rewritting them ...

Blogging Mechanism - Link Management

Execution Plan

Execution Results / Attempts

Status: Not Started

Execution has not yet begun. This section will be updated when work commences.

Blogging Mechanism - SEO

· One min read

Execution Plan

Establish SEO mechanisms and optimizations for blog content visibility, including:

  • Frontmatter cleanup and standardization
  • SEO improvements and optimizations
  • Integration with Docusaurus SEO features
  • Proof of concept implementation

Execution Results / Attempts

✅ Initial SEO Work Completed (2025-09-10)

Work Period: September 10, 2025

Commits: 3 commits related to SEO improvements

Key Accomplishments:

  • Cleaned up blog post frontmatter
  • Established mechanisms to keep frontmatter up to date
  • Created plan for SEO improvements
  • Implemented SEO proof of concept
  • Applied SEO improvements and retheme

Notable Commits:

  • fb310e2f (2025-09-10): Cleaning up blog post frontmatter + mechanisms to keep frontmatter up to date + plan for SEO
  • e3cacacea (2025-09-10): SEO improvements, retheme, etc
  • 103e8f1d (2025-09-10): Adding SEO poc

Status: Initial SEO work has been completed, including frontmatter cleanup and SEO improvements. Further integration with Docusaurus SEO features is planned for future work.

Bundle Size Optimization

· 3 min read

Execution Plan

Optimize bundle sizes and load times for both Storybook and the main blog to improve web performance:

Goals

  1. Reduce Storybook bundle sizes - Currently seeing warnings for large bundles (1.41 MiB for force-graph libraries)
  2. Improve initial load time - Reduce time to first paint and interactive
  3. Better code splitting - Ensure heavy libraries load only when needed
  4. Optimize caching - Separate chunks for better browser caching

Areas to Optimize

  1. Storybook Build

    • Large bundles: 70.fd609f3c.iframe.bundle.js (1.41 MiB), 878.38cfd5e5.iframe.bundle.js (983 KiB)
    • Main entrypoint: 1.43 MiB combined
    • Force-graph libraries (react-force-graph-2d, d3-force) are heavy and should be code-split
  2. Docusaurus Blog Build

    • Optimize production bundle sizes
    • Ensure proper tree-shaking
    • Lazy load heavy components (Graph component)
  3. Webpack Configuration

    • Configure code splitting for better chunk separation
    • Optimize chunk sizes and caching strategies
    • Enable tree-shaking and dead code elimination

Execution Results / Attempts

✅ Initial Webpack Optimization (2025-01-20)

What We Tried:

  1. Added webpack code splitting configuration in .storybook/main.ts:

    • Configured splitChunks to separate large libraries into their own chunks
    • Created separate chunks for force-graph libraries (react-force-graph-2d, d3-force)
    • Separated Storybook addons into their own chunks
    • Set usedExports: true to enable tree-shaking
  2. Chunk Separation Strategy:

    forceGraph: {
    name: 'force-graph',
    test: /[\\/]node_modules[\\/](react-force-graph|force-graph|d3-)[\\/]/,
    chunks: 'all',
    priority: 30,
    enforce: true,
    }

Results:

  • ✅ Code splitting configuration added successfully
  • ✅ Force-graph libraries are now in separate chunks
  • ⚠️ Bundle size warnings still present (expected - these are large libraries)
  • ⚠️ Main entrypoint still shows 1.43 MiB (includes runtime + main bundle)

What Worked:

  • Webpack configuration successfully merged with Storybook's existing optimization settings
  • Chunk separation is working - force-graph libraries are isolated
  • Configuration is non-breaking and merges safely with Storybook defaults

What Didn't Work / Limitations:

  • Bundle size warnings persist because:
    • react-force-graph-2d and d3-force are inherently large libraries (~1.4 MiB)
    • Storybook itself bundles many development dependencies
    • These are dev tools, so absolute bundle size is less critical than production
  • The warnings are informational - Storybook is primarily a development tool

Current Status:

  • Code splitting is configured and working
  • Large libraries are properly isolated into separate chunks
  • Bundle size warnings remain but are expected for heavy libraries
  • Further optimization would require:
    • Lazy loading stories that use heavy components
    • Removing unused Storybook addons
    • Considering alternative lighter libraries (if available)

Next Steps

  1. Lazy Load Heavy Stories

    • Only load Graph stories when they're actually viewed
    • Use React.lazy() or dynamic imports for Graph component stories
  2. Review Storybook Addons

    • Audit which addons are actually used
    • Remove unused addons (@storybook/addon-interactions, @storybook/addon-links if not needed)
  3. Docusaurus Production Optimization

    • Apply similar code splitting strategies to Docusaurus build
    • Ensure Graph component is lazy-loaded in production
    • Optimize CSS bundle sizes
  4. Monitor and Measure

    • Track bundle sizes over time
    • Measure actual load times (not just bundle sizes)
    • Use Lighthouse/WebPageTest for real-world performance metrics

Plan - Leveraging GenAI to Enhance Blog

· One min read
  • For my blog ...
    • I don't want AI blob ...
    • I want my posts to be from "me"
      • I need to be able to stand behind each of my posts ...
    • I want AI to help explore topics to learn / understand ...

GenAI Assisted Blog Posts

  • Turn a lot of the posts about topics generated/docuemnted by GenAI into a todo list to learn more about the topic ...

    • Help me generate a plan ... to learn about XYZ ...
  • Make "Working Backwards Posts"

    • Make a final blog post regarding what I learned ... what I did ... what the problem statement was ... etc ...
  • I should have a prompt that helps me generate these ...

    • help me put together a plan to tinker with ... xyzzy ...
    • Learn my style from other posts ...
  • Write a prompt to skim through recently edited / created blog files in git ... untracked, etc ... and initialize them ... go through them all first ...

    • Don't add content ...
    • Mark them as draft ...
    • Add top 5 questions to answer them ...
    • Then add a makefile target to list all the drafts ...

Execution Plan

Execution Results / Attempts

Status: Not Started

Execution has not yet begun. This section will be updated when work commences.

Blog Structure - Changelog & Roadmap

· 3 min read

Execution Plan

Organize and structure the changelog and roadmap sections of the blog, including:

  • Changelog tab/page with GitHub-style heatmap visualization
  • Structure for changelog entries with frontmatter
  • Automated changelog data generation from markdown files
  • Roadmap integration (migrated to changelog entries)

Execution Results / Attempts

✅ Changelog System Completed (2025-01-20)

Work Period: January 20, 2025

Key Accomplishments:

  • Created changelog directory structure (changelog/)
  • Implemented changelog entry format with frontmatter
  • Built automated changelog data generation script (scripts/generate-changelog-data.js)
  • Created Changelog React component with heatmap visualization
  • Implemented GitHub-style month/quarter/year heatmap display
  • Added changelog page route (/changelog)
  • Migrated roadmap items to changelog entries
  • Established naming conventions for changelog entries
  • Integrated changelog generation into build process (npm lifecycle hooks)

Components Created:

  • Changelog Component System - See Component Creation Entry for detailed component architecture
    • Main Changelog component (src/components/Changelog/Changelog.tsx)
    • Modular sub-components (DateOverlay, HeatmapRow, LegendSidebar, Legend, Filters, QuarterSection)
    • Heatmap visualization with month/quarter/year grouping
    • Separate rows for content vs development categories
    • Quarter-based list view with horizontal scrolling
    • Entry filtering and navigation
  • Changelog Utilities (src/components/Changelog/changelogUtils.ts)
    • Data loading and processing
  • Changelog Types (src/components/Changelog/types.ts)
    • TypeScript interfaces for changelog entries

Scripts Created:

  • scripts/generate-changelog-data.js: Automatically scans changelog/ directory, parses frontmatter, and generates JSON data file
    • Runs automatically via npm prestart and prebuild hooks
    • Generates src/components/Changelog/changelog-data.json

Documentation Created:

  • NAMING_CONVENTIONS.md: Comprehensive naming conventions for changelog entries
  • docs/6-techniques/3-blogging-techniques/changelog-system.md: Changelog entry format and guidelines
  • docs/6-techniques/3-blogging-techniques/changelog-sync-with-git-plan.md: Plan for syncing changelog with git history
  • prompts/heal/heal-blog-changelog.md: Reusable prompt for inferring and enriching changelog entries from git history

Related Links:

Roadmap Migration:

  • Migrated all roadmap items from ROADMAP.md files to changelog entries with planned status
  • Removed deprecated ROADMAP.md files
  • Roadmap items now tracked as changelog entries

Status: Changelog system has been successfully implemented. The blog now has a comprehensive changelog system with automated data generation, GitHub-style visualization, and structured entry format. Roadmap items have been migrated to changelog entries for unified tracking.

Blog Structure - Habits

· One min read

Blog Section - Habits

  • Separate the habits ...
    • One back log of action items ...
    • And one general habit guidance ...

Execution Plan

Execution Results / Attempts

Status: Not Started

Execution has not yet begun. This section will be updated when work commences.

Blog Structure - Techniques

· One min read

Blog Sections - Strategy vs Technique

  • I need to add a strategy section to the blog ...
    • Strategies guide approach / action items
    • They are on the planning side ...
  • Techniques are part of the execution
    • They are functions / approaches / methods / patterns with regards to execution ...
    • I may have a strategy in applying a particular technique ..

Blog Posts - Strategies / Processes

  • Write a post on my working method
  • Another on thinking method

Execution Plan

Execution Results / Attempts

Status: Not Started

Execution has not yet begun. This section will be updated when work commences.

Changelog Directory Structure

· One min read

This directory contains changelog entries organized by category.

Directory Structure

  • content/ - Content-related changes (blog posts, documentation, content enhancements)
  • development/ - Development/infrastructure changes (components, mechanics, infrastructure, optimization, structure)

File Organization

Content Changes (content/)

Place entries related to:

  • New blog posts (content-post-*)
  • Documentation updates (documentation-*)
  • Content enhancements

Example: content/2025-01-15-content-post-knowledge-agents-design.md

Development Changes (development/)

Place entries related to:

  • Component creation/enhancement (component-*)
  • Blogging mechanics (mechanic-*)
  • Infrastructure improvements (infrastructure-*)
  • Performance optimizations (optimization-*)
  • Structure changes (structure-*)
  • Refactoring (refactoring-*)
  • Bug fixes (bugfix-*)

Example: development/2025-01-15-component-creation-svg-kanban.md

Backward Compatibility

Files in the root changelog/ directory are automatically categorized:

  • Files with content-post-* prefix → content category
  • All other files → development category

However, it's recommended to move files to the appropriate subdirectory for better organization.

Migration Guide

To migrate existing files:

  1. Content entries → Move to content/ subdirectory
  2. Development entries → Move to development/ subdirectory

The generation script automatically handles subdirectories, so slugs will include the subdirectory path (e.g., content/2025-01-15-content-post-...).

See Also

GraphRenderer Component Refactoring Plan

· 21 min read

Execution Plan

Refactor the 3382-line GraphRenderer.tsx into smaller, composable components and utilities while maintaining all existing functionality. This plan follows principles that a principal frontend engineer would approve.

Overview

Component Organization Strategy

Subdirectory Structure with Index Files

Goal: Organize components into subdirectories with index.tsx files for cleaner imports and better maintainability.

Target Directory Structure

src/components/Graph/
├── GraphRenderer/ # Main component (stays at root for now)
│ ├── index.tsx # Re-exports GraphRenderer
│ ├── GraphRenderer.tsx # Main implementation
│ ├── GraphRenderer.module.css
│ └── GraphRenderer.stories.tsx
├── GraphMenuBar/
│ ├── index.tsx # Re-exports GraphMenuBar
│ ├── GraphMenuBar.tsx
│ └── GraphMenuBar.stories.tsx
├── GraphInfoPanel/
│ ├── index.tsx # Re-exports GraphInfoPanel
│ ├── GraphInfoPanel.tsx
│ └── GraphInfoPanel.stories.tsx
├── GraphCanvas/
│ ├── index.tsx # Re-exports GraphCanvas
│ ├── GraphCanvas.tsx
│ └── GraphCanvas.stories.tsx
├── GraphRightClickMenu/ # New component (extracted)
│ ├── index.tsx
│ ├── GraphRightClickMenu.tsx
│ └── GraphRightClickMenu.stories.tsx
├── GraphContextMenu/ # New component (extracted)
│ ├── index.tsx
│ ├── GraphContextMenu.tsx
│ └── GraphContextMenu.stories.tsx
├── hooks/ # Custom hooks
│ ├── index.ts # Re-exports all hooks
│ ├── useGraphDimensions.ts
│ ├── useGraphState.ts
│ ├── useGraphData.ts
│ ├── useGraphInteractions.ts
│ ├── useGraphCanvasSetup.ts
│ ├── useGraphMenuHandlers.ts
│ └── useGraphUrlFragment.ts
├── utils/ # Utility functions
│ ├── index.ts # Re-exports all utils
│ ├── graphConstants.ts
│ ├── GraphDataUtils.ts
│ ├── GraphNodeUtils.ts
│ ├── GraphRenderingUtils.ts
│ ├── GraphTextUtils.ts
│ ├── GraphCanvasDrawingUtils.ts
│ ├── GraphEdgeDrawingUtils.ts
│ └── graphUtils.ts # Backward compatibility re-exports
├── types.ts # Shared types
└── README.md # Component documentation

Index File Pattern

Each component subdirectory will have an index.tsx that re-exports the component:

// GraphMenuBar/index.tsx
export { GraphMenuBar } from './GraphMenuBar';
export type { GraphMenuBarProps } from './GraphMenuBar';

This allows clean imports:

// Before
import { GraphMenuBar } from './GraphMenuBar/GraphMenuBar';

// After
import { GraphMenuBar } from './GraphMenuBar';

Story Organization

Stories will be co-located with components in their subdirectories:

// GraphMenuBar/GraphMenuBar.stories.tsx
import { Meta, StoryObj } from '@storybook/react';
import { GraphMenuBar } from './GraphMenuBar';

const meta: Meta<typeof GraphMenuBar> = {
title: 'Graph/GraphMenuBar',
component: GraphMenuBar,
};

export default meta;
type Story = StoryObj<typeof GraphMenuBar>;

export const Default: Story = {
// ...
};

Benefits of This Structure

  1. Cleaner Imports: import { GraphMenuBar } from './GraphMenuBar' instead of './GraphMenuBar/GraphMenuBar'
  2. Co-location: Component, styles, stories, and tests in one place
  3. Better Discoverability: Easy to find all files related to a component
  4. Scalability: Easy to add new components without cluttering root
  5. Maintainability: Clear boundaries between components

Migration Strategy

Phase 0: Reorganize Existing Components (Before refactoring)

  1. Create subdirectories for existing components

    mkdir -p src/components/Graph/GraphMenuBar
    mkdir -p src/components/Graph/GraphInfoPanel
    mkdir -p src/components/Graph/GraphCanvas
  2. Move component files

    mv GraphMenuBar.tsx GraphMenuBar/GraphMenuBar.tsx
    mv GraphMenuBar.stories.tsx GraphMenuBar/GraphMenuBar.stories.tsx
  3. Create index.tsx files

    // GraphMenuBar/index.tsx
    export { GraphMenuBar } from './GraphMenuBar';
    export type { GraphMenuBarProps } from './GraphMenuBar';
  4. Update imports in GraphRenderer

    // Before
    import { GraphMenuBar } from './GraphMenuBar';

    // After (no change needed if index.tsx is created)
    import { GraphMenuBar } from './GraphMenuBar';
  5. Create hooks/ subdirectory

    mkdir -p src/components/Graph/hooks
    mv useGraphState.ts hooks/
    mv useGraphData.ts hooks/
    mv useGraphInteractions.ts hooks/
  6. Create hooks/index.ts

    // hooks/index.ts
    export { useGraphState } from './useGraphState';
    export { useGraphData } from './useGraphData';
    export { useGraphInteractions } from './useGraphInteractions';
  7. Create utils/ subdirectory (if not exists)

    mkdir -p src/components/Graph/utils
    # Move utility files to utils/
  8. Update all imports

    • Update GraphRenderer imports
    • Update Storybook stories
    • Update tests
    • Update documentation

Timing: This reorganization should happen before starting the refactoring phases, as it provides a clean foundation.

Current State Analysis

File Size: 3382 lines

Main Sections:

  1. Drawing Functions (~600 lines): drawNodeCircle, drawDebugSectionSeparators, drawTitle, drawStatusIndicator
  2. Edge Rendering Functions (~100 lines): getEdgeWidth, getEdgeCoordinates, drawComparisonEdge, drawEdgeLabel
  3. Main Component Logic (~2600 lines): State, event handlers, dimension calculations, canvas setup, menus, info panel
  4. Constants: NEO4J_COLORS, DEBUG_SHOW_NODE_SECTIONS

Existing Utilities (Already Extracted):

  • GraphDataUtils.ts - Tree traversal, data cleaning
  • GraphNodeUtils.ts - Node properties, styling, validation
  • GraphRenderingUtils.ts - Rendering calculations, coordinates
  • GraphTextUtils.ts - Text processing, wrapping, font sizing
  • NodeRenderer.ts - Node rendering class
  • useGraphData.ts - Graph data hooks
  • useGraphInteractions.ts - Interaction hooks
  • useGraphState.ts - State management hooks

Existing Components (Already Extracted):

  • GraphCanvas.tsx - Canvas wrapper
  • GraphInfoPanel.tsx - Info panel component
  • GraphMenuBar.tsx - Menu bar component

Refactoring Strategy

Phase 1: Extract Canvas Drawing Utilities (Low Risk)

Goal: Move pure drawing functions to utility files

1.1 Create GraphCanvasDrawingUtils.ts

Extract:

  • drawNodeCircledrawNodeCircle
  • drawDebugSectionSeparatorsdrawDebugSectionSeparators
  • drawStatusIndicatordrawStatusIndicator
  • drawTitledrawTitle (complex, ~400 lines - keep as-is but move to utils)

Location: src/components/Graph/GraphCanvasDrawingUtils.ts

Dependencies:

  • Canvas context
  • Node data
  • Styling parameters (colors, sizes)

Risk: Low - Pure functions, no component state

1.2 Create GraphEdgeDrawingUtils.ts

Extract:

  • drawComparisonEdgedrawComparisonEdge
  • drawEdgeLabeldrawEdgeLabel
  • getEdgeWidthgetEdgeWidth (already in GraphRenderingUtils? Check)

Location: src/components/Graph/GraphEdgeDrawingUtils.ts

Risk: Low - Pure functions

Phase 2: Extract Dimension Calculation Logic (Low Risk)

Goal: Move responsive dimension calculations to a custom hook

2.1 Create useGraphDimensions.ts

Extract:

  • Dimension calculation logic (lines ~2349-2361)
  • baseGraphAreaHeight, graphCanvasHeight, graphAreaHeight calculations
  • graphWidth, panelWidth calculations
  • Container width measurement logic

Location: src/components/Graph/useGraphDimensions.ts

Returns:

{
graphAreaHeight: number;
graphCanvasHeight: number;
graphWidth: number;
panelWidth: number;
actualContainerWidth: number;
isMobile: boolean;
}

Risk: Low - Isolated logic, easy to test

Phase 3: Extract Event Handlers (Medium Risk)

Goal: Move event handler logic to custom hooks

3.1 Enhance useGraphInteractions.ts

Extract:

  • handleNodeClickuseNodeClickHandler
  • handleNodeRightClickuseNodeRightClickHandler
  • handleLinkClickuseLinkClickHandler
  • handleLinkRightClickuseLinkRightClickHandler
  • handleNodeDraguseNodeDragHandler
  • handleNodeDragEnduseNodeDragEndHandler
  • handleZoomuseZoomHandler
  • handleWheeluseWheelHandler

Location: src/components/Graph/useGraphInteractions.ts (enhance existing)

Risk: Medium - Need to ensure all dependencies are passed correctly

3.2 Create useGraphMenuHandlers.ts

Extract:

  • copyAnchorLinkuseCopyAnchorLink
  • togglePaneuseTogglePane
  • Context menu click outside handler
  • Right-click menu logic

Location: src/components/Graph/useGraphMenuHandlers.ts

Risk: Low - Isolated menu logic

Phase 4: Extract Canvas Setup Logic (Medium Risk)

Goal: Move canvas initialization and event listeners to a hook

4.1 Create useGraphCanvasSetup.ts

Extract:

  • Canvas ref setup
  • Event listener registration (wheel, contextmenu)
  • Canvas cleanup
  • nodeCanvasObject and linkCanvasObject creation

Location: src/components/Graph/useGraphCanvasSetup.ts

Returns:

{
graphRef: RefObject<any>;
nodeCanvasObject: (node, ctx, globalScale) => void;
linkCanvasObject: (link, ctx, globalScale) => void;
linkCanvasObjectMode: (link) => string;
}

Risk: Medium - Complex setup logic, need to ensure all dependencies

Phase 5: Extract Menu Components (Low Risk)

Goal: Extract inline menu JSX to separate components

5.1 Create GraphRightClickMenu.tsx

Extract:

  • Right-click menu JSX (lines ~2425-2486)
  • Menu item rendering logic

Location: src/components/Graph/GraphRightClickMenu.tsx

Props:

{
menu: { nodeId: string; x: number; y: number } | null;
isDarkMode: boolean;
expandedNodes: Set<string>;
onToggleExpansion: (nodeId: string) => void;
onCopyLink: (nodeId: string) => void;
onClose: () => void;
}

Risk: Low - Pure presentational component

5.2 Create GraphContextMenu.tsx

Extract:

  • Context menu JSX (lines ~2487-2510)

Location: src/components/Graph/GraphContextMenu.tsx

Props:

{
menu: { x: number; y: number; nodeId?: string; edgeId?: string } | null;
isDarkMode: boolean;
onCopyLink: (nodeId?: string, edgeId?: string) => void;
onClose: () => void;
}

Risk: Low - Pure presentational component

Phase 6: Extract URL Fragment Handling (Low Risk)

Goal: Move URL fragment parsing and highlighting to a hook

6.1 Create useGraphUrlFragment.ts

Extract:

  • URL fragment parsing logic
  • highlightNode and highlightEdge calls from URL
  • Scroll to graph logic

Location: src/components/Graph/useGraphUrlFragment.ts

Risk: Low - Isolated URL handling

Phase 7: Extract Constants (Low Risk)

Goal: Move constants to a separate file

7.1 Create graphConstants.ts

Extract:

  • NEO4J_COLORSNEO4J_COLORS
  • DEBUG_SHOW_NODE_SECTIONSDEBUG_SHOW_NODE_SECTIONS

Location: src/components/Graph/graphConstants.ts

Risk: Low - Simple constants

Phase 8: Refactor Main Component (High Risk - Do Last)

Goal: Simplify GraphRendererImpl to orchestrate hooks and components

8.1 Final GraphRendererImpl Structure

const GraphRendererImpl = ({ ... }) => {
// Hooks
const dimensions = useGraphDimensions(width, height, paneVisible, isMobile);
const graphState = useGraphState(initialExpandedNodes);
const interactions = useGraphInteractions(/* deps */);
const canvasSetup = useGraphCanvasSetup(/* deps */);
const menuHandlers = useGraphMenuHandlers(graphId);
const urlFragment = useGraphUrlFragment(/* deps */);

// Memoized callbacks
const nodeCanvasObject = canvasSetup.nodeCanvasObject;
const linkCanvasObject = canvasSetup.linkCanvasObject;

// Render
return (
<div>
<GraphMenuBar />
<div className={styles.graphArea}>
<GraphCanvas>
<ForceGraph2D {...props} />
</GraphCanvas>
{paneVisible && <GraphInfoPanel />}
</div>
<GraphRightClickMenu />
<GraphContextMenu />
</div>
);
};

Risk: High - This is the integration point, need careful testing

Implementation Order (Risk-Based)

Phase 0: Reorganize Structure (Week 0 - Prerequisite)

Goal: Set up subdirectory structure before refactoring

  1. ✅ Create subdirectories for existing components
  2. ✅ Move components to subdirectories with index.tsx
  3. ✅ Move stories to component subdirectories
  4. ✅ Create hooks/ subdirectory and move hooks
  5. ✅ Create utils/ subdirectory (if needed)
  6. ✅ Update all imports across codebase
  7. ✅ Verify all tests still pass
  8. ✅ Verify Storybook stories still work

Timing: Do this before starting Phase 1

Week 1: Low-Risk Extractions

  1. ✅ Phase 7: Extract Constants → utils/graphConstants.ts
  2. ✅ Phase 1: Extract Canvas Drawing Utilities → utils/GraphCanvasDrawingUtils.ts & utils/GraphEdgeDrawingUtils.ts
  3. ✅ Phase 2: Extract Dimension Calculation Logic → hooks/useGraphDimensions.ts
  4. ✅ Phase 5: Extract Menu Components → GraphRightClickMenu/ & GraphContextMenu/

Week 2: Medium-Risk Extractions

  1. ✅ Phase 3: Extract Event Handlers → hooks/useGraphInteractions.ts (enhance)
  2. ✅ Phase 4: Extract Canvas Setup Logic → hooks/useGraphCanvasSetup.ts
  3. ✅ Phase 6: Extract URL Fragment Handling → hooks/useGraphUrlFragment.ts
  4. ✅ Phase 7: Extract Menu Handlers → hooks/useGraphMenuHandlers.ts

Week 3: High-Risk Integration

  1. ✅ Phase 8: Refactor Main Component
  2. ✅ Comprehensive Testing
  3. ✅ Update Documentation

Testing Strategy

Test Directory Structure

test/
├── e2e/ # End-to-end tests (Playwright)
│ ├── graph-renderer.spec.ts
│ ├── graph-selection-state.spec.ts
│ ├── graph-title-rendering.spec.ts
│ └── helpers/
│ └── canvas-utils.ts
├── unit/ # Unit tests (Jest)
│ └── GraphRenderer.title.test.ts
├── utils/ # Test utilities
│ └── canvasMock.ts
└── setup.ts # Jest setup

Unit Tests (Jest) - test/unit/

Phase 1: Utility Function Tests

Location: test/unit/

New Test Files to Create:

  1. GraphCanvasDrawingUtils.test.ts

    • Test drawNodeCircle with various parameters
    • Test drawDebugSectionSeparators (when debug enabled)
    • Test drawStatusIndicator for leaf vs parent nodes
    • Test drawTitle with various text lengths and zoom levels
    • Use createMockCanvasContext() from test/utils/canvasMock.ts
  2. GraphEdgeDrawingUtils.test.ts

    • Test drawComparisonEdge rendering
    • Test drawEdgeLabel with various labels and scales
    • Test getEdgeWidth calculations
  3. graphConstants.test.ts

    • Test NEO4J_COLORS array structure
    • Test DEBUG_SHOW_NODE_SECTIONS flag
  4. useGraphDimensions.test.ts

    • Test dimension calculations for mobile vs desktop
    • Test pane visibility impact on dimensions
    • Test container width measurement
    • Use React Testing Library to test hook

Update Existing:

  • GraphRenderer.title.test.ts: Update imports if drawTitle moves to utils

Phase 2: Hook Tests

Location: test/unit/

New Test Files:

  1. useGraphMenuHandlers.test.ts

    • Test useCopyAnchorLink with clipboard API
    • Test useTogglePane state changes
    • Test context menu click outside handler
  2. useGraphUrlFragment.test.ts

    • Test URL fragment parsing
    • Test highlightNode from URL
    • Test highlightEdge from URL
    • Test scroll to graph behavior
  3. useGraphCanvasSetup.test.ts

    • Test canvas ref setup
    • Test event listener registration
    • Test nodeCanvasObject creation
    • Test linkCanvasObject creation

Enhance Existing:

  • useGraphInteractions.ts (if exists): Add tests for extracted handlers

Test Utilities to Create/Update

Location: test/utils/

  1. graphHookTestUtils.ts (New)

    // Utilities for testing graph hooks
    export function renderGraphHook<T>(hook: () => T, wrapper?: ReactWrapper)
    export function createMockGraphRef()
    export function createMockGraphData()
  2. canvasMock.ts (Update)

    • Add more mock methods if needed for new drawing functions
    • Ensure compatibility with extracted drawing utilities

End-to-End Tests (Playwright) - test/e2e/

Update Strategy for E2E Tests

Key Principle: E2E tests should remain largely unchanged since they test the public API of GraphRenderer, not internal implementation details.

Files to Update:

  1. graph-renderer.spec.ts

    • No changes needed - Tests public API (canvas rendering, interactions)
    • May need to update selectors if component structure changes slightly
    • Verify canvas still renders correctly after refactoring
  2. graph-selection-state.spec.ts

    • No changes needed - Tests selection behavior (public API)
    • Verify node/edge selection still works after refactoring
    • Test URL hash behavior still works
  3. graph-title-rendering.spec.ts

    • No changes needed - Tests title rendering (visual output)
    • Verify ellipsis regression test still passes
    • May need screenshot updates if rendering changes slightly

New E2E Tests to Add:

  1. graph-responsive-behavior.spec.ts (New)

    // Test responsive behavior
    - Test mobile layout (pane below graph)
    - Test desktop layout (pane beside graph)
    - Test pane visibility toggle
    - Test graph area resizing
    - Test canvas overflow prevention
  2. graph-menu-interactions.spec.ts (New)

    // Test menu interactions
    - Test right-click menu
    - Test context menu
    - Test copy anchor link
    - Test menu positioning

E2E Test Helpers to Update:

  1. helpers/canvas-utils.ts
    • No changes needed - Generic canvas utilities
    • May add helpers for testing responsive behavior if needed

Integration Tests (New Category)

Location: test/integration/ (Create if doesn't exist)

Purpose

Test interactions between hooks and components in isolation from full E2E flow.

New Test Files:

  1. GraphRenderer.integration.test.tsx

    // Test GraphRenderer with all hooks integrated
    - Test component renders with all hooks
    - Test hook interactions (e.g., dimension changes trigger re-render)
    - Test state synchronization between hooks
    - Use React Testing Library
  2. GraphHooks.integration.test.tsx

    // Test hook interactions
    - Test useGraphDimensions + useGraphState interaction
    - Test useGraphInteractions + useGraphCanvasSetup interaction
    - Test useGraphUrlFragment + useGraphState interaction

Test Update Checklist Per Phase

Phase 1: Extract Constants & Drawing Utilities

  • Create GraphCanvasDrawingUtils.test.ts
  • Create GraphEdgeDrawingUtils.test.ts
  • Create graphConstants.test.ts
  • Update GraphRenderer.title.test.ts imports if needed
  • Run unit tests: yarn test
  • Verify all tests pass

Phase 2: Extract Dimension Calculations

  • Create useGraphDimensions.test.ts
  • Test mobile vs desktop calculations
  • Test pane visibility impact
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify no regressions)

Phase 3: Extract Event Handlers

  • Enhance useGraphInteractions.test.ts (if exists)
  • Test all event handlers in isolation
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify interactions still work)

Phase 4: Extract Canvas Setup

  • Create useGraphCanvasSetup.test.ts
  • Test canvas ref setup
  • Test event listener registration
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify canvas still renders)

Phase 5: Extract Menu Components

  • Create GraphRightClickMenu.test.tsx
  • Create GraphContextMenu.test.tsx
  • Test menu rendering and interactions
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify menus still work)

Phase 6: Extract URL Fragment Handling

  • Create useGraphUrlFragment.test.ts
  • Test URL parsing and highlighting
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify URL hash still works)

Phase 7: Extract Menu Handlers

  • Create useGraphMenuHandlers.test.ts
  • Test clipboard API interactions
  • Test pane toggle
  • Run unit tests: yarn test
  • Run E2E tests: yarn test:e2e (verify menu actions still work)

Phase 8: Refactor Main Component

  • Create GraphRenderer.integration.test.tsx
  • Test full component with all hooks
  • Run all unit tests: yarn test
  • Run all E2E tests: yarn test:e2e
  • Visual regression test in Storybook
  • Performance test (ensure no degradation)

Test Maintenance Strategy

After Each Phase:

  1. Run Test Suite

    # Unit tests
    yarn test

    # E2E tests
    yarn test:e2e

    # With coverage
    yarn test:coverage
  2. Update Test Documentation

    • Update test/README.md if test structure changes
    • Update test/e2e/README.md if E2E tests change
    • Update test/unit/README.md if unit tests change
  3. Fix Broken Tests

    • Update imports if code moves
    • Update mocks if APIs change
    • Update selectors if component structure changes
  4. Add New Tests

    • Add tests for newly extracted code
    • Ensure coverage doesn't decrease
    • Add integration tests for hook interactions

Test Coverage Goals:

  • Unit Tests: > 80% coverage for utility functions
  • Hook Tests: > 70% coverage for custom hooks
  • Component Tests: > 60% coverage for components
  • E2E Tests: Cover all critical user flows

Regression Testing

Visual Regression Tests

  • Use Storybook for visual regression testing
  • Compare screenshots before/after refactoring
  • Test all graph states (expanded, collapsed, selected, etc.)

Performance Regression Tests

  • Measure render time before/after refactoring
  • Measure memory usage
  • Test with large graphs (100+ nodes)
  • Ensure no performance degradation

Functional Regression Tests

  • Run full E2E test suite after each phase
  • Test all user interactions
  • Test all responsive breakpoints
  • Test all pane visibility states

Test Utilities to Create

test/utils/graphHookTestUtils.ts (New)

import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';

/**
* Renders a graph hook with necessary providers
*/
export function renderGraphHook<T>(
hook: () => T,
options?: {
wrapper?: ({ children }: { children: ReactNode }) => JSX.Element;
}
) {
// Implementation
}

/**
* Creates a mock graph ref for testing
*/
export function createMockGraphRef() {
// Implementation
}

/**
* Creates mock graph data for testing
*/
export function createMockGraphData() {
// Implementation
}

test/utils/graphComponentTestUtils.tsx (New)

/**
* Utilities for testing graph components
*/
export function renderGraphComponent(props: GraphRendererProps) {
// Implementation with all necessary providers
}

export function waitForGraphToStabilize() {
// Helper to wait for force graph to stabilize
}

E2E Test Updates

Minimal Changes Required

E2E tests should require minimal changes because they test the public API. However:

  1. Selector Updates (if component structure changes)

    • Update canvas selectors if wrapper structure changes
    • Update menu selectors if menu components are extracted
  2. Wait Strategy Updates (if initialization changes)

    • Update wait times if hook initialization changes
    • Update wait conditions if component mounting changes
  3. Screenshot Updates (if visual changes)

    • Update baseline screenshots if rendering changes
    • Add new screenshots for new features

E2E Test Maintenance

  • Keep E2E tests focused on user-facing behavior
  • Don't test internal implementation details
  • Use page objects if tests become complex
  • Add visual regression tests for critical UI states

Blog Post and Documentation Updates

Files That Import Graph Components

Documentation Files:

  1. docs/6-techniques/3-blogging-techniques/1-embed-structural-components/graph.mdx

    • Imports: GraphRenderer, NodeRendererDemo
    • Usage: Component documentation and examples
    • Impact: High - Main component documentation
  2. docs/3-mental-models/6-understanding-the-genai-domain/2025-11-10-ai-framework-landscape.md

    • Imports: AIFrameworkGraph
    • Usage: Displays AI framework comparison graph
    • Impact: High - Live graph visualization

Blog Posts:

  1. blog/2025-03-07-DFS-vs-BFS.md

    • May reference graph concepts (needs verification)
    • Impact: Low - Likely just mentions, not imports
  2. blog/2025-09-27-my-contributions.mdx

    • May reference graph components (needs verification)
    • Impact: Low - Likely just mentions, not imports

Import Path Updates Required

When components move to subdirectories, import paths in MDX files need updates:

Before:

import GraphRenderer from '@site/src/components/Graph/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph';

After (if components move to subdirectories):

// Option 1: If index.tsx is created, no change needed
import GraphRenderer from '@site/src/components/Graph/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph';

// Option 2: If explicit paths are preferred
import GraphRenderer from '@site/src/components/Graph/GraphRenderer/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph/AIFrameworkGraph';

Recommendation: Use index.tsx files so imports don't need to change.

Update Strategy for Blog Posts and Docs

Phase 0: Before Reorganization

  1. Audit all imports

    # Find all files importing Graph components
    grep -r "from '@site/src/components/Graph" blog/ docs/
  2. Document current import paths

    • List all files that import Graph components
    • Note which components are imported
    • Create checklist for updates

Phase 0: During Reorganization

  1. Update import paths (if needed)

    • If using index.tsx, imports may not need changes
    • If not using index.tsx, update all import paths
    • Test each file after updating
  2. Verify components still work

    • Build Docusaurus site: make build
    • Check each page that uses Graph components
    • Verify graphs render correctly
    • Test interactive features (clicking, zooming, etc.)

After Each Refactoring Phase

  1. Test affected pages

    • Rebuild Docusaurus: make build
    • Check pages that use Graph components
    • Verify no regressions
  2. Update documentation if needed

    • Update component documentation if APIs change
    • Update examples if usage patterns change
    • Update README files if structure changes

Files to Update Checklist

Documentation:

  • docs/6-techniques/3-blogging-techniques/1-embed-structural-components/graph.mdx

    • Update GraphRenderer import if path changes
    • Update NodeRendererDemo import if path changes
    • Verify examples still work
    • Update documentation if component API changes
  • docs/3-mental-models/6-understanding-the-genai-domain/2025-11-10-ai-framework-landscape.md

    • Update AIFrameworkGraph import if path changes
    • Verify graph renders correctly
    • Test interactive features

Blog Posts:

  • blog/2025-03-07-DFS-vs-BFS.md

    • Check if it actually imports components (may just mention)
    • Update if needed
  • blog/2025-09-27-my-contributions.mdx

    • Check if it actually imports components (may just mention)
    • Update if needed

Other Documentation:

  • Check all files in docs/ that mention "graph" or "Graph"
    • Update import paths if needed
    • Update examples if component API changes
    • Update code snippets if usage patterns change

Testing Blog Posts and Docs

After Each Phase:

  1. Build Docusaurus

    cd bytesofpurpose-blog
    yarn build
  2. Check for Build Errors

    • Look for import errors
    • Look for component not found errors
    • Fix any broken imports
  3. Visual Verification

    • Start dev server: yarn start
    • Navigate to each page that uses Graph components
    • Verify graphs render correctly
    • Test interactive features
  4. Anchor Link Testing

    • Test URL hash navigation (e.g., #graph-node-123)
    • Verify nodes/edges highlight correctly
    • Verify scrolling to graph works

Backward Compatibility Strategy

Goal: Ensure existing blog posts and docs continue to work without changes.

Strategy:

  1. Use index.tsx files - Allows imports to remain unchanged
  2. Maintain public API - Don't change component props or behavior
  3. Re-export from root - Consider re-exporting from Graph/index.ts for convenience

Example re-export file:

// src/components/Graph/index.ts
// Re-export all public components for convenience
export { GraphRenderer } from './GraphRenderer';
export { AIFrameworkGraph } from './AIFrameworkGraph';
export { NodeRendererDemo } from './NodeRendererDemo';
export type { GraphRendererProps } from './GraphRenderer';

This allows imports like:

import { GraphRenderer, AIFrameworkGraph } from '@site/src/components/Graph';

Documentation Update Guidelines

When to Update Documentation:

  • ✅ Component moves to subdirectory (update import paths)
  • ✅ Component API changes (update examples)
  • ✅ New features added (document new features)
  • ✅ Breaking changes (document migration path)
  • ❌ Internal refactoring only (no doc updates needed if public API unchanged)

What to Update:

  1. Import statements - If paths change
  2. Code examples - If API changes
  3. Usage patterns - If best practices change
  4. Component documentation - If features change
  5. README files - If structure changes

What NOT to Update:

  • Internal implementation details (unless relevant to users)
  • File structure (unless it affects imports)
  • Utility functions (unless they're part of public API)

Storybook Story Updates

Story Path Updates

When components move to subdirectories, Storybook story paths may need updates:

Before:

// GraphMenuBar.stories.tsx (at root)
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Graph/GraphMenuBar" />

After:

// GraphMenuBar/GraphMenuBar.stories.tsx
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Graph/GraphMenuBar" />
// Path stays the same - Storybook uses title, not file path

Story Co-location Benefits

  • Stories live next to components
  • Easy to find component documentation
  • Stories can import from ./ComponentName (same directory)
  • Better organization in Storybook sidebar

Story Import Updates

When components move to subdirectories:

Before:

// GraphMenuBar.stories.tsx
import { GraphMenuBar } from './GraphMenuBar';

After:

// GraphMenuBar/GraphMenuBar.stories.tsx
import { GraphMenuBar } from './GraphMenuBar'; // Same directory
// OR
import { GraphMenuBar } from '.'; // From index.tsx

Migration Checklist

Phase 0: Reorganization (Before Refactoring)

  • Create subdirectories for existing components
  • Move component files to subdirectories
  • Create index.tsx files for each component
  • Move stories to component subdirectories
  • Create hooks/ subdirectory
  • Move hooks to hooks/ subdirectory
  • Create hooks/index.ts
  • Create utils/ subdirectory (if needed)
  • Update all imports in GraphRenderer
  • Update all imports in stories
  • Update all imports in tests
  • Audit blog posts and docs for Graph component imports
  • Update import paths in blog posts and docs (if needed)
  • Build Docusaurus: make build
  • Verify all pages with Graph components render correctly
  • Test interactive features in blog posts/docs
  • Run tests: yarn test
  • Run E2E tests: yarn test:e2e
  • Verify Storybook stories work
  • Update Storybook story paths if needed
  • Test in Docusaurus
  • Code review
  • Merge

For Each Refactoring Phase:

  • Create new file(s) in appropriate subdirectory
  • Move code to new file(s)
  • Create index.tsx if new component
  • Create stories in component subdirectory
  • Update imports in GraphRenderer
  • Update imports in stories
  • Update imports in tests
  • Build Docusaurus: make build
  • Verify blog posts/docs with Graph components still work
  • Test interactive features in blog posts/docs
  • Run tests
  • Check Storybook stories
  • Test in Docusaurus
  • Update documentation (if API changes)
  • Code review
  • Merge

Success Criteria

  1. ✅ GraphRenderer.tsx reduced to < 500 lines
  2. ✅ All existing functionality preserved
  3. ✅ No performance degradation
  4. ✅ All tests passing
  5. ✅ Storybook stories working
  6. ✅ Docusaurus integration working
  7. ✅ Code review approved
  8. ✅ Documentation updated

Notes

  • Incremental Approach: Each phase is independent and can be merged separately
  • Backward Compatibility: Maintain existing public API
  • Type Safety: Ensure all extracted code is properly typed
  • Performance: Monitor for any performance regressions
  • Documentation: Update JSDoc comments as code moves

Potential Challenges

  1. Circular Dependencies: Watch for circular imports between utilities
  2. Hook Dependencies: Ensure all hook dependencies are correctly passed
  3. Ref Management: Graph ref needs careful handling across hooks
  4. State Synchronization: Ensure state updates don't cause infinite loops
  5. Event Handler Context: Ensure event handlers have correct context

Future Improvements (Post-Refactoring)

  1. Consider extracting ForceGraph2D wrapper to separate component
  2. Consider using React Context for graph state (if needed)
  3. Consider memoization optimizations
  4. Consider TypeScript strict mode improvements
  5. Consider adding more comprehensive error boundaries

Execution Results / Attempts

✅ Work In Progress (2025-11-08 to 2025-11-17)

Work Period: November 8, 2025 to November 17, 2025

Commits: 10 commits related to graph component refactoring

Key Accomplishments:

  • Initial graph component implementation
  • Added menu bar to graph component
  • Made graph component reactive/responsive
  • Added anchor links to specific nodes in graphs
  • Added integration and E2E tests for graph component
  • Checkpointed graph renderer refactoring work
  • Finalized graph component as part of blog structure overhaul
  • Revamped graph component with modularization
  • Added Storybook tab to document components
  • Improved graph rendering on mobile devices

Notable Commits:

  • a64d629e (2025-11-08): Updating authors and adding graph component plus stats structures and algos
  • 7333d884 (2025-11-08): Making graph component reactive
  • d2e8bf6d (2025-11-08): Adding menu bar to graph component
  • 92e82a04 (2025-11-08): Added ability to have anchor links to specific nodes in specific graphs
  • f57ee652 (2025-11-10): Adding integ and e2e tests for graph component
  • b5c58a8a (2025-11-10): Checkpointing graph renderer
  • cca8ae25 (2025-11-12): Big blog structure overhaul + finalization of graph component
  • e657ebde (2025-11-12): Revamp to readmes plus fix for graph
  • 7634d68b (2025-11-16): Revamping graph component, modularizing it, etc. Also added storybook tab to document components
  • 6ec4aaac (2025-11-17): Revamp component setup, story book stories, graph render on mobile, etc

Status: Work is in progress. The graph component has been significantly refactored and modularized, with Storybook integration added for documentation. Mobile responsiveness has been improved. Further refactoring work continues based on the comprehensive plan outlined above.