Documentation
¶
Index ¶
- Constants
- Variables
- func AnimatedModalOverlay(gtx layout.Context, th *Theme, anim *modalShowState, content layout.Widget) layout.Dimensions
- func BorderedEditor(gtx layout.Context, th *Theme, editor *widget.Editor, hint string) layout.Dimensions
- func BorderedMonoEditor(gtx layout.Context, th *Theme, editor *widget.Editor, hint string) layout.Dimensions
- func CopyToClipboard(gtx layout.Context, text string)
- func DangerButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
- func Divider(gtx layout.Context, col color.NRGBA, verticalMargin unit.Dp) layout.Dimensions
- func EdgeLine(gtx layout.Context, col color.NRGBA, edge string) layout.Dimensions
- func FillBackground(gtx layout.Context, col color.NRGBA, w layout.Widget) layout.Dimensions
- func FormatActivityTime(t time.Time, now time.Time) string
- func IconChevronLeft(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconChevronRight(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconClose(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconCog(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconDatabase(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconEye(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconFilter(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconFolder(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconLogs(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconMail(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconPlus(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconSearch(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconSettings(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconSites(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func IconTerminal(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
- func KVRows(gtx layout.Context, th *Theme, items []KV) layout.Dimensions
- func LabeledInput(gtx layout.Context, th *Theme, label string, editor *widget.Editor, ...) layout.Dimensions
- func LayoutHealthBadge(gtx layout.Context, kind HealthBadgeKind, th *Theme) layout.Dimensions
- func LayoutLogo(gtx layout.Context, th *Theme, size unit.Dp) layout.Dimensions
- func LiveStatusDot(gtx layout.Context, th *Theme, key string, live bool) layout.Dimensions
- func LoadFontCollection() ([]font.FontFace, error)
- func Loader(gtx layout.Context, th *Theme, size unit.Dp) layout.Dimensions
- func ModalOverlay(gtx layout.Context, th *Theme, content layout.Widget) layout.Dimensions
- func NewModalAnim() *modalShowState
- func PrimaryButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
- func RoundedFill(gtx layout.Context, col color.NRGBA, radius unit.Dp, w layout.Widget) layout.Dimensions
- func SecondaryButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
- func Section(gtx layout.Context, th *Theme, title string, content layout.Widget) layout.Dimensions
- func SectionDirty(gtx layout.Context, th *Theme, title string, content layout.Widget) layout.Dimensions
- func SelectableLabel(gtx layout.Context, th *Theme, sel *widget.Selectable, text string, ...) layout.Dimensions
- func SiteAvatar(gtx layout.Context, th *Theme, name string, size unit.Dp) layout.Dimensions
- func SmallButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
- func StatusForSite(started bool) (key, label string)
- func StatusPill(gtx layout.Context, th *Theme, key string, live bool) layout.Dimensions
- func SuccessButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
- func TabBar(gtx layout.Context, th *Theme, tabs []string, active int, ...) layout.Dimensions
- func TruncateWords(s string, maxRunes int) string
- type ActivityTab
- type CloneModal
- type ConfirmDialog
- func (cd *ConfirmDialog) HandleUserInteractions(gtx layout.Context) (confirmed, cancelled bool)
- func (cd *ConfirmDialog) Layout(gtx layout.Context, th *Theme, style ConfirmDialogStyle) layout.Dimensions
- func (cd *ConfirmDialog) LayoutWithExtras(gtx layout.Context, th *Theme, style ConfirmDialogStyle, extras layout.Widget) layout.Dimensions
- type ConfirmDialogStyle
- type DBCredentials
- type Dims
- type Dropdown
- type HealthBadgeKind
- type HealthBlockerModal
- type HealthPanel
- type HookEditor
- func (he *HookEditor) Close()
- func (he *HookEditor) HandleUserInteractions(gtx layout.Context, state *UIState)
- func (he *HookEditor) IsVisible() bool
- func (he *HookEditor) Layout(gtx layout.Context, th *Theme) layout.Dimensions
- func (he *HookEditor) Open(siteID string, h hooks.Hook, onSubmit func(hooks.Hook))
- type HookOutput
- type HookSnapshot
- type HooksPanel
- func (hp *HooksPanel) HandleUserInteractions(gtx layout.Context, siteID string)
- func (hp *HooksPanel) HasActiveModal() bool
- func (hp *HooksPanel) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
- func (hp *HooksPanel) LayoutModalLayer(gtx layout.Context, th *Theme) layout.Dimensions
- type IconFunc
- type KV
- type LifecycleSnapshot
- type LinkChecker
- type LogViewer
- type ModalFocus
- type ModalKeyResult
- type NavRail
- type NavView
- type NewSiteModal
- type NoticeSnapshot
- type Notification
- type NotificationType
- type Notifications
- func (n *Notifications) Add(msg string, t NotificationType)
- func (n *Notifications) Error(msg string)
- func (n *Notifications) HandleUserInteractions(gtx layout.Context)
- func (n *Notifications) Info(msg string)
- func (n *Notifications) Layout(gtx layout.Context, th *Theme) layout.Dimensions
- func (n *Notifications) LayoutBell(gtx layout.Context, th *Theme) layout.Dimensions
- func (n *Notifications) ShowError(msg string)
- func (n *Notifications) ShowInfo(msg string)
- func (n *Notifications) ShowSuccess(msg string)
- func (n *Notifications) Success(msg string)
- type OutputView
- type Palette
- type ProfilingPanel
- type Radii
- type ServicesHealth
- type ServicesHealthStatus
- type SettingsPanel
- type SiteDetail
- type SitesPanel
- type SnapshotsPanel
- type Spacing
- type TextInput
- type TextSizes
- type Theme
- func (t *Theme) ContrastText(bg color.NRGBA) color.NRGBA
- func (th *Theme) Danger(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
- func (t *Theme) Disabled(c color.NRGBA) color.NRGBA
- func (t *Theme) Hovered(c color.NRGBA) color.NRGBA
- func (th *Theme) Primary(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
- func (th *Theme) PrimaryGated(gtx layout.Context, btn *widget.Clickable, text string, enabled bool) layout.Dimensions
- func (t *Theme) ResolvedMode() ThemeMode
- func (th *Theme) Secondary(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
- func (t *Theme) SetMode(mode ThemeMode)
- func (th *Theme) Small(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
- func (th *Theme) SmallGated(gtx layout.Context, btn *widget.Clickable, text string, enabled bool) layout.Dimensions
- func (th *Theme) Success(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
- type ThemeMode
- type UI
- type UIState
- func (s *UIState) ActiveError() string
- func (s *UIState) ActivityFull(siteID string) ([]storage.ActivityEvent, bool)
- func (s *UIState) ActivityRecent(siteID string) []storage.ActivityEvent
- func (s *UIState) AppendActivity(siteID string, ev storage.ActivityEvent)
- func (s *UIState) AppendLinkCheckOutput(line string)
- func (s *UIState) ClearActivity(siteID string)
- func (s *UIState) ClearDeleteConfirm() (id string, purgeVolume bool)
- func (s *UIState) ClearHookOutput(siteID string)
- func (s *UIState) ClearInitError()
- func (s *UIState) DiskFreeBytes() int64
- func (s *UIState) DismissCloneModal()
- func (s *UIState) DismissDeleteConfirm()
- func (s *UIState) GetCloneModalState() (show bool, id, name string)
- func (s *UIState) GetDeleteConfirmState() (show bool, name string, purgeVolume bool)
- func (s *UIState) GetInitError() string
- func (s *UIState) GetLinkCheckState() (output string, loading bool)
- func (s *UIState) GetLogState() (output, service string, loading bool)
- func (s *UIState) GetRetryInit() func()
- func (s *UIState) GetSearchTerm() string
- func (s *UIState) GetSelectedID() string
- func (s *UIState) GetSites() []types.Site
- func (s *UIState) GetWPCLIState() (output string, loading bool)
- func (s *UIState) HealthClearFirstFire()
- func (s *UIState) HealthHydrateSeen(keys []string)
- func (s *UIState) HealthSeenKeys() []string
- func (s *UIState) HealthShouldToast(key string) bool
- func (s *UIState) HealthSnapshot() health.Snapshot
- func (s *UIState) HookAllDone(siteID string, summary hooks.Summary)
- func (s *UIState) HookSnapshot(siteID string) HookSnapshot
- func (s *UIState) HookTaskDone(siteID string, r hooks.Result)
- func (s *UIState) HookTaskOutput(siteID string, line string, stderr bool)
- func (s *UIState) HookTaskStarted(siteID string, h hooks.Hook)
- func (s *UIState) Invalidate()
- func (s *UIState) IsCloneLoading() bool
- func (s *UIState) IsExportLoading() bool
- func (s *UIState) IsShowNewSiteModal() bool
- func (s *UIState) IsSiteToggling(id string) bool
- func (s *UIState) LifecyclePlanDone(siteID string, res orch.Result)
- func (s *UIState) LifecyclePullProgress(siteID string, p docker.PullProgress)
- func (s *UIState) LifecycleSnapshot(siteID string) LifecycleSnapshot
- func (s *UIState) LifecycleStepDone(siteID string, step orch.StepResult)
- func (s *UIState) LifecycleStepStarted(siteID string, step orch.StepResult)
- func (s *UIState) NavCollapsed() bool
- func (s *UIState) NavView() NavView
- func (s *UIState) NoticeSnapshot() NoticeSnapshot
- func (s *UIState) ResetLifecycleProgress(siteID string)
- func (s *UIState) SelectedSite() *types.Site
- func (s *UIState) ServicesHealthSnapshot() ServicesHealth
- func (s *UIState) SetActivityFull(siteID string, evs []storage.ActivityEvent)
- func (s *UIState) SetActivityRecent(siteID string, evs []storage.ActivityEvent)
- func (s *UIState) SetCloneLoading(loading bool)
- func (s *UIState) SetDeletePurgeVolume(purge bool)
- func (s *UIState) SetDiskFreeBytes(n int64)
- func (s *UIState) SetExportLoading(loading bool)
- func (s *UIState) SetHealthSnapshot(snap health.Snapshot)
- func (s *UIState) SetInitDone()
- func (s *UIState) SetInitError(msg string)
- func (s *UIState) SetLinkCheckLoading(loading bool)
- func (s *UIState) SetLinkCheckOutput(output string)
- func (s *UIState) SetLogLoading(loading bool)
- func (s *UIState) SetLogOutput(service, output string)
- func (s *UIState) SetNavCollapsed(c bool)
- func (s *UIState) SetNavView(v NavView)
- func (s *UIState) SetNotice(msg string)
- func (s *UIState) SetNoticeBusy(busy bool)
- func (s *UIState) SetNoticeWithAction(msg, label string, action func())
- func (s *UIState) SetRetryInit(fn func())
- func (s *UIState) SetSearchTerm(term string)
- func (s *UIState) SetSelectedID(id string)
- func (s *UIState) SetServicesHealth(h ServicesHealth)
- func (s *UIState) SetShowNewSiteModal(show bool)
- func (s *UIState) SetSiteToggling(id string, toggling bool)
- func (s *UIState) SetSites(sites []types.Site)
- func (s *UIState) SetWPCLILoading(loading bool)
- func (s *UIState) SetWPCLIOutput(output string)
- func (s *UIState) SetWindow(w *app.Window)
- func (s *UIState) ShowCloneModal(id, name string)
- func (s *UIState) ShowDeleteConfirm(id, name string)
- func (s *UIState) ShowError(msg string)
- func (s *UIState) TriggerNoticeAction() bool
- func (s *UIState) UpdateSite(site types.Site)
- type VersionEditor
- type WPCLIPanel
Constants ¶
const ( StatusOk = "ok" StatusWarn = "warn" StatusErr = "err" StatusIdle = "idle" )
Status keys mirror the design's four states. Locorum's data model only distinguishes Running (ok) and Stopped (idle); Warning and Error are reserved for richer health signals later.
const ActivityFullMax = 200
ActivityFullMax caps the per-site row count cached for the Activity tab. The DB enforces the same retention via storage.ActivityRetentionDefault; duplicating the constant here means the UI never holds more than the designed maximum even if a future schema change widens retention.
const ActivityRecentMax = 5
ActivityRecentMax caps the per-site row count cached for the overview panel. Mirrors sites.activityRecentLimit; declared here so the UI layer is self-contained.
const MaxHookOutputLinesPerSite = 200
MaxHookOutputLinesPerSite caps how many output lines we keep in memory for a site's live-output panel. Older lines are dropped (the on-disk run log retains the full output).
Variables ¶
var IconSize = unit.Dp(16)
IconSize is the default icon dimension, sized to balance with body text.
var LogoSize = unit.Dp(20)
LogoSize is the default mark dimension used in the rail brand.
var MonoFont = font.Font{Typeface: "JetBrains Mono"}
MonoFont is the font.Font value to use for code/output text (logs, WP-CLI output, link checker, DB credentials).
Functions ¶
func AnimatedModalOverlay ¶
func AnimatedModalOverlay(gtx layout.Context, th *Theme, anim *modalShowState, content layout.Widget) layout.Dimensions
AnimatedModalOverlay draws the overlay with a 200ms fade-in driven by anim. Callers should keep an *modalShowState (via NewModalAnim) on their modal struct and pass it here.
func BorderedEditor ¶
func BorderedEditor(gtx layout.Context, th *Theme, editor *widget.Editor, hint string) layout.Dimensions
BorderedEditor draws a text editor with a border.
func BorderedMonoEditor ¶
func BorderedMonoEditor(gtx layout.Context, th *Theme, editor *widget.Editor, hint string) layout.Dimensions
BorderedMonoEditor draws a bordered text editor using the monospace font, suitable for code or shell-command input.
func CopyToClipboard ¶
CopyToClipboard writes text to the system clipboard.
func DangerButton ¶
func EdgeLine ¶
EdgeLine paints a 1-px line along one edge of the constrained area. edge: "top" | "bottom" | "left" | "right". The widget reports its size as gtx.Constraints.Min so it doesn't inflate the surrounding Stack — inside a Stack's Expanded pass, Min equals the largest Stacked child.
func FillBackground ¶
FillBackground paints a rectangle with the given color behind the widget.
func FormatActivityTime ¶
FormatActivityTime renders t as a short string suitable for the Activity feed's leading time chip. Uses relative form for recent events and absolute for older ones — the goal is "readable at a glance, unambiguous for old entries":
< 60 seconds "just now" < 60 minutes "Nm ago" same calendar day "15:04" yesterday "Yesterday 15:04" same year "Jan 2 15:04" older "2006-01-02"
now is taken as a parameter so the caller can pin a clock for tests and so the function never depends on time.Now's monotonic clock semantics. All formatting uses now's location so a local-timezone "Yesterday" is computed against the user's wall clock rather than UTC.
func IconChevronLeft ¶
func IconChevronLeft(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
IconChevronLeft — a left-pointing angle bracket "‹".
func IconChevronRight ¶
func IconChevronRight(gtx layout.Context, th *Theme, size unit.Dp, col color.NRGBA) layout.Dimensions
IconChevronRight — a right-pointing angle bracket "›".
func IconDatabase ¶
IconDatabase — a stacked-cylinder database mark.
func IconFilter ¶
IconFilter — a funnel: a closed flared shape narrowing to the bottom.
func IconFolder ¶
IconFolder — a folder with a tab corner.
func IconSearch ¶
IconSearch — a magnifying glass: circle + diagonal handle.
func IconSettings ¶
IconSettings — three horizontal sliders with knob dots, an unambiguous "preferences" silhouette that scales cleanly even at 14dp.
func IconTerminal ¶
IconTerminal — a rounded rect with a "> " prompt, used for Shell action.
func LabeledInput ¶
func LabeledInput(gtx layout.Context, th *Theme, label string, editor *widget.Editor, hint string) layout.Dimensions
LabeledInput draws a label above a styled text editor.
func LayoutHealthBadge ¶
func LayoutHealthBadge(gtx layout.Context, kind HealthBadgeKind, th *Theme) layout.Dimensions
LayoutHealthBadge paints a small dot in the given foreground colour. Used by the nav rail to flag the Settings entry. Caller is responsible for positioning.
func LayoutLogo ¶
LayoutLogo draws the LocorumMark — a vertical accent bar plus three horizontal bars of decreasing width and decreasing opacity, forming a stylised "L". Geometry is specified in a 32×32 design grid; visible content occupies x: 5..27 (span 22) × y: 6..26 (span 20). The bars are scaled and offset so that visible content fills the requested size, preserving the original 22:20 aspect ratio.
func LiveStatusDot ¶
LiveStatusDot draws a small filled circle in the status color. When status==StatusOk and live==true, it animates an expanding pulse ring on a 2-second cycle. The widget reports a square layout sized to fit the largest pulse extent so neighbouring text isn't shoved around as the ring grows.
func LoadFontCollection ¶
LoadFontCollection parses the embedded Inter (sans-serif) and JetBrains Mono (monospace) faces, plus the bundled gofont family as a unicode fallback, and returns them as a font.FontFace collection suitable for text.NewShaper. Without the gofont fallback, glyphs missing from Inter or JetBrains Mono cause Gio to escape to system fontconfig, which on Linux triggers GLib-GIO-CRITICAL warnings on every frame.
func ModalOverlay ¶
ModalOverlay draws a semi-transparent overlay and centers the content widget. It is the legacy entry point with no fade animation.
func NewModalAnim ¶
func NewModalAnim() *modalShowState
NewModalAnim returns a fresh animation state. Call (*ModalAnim).Show on the frame where the modal becomes visible and (*ModalAnim).Hide on the frame where it disappears. Pass the returned value to AnimatedModalOverlay.
func PrimaryButton ¶
func PrimaryButton(gtx layout.Context, th *Theme, btn *widget.Clickable, text string) layout.Dimensions
Backward-compatible top-level helpers (delegate to *Theme methods).
func RoundedFill ¶
func RoundedFill(gtx layout.Context, col color.NRGBA, radius unit.Dp, w layout.Widget) layout.Dimensions
RoundedFill paints a rounded-rect background behind the widget.
func SecondaryButton ¶
func SectionDirty ¶
func SectionDirty(gtx layout.Context, th *Theme, title string, content layout.Widget) layout.Dimensions
SectionDirty renders a Section with the title coloured by th.Color.Brand, signalling that the contained controls have unsaved changes.
func SelectableLabel ¶
func SelectableLabel(gtx layout.Context, th *Theme, sel *widget.Selectable, text string, size unit.Sp, col color.NRGBA, f font.Font) layout.Dimensions
SelectableLabel renders a widget.Selectable with material-style text appearance. Users can click-drag to select text and Ctrl+C to copy.
func SiteAvatar ¶
SiteAvatar renders a rounded square containing the first two alphanumerics from name (uppercase mono semibold) on a Bg2 surface with a 1px Line border. Used in the sites list (size=36) and in the site detail header (size=30). Favicons are not yet wired in.
func SmallButton ¶
func StatusForSite ¶
StatusForSite maps a site's Started flag onto a (status key, label) pair. A running site uses the live-pulse "ok" treatment; a stopped site is the neutral "idle" gray (rather than red "err"), since stopping is normal.
func StatusPill ¶
StatusPill renders a rounded pill containing a colored dot + uppercase mono status label. Used in the site detail header and at the top of the nav rail brand area. live=true enables the pulse ring on "ok".
func SuccessButton ¶
func TabBar ¶
func TabBar(gtx layout.Context, th *Theme, tabs []string, active int, clicks []*widget.Clickable) layout.Dimensions
TabBar renders a horizontal row of tab buttons. The active tab is highlighted with the primary accent color and an underline indicator.
func TruncateWords ¶
TruncateWords returns s shortened to at most maxRunes runes, breaking at the last word boundary that fits and appending an ellipsis. Strings shorter than the budget are returned unchanged. If no whitespace exists within the budget, falls back to a hard rune-boundary cut.
Types ¶
type ActivityTab ¶
type ActivityTab struct {
// contains filtered or unexported fields
}
ActivityTab renders the per-site lifecycle audit feed. Each row is one orch.Plan outcome; clicking a row toggles an inline expander with the step list and final error captured at write time.
State that needs to survive across frames lives on this struct: the scroll position, the per-row expand toggles, and the per-site set of loads we've already kicked off. Storage reads happen in goroutines — Layout() is purely a function of the cached snapshot.
func NewActivityTab ¶
func NewActivityTab(state *UIState, sm *sites.SiteManager) *ActivityTab
func (*ActivityTab) HandleUserInteractions ¶
func (at *ActivityTab) HandleUserInteractions(layout.Context)
HandleUserInteractions is a no-op today — Layout() consumes clicks as it renders so the matching row's expander opens within the same frame. Kept as a stub so the tab plugs into SiteDetail's HandleUserInteractions dispatch without an awkward conditional.
func (*ActivityTab) Layout ¶
func (at *ActivityTab) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
Layout renders the activity tab body for siteID. Triggers a one-time background load of the full per-site history on first paint and on site-switch.
type CloneModal ¶
type CloneModal struct {
// contains filtered or unexported fields
}
CloneModal is a dialog for cloning a site with a new name.
func NewCloneModal ¶
func NewCloneModal(state *UIState, sm *sites.SiteManager, toasts *Notifications) *CloneModal
func (*CloneModal) HandleUserInteractions ¶
func (cm *CloneModal) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions processes Cancel / Clone button clicks. Called by the root UI before Layout when the modal is visible.
func (*CloneModal) Layout ¶
func (cm *CloneModal) Layout(gtx layout.Context, th *Theme) layout.Dimensions
type ConfirmDialog ¶
type ConfirmDialog struct {
// contains filtered or unexported fields
}
ConfirmDialog holds state for a reusable confirmation modal dialog.
func (*ConfirmDialog) HandleUserInteractions ¶
func (cd *ConfirmDialog) HandleUserInteractions(gtx layout.Context) (confirmed, cancelled bool)
HandleUserInteractions reads the confirm/cancel button click state for the frame. Must be called before Layout each frame and only once (Clicked() consumes events).
func (*ConfirmDialog) Layout ¶
func (cd *ConfirmDialog) Layout(gtx layout.Context, th *Theme, style ConfirmDialogStyle) layout.Dimensions
Layout renders the confirmation dialog inside a modal overlay. Use HandleUserInteractions to detect confirm/cancel clicks.
func (*ConfirmDialog) LayoutWithExtras ¶
func (cd *ConfirmDialog) LayoutWithExtras(gtx layout.Context, th *Theme, style ConfirmDialogStyle, extras layout.Widget) layout.Dimensions
LayoutWithExtras renders the confirmation dialog with an optional extras widget (e.g. a checkbox) sandwiched between the message and the action buttons. Pass nil for extras when no additional UI is needed; the result is identical to Layout().
type ConfirmDialogStyle ¶
type ConfirmDialogStyle struct {
Title string
Message string
ConfirmLabel string
ConfirmColor color.NRGBA
}
ConfirmDialogStyle configures the appearance of a ConfirmDialog.
type DBCredentials ¶
type DBCredentials struct {
// contains filtered or unexported fields
}
DBCredentials renders the Database section with selectable values, copy buttons, and an opt-in host-port publish toggle so the user can connect from desktop DB clients.
func NewDBCredentials ¶
func NewDBCredentials() *DBCredentials
func (*DBCredentials) Bind ¶
func (dc *DBCredentials) Bind(sm *sites.SiteManager, state *UIState, toasts *Notifications)
Bind stores the SiteManager + UI bridges DBCredentials needs for the publish-port flow. Called from NewSiteDetail after construction so the existing zero-arg NewDBCredentials still compiles.
func (*DBCredentials) HandleUserInteractions ¶
func (dc *DBCredentials) HandleUserInteractions(gtx layout.Context, site *types.Site)
HandleUserInteractions processes per-row Copy button clicks + the publish-port toggle.
func (*DBCredentials) Layout ¶
func (dc *DBCredentials) Layout(gtx layout.Context, th *Theme, site *types.Site) layout.Dimensions
type Dims ¶
type Dims struct {
RailExpanded unit.Dp
RailCollapsed unit.Dp
SitesListWidth unit.Dp
ModalWidth unit.Dp
LoaderSize unit.Dp
LoaderSizeSM unit.Dp
OutputAreaMax unit.Dp
LabelColWidth unit.Dp
// Legacy alias for the old single-sidebar layout.
SidebarWidth unit.Dp
}
Dims holds fixed layout dimensions independent of theme mode.
RailExpanded — Column 1 nav rail width, expanded. RailCollapsed — Column 1 nav rail width, collapsed (icons only). SitesListWidth — Column 2 sites-list panel width.
func DefaultDims ¶
func DefaultDims() *Dims
type HealthBadgeKind ¶
type HealthBadgeKind int
HealthBadgeKind is the styling key for the nav-rail badge.
const ( HealthBadgeNone HealthBadgeKind = iota HealthBadgeInfo // hidden in the rail; shown only in the panel HealthBadgeWarn // amber HealthBadgeBlocker // red )
func HealthBadgeFor ¶
func HealthBadgeFor(snap health.Snapshot) HealthBadgeKind
HealthBadgeFor maps a snapshot onto the rail-badge styling. Returns HealthBadgeNone when the snapshot has no findings or only Info-level ones.
type HealthBlockerModal ¶
type HealthBlockerModal struct {
// contains filtered or unexported fields
}
HealthBlockerModal renders the full-screen modal that fires when at least one Blocker finding is present. The user has two options: "Re-check" (calls runner.RunNow) and "Quit". There is deliberately no "Ignore" — DDEV's discipline.
func NewHealthBlockerModal ¶
func NewHealthBlockerModal(state *UIState, runNow func(), onQuit func()) *HealthBlockerModal
NewHealthBlockerModal builds the modal. quit is invoked when the user clicks Quit; main.go wires it to a graceful shutdown.
func (*HealthBlockerModal) HandleUserInteractions ¶
func (m *HealthBlockerModal) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions processes button clicks. Called by the root UI before Layout when the modal is visible.
func (*HealthBlockerModal) HasBlocker ¶
func (m *HealthBlockerModal) HasBlocker() bool
HasBlocker reports whether the current snapshot contains a blocker.
func (*HealthBlockerModal) Layout ¶
func (m *HealthBlockerModal) Layout(gtx layout.Context, th *Theme) layout.Dimensions
Layout renders the blocker modal as a full-screen overlay.
type HealthPanel ¶
type HealthPanel struct {
// contains filtered or unexported fields
}
HealthPanel renders the System Health card in the Settings panel. It reads the snapshot from UIState (atomic, lock-free) every frame and renders one row per Finding plus a "Re-check now" button.
HealthPanel does NOT own the runner — it only reads. Action invocations route back through the runner via the optional submitAction callback, which the wiring layer (main.go) provides as a closure over runner.SubmitAction.
func NewHealthPanel ¶
func NewHealthPanel(state *UIState, submitAction func(id string, a health.Action) error, runNow func()) *HealthPanel
NewHealthPanel constructs the panel. submitAction is the runner's SubmitAction wrapped in a closure; runNow is runner.RunNow + Snapshot publication. Both may be nil for tests.
func (*HealthPanel) HandleUserInteractions ¶
func (p *HealthPanel) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions reads the re-check button and any per-finding action button. Called by the parent panel each frame.
func (*HealthPanel) Layout ¶
func (p *HealthPanel) Layout(gtx layout.Context, th *Theme) layout.Dimensions
Layout renders the System Health card.
type HookEditor ¶
type HookEditor struct {
// contains filtered or unexported fields
}
HookEditor is the add/edit dialog for a single hook. It is created once per SiteDetail and mutated to represent either a new hook (Open with Hook.ID == 0) or an existing one (Open with Hook.ID != 0).
func NewHookEditor ¶
func NewHookEditor() *HookEditor
NewHookEditor constructs a HookEditor with the active event list as dropdown options.
func (*HookEditor) HandleUserInteractions ¶
func (he *HookEditor) HandleUserInteractions(gtx layout.Context, state *UIState)
HandleUserInteractions runs each frame the editor is visible.
func (*HookEditor) IsVisible ¶
func (he *HookEditor) IsVisible() bool
IsVisible reports whether the editor is open.
func (*HookEditor) Layout ¶
func (he *HookEditor) Layout(gtx layout.Context, th *Theme) layout.Dimensions
Layout draws the modal. Caller is responsible for only invoking when IsVisible() is true.
type HookOutput ¶
type HookOutput struct {
// contains filtered or unexported fields
}
HookOutput renders the live output panel for the most recent hook run on the selected site. It tracks no per-output state of its own — everything it draws comes from UIState.HookSnapshot.
func NewHookOutput ¶
func NewHookOutput(state *UIState, sm *sites.SiteManager) *HookOutput
NewHookOutput builds a fresh output panel. `sm` is unused at present but reserved for future cancel-run / re-run integration.
func (*HookOutput) HandleUserInteractions ¶
func (ho *HookOutput) HandleUserInteractions(gtx layout.Context, siteID string)
HandleUserInteractions handles open-log and clear-output clicks.
func (*HookOutput) Layout ¶
func (ho *HookOutput) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
Layout renders the panel for the given site.
type HookSnapshot ¶
type HookSnapshot struct {
Running *hooks.Hook
Last *hooks.Result
Summary *hooks.Summary
Lines []hookLine
}
HookSnapshot is a frame-stable copy of the per-site hook output / progress. Renderers receive a snapshot so the layout pass never holds the state mutex while iterating.
func (HookSnapshot) HasActivity ¶
func (h HookSnapshot) HasActivity() bool
HasActivity reports whether there is anything worth displaying.
type HooksPanel ¶
type HooksPanel struct {
// contains filtered or unexported fields
}
HooksPanel is the per-site hooks tab. It loads hooks lazily on display, caches them in memory, and refreshes whenever the user makes a change.
func NewHooksPanel ¶
func NewHooksPanel(state *UIState, sm *sites.SiteManager, provider hookListProvider, toasts *Notifications) *HooksPanel
NewHooksPanel builds a HooksPanel.
func (*HooksPanel) HandleUserInteractions ¶
func (hp *HooksPanel) HandleUserInteractions(gtx layout.Context, siteID string)
HandleUserInteractions processes clicks for the hooks tab. It delegates to the editor / confirm dialog as needed.
func (*HooksPanel) HasActiveModal ¶
func (hp *HooksPanel) HasActiveModal() bool
HasActiveModal reports whether the panel is showing the editor or the delete-confirm modal.
func (*HooksPanel) Layout ¶
func (hp *HooksPanel) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
Layout renders the hooks tab body for the given site.
func (*HooksPanel) LayoutModalLayer ¶
func (hp *HooksPanel) LayoutModalLayer(gtx layout.Context, th *Theme) layout.Dimensions
LayoutModalLayer is called from the root UI's modal stack so the hook editor and delete-confirm dialogs sit above the rest of the chrome.
type IconFunc ¶
IconFunc paints a stroke icon at the requested size in the given color. All icons are designed against a 24×24 grid with a 1.6 stroke width and scale uniformly.
type LifecycleSnapshot ¶
type LifecycleSnapshot struct {
PlanName string
Steps []orch.StepResult
Pulls []docker.PullProgress
FinalError error
RolledBack bool
Done bool
}
LifecycleSnapshot is a frame-stable copy of a site's running lifecycle Plan. Renderers receive a snapshot so the Layout pass never holds the state mutex while iterating.
func (LifecycleSnapshot) HasActivity ¶
func (l LifecycleSnapshot) HasActivity() bool
HasActivity reports whether there is anything worth displaying.
type LinkChecker ¶
type LinkChecker struct {
// contains filtered or unexported fields
}
LinkChecker provides a UI panel for checking broken links on a running site.
func NewLinkChecker ¶
func NewLinkChecker(state *UIState, sm *sites.SiteManager) *LinkChecker
func (*LinkChecker) HandleUserInteractions ¶
func (lc *LinkChecker) HandleUserInteractions(gtx layout.Context, siteID string)
HandleUserInteractions processes the Check Links button click.
func (*LinkChecker) Layout ¶
func (lc *LinkChecker) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
type LogViewer ¶
type LogViewer struct {
// contains filtered or unexported fields
}
LogViewer renders the container log viewer panel with service selector and output area.
func NewLogViewer ¶
func NewLogViewer(state *UIState, sm *sites.SiteManager) *LogViewer
func (*LogViewer) HandleUserInteractions ¶
HandleUserInteractions processes the Refresh button click.
type ModalFocus ¶
FocusModalKeys declares tag as a key event receiver and requests focus on the first call after the modal becomes visible. Call from the modal's Layout() before Process is called for the next frame.
func NewModalFocus ¶
func NewModalFocus() *ModalFocus
NewModalFocus creates a focus tracker for a modal. Tag should be a stable pointer (e.g. &ModalFocus{} stored on the modal struct).
func (*ModalFocus) Layout ¶
func (mf *ModalFocus) Layout(gtx layout.Context)
Layout registers the focus tag and requests keyboard focus the first frame it is shown. Call OnHide when the modal closes to re-arm focus for next time.
func (*ModalFocus) OnHide ¶
func (mf *ModalFocus) OnHide()
OnHide resets the focus tracker so the next time the modal is shown, focus is requested again.
type ModalKeyResult ¶
ModalKeyResult reports which key terminated a frame's key processing.
func ProcessModalKeys ¶
func ProcessModalKeys(gtx layout.Context, tag event.Tag) ModalKeyResult
ProcessModalKeys consumes Escape/Enter key events delivered to the given tag and returns which one fired (if any). Call once per frame from HandleUserInteractions while the modal is visible.
The caller is responsible for declaring the tag in the layout pass via FocusModalKeys, which also requests focus the first time it is shown.
type NavRail ¶
type NavRail struct {
// contains filtered or unexported fields
}
NavRail is the leftmost column: the brand mark, two top-level nav items (Sites / Settings), a hardcoded GROUPS section, and a collapse chevron at the bottom. The rail's width is read from UIState.NavCollapsed and its right edge bears a 1-px line.
func NewNavRail ¶
func NewNavRail(state *UIState, sm *sites.SiteManager) *NavRail
func (*NavRail) HandleUserInteractions ¶
HandleUserInteractions processes clicks on the nav items and the collapse toggle. Called by the root UI before Layout each frame.
type NavView ¶
type NavView string
NavView identifies which root area is shown in columns 2+3. The nav rail in column 1 toggles this; the chrome adapts accordingly.
const ( )
type NewSiteModal ¶
type NewSiteModal struct {
// contains filtered or unexported fields
}
func NewNewSiteModal ¶
func NewNewSiteModal(state *UIState, sm *sites.SiteManager, toasts *Notifications) *NewSiteModal
func (*NewSiteModal) HandleUserInteractions ¶
func (m *NewSiteModal) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions processes Cancel / Browse / Create button clicks. Called by the root UI before Layout when the modal is visible.
func (*NewSiteModal) Layout ¶
func (m *NewSiteModal) Layout(gtx layout.Context, th *Theme) layout.Dimensions
type NoticeSnapshot ¶
NoticeSnapshot is a frame-stable copy of the notice banner state. The Layout pass reads this once per frame so it can render the message and (optionally) an action button without holding the state mutex.
type Notification ¶
type Notification struct {
ID int64
Type NotificationType
Message string
CreatedAt time.Time
Duration time.Duration
// contains filtered or unexported fields
}
Notification is a single message with a type, creation time, and TTL after which the floating banner auto-docks into the history panel.
type NotificationType ¶
type NotificationType int
NotificationType determines the visual style of a notification.
const ( NotificationError NotificationType = iota NotificationSuccess NotificationInfo )
type Notifications ¶
type Notifications struct {
// contains filtered or unexported fields
}
Notifications is a notification center that floats new entries transiently in the bottom-right corner and docks expired entries into a history panel toggled by a bell icon. Archive entries persist until the user dismisses them individually or clears all.
func NewNotifications ¶
func NewNotifications(state *UIState) *Notifications
func (*Notifications) Add ¶
func (n *Notifications) Add(msg string, t NotificationType)
Add inserts a new notification of the given type and starts its floating timer.
func (*Notifications) Error ¶
func (n *Notifications) Error(msg string)
Error / Success / Info are sugar over Add.
func (*Notifications) HandleUserInteractions ¶
func (n *Notifications) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions processes the bell-toggle and archive-dismiss clicks. Call from the root UI before Layout each frame.
func (*Notifications) Info ¶
func (n *Notifications) Info(msg string)
func (*Notifications) Layout ¶
func (n *Notifications) Layout(gtx layout.Context, th *Theme) layout.Dimensions
Layout draws floating notifications in the bottom-right and, when the bell is open, the history panel above them.
func (*Notifications) LayoutBell ¶
func (n *Notifications) LayoutBell(gtx layout.Context, th *Theme) layout.Dimensions
LayoutBell draws the bell icon with an unread-count badge. Call from the sidebar so the bell sits beside the search field or app title.
func (*Notifications) ShowError ¶
func (n *Notifications) ShowError(msg string)
ShowError / ShowSuccess preserve the previous toast API.
func (*Notifications) ShowInfo ¶
func (n *Notifications) ShowInfo(msg string)
func (*Notifications) ShowSuccess ¶
func (n *Notifications) ShowSuccess(msg string)
func (*Notifications) Success ¶
func (n *Notifications) Success(msg string)
type OutputView ¶
type OutputView struct {
// contains filtered or unexported fields
}
OutputView is the persistent state for an output panel (logs, WP-CLI output, link-checker results). It wraps a read-only widget.Editor so the user can click-drag to select text and Ctrl+C to copy. lastText caches the most recently applied content; SetText resets the caret and selection, so we only re-apply when the output actually changes.
func NewOutputView ¶
func NewOutputView() *OutputView
NewOutputView constructs an OutputView with a read-only editor.
func (*OutputView) Layout ¶
func (ov *OutputView) Layout(gtx layout.Context, th *Theme, output, placeholder string, maxHeight unit.Dp) layout.Dimensions
Layout renders the output panel: a Surface-colored card containing a scrollable, selectable monospace text area. When output is empty, placeholder is shown via the editor's hint.
type Palette ¶
type Palette struct {
// ── Design tokens ─────────────────────────────────────────────────
// Surface hierarchy: Bg flush / Bg1 panels / Bg2 hover-active /
// Bg3 input fills.
Bg color.NRGBA
Bg1 color.NRGBA
Bg2 color.NRGBA
Bg3 color.NRGBA
// Lines: Line for muted dividers; LineStrong for input/button borders.
Line color.NRGBA
LineStrong color.NRGBA
// Foreground hierarchy.
Fg color.NRGBA // body text
Fg2 color.NRGBA // secondary
Fg3 color.NRGBA // muted
// Accent (single retro cyan, used sparingly).
Accent color.NRGBA
AccentSoft color.NRGBA // tint background
AccentLine color.NRGBA // tint border
AccentFg color.NRGBA // text on accent surface
// Status: each pair is solid (foreground / dot / border-base) and
// soft (background tint).
Ok color.NRGBA
OkSoft color.NRGBA
Warn color.NRGBA
WarnSoft color.NRGBA
Err color.NRGBA
ErrSoft color.NRGBA
// Active/hover row tint (semi-transparent — paint over Bg1).
RowActive color.NRGBA
// Modal backdrop overlay.
Overlay color.NRGBA
// ── Legacy aliases (back-compat with existing widget code) ───────
// Surface aliases.
SidebarBg color.NRGBA // Bg
ContentBg color.NRGBA // Bg
SurfaceDeep color.NRGBA // Bg1
Surface color.NRGBA // Bg1
SurfaceAlt color.NRGBA // Bg2
SurfaceElevated color.NRGBA // Bg1
// Text aliases.
TextPrimary color.NRGBA // Fg
TextStrong color.NRGBA // Fg
TextSecondary color.NRGBA // Fg2
TextMuted color.NRGBA // Fg3
OnPrimary color.NRGBA // AccentFg
// Brand alias — formerly gold; now the cyan accent.
Brand color.NRGBA // Accent
// Action aliases.
Primary color.NRGBA // Accent
Danger color.NRGBA // Err
DangerDeep color.NRGBA // Err
Success color.NRGBA // Ok
// Banner aliases.
InfoBg color.NRGBA // pre-blended cyan-tinted surface
InfoFg color.NRGBA // Accent
SuccessBg color.NRGBA // pre-blended green-tinted surface
SuccessFg color.NRGBA // Ok
DangerBg color.NRGBA // pre-blended red-tinted surface
DangerFg color.NRGBA // Err
// Structural aliases.
Border color.NRGBA // Line
BorderFocused color.NRGBA // Accent
Separator color.NRGBA // Line
// Utility.
White color.NRGBA
}
Palette holds the semantic color set for a single theme mode (dark or light). The "design token" fields (Bg, Bg1, Fg, Accent, etc.) are the canonical names used by new layout code; the legacy fields below them (SidebarBg, Surface, TextPrimary, etc.) are aliases retained so existing widgets keep compiling — they map onto the same underlying colors.
func DarkPalette ¶
func DarkPalette() *Palette
DarkPalette returns the dark-mode palette: deep neutral grays with the same retro-cyan accent.
func LightPalette ¶
func LightPalette() *Palette
LightPalette returns the light-mode palette: warm whites + neutral grays with the same retro-cyan accent.
type ProfilingPanel ¶
type ProfilingPanel struct {
// contains filtered or unexported fields
}
ProfilingPanel is the per-site SPX profiler tab. It owns the toggle, the URL/key card, and the recent-reports list. SPX itself runs inside the existing PHP-FPM container — this panel never spawns or touches Docker; it strictly drives SiteManager and reads the profile-data directory via the SiteManager helpers.
func NewProfilingPanel ¶
func NewProfilingPanel(state *UIState, sm *sites.SiteManager, toasts *Notifications) *ProfilingPanel
NewProfilingPanel constructs a ProfilingPanel. State + SiteManager are required; toasts may be nil (errors then route only through the global error banner via state.ShowError).
func (*ProfilingPanel) HandleUserInteractions ¶
func (pp *ProfilingPanel) HandleUserInteractions(gtx layout.Context, site *types.Site)
HandleUserInteractions processes button clicks. Must be called once per frame, before Layout.
func (*ProfilingPanel) Layout ¶
func (pp *ProfilingPanel) Layout(gtx layout.Context, th *Theme, site *types.Site) layout.Dimensions
Layout renders the panel.
type Radii ¶
Radii is the corner-radius scale: R1 (4dp) for tight chips, R2 (6dp) for buttons/inputs, R3 (10dp) for panels, R4 (14dp) for the outer window. SM/MD/LG aliases retained for back-compat.
func DefaultRadii ¶
func DefaultRadii() *Radii
type ServicesHealth ¶
type ServicesHealth struct {
Status ServicesHealthStatus
Detail string
}
ServicesHealth captures the rolled-up health of Locorum's global services. Status is the worst observed state across the three; Detail is a human-readable suffix shown in the top status bar.
type ServicesHealthStatus ¶
type ServicesHealthStatus int
ServicesHealthStatus is a tri-state for the global-services bar.
const ( ServicesHealthUnknown ServicesHealthStatus = iota ServicesHealthHealthy ServicesHealthDegraded ServicesHealthDown )
type SettingsPanel ¶
type SettingsPanel struct {
// contains filtered or unexported fields
}
SettingsPanel takes over columns 2+3 when the nav rail's Settings item is active. Sections (top to bottom):
- System Health: runner findings + re-check.
- Appearance: theme picker (System / Light / Dark).
- New site defaults: pre-fill values for the new-site modal.
- Network & TLS: router HTTP/HTTPS host ports + mkcert path.
Each section reads from sm.Config() at construction time and pushes validated changes back through the typed setters. Validation errors surface as a transient toast — never an uncaught panic.
func NewSettingsPanel ¶
func NewSettingsPanel(state *UIState, sm *sites.SiteManager, onThemeChange func(ThemeMode)) *SettingsPanel
NewSettingsPanel constructs a SettingsPanel. onThemeChange is invoked whenever the user changes the theme mode (e.g. to apply + persist).
func (*SettingsPanel) HandleUserInteractions ¶
func (s *SettingsPanel) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions watches the theme picker for selection changes, syncs the engine→version dropdown, and persists any changed defaults.
func (*SettingsPanel) Layout ¶
func (s *SettingsPanel) Layout(gtx layout.Context, th *Theme) layout.Dimensions
func (*SettingsPanel) SetHealthPanel ¶
func (s *SettingsPanel) SetHealthPanel(hp *HealthPanel)
SetHealthPanel attaches the system-health panel renderer. Optional — callers that don't wire a runner (early startup, tests) can leave it nil and the section is omitted from the layout.
type SiteDetail ¶
type SiteDetail struct {
// contains filtered or unexported fields
}
SiteDetail is column 3: a header bar (avatar/name/domain/status pill + action buttons), a tab strip, and the active tab's body content. Hosts the per-tab sub-components (DB credentials, logs, WP-CLI, hooks, etc).
func NewSiteDetail ¶
func NewSiteDetail(state *UIState, sm *sites.SiteManager, toasts *Notifications) *SiteDetail
func (*SiteDetail) HandleUserInteractions ¶
func (sd *SiteDetail) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions processes header-bar clicks, tab selection, and per-tab sub-component interactions. Called by the root UI before Layout each frame.
func (*SiteDetail) HooksPanel ¶
func (sd *SiteDetail) HooksPanel() *HooksPanel
HooksPanel exposes the hooks tab so the root UI can render its modal overlays above the main chrome.
func (*SiteDetail) Layout ¶
func (sd *SiteDetail) Layout(gtx layout.Context, th *Theme) layout.Dimensions
type SitesPanel ¶
type SitesPanel struct {
// contains filtered or unexported fields
}
SitesPanel is column 2: a fixed-width sites list with a sticky-feeling header (title, count, +New button, search input) above scrollable rows.
func NewSitesPanel ¶
func NewSitesPanel(state *UIState, sm *sites.SiteManager, toasts *Notifications) *SitesPanel
func (*SitesPanel) HandleUserInteractions ¶
func (p *SitesPanel) HandleUserInteractions(gtx layout.Context)
HandleUserInteractions reads search text, the +New click, and per-row selection clicks into UIState.
func (*SitesPanel) Layout ¶
func (p *SitesPanel) Layout(gtx layout.Context, th *Theme) layout.Dimensions
type SnapshotsPanel ¶
type SnapshotsPanel struct {
// contains filtered or unexported fields
}
SnapshotsPanel lists snapshots for a site, lets the user create a new one, and offers per-row Restore + Delete actions. Lives in the site detail panel as a tab next to Logs / WP-CLI / Hooks.
func NewSnapshotsPanel ¶
func NewSnapshotsPanel(state *UIState, sm *sites.SiteManager, toasts *Notifications) *SnapshotsPanel
func (*SnapshotsPanel) HandleUserInteractions ¶
func (p *SnapshotsPanel) HandleUserInteractions(gtx layout.Context, site *types.Site)
HandleUserInteractions processes button clicks. Called by the parent before Layout when this panel is visible.
func (*SnapshotsPanel) Layout ¶
func (p *SnapshotsPanel) Layout(gtx layout.Context, th *Theme, site *types.Site) layout.Dimensions
type Spacing ¶
type Spacing struct {
XXS unit.Dp
XS unit.Dp
SM unit.Dp
MD unit.Dp
LG unit.Dp
XL unit.Dp
XXL unit.Dp
}
Spacing is the padding/margin scale, calibrated to the design's em rhythm at an 18px base (so 1em ≈ 18dp). XS≈0.35em, SM≈0.55em, MD≈0.85em, LG≈1.1em, XL≈1.55em.
func DefaultSpacing ¶
func DefaultSpacing() *Spacing
type TextInput ¶
TextInput wraps widget.Editor with a self-resetting Changed() helper that returns true the first time it's called after the user has modified the text, then resets until the next change.
func NewMultiline ¶
NewMultiline returns a multi-line TextInput.
func NewTextInput ¶
NewTextInput returns a single-line TextInput preloaded with the given value.
func (*TextInput) Changed ¶
Changed returns true if the text changed since the last call to Changed, then resets. Pair with Update() each frame.
type TextSizes ¶
type TextSizes struct {
Micro unit.Sp
Mono unit.Sp
MonoSM unit.Sp
Body unit.Sp
Tab unit.Sp
Header unit.Sp
Section unit.Sp
H1 unit.Sp
// Legacy aliases.
XS unit.Sp
SM unit.Sp
Base unit.Sp
LG unit.Sp
}
TextSizes is the typography scale, em-based at an 18sp base.
Micro 12sp — uppercase mono labels (~0.65em) Mono 13sp — mono captions, status, domain (~0.72em) MonoSM 14sp — mono values (~0.78em) Body 15sp — body text, nav items (~0.85em) Tab 15sp — tab labels (~0.82em, rounded up) Header 17sp — detail header name, section heading (~0.92em) H1 22sp — modal titles
XS/SM/Base/LG are aliases retained for back-compat with existing widgets.
func DefaultTextSizes ¶
func DefaultTextSizes() *TextSizes
type Theme ¶
type Theme struct {
*material.Theme
Color *Palette
Spacing *Spacing
Sizes *TextSizes
Radii *Radii
Dims *Dims
Mode ThemeMode // user preference (Dark, Light, or System)
}
Theme bundles the material theme plus the custom palette, spacing, text sizes, corner radii, and layout dimensions. It is threaded through every Layout() function in the UI. Access the underlying *material.Theme via th.Theme (e.g. material.Body2(th.Theme, "...")).
func NewTheme ¶
func NewTheme() *Theme
NewTheme constructs a Theme with the system-resolved palette as default. Use (*Theme).SetMode to switch palettes at runtime.
func (*Theme) ContrastText ¶
ContrastText returns black or white depending on whether the input background color is light or dark, optimised for body text legibility.
func (*Theme) Disabled ¶
Disabled returns a desaturated, alpha-reduced version of the input color, suitable for disabled controls.
func (*Theme) Hovered ¶
Hovered returns a slightly lighter (dark theme) or darker (light theme) variant of the input color, suitable for hover states.
func (*Theme) PrimaryGated ¶
func (th *Theme) PrimaryGated(gtx layout.Context, btn *widget.Clickable, text string, enabled bool) layout.Dimensions
PrimaryGated draws a primary button that is visually muted and ignores clicks when enabled is false. Pair with .Changed() / dirty-tracking so the button only activates when the user has edited something.
func (*Theme) ResolvedMode ¶
ResolvedMode returns the effective theme mode, resolving ThemeSystem to either ThemeDark or ThemeLight via DetectSystemTheme.
func (*Theme) Secondary ¶
func (th *Theme) Secondary(gtx layout.Context, btn *widget.Clickable, text string) layout.Dimensions
Secondary draws a muted surface secondary action button.
func (*Theme) SetMode ¶
SetMode swaps the active palette to the requested mode. ThemeSystem resolves to Dark or Light via DetectSystemTheme().
type ThemeMode ¶
type ThemeMode int
ThemeMode selects the active color palette. ThemeSystem follows the host OS setting (resolved to Dark or Light at theme construction / switch time).
func DetectSystemTheme ¶
func DetectSystemTheme() ThemeMode
DetectSystemTheme inspects the host OS for a light/dark preference. Falls back to ThemeDark if the preference can't be determined.
func ParseThemeMode ¶
ParseThemeMode converts a stored string into a ThemeMode. Unknown / empty values fall back to ThemeSystem (so a freshly-installed app follows the OS).
type UI ¶
type UI struct {
Theme *Theme
State *UIState
SM *sites.SiteManager
// Sub-components
SitesPanel *SitesPanel
Settings *SettingsPanel
SiteDetail *SiteDetail
NewSite *NewSiteModal
Toasts *Notifications
// Modals
CloneModal *CloneModal
HealthBlocker *HealthBlockerModal
// contains filtered or unexported fields
}
func New ¶
func New(sm *sites.SiteManager) *UI
func (*UI) HandleUserInteractions ¶
HandleUserInteractions processes all user input for the current frame. Modal interactions are only processed when their modal is visible, preventing phantom clicks against hidden widgets.
type UIState ¶
type UIState struct {
// contains filtered or unexported fields
}
UIState holds all mutable UI state, protected by a mutex for thread-safe access from background goroutines (Docker operations, site loading, etc.).
func NewUIState ¶
func NewUIState() *UIState
func (*UIState) ActiveError ¶
ActiveError returns the current error message if it hasn't expired, or "".
func (*UIState) ActivityFull ¶
func (s *UIState) ActivityFull(siteID string) ([]storage.ActivityEvent, bool)
ActivityFull returns a snapshot copy of the cached full rows for siteID and a flag indicating whether the full cache has been populated. The caller uses the flag to decide whether to kick off a load.
func (*UIState) ActivityRecent ¶
func (s *UIState) ActivityRecent(siteID string) []storage.ActivityEvent
ActivityRecent returns a snapshot copy of the cached recent rows for siteID. Returns an empty slice (not nil) if no cache entry exists.
func (*UIState) AppendActivity ¶
func (s *UIState) AppendActivity(siteID string, ev storage.ActivityEvent)
AppendActivity prepends ev to both the recent and (if loaded) full cache for siteID, trimming each to its respective cap. Used from the OnActivityAppended callback.
The full cache is only mutated if it was previously loaded — otherwise the row is on disk and will appear next time the Activity tab is opened. This avoids growing an unbounded cache for sites the user never visits.
func (*UIState) AppendLinkCheckOutput ¶
func (*UIState) ClearActivity ¶
ClearActivity drops the cache entry for siteID. Called when a site is removed so we don't leak per-site state for the lifetime of the process.
func (*UIState) ClearDeleteConfirm ¶
ClearDeleteConfirm closes the delete confirmation modal and returns the target site ID and the user's purge choice.
func (*UIState) ClearHookOutput ¶
ClearHookOutput discards the cached output for a site (e.g. when the user switches sites or the panel resets).
func (*UIState) ClearInitError ¶
func (s *UIState) ClearInitError()
ClearInitError clears the init error.
func (*UIState) DiskFreeBytes ¶
DiskFreeBytes returns the cached host-filesystem free-byte reading. Zero means "unknown" (typical until the first health cycle completes).
func (*UIState) DismissCloneModal ¶
func (s *UIState) DismissCloneModal()
func (*UIState) DismissDeleteConfirm ¶
func (s *UIState) DismissDeleteConfirm()
DismissDeleteConfirm closes the delete confirmation modal without deleting.
func (*UIState) GetCloneModalState ¶
func (*UIState) GetDeleteConfirmState ¶
GetDeleteConfirmState returns the current delete confirmation state.
func (*UIState) GetInitError ¶
GetInitError returns the current initialization error, or "".
func (*UIState) GetLinkCheckState ¶
func (*UIState) GetLogState ¶
GetLogState returns the current log viewer state.
func (*UIState) GetRetryInit ¶
func (s *UIState) GetRetryInit() func()
GetRetryInit returns the retry callback.
func (*UIState) GetSearchTerm ¶
GetSearchTerm returns the current search filter.
func (*UIState) GetSelectedID ¶
GetSelectedID returns the selected site ID.
func (*UIState) GetWPCLIState ¶
GetWPCLIState returns the current WP-CLI state.
func (*UIState) HealthClearFirstFire ¶
func (s *UIState) HealthClearFirstFire()
HealthClearFirstFire ends the first-fire suppression window. Called once after the first snapshot finishes. Subsequent toasts behave normally.
func (*UIState) HealthHydrateSeen ¶
HealthHydrateSeen seeds the seen-keys set from the persisted JSON. Idempotent.
func (*UIState) HealthSeenKeys ¶
HealthSeenKeys returns a snapshot of the seen-keys set, suitable for JSON serialisation into the persistent settings table.
func (*UIState) HealthShouldToast ¶
HealthShouldToast reports whether the given finding key has been seen before in this process. The first call for any key returns true (the caller should fire a toast); subsequent calls return false.
Returns false during the first-fire window — the runner publishes the initial snapshot but the UI suppresses toasts so a fresh install isn't flooded.
func (*UIState) HealthSnapshot ¶
HealthSnapshot returns the most recently stored snapshot. Never nil because NewUIState publishes an empty snapshot at construction time.
func (*UIState) HookAllDone ¶
HookAllDone records the run summary.
func (*UIState) HookSnapshot ¶
func (s *UIState) HookSnapshot(siteID string) HookSnapshot
HookSnapshot returns a copy of the per-site hook output for safe reading from a Layout pass.
func (*UIState) HookTaskDone ¶
HookTaskDone records the result and clears the running marker.
func (*UIState) HookTaskOutput ¶
HookTaskOutput appends a line to the site's output ring.
func (*UIState) HookTaskStarted ¶
HookTaskStarted clears any prior summary and records that h is running.
func (*UIState) Invalidate ¶
func (s *UIState) Invalidate()
Invalidate triggers a redraw from any goroutine safely.
func (*UIState) IsCloneLoading ¶
func (*UIState) IsExportLoading ¶
IsExportLoading returns whether an export is in progress.
func (*UIState) IsShowNewSiteModal ¶
IsShowNewSiteModal returns whether the new site modal is visible.
func (*UIState) IsSiteToggling ¶
IsSiteToggling returns whether a site is currently starting or stopping.
func (*UIState) LifecyclePlanDone ¶
LifecyclePlanDone records the final Result.
func (*UIState) LifecyclePullProgress ¶
func (s *UIState) LifecyclePullProgress(siteID string, p docker.PullProgress)
LifecyclePullProgress records the latest pull progress for an image. Per-image: aggregated across layers by the engine before it reaches us.
func (*UIState) LifecycleSnapshot ¶
func (s *UIState) LifecycleSnapshot(siteID string) LifecycleSnapshot
LifecycleSnapshot returns a frame-stable copy of the lifecycle state.
func (*UIState) LifecycleStepDone ¶
func (s *UIState) LifecycleStepDone(siteID string, step orch.StepResult)
LifecycleStepDone updates the recorded step (matched by name) with the final outcome.
func (*UIState) LifecycleStepStarted ¶
func (s *UIState) LifecycleStepStarted(siteID string, step orch.StepResult)
LifecycleStepStarted records an in-flight step. Earlier completed steps are preserved so the GUI shows the full trail.
func (*UIState) NavCollapsed ¶
NavCollapsed reports whether the nav rail is in icon-only collapsed mode.
func (*UIState) NoticeSnapshot ¶
func (s *UIState) NoticeSnapshot() NoticeSnapshot
NoticeSnapshot returns the current banner state as a frame-stable copy.
func (*UIState) ResetLifecycleProgress ¶
ResetLifecycleProgress clears the cached Plan progress for a site, in preparation for a fresh lifecycle method run.
func (*UIState) SelectedSite ¶
SelectedSite returns the currently selected site, or nil.
func (*UIState) ServicesHealthSnapshot ¶
func (s *UIState) ServicesHealthSnapshot() ServicesHealth
ServicesHealthSnapshot returns the current global-services health.
func (*UIState) SetActivityFull ¶
func (s *UIState) SetActivityFull(siteID string, evs []storage.ActivityEvent)
SetActivityFull replaces the full-rows cache for siteID and marks the full cache as loaded. Mirrors SetActivityRecent's copy semantics.
If evs is longer than ActivityFullMax, only the newest N are kept.
func (*UIState) SetActivityRecent ¶
func (s *UIState) SetActivityRecent(siteID string, evs []storage.ActivityEvent)
SetActivityRecent replaces the recent-rows cache for siteID. Caller is responsible for fetching newest-first; this method does not re-sort.
The slice is copied (not retained) so the caller can recycle the input. If evs is longer than ActivityRecentMax, only the first N entries are kept — the recent panel never renders more than that.
func (*UIState) SetCloneLoading ¶
func (*UIState) SetDeletePurgeVolume ¶
SetDeletePurgeVolume toggles the "also delete database volume" choice in the delete-confirm modal.
func (*UIState) SetDiskFreeBytes ¶
SetDiskFreeBytes stores the most recent host-filesystem free-byte reading for the top status bar. The runner publishes this via the disk-low check; main.go pulls it out and pushes here on the same cadence the services- health bar polls so the UI updates feel synchronous to the user.
func (*UIState) SetExportLoading ¶
SetExportLoading sets the export loading state.
func (*UIState) SetHealthSnapshot ¶
SetHealthSnapshot publishes a new snapshot from the runner. Lock-free (atomic.Pointer). Triggers a window invalidation so the Layout pass picks up the new content on the next frame.
Toast bookkeeping is delegated to the caller, which knows when first-fire suppression should apply (see UIState.HealthShouldToast).
func (*UIState) SetInitDone ¶
func (s *UIState) SetInitDone()
SetInitDone marks initialization as complete.
func (*UIState) SetInitError ¶
SetInitError records an initialization failure.
func (*UIState) SetLinkCheckLoading ¶
func (*UIState) SetLinkCheckOutput ¶
func (*UIState) SetLogLoading ¶
SetLogLoading sets the log viewer loading state.
func (*UIState) SetLogOutput ¶
SetLogOutput updates the log viewer content.
func (*UIState) SetNavCollapsed ¶
SetNavCollapsed toggles the rail's collapsed state.
func (*UIState) SetNavView ¶
SetNavView switches the active root view. Triggers a redraw so the chrome can swap columns 2 and 3 immediately.
func (*UIState) SetNotice ¶
SetNotice sets a persistent informational banner with no action button (or clears it with ""). Used for non-fatal status like "HTTPS will be untrusted". Always clears any prior action callback.
func (*UIState) SetNoticeBusy ¶
SetNoticeBusy gates the banner action button while a triggered task is in flight, swapping the label for an in-progress hint.
func (*UIState) SetNoticeWithAction ¶
SetNoticeWithAction sets a persistent banner with an action button. The callback fires when the user clicks the button; it should kick off any long-running work in its own goroutine and call SetNoticeBusy to gate double-clicks.
func (*UIState) SetRetryInit ¶
func (s *UIState) SetRetryInit(fn func())
SetRetryInit sets the retry callback.
func (*UIState) SetSearchTerm ¶
SetSearchTerm updates the sidebar search filter.
func (*UIState) SetSelectedID ¶
SetSelectedID sets the selected site ID.
func (*UIState) SetServicesHealth ¶
func (s *UIState) SetServicesHealth(h ServicesHealth)
SetServicesHealth replaces the rolled-up global-services health snapshot shown in the top status bar.
func (*UIState) SetShowNewSiteModal ¶
SetShowNewSiteModal controls visibility of the new site modal.
func (*UIState) SetSiteToggling ¶
SetSiteToggling sets the loading state for a site's start/stop operation.
func (*UIState) SetWPCLILoading ¶
SetWPCLILoading sets the WP-CLI loading state.
func (*UIState) SetWPCLIOutput ¶
SetWPCLIOutput updates the WP-CLI output content.
func (*UIState) ShowCloneModal ¶
func (*UIState) ShowDeleteConfirm ¶
ShowDeleteConfirm opens the delete confirmation modal for a site.
func (*UIState) TriggerNoticeAction ¶
TriggerNoticeAction atomically claims the busy slot and invokes the banner's action callback. Returns true if an action was started, false when no callback is registered or one is already in flight. The action is responsible for clearing the busy state when it completes.
func (*UIState) UpdateSite ¶
UpdateSite replaces a single site in the list by ID.
type VersionEditor ¶
type VersionEditor struct {
// contains filtered or unexported fields
}
VersionEditor shows read-only version info when a site is running, and editable dropdowns when it is stopped. The DB row understands both the engine kind and the version so users can switch between MySQL and MariaDB; engine swaps and unsafe version transitions route through the migrate-via-snapshot flow rather than landing in-place.
func NewVersionEditor ¶
func NewVersionEditor(state *UIState, sm *sites.SiteManager, toasts *Notifications) *VersionEditor
func (*VersionEditor) HandleUserInteractions ¶
func (ve *VersionEditor) HandleUserInteractions(gtx layout.Context, site *types.Site)
HandleUserInteractions processes the Save button click on the version editor. Only meaningful when the site is stopped; no-op otherwise.
func (*VersionEditor) Layout ¶
func (ve *VersionEditor) Layout(gtx layout.Context, th *Theme, site *types.Site) layout.Dimensions
type WPCLIPanel ¶
type WPCLIPanel struct {
// contains filtered or unexported fields
}
WPCLIPanel renders the WP-CLI command input and output panel.
func NewWPCLIPanel ¶
func NewWPCLIPanel(state *UIState, sm *sites.SiteManager) *WPCLIPanel
func (*WPCLIPanel) HandleUserInteractions ¶
func (wp *WPCLIPanel) HandleUserInteractions(gtx layout.Context, siteID string)
HandleUserInteractions processes the Run button click.
func (*WPCLIPanel) Layout ¶
func (wp *WPCLIPanel) Layout(gtx layout.Context, th *Theme, siteID string) layout.Dimensions
Source Files
¶
- activitytab.go
- avatar.go
- clonemodal.go
- dbcredentials.go
- fonts.go
- healthpanel.go
- hookeditor.go
- hookoutput.go
- hookspanel.go
- icons.go
- linkchecker.go
- logo.go
- logviewer.go
- modal.go
- modalkeys.go
- navrail.go
- newsite.go
- notifications.go
- panels.go
- profilingpanel.go
- settingspanel.go
- sitedetail.go
- sitespanel.go
- snapshotspanel.go
- state.go
- status.go
- textinput.go
- theme.go
- theme_detect.go
- timefmt.go
- ui.go
- versioneditor.go
- widgets.go
- wpcli.go