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

Copy Markdown View Source

The version-history modal's body and footer, shared by every admin page that has one.

A collection, a post, a blogger, a team and a tag all keep AshPaperTrail history and all show it the same way: a list of versions, each with when it happened, which action wrote it, who by, and which fields it touched — plus a preview that opens the changes in place and a Restore beside it. Only the record differs, so only the record's page owns the modal shell and the head; everything inside it is this module.

The event contract

panel/1 renders buttons, not callbacks — the page must handle four events, which is the set the existing pages already implement:

  • "toggle_version_preview" with phx-value-version-id
  • "restore_version" with phx-value-version-id
  • "versions_prev_page" and "versions_next_page"

Pair it with MishkaCmsCore.CoreComponents.modal/1 given padding_class="p-0" and MishkaCmsCoreWeb.Templates.CardChrome.modal_head/1, the way MishkaBlogWeb.Live.Admin.Dashboard.Post.Index does.

Summary

Functions

Chip colours for the action a version came from.

The word a version's chip shows for the action that wrote it. An action this does not name shows as it is stored.

Who wrote version, for the reader whose read loaded its :user.

One changed value, formatted for the preview box.

Which fields a version touched, as one line.

The last page of history, so the pager never offers a page that does not exist.

The ids among versions' authors that are masters, for panel/1's :master_ids.

The scrolling list of versions and the pager under it.

Functions

action_color(action)

@spec action_color(atom()) :: String.t()

Chip colours for the action a version came from.

PaperTrail stores the resource's own action name, so a master's edit arrives as :master_update and a publish as :publish. Anything unrecognised reads neutral rather than colourless — the earlier version of this map covered only :create/:update/:destroy, which left most real badges unstyled.

action_label(action)

@spec action_label(atom()) :: String.t() | atom()

The word a version's chip shows for the action that wrote it. An action this does not name shows as it is stored.

author(version, master_ids)

@spec author(map(), MapSet.t()) :: String.t()

Who wrote version, for the reader whose read loaded its :user.

The email the reader may read, "Master" when master_ids holds the version's user_id, "System" for a version with no user, and "Unknown" for a user the reader's read did not return.

change_value(value)

@spec change_value(term()) :: String.t()

One changed value, formatted for the preview box.

Maps and lists are pretty-printed, a string is shown as written, and anything else falls back to inspect/1. Formatting here rather than in the template keeps the value off its own line — under whitespace-pre-wrap the template's own indentation would otherwise render as part of the value.

changed_fields(changes)

@spec changed_fields(map() | nil) :: String.t() | nil

Which fields a version touched, as one line.

last_page(total, per_page)

@spec last_page(non_neg_integer(), pos_integer()) :: pos_integer()

The last page of history, so the pager never offers a page that does not exist.

master_ids(versions)

@spec master_ids([map()]) :: MapSet.t()

The ids among versions' authors that are masters, for panel/1's :master_ids.

Reads once, off the render: call it where the versions are loaded. An empty set when the read fails, so a master's version reads "Unknown" rather than breaking the modal.

panel(assigns)

The scrolling list of versions and the pager under it.

:preview_id is the one version whose changes are open; the list is an accordion, so at most one is. The "Current" badge is only correct on the first page — it marks the newest version, and page two's first row is not that.

Attributes

  • id (:string) (required)
  • versions (:list) (required)
  • loading (:boolean) (required)
  • page (:integer) (required)
  • per_page (:integer) (required)
  • total (:integer) (required)
  • preview_id (:any) - Defaults to nil.
  • master_ids (:any) - master_ids/1 of :versions, so a master's version reads "Master" to a site user. Defaults to MapSet.new([]).
  • empty_title (:string) - Defaults to nil.
  • empty_hint (:string) - Defaults to nil.
  • toggle_event (:string) - Defaults to "toggle_version_preview".
  • restore_event (:string) - Defaults to "restore_version".
  • prev_event (:string) - Defaults to "versions_prev_page".
  • next_event (:string) - Defaults to "versions_next_page".