MishkaCmsCore.Builder.Descriptor (Mishka CMS Core v0.0.1)

Copy Markdown View Source

The one validated shape every page-builder registry entry takes — an inspector section, a right-rail tab, a Studio tab, a canvas toolbar action, a command-palette command, an audit check, a marketplace source, an AI backend.

§28 lists these as eight separate structs that all carry the same six fields. They are one struct here, with kind naming which registry an entry belongs to, because the alternative is eight modules differing only in their moduledoc — and one shape means a plugin author learns the contract once and Events.collect/2 can sort and de-duplicate every registry with the same code.

render and run are {module, function} tuples or a LiveComponent module, never closures: a descriptor travels through a MishkaInstaller hook payload, which is plain-map only. This is the MishkaCmsCore.Dashboard.Widget rule, for the same reason.

Permissions

permissions is a list of permission names where holding any is enough, checked the same way a dashboard widget's is. An empty list means everyone who can open the builder sees it. A section a viewer may not see is filtered out of the registry, so it never renders and its events never fire.

Summary

Functions

A sample %MishkaCmsCore.Builder.Descriptor{} populated from defaults + type-based fallbacks.

A descriptor's de-duplication key. Tolerates a plain map so a plugin that builds its entry by hand instead of through builder/1 still sorts and de-duplicates rather than crashing the registry.

Every registry a descriptor can belong to.

A descriptor's display label, falling back to its key.

Filters a collected registry down to what this viewer may see.

Whether user may see this descriptor — an empty permission list means everyone, otherwise holding any one of the listed permissions is enough.

A descriptor's sort priority; anything unreadable sorts last.

Renders a descriptor's component with assigns. A descriptor whose render ref is missing or raises degrades to nothing rather than taking the panel down — the extension-isolation boundary the runtime already applies to broken templates.

Types

t()

@type t() :: %MishkaCmsCore.Builder.Descriptor{
  config: map() | nil,
  description: String.t() | nil,
  group: String.t() | nil,
  icon: String.t() | nil,
  key: String.t(),
  kind: atom(),
  label: String.t() | nil,
  permissions: list() | nil,
  priority: integer() | nil,
  render: any() | nil,
  run: any() | nil,
  shortcut: String.t() | nil
}

Functions

builder(attrs_or_input, error \\ false)

enforce_keys()

enforce_keys(field)

example()

A sample %MishkaCmsCore.Builder.Descriptor{} populated from defaults + type-based fallbacks.

key(other)

@spec key(map()) :: String.t()

A descriptor's de-duplication key. Tolerates a plain map so a plugin that builds its entry by hand instead of through builder/1 still sorts and de-duplicates rather than crashing the registry.

keys()

keys(field)

kinds()

@spec kinds() :: [atom()]

Every registry a descriptor can belong to.

label(descriptor)

@spec label(map()) :: String.t()

A descriptor's display label, falling back to its key.

permitted(descriptors, user)

@spec permitted(list(), map() | nil) :: list()

Filters a collected registry down to what this viewer may see.

permitted?(arg1, user)

@spec permitted?(map(), map() | nil) :: boolean()

Whether user may see this descriptor — an empty permission list means everyone, otherwise holding any one of the listed permissions is enough.

priority(arg1)

@spec priority(map()) :: integer()

A descriptor's sort priority; anything unreadable sorts last.

render(descriptor, assigns)

@spec render(map(), map()) :: Phoenix.LiveView.Rendered.t() | nil

Renders a descriptor's component with assigns. A descriptor whose render ref is missing or raises degrades to nothing rather than taking the panel down — the extension-isolation boundary the runtime already applies to broken templates.