MishkaCmsCoreWeb.Templates.HistoryTimeline (Mishka CMS Core v0.0.1)

Copy Markdown View Source

The visual editor's history, drawn as a MishkaGervaz custom table template: a vertical rail with a bucket-tinted node per change, the assistant's own words where it has them, and a Revert on every row whose document was kept.

Backed by MishkaCmsCore.Runtime.PageBuilderEvent and opened from the builder's Record-history sheet. It replaced a hand-rolled <ol> over the in-memory undo stack, which meant the sheet showed one session's ops, called every author "You", and lost everything on reload.

Why a second timeline template

MishkaCmsCoreWeb.Templates.ActivityTimeline draws a vertical timeline too, and is deliberately NOT extended: it binds row content by column POSITION, and its dot_class / node_class helpers are public API for MishkaCmsCore.Activity.ActivityEntry and MishkaDocument.EventLog. Reusing it would couple three unrelated tables through a shared private vocabulary. This follows MishkaCmsCoreWeb.Templates.ReviewComments instead — filter pills, per-row buttons, one static column the template unpacks itself.

A template owns the whole table, so the filter bar and the footer are here. No UI adapter is involved: everything this draws is either the template's own markup or a column's render.

Two rules that are easy to get wrong

filter_values is keyed by the filter's ATOM name — gervaz builds it with Map.put(acc, filter.name, value). Reading it with a string key answers nil silently, and the table then renders unfiltered with every pill unchecked, which looks like the pills are unwired.

Author branches on author_type BEFORE the masking ladder. Every row carries a human author_id, including an assistant's — it is whoever's editor ran the prompt — so a ladder that matches an email-bearing author first would print the operator's address under the assistant's work. See MishkaCmsCore.Runtime.PageBuilderEvent.

Summary

Functions

render_bulk_actions(assigns)

Callback implementation for MishkaGervaz.Table.Behaviours.Template.render_bulk_actions/1.

render_empty(assigns)

Callback implementation for MishkaGervaz.Table.Behaviours.Template.render_empty/1.

render_error(assigns)

Callback implementation for MishkaGervaz.Table.Behaviours.Template.render_error/1.

render_filters(assigns)

The four pills — All / Content / Style / Publish — as radios rather than a dropdown.

"All" is the empty value of the one :select filter, so switching to it clears rather than filtering on a fourth thing.

render_header(assigns)

Callback implementation for MishkaGervaz.Table.Behaviours.Template.render_header/1.

render_loading(assigns)

The timeline, before it knows what happened.

Three rows the shape of a real one — dot, connector, a title and a line of detail — so the sheet settles into its content instead of replacing a centred spinner with a list.

render_template_switcher(assigns)

Callback implementation for MishkaGervaz.Table.Behaviours.Template.render_template_switcher/1.