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 }}