Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions lib/mast_web/components/layouts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,48 @@ defmodule MastWeb.Layouts do

def app(assigns) do
~H"""
<div class="flex min-h-screen bg-[var(--mast-bg-primary)] text-[var(--mast-font-primary)]">
<.ui_sidebar active={@active}>
<div class="drawer bg-[var(--mast-bg-primary)] text-[var(--mast-font-primary)]">
<input id="app-drawer" type="checkbox" class="drawer-toggle" />

<div class="drawer-content flex min-h-screen">
<.ui_sidebar active={@active}>
<:nav key="dashboard" navigate={~p"/"} icon="hero-squares-2x2">Dashboard</:nav>
<:nav key="servers" navigate={~p"/"} icon="hero-server-stack">Servers</:nav>
<:nav key="alerts" navigate={~p"/alerts"} icon="hero-bell-alert">Alerts</:nav>
<:nav key="audit" navigate={~p"/audit"} icon="hero-document-text">Audit</:nav>
<:nav key="settings" navigate={~p"/settings"} icon="hero-cog-6-tooth">Settings</:nav>
<:footer>
<.theme_toggle />
<span class="text-[10px] text-[var(--mast-font-tertiary)] font-mono">
v{Mast.version()}
</span>
</:footer>
</.ui_sidebar>

<div class="flex-1 min-w-0 flex flex-col">
<header class="lg:hidden flex items-center gap-3 h-14 px-4 border-b border-[var(--mast-border)] bg-[var(--mast-bg-sidebar)]">
<label
for="app-drawer"
class="p-2 -ml-2 rounded-[var(--radius-field)] text-[var(--mast-font-secondary)] hover:text-[var(--mast-font-primary)] hover:bg-[var(--mast-bg-card-hover)] cursor-pointer"
aria-label="Open menu"
>
<.icon name="hero-bars-3" class="size-5" />
</label>
<div class="flex items-center gap-2">
<img src="/images/favicon.svg" alt="" class="size-6 rounded-md" />
<span class="text-sm font-semibold tracking-tight">Mast</span>
</div>
</header>

<main class="flex-1 min-w-0 px-4 py-5 sm:px-6 sm:py-6 lg:px-10 lg:py-8">
<div class="mx-auto max-w-7xl">
{render_slot(@inner_block)}
</div>
</main>
</div>
</div>

<.ui_mobile_drawer toggle_id="app-drawer" active={@active}>
<:nav key="dashboard" navigate={~p"/"} icon="hero-squares-2x2">Dashboard</:nav>
<:nav key="servers" navigate={~p"/"} icon="hero-server-stack">Servers</:nav>
<:nav key="alerts" navigate={~p"/alerts"} icon="hero-bell-alert">Alerts</:nav>
Expand All @@ -35,13 +75,7 @@ defmodule MastWeb.Layouts do
v{Mast.version()}
</span>
</:footer>
</.ui_sidebar>

<main class="flex-1 min-w-0 px-6 py-6 lg:px-10 lg:py-8">
<div class="mx-auto max-w-7xl">
{render_slot(@inner_block)}
</div>
</main>
</.ui_mobile_drawer>

<.flash_group flash={@flash} />
</div>
Expand Down
16 changes: 12 additions & 4 deletions lib/mast_web/components/ui/charts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ defmodule MastWeb.Components.UI.Charts do
|> assign(:until_ms, to_unix_ms(assigns[:until]))

~H"""
<div class="w-full">
<div class="w-full min-w-0">
<%= if @empty? do %>
<div class="h-[180px] flex items-center justify-center rounded-[var(--radius-sm)] bg-[var(--mast-bg-secondary)] text-xs text-[var(--mast-font-tertiary)]">
Waiting for more samples...
</div>
<% else %>
<div class="w-full h-[180px] relative">
<div class="w-full min-w-0 h-[180px] relative overflow-hidden">
<canvas
id={@id}
phx-hook=".MetricChart"
Expand All @@ -58,7 +58,7 @@ defmodule MastWeb.Components.UI.Charts do
data-since={@since_ms}
data-until={@until_ms}
aria-label={@label}
class="rounded-[var(--radius-sm)] bg-[var(--mast-bg-secondary)]"
class="rounded-[var(--radius-sm)] bg-[var(--mast-bg-secondary)] !w-full !max-w-full"
>
</canvas>
</div>
Expand Down Expand Up @@ -86,9 +86,17 @@ defmodule MastWeb.Components.UI.Charts do
mounted() {
this.render()
this.el.addEventListener("dblclick", () => this.chart?.resetZoom())
// Chart.js's ResizeObserver can miss flex/grid resizes when the
// parent shrinks below the canvas's intrinsic width. Force a
// resize on window changes as a fallback.
this._onResize = () => this.chart?.resize()
window.addEventListener("resize", this._onResize)
},
updated() { this.render() },
destroyed() { this.chart?.destroy() },
destroyed() {
window.removeEventListener("resize", this._onResize)
this.chart?.destroy()
},
render() {
const series = JSON.parse(this.el.dataset.series)
const unit = this.el.dataset.unit || ""
Expand Down
14 changes: 7 additions & 7 deletions lib/mast_web/components/ui/containers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule MastWeb.Components.UI.Containers do
]}>
<header
:if={@header != [] or @title != [] or @subtitle != [] or @actions != []}
class="flex items-start justify-between gap-4 px-5 pt-5 pb-3"
class="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3 sm:gap-4 px-5 pt-5 pb-3"
>
<div :if={@title != [] or @subtitle != []} class={["min-w-0", @actions == [] && "flex-1"]}>
<h2
Expand Down Expand Up @@ -142,15 +142,15 @@ defmodule MastWeb.Components.UI.Containers do
>
<div
class={[
"w-full max-w-md bg-[var(--mast-bg-card)] border border-[var(--mast-border)]",
"rounded-[var(--radius-box)] shadow-xl overflow-hidden",
"w-full max-w-md max-h-[calc(100vh-2rem)] bg-[var(--mast-bg-card)] border border-[var(--mast-border)]",
"rounded-[var(--radius-box)] shadow-xl overflow-hidden flex flex-col",
@class
]}
phx-click-away={@on_cancel}
>
<header
:if={@title != [] or @subtitle != []}
class="flex items-start justify-between gap-4 px-5 pt-5 pb-3"
class="flex items-start justify-between gap-4 px-5 pt-5 pb-3 shrink-0"
>
<div class="min-w-0">
<h2
Expand All @@ -173,13 +173,13 @@ defmodule MastWeb.Components.UI.Containers do
</button>
</header>

<div class="px-5 pb-5">
<div class="px-5 pb-5 overflow-y-auto flex-1 min-h-0">
{render_slot(@inner_block)}
</div>

<footer
:if={@footer != []}
class="flex items-center justify-end gap-2 px-5 py-3 border-t border-[var(--mast-border)] bg-[var(--mast-bg-secondary)]"
class="flex items-center justify-end gap-2 px-5 py-3 border-t border-[var(--mast-border)] bg-[var(--mast-bg-secondary)] shrink-0"
>
{render_slot(@footer)}
</footer>
Expand Down Expand Up @@ -209,7 +209,7 @@ defmodule MastWeb.Components.UI.Containers do
~H"""
<section class={[
"bg-[var(--mast-bg-card)] border border-[var(--mast-border)]",
"rounded-[var(--radius-box)] p-5 shadow-sm",
"rounded-[var(--radius-box)] p-5 shadow-sm min-w-0 overflow-hidden",
@class
]}>
<header class="flex items-center gap-3 mb-4">
Expand Down
14 changes: 8 additions & 6 deletions lib/mast_web/components/ui/data.ex
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,15 @@ defmodule MastWeb.Components.UI.Data do

def ui_card_title(assigns) do
~H"""
<span class="inline-flex items-center gap-2 w-full">
<span class="flex flex-wrap items-center gap-x-2 gap-y-1 w-full min-w-0">
<span class={[@icon, "size-4 shrink-0", card_title_color(@color)]} />
<span class="text-[14px] font-semibold text-[var(--mast-font-primary)]">
<span class="text-[14px] font-semibold text-[var(--mast-font-primary)] min-w-0 break-words">
{render_slot(@inner_block)}
</span>
<span class="flex-1" />
<span :if={@meta != []} class="text-[12px] text-[var(--mast-font-tertiary)]">
<span
:if={@meta != []}
class="text-[12px] text-[var(--mast-font-tertiary)] ml-auto whitespace-nowrap"
>
{render_slot(@meta)}
</span>
</span>
Expand Down Expand Up @@ -269,11 +271,11 @@ defmodule MastWeb.Components.UI.Data do
<div
:for={{row, idx} <- Enum.with_index(@row)}
class={[
"h-11 px-5 flex items-center gap-4",
"py-2 sm:h-11 sm:py-0 px-5 flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-4",
idx < length(@row) - 1 && "border-b border-[var(--mast-border)]"
]}
>
<span class="text-[13px] font-medium text-[var(--mast-font-secondary)] w-40 shrink-0">
<span class="text-[13px] font-medium text-[var(--mast-font-secondary)] sm:w-40 shrink-0">
{row.label}
</span>
<span class="text-[13px] font-mono text-[var(--mast-font-primary)] flex-1 min-w-0 truncate">
Expand Down
36 changes: 20 additions & 16 deletions lib/mast_web/components/ui/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ defmodule MastWeb.Components.UI.Domain do

<hr class="border-t border-[var(--mast-border)] my-4" />

<div class="flex items-center gap-4">
<div class="flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4">
<.ui_metric_tile label="Memory" value={format_memory(@memory_mb)} />
<.ui_metric_tile label="Processes" value={format_count(@processes)} />
<.ui_metric_tile label="Msg Queue" value={format_count(@msg_queue)} />
Expand Down Expand Up @@ -297,26 +297,30 @@ defmodule MastWeb.Components.UI.Domain do
def ui_audit_row(assigns) do
~H"""
<div class={[
"flex items-center gap-3 px-4 py-3 border-b border-[var(--mast-border)] last:border-0 hover:bg-[var(--mast-bg-card-hover)]",
"flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-3 px-4 py-3 border-b border-[var(--mast-border)] last:border-0 hover:bg-[var(--mast-bg-card-hover)]",
audit_row_bg(@variant)
]}>
<div class="size-8 rounded-full bg-[var(--mast-bg-tertiary)] flex items-center justify-center shrink-0">
<span class={[audit_icon(@variant), "size-4", audit_icon_color(@variant)]} />
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 flex-wrap text-sm">
<span class="font-medium text-[var(--mast-font-primary)]">{@actor}</span>
<.ui_badge variant={audit_badge_variant(@variant)} dot={false}>
{audit_label(@variant)}
</.ui_badge>
<span class="text-[var(--mast-font-secondary)]">{@verb}</span>
<span :if={@target} class="font-mono text-[var(--mast-font-primary)]">{@target}</span>
<div class="flex items-start gap-3 flex-1 min-w-0">
<div class="size-8 rounded-full bg-[var(--mast-bg-tertiary)] flex items-center justify-center shrink-0">
<span class={[audit_icon(@variant), "size-4", audit_icon_color(@variant)]} />
</div>
<div :if={@detail} class="text-xs text-[var(--mast-font-tertiary)] mt-0.5 truncate">
{@detail}
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 flex-wrap text-sm">
<span class="font-medium text-[var(--mast-font-primary)]">{@actor}</span>
<.ui_badge variant={audit_badge_variant(@variant)} dot={false}>
{audit_label(@variant)}
</.ui_badge>
<span class="text-[var(--mast-font-secondary)]">{@verb}</span>
<span :if={@target} class="font-mono text-[var(--mast-font-primary)]">{@target}</span>
</div>
<div :if={@detail} class="text-xs text-[var(--mast-font-tertiary)] mt-0.5 truncate">
{@detail}
</div>
</div>
</div>
<div class="text-xs text-[var(--mast-font-tertiary)] tabular-nums shrink-0">{@time}</div>
<div class="text-xs text-[var(--mast-font-tertiary)] tabular-nums shrink-0 pl-11 sm:pl-0">
{@time}
</div>
</div>
"""
end
Expand Down
Loading
Loading