generated from coulomb/repo-seed
- Add mockPapaParse helper to centralize CSV mocking - Fix test assertions to match actual output (German month names) - Add missing DOM elements to test setup (projectFile, csvFile, etc.) - Update vitest to v4.0.14 for improved testing capabilities - Make setupEventHandlers globally accessible for testing - Use textContent instead of innerText for better consistency - Fix autoLoadDefaultProject test to check all three fallback paths - Add proper event handler setup in integration tests - Improve error handling test assertions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
5.1 KiB
5.1 KiB
SVG Template Refactoring Plan
Current Architecture Problems
The Issue
While template.svg files exist in example/ and my-project/, they only contain:
- Outer SVG wrapper with styling
- Two macros:
{{MONTHS}}and{{LANES}}
The actual SVG generation is hardcoded in generator.js:
- Lines 40-69: Month grid generation (lines, labels, styling)
- Lines 78-129: Lane generation (backgrounds, labels, task items)
This makes templates non-editable in SVG tools - users can only change colors/styling in the wrapper, not the actual timeline structure.
Goals
- Move SVG structure to templates: Extract hardcoded SVG patterns from JavaScript to template files
- Use placeholders for dynamic data: Replace actual values with
{{VARIABLE}}placeholders - Make templates editable: Users should be able to open templates in Inkscape/Adobe Illustrator and modify the timeline layout
- Maintain flexibility: Keep the ability to handle varying numbers of months, lanes, and items
Proposed Template Structure
Month Template Section
Instead of generating months in JS, the template should contain a sample month element with placeholders:
<!-- Sample month element - will be cloned for each month -->
<g class="month-template" id="month-template">
<line x1="{{MONTH_X}}" y1="{{GRID_TOP}}" x2="{{MONTH_X}}" y2="{{GRID_BOTTOM}}"
stroke="#E3E8EF" />
<text x="{{MONTH_X}}" y="{{MONTH_Y}}" fill="#5C6B7A" font-size="12">
{{MONTH_LABEL}}
</text>
</g>
Lane Template Section
Similarly, lanes should be defined once:
<!-- Sample lane element - will be cloned for each lane -->
<g class="lane-template" id="lane-template">
<rect x="{{LANE_X}}" y="{{LANE_Y}}" width="{{LANE_WIDTH}}" height="{{LANE_HEIGHT}}"
fill="#FFFFFF" stroke="#E3E8EF" rx="10" />
<text x="{{LABEL_X}}" y="{{LABEL_Y}}" fill="#0B1F3B" font-size="14" font-weight="600">
{{LANE_NAME}}
</text>
</g>
Task Item Template
Task items within lanes:
<!-- Sample task item - will be cloned for each task -->
<g class="task-template" id="task-template">
<circle cx="{{TASK_X}}" cy="{{TASK_Y}}" r="5" fill="#0A4D8C" />
<text x="{{TEXT_X}}" y="{{TEXT_Y}}" font-size="12" fill="#0B1F3B">
<tspan class="item-id">{{TASK_ID}}: </tspan>
<tspan class="item-title">{{TASK_TITLE}}</tspan>
</text>
</g>
Generator Refactoring
The generator.js should:
- Load and parse template: Read template SVG
- Extract template elements: Find elements with
id="*-template" - Clone and populate: For each data item, clone the template and replace placeholders
- Position elements: Calculate positions based on layout constants
- Inject into template: Replace
{{MONTHS}}and{{LANES}}macros with generated content
Variables Dictionary
Layout Constants
{{GRID_LEFT}},{{GRID_TOP}},{{GRID_BOTTOM}}- Grid boundaries{{MONTH_WIDTH}}- Width of each month column{{LANE_HEIGHT}}- Height of each lane row{{LANE_GAP}}- Spacing between lanes
Month Variables
{{MONTH_X}}- X position{{MONTH_Y}}- Y position for label{{MONTH_LABEL}}- Month name (e.g., "Jan 25")
Lane Variables
{{LANE_X}},{{LANE_Y}}- Lane position{{LANE_WIDTH}},{{LANE_HEIGHT}}- Lane dimensions{{LANE_NAME}}- Lane/Epic name{{LABEL_X}},{{LABEL_Y}}- Label position
Task Variables
{{TASK_X}},{{TASK_Y}}- Task marker position{{TEXT_X}},{{TEXT_Y}}- Text position{{TASK_ID}}- Task ID (e.g., "T-1"){{TASK_TITLE}}- Task title
Migration Strategy
Phase 1: Extract to Simple Templates
- Create new
template-v2.svgfiles with template elements - Update generator to use template-based approach
- Keep existing templates as fallback
- Test with both approaches
Phase 2: Enhance Template Editing
- Add template validation
- Document template variables
- Create template editing guide
- Provide example templates with different layouts
Phase 3: Remove Hardcoded SVG
- Migrate existing templates to new format
- Remove hardcoded SVG generation
- Update tests
- Update documentation
Test Updates Needed
- Tests for template parsing and validation
- Tests for variable substitution
- Tests for template cloning logic
- Integration tests with real templates
- Tests for backward compatibility with old templates
Benefits
- User-editable templates: Can modify in any SVG editor
- Visual template design: See actual layout while editing
- Reusable patterns: Template elements can be copied/modified
- Separation of concerns: Presentation (SVG) vs. logic (JS)
- Easier customization: Change fonts, colors, shapes without touching code
Risks
- Complexity: More complex generator logic
- Performance: Template parsing and cloning overhead
- Compatibility: Need to support both old and new templates
- Testing: More edge cases to test
Next Steps
- Review and approve this plan
- Create proof-of-concept with one template
- Refactor generator.js gradually
- Update tests
- Document new template format
- Migrate existing templates