2026-05-01 01:51:06 +03:00
{{ define "admin/settings.html" }}
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > WarpBox Admin Settings< / title >
< link rel = "icon" type = "image/png" href = "/static/WarpBoxLogo.png" >
< link rel = "stylesheet" href = "/static/css/app.css" >
< link rel = "stylesheet" href = "/static/css/window.css" >
< link rel = "stylesheet" href = "/static/css/components/buttons.css" >
< link rel = "stylesheet" href = "/static/css/components/toast.css" >
< link rel = "stylesheet" href = "/static/css/admin.css" >
< link rel = "stylesheet" href = "/static/css/settings.css" >
< / head >
< body >
< div class = "admin-shell" >
< div class = "admin-frame" >
{{ template "admin/header.html" . }}
< div class = "win98-window admin-workspace-window" role = "main" >
< div class = "win98-titlebar" >
< div class = "win98-titlebar-label" >
< img class = "win98-titlebar-icon" src = "/static/WarpBoxLogo.png" alt = "" aria-hidden = "true" >
< h1 > WarpBox Settings< / h1 >
< / div >
< div class = "win98-window-controls" aria-hidden = "true" >
< button class = "win98-control" type = "button" > _< / button >
< button class = "win98-control" type = "button" > □< / button >
< button class = "win98-control" type = "button" > x< / button >
< / div >
< / div >
< nav class = "menu-bar" aria-label = "Settings toolbar" >
< div class = "menu-item" >
< button class = "menu-button" type = "button" aria-expanded = "false" > File< / button >
< div class = "menu-popup" >
< button class = "menu-action" type = "button" data-command = "save" > < span > S< / span > < span > Save overrides< / span > < span class = "shortcut" > Ctrl+S< / span > < / button >
< button class = "menu-action" type = "button" data-command = "export" > < span > E< / span > < span > Export settings JSON< / span > < span > < / span > < / button >
< button class = "menu-action" type = "button" data-command = "import" > < span > I< / span > < span > Import settings JSON< / span > < span > < / span > < / button >
< div class = "menu-separator" > < / div >
< button class = "menu-action" type = "button" data-command = "discard" > < span > D< / span > < span > Discard unsaved changes< / span > < span > < / span > < / button >
< / div >
< / div >
< div class = "menu-item" >
< button class = "menu-button" type = "button" aria-expanded = "false" > View< / button >
< div class = "menu-popup" >
< button class = "menu-action" type = "button" data-command = "show-all" > < span > A< / span > < span > Show all settings< / span > < span > < / span > < / button >
< button class = "menu-action" type = "button" data-command = "show-changed" > < span > C< / span > < span > Show changed only< / span > < span > < / span > < / button >
< button class = "menu-action" type = "button" data-command = "show-locked" > < span > L< / span > < span > Show locked only< / span > < span > < / span > < / button >
< / div >
< / div >
< div class = "menu-item" >
< button class = "menu-button" type = "button" aria-expanded = "false" > Settings< / button >
< div class = "menu-popup" >
< button class = "menu-action" type = "button" data-command = "reset-defaults" > < span > R< / span > < span > Reset editable to defaults< / span > < span > < / span > < / button >
< button class = "menu-action" type = "button" data-command = "reload" > < span > F< / span > < span > Reload current values< / span > < span class = "shortcut" > F5< / span > < / button >
< / div >
< / div >
< div class = "menu-item" >
< button class = "menu-button" type = "button" aria-expanded = "false" > Help< / button >
< div class = "menu-popup" >
< button class = "menu-action" type = "button" data-command = "legend" > < span > ?< / span > < span > Explain sources< / span > < span > < / span > < / button >
< button class = "menu-action" type = "button" data-command = "reset-help" > < span > !< / span > < span > Reset semantics< / span > < span > < / span > < / button >
< / div >
< / div >
< / nav >
< div class = "admin-workspace-body settings-page-body" >
< section class = "settings-summary-grid" aria-label = "Settings summary" >
< article class = "settings-stat-card is-info" >
< p class = "settings-stat-label" > Visible settings< / p >
< p class = "settings-stat-value" id = "visibleCount" > {{ len .Rows }}< / p >
< p class = "settings-stat-note" > Filtered by search and category< / p >
< / article >
< article class = "settings-stat-card is-ok" >
< p class = "settings-stat-label" > Editable< / p >
< p class = "settings-stat-value" id = "editableCount" > 0< / p >
< p class = "settings-stat-note" > Runtime override supported< / p >
< / article >
< article class = "settings-stat-card is-warning" >
< p class = "settings-stat-label" > Unsaved< / p >
< p class = "settings-stat-value" id = "unsavedCount" > 0< / p >
< p class = "settings-stat-note" > Draft changes in browser< / p >
< / article >
< article class = "settings-stat-card is-danger" >
< p class = "settings-stat-label" > Locked< / p >
< p class = "settings-stat-value" id = "lockedCount" > 0< / p >
< p class = "settings-stat-note" > Environment only< / p >
< / article >
< / section >
< section class = "settings-main-grid" >
< aside class = "settings-sidebar-panel" >
< section class = "settings-panel settings-sidebar" >
< div class = "settings-panel-header" >
< div class = "settings-panel-title" > Categories < span class = "settings-panel-sub" > search and scope< / span > < / div >
< / div >
< div class = "settings-panel-body" >
< div class = "settings-search" >
< label for = "settingsSearch" > Search< / label >
< input class = "settings-input" id = "settingsSearch" type = "search" placeholder = "Search label, env var, description" >
< / div >
< ul class = "settings-category-list" id = "categoryList" >
{{ range .Categories }}
< li >
< button class = "settings-category-button{{ if eq .Key " all " } } is-active { { end } } " type = "button" data-category = "{{ .Key }}" >
< span > {{ .Icon }}< / span >
< span > {{ .Label }}< / span >
< span class = "settings-category-count" > {{ .Count }}< / span >
< / button >
< / li >
{{ end }}
< / ul >
< / div >
< / section >
< / aside >
< section class = "settings-workbench" >
< section class = "settings-hero-panel" >
< div class = "settings-hero-copy" >
< h2 > Administrative runtime settings< / h2 >
< p > Edit safe runtime overrides without hiding where each value came from. Hard storage and security-sensitive environment settings stay visible but locked.< / p >
< / div >
< div class = "settings-hero-legend" >
< div class = "settings-legend-row" > < span class = "settings-badge badge-default" > default< / span > < span > Built-in application value< / span > < / div >
< div class = "settings-legend-row" > < span class = "settings-badge badge-env" > environment< / span > < span > Loaded from env< / span > < / div >
< div class = "settings-legend-row" > < span class = "settings-badge badge-db" > db override< / span > < span > Saved from admin UI< / span > < / div >
< div class = "settings-legend-row" > < span class = "settings-badge badge-hard" > hard env< / span > < span > Visible, not editable here< / span > < / div >
< / div >
< / section >
< section class = "settings-panel" >
< div class = "settings-panel-header" >
< div class = "settings-panel-title" > Settings grid < span class = "settings-panel-sub" > edit, inspect, import, export< / span > < / div >
< div class = "settings-panel-tools" >
< span class = "settings-dirty-chip" id = "dirtyChip" > 0 unsaved< / span >
< button class = "win98-button settings-tool-button" id = "exportButton" type = "button" > Export JSON< / button >
< button class = "win98-button settings-tool-button" id = "importButton" type = "button" > Import JSON< / button >
< button class = "win98-button settings-tool-button" id = "resetButton" type = "button" > Reset Defaults< / button >
< button class = "win98-button settings-tool-button" id = "saveButton" type = "button" disabled > Save< / button >
< / div >
< / div >
< div class = "settings-panel-body" >
< div class = "settings-action-summary" id = "actionSummary" > No unsaved changes.< / div >
< div class = "settings-groups" id = "settingsGroups" >
{{ range .Categories }}
{{ if ne .Key "all" }}
< section class = "settings-group" data-category = "{{ .Key }}" >
< div class = "settings-group-title" > {{ .Label }}< / div >
< div class = "settings-table-wrap" >
< table class = "settings-table" >
< thead >
< tr >
< th > Setting< / th >
< th > Source< / th >
< th > Value< / th >
< th > Actions< / th >
< / tr >
< / thead >
< tbody >
{{ range .Rows }}
< tr class = "setting-row{{ if .Locked }} is-locked{{ end }}"
data-key="{{ .Key }}"
data-label="{{ .Label }}"
data-category="{{ .Category }}"
data-type="{{ .Type }}"
data-original="{{ .Value }}"
data-default="{{ .DefaultValue }}"
data-env-name="{{ .EnvName }}"
data-source="{{ .Source }}"
data-source-badge="{{ .SourceBadge }}"
data-description="{{ .Description }}"
data-minimum="{{ .Minimum }}">
< td >
< div class = "setting-meta" >
< strong > {{ .Label }}< / strong >
< code > {{ .EnvName }}< / code >
< / div >
< / td >
< td >
< span class = "settings-badge{{ if eq .SourceBadge " default " } } badge-default { { else if eq . SourceBadge " environment " } } badge-env { { else if eq . SourceBadge " db override " } } badge-db { { else } } badge-hard { { end } } " data-role = "source-badge" > {{ .SourceBadge }}< / span >
< / td >
< td >
< div class = "setting-control" >
{{ if eq .Type "bool" }}
< select class = "settings-select setting-input" { { if . Locked } } disabled { { end } } >
< option value = "true" { { if eq . Value " true " } } selected { { end } } > true< / option >
< option value = "false" { { if eq . Value " false " } } selected { { end } } > false< / option >
< / select >
{{ else }}
2026-05-01 02:14:05 +03:00
< div class = "setting-input-row" >
< input class = "settings-input setting-input" type = "text" value = "{{ .Value }}" { { if . Locked } } disabled { { end } } >
{{ if eq .Type "size_gb" }}< span class = "settings-badge badge-default" > GB< / span > {{ end }}
< / div >
2026-05-01 01:51:06 +03:00
{{ end }}
2026-05-01 02:14:05 +03:00
< div class = "setting-hint" data-role = "hint" > {{ if .Locked }}Locked by environment or hard runtime implication.{{ else if eq .Type "size_gb" }}Use GB values. Decimals allowed, for example `0.5`.{{ else if .DefaultValue }}Default: {{ .DefaultValue }}{{ end }}< / div >
2026-05-01 01:51:06 +03:00
< / div >
< / td >
< td class = "setting-actions" >
< button class = "win98-button settings-mini-button row-reset" type = "button" { { if . Locked } } disabled { { end } } > Reset< / button >
< button class = "win98-button settings-mini-button row-info" type = "button" > Info< / button >
< / td >
< / tr >
{{ end }}
< / tbody >
< / table >
< / div >
< / section >
{{ end }}
{{ end }}
< / div >
< / div >
< / section >
< / section >
< / section >
< / div >
< footer class = "status-bar admin-dashboard-statusbar" >
< span id = "statusLeft" > No unsaved changes< / span >
< span id = "statusMiddle" > category: all< / span >
< span id = "statusRight" > admin only< / span >
< / footer >
< / div >
< / div >
< / div >
< div id = "modal-backdrop" class = "settings-modal-backdrop" > < / div >
< div id = "doc-popup" class = "settings-popup" role = "dialog" aria-modal = "true" aria-labelledby = "doc-popup-title" >
< div class = "settings-popup-titlebar" >
< strong id = "doc-popup-title" > Details< / strong >
< button class = "win98-button settings-popup-close" id = "doc-popup-close" type = "button" > Close< / button >
< / div >
< div class = "settings-popup-body" id = "doc-popup-body" > < / div >
< / div >
< input id = "settingsImportInput" type = "file" accept = "application/json,.json" hidden >
< div id = "toast" class = "wb-toast" role = "status" aria-live = "polite" > < / div >
< script id = "settings-rows" type = "application/json" > { { toJSON . RowsJSON } } < / script >
< script src = "/static/js/warpbox-ui.js" > < / script >
< script src = "/static/js/admin/settings.js" > < / script >
< / body >
< / html >
{{ end }}