---
id: 12208
title: Extract the shared timeline contract into Neo.app.content.Component
state: CLOSED
labels:
  - enhancement
  - ai
  - refactoring
assignees:
  - neo-opus-ada
createdAt: '2026-05-30T17:25:04Z'
updatedAt: '2026-05-30T22:29:07Z'
githubUrl: 'https://github.com/neomjs/neo/issues/12208'
author: neo-opus-ada
commentsCount: 0
parentIssue: 12204
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy:
  - '[x] 12207 Rename timeline-node model/store TicketTimelineSection(s) → TimelineSection(s)'
  - '[x] 12206 Promote portal canvas view-glue (bridge + CanvasWrapper) to shared'
blocking:
  - '[x] 12209 Make portal content cross-link URLs per-content-type config'
closedAt: '2026-05-30T22:29:07Z'
---
# Extract the shared timeline contract into Neo.app.content.Component

## Context
Part of epic #12207 (foundation step 4). The per-type parsers (issue/PR/discussion) share scaffolding that belongs in the framework Component so each type only supplies its parser.

## The Fix
Lift the SHARED scaffolding up into `Neo.app.content.Component` (or a `TimelineContent` base/mixin): the timeline-item / comment-item / body-item HTML templates, `formatTimestamp`, the `sections`-store push, and the IntersectionObserver wiring (it targets `.neo-timeline-item[data-record-id]` generically). Keep the issue-specific `renderTimeline` line-walker + the event-type/label/commit machinery in `apps/portal/view/news/tickets/Component.mjs` as the **Issue specialization**.

## Architectural Reality
`tickets/Component.mjs:271-402` (modifyMarkdown pipeline), `:425-584` (renderTimeline), `:479-489` (issue event-type table). The shared seam is the OUTPUT contract — all parsers emit the same `{id, image|color, icon, name, tag}` nodes + `.neo-timeline-item` HTML; the canvas never parses markdown.

## Acceptance Criteria
- [ ] Tickets tab unchanged.
- [ ] A new content type can subclass the shared Component and supply only a `modifyMarkdown`/`renderTimeline` parser.

## Related
Epic #12207. Depends on foundation steps 2 + 3; unblocks the per-type views (7, 8) and step 5.

## Timeline

- 2026-05-30T17:25:05Z @neo-opus-ada added the `enhancement` label
- 2026-05-30T17:25:05Z @neo-opus-ada added the `ai` label
- 2026-05-30T17:25:05Z @neo-opus-ada added the `refactoring` label
- 2026-05-30T17:30:13Z @neo-opus-ada added parent issue #12207
- 2026-05-30T17:31:30Z @neo-opus-ada marked this issue as blocking #12209
- 2026-05-30T17:34:53Z @neo-opus-ada removed parent issue #12207
- 2026-05-30T17:34:54Z @neo-opus-ada added parent issue #12204
- 2026-05-30T17:35:56Z @neo-opus-ada marked this issue as being blocked by #12206
- 2026-05-30T17:35:57Z @neo-opus-ada marked this issue as being blocked by #12207
- 2026-05-30T20:46:17Z @neo-opus-ada cross-referenced by PR #12224
- 2026-05-30T21:09:04Z @neo-opus-ada assigned to @neo-opus-ada
- 2026-05-30T21:49:07Z @neo-opus-ada cross-referenced by PR #12233
- 2026-05-30T22:29:07Z @tobiu referenced in commit `1b9b684` - "refactor(portal): extract Portal.view.content.Component timeline base (#12208) (#12233)

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-30T22:29:07Z @tobiu closed this issue
- 2026-05-31T18:28:40Z @neo-gpt cross-referenced by #12204
- 2026-05-31T18:51:48Z @neo-opus-ada cross-referenced by PR #12266
- 2026-05-31T21:04:28Z @neo-opus-ada cross-referenced by #12209

