A dashboard page: an ordered set of placed widgets owned by a user (personal) or by the system / a role (shared).
The layout field is a JSONB list of widget instances — read-whole,
write-whole, mirroring phoenix_kit_crm's per-user view_config precedent.
Geometry is embedded per widget (see PhoenixKitDashboards.Layout) so
add/remove is atomic. Each instance is a map:
%{
"id" => "<uuid>", # instance id (unique within the dashboard)
"widget_key" => "emails.deliverability", # which catalog widget type
"view" => "detailed", # selected render variant, or nil
"settings" => %{ ... }, # per-instance customizations
"pixel" => %{"fx" => .., "fy" => .., "fw" => .., "fh" => ..}, # pixel canvas (px)
"bp" => %{"desktop" => %{"w" => 6, "h" => 2, "hidden" => false, "pos" => 0}, ...}
} # grid: per-breakpoint span/order/visibilityGrid dashboards place each widget at explicit cells per breakpoint tier —
%{x, y, w, h, hidden, pos} under "bp" (TV 16 / Desktop 12 / iPad 8 /
Phone 4 columns; see PhoenixKitDashboards.Breakpoints). Pixel dashboards
use pixel (absolute px + z-order). The config JSONB column holds
dashboard-level state: "type" ("grid" | "pixel", fixed at creation),
"home_bp", and per-breakpoint "breakpoints" metadata
(%{bp => %{"state" => "custom"}}).
Scope
"personal"—owner_user_uuidset; private to that user."system"—owner_user_uuidnil; visible to everyone (admin-authored)."role"—role_uuidset; visible to members of that role.
Summary
Functions
Changeset for creating / updating a dashboard's metadata.
Changeset that only replaces the config map.
Changeset that only replaces the layout (the hot path during editing).
List of valid layout-mode strings.
Slugify a title (lowercase, dashes, ASCII-only), falling back to "dashboard"
for a blank result. The [owner_user_uuid, slug] pair is unique, so the context
suffixes on collision.
The dashboard's fixed type — "grid" (responsive breakpoints) or "pixel"
(free canvas). Reads config["type"], falling back to the legacy
config["mode"] ("free" → "pixel"), defaulting to "grid".
Types
@type t() :: %PhoenixKitDashboards.Schemas.Dashboard{ __meta__: term(), config: map(), inserted_at: DateTime.t() | nil, is_default: boolean(), layout: [map()], owner_user_uuid: String.t() | nil, position: integer(), role_uuid: String.t() | nil, scope: String.t(), slug: String.t() | nil, title: String.t() | nil, updated_at: DateTime.t() | nil, uuid: String.t() | nil }
Functions
@spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
Changeset for creating / updating a dashboard's metadata.
@spec config_changeset(t(), map()) :: Ecto.Changeset.t()
Changeset that only replaces the config map.
@spec layout_changeset(t(), [map()]) :: Ecto.Changeset.t()
Changeset that only replaces the layout (the hot path during editing).
Internal render mode — "free" (pixel canvas) or "grid" — derived from the
dashboard type/1. Kept as the builder's rendering switch; the user-facing
concept is type/1 (chosen at creation).
@spec layout_modes() :: [String.t()]
List of valid layout-mode strings.
Slugify a title (lowercase, dashes, ASCII-only), falling back to "dashboard"
for a blank result. The [owner_user_uuid, slug] pair is unique, so the context
suffixes on collision.
The dashboard's fixed type — "grid" (responsive breakpoints) or "pixel"
(free canvas). Reads config["type"], falling back to the legacy
config["mode"] ("free" → "pixel"), defaulting to "grid".