feat(console): render standalone terminal fullscreen

This commit is contained in:
2026-06-20 17:38:48 -05:00
parent de4f1485b1
commit 96439b43e2
3 changed files with 156 additions and 18 deletions

View File

@@ -0,0 +1,5 @@
{{define "shell"}}
<main class="console-fullscreen-shell">
{{template "content" .}}
</main>
{{end}}

View File

@@ -34,13 +34,17 @@ type ViewData struct {
func NewRenderer() (*Renderer, error) {
functions := template.FuncMap{
"icon": icon,
"contains": strings.Contains,
"distroIconClass": distroIconClass,
"uptime": formatUptime,
"safeHTML": func(value string) template.HTML { return template.HTML(value) },
"nowYear": func() int { return time.Now().Year() },
"lower": strings.ToLower,
"icon": icon,
"contains": strings.Contains,
"distroIconClass": distroIconClass,
"nodeIconClass": nodeIconClass,
"nodeIconPending": nodeIconPending,
"packageManagerIconClass": packageManagerIconClass,
"packageManagerLabel": packageManagerLabel,
"uptime": formatUptime,
"safeHTML": func(value string) template.HTML { return template.HTML(value) },
"nowYear": func() int { return time.Now().Year() },
"lower": strings.ToLower,
"splitLines": func(value string) []string {
var lines []string
for _, line := range strings.Split(value, "\n") {
@@ -68,6 +72,8 @@ func (r *Renderer) Render(w http.ResponseWriter, name string, data ViewData) {
layout := "layouts/app.gohtml"
if data.Shell == "auth" {
layout = "layouts/auth.gohtml"
} else if data.Shell == "console" {
layout = "layouts/console.gohtml"
}
parsed, err := template.New("base").Funcs(r.functions).ParseFS(
@@ -137,6 +143,57 @@ func distroIconClass(distro string) string {
}
}
func nodeIconClass(distro, packageManager string) string {
if className := distroIconClass(distro); className != "ti ti-server-2" {
return className
}
switch strings.ToLower(strings.TrimSpace(packageManager)) {
case "apt":
return "fa-brands fa-debian"
case "pacman":
return "ti ti-brand-archlinux"
default:
return "ti ti-server-2"
}
}
func nodeIconPending(distro, packageManager string) bool {
distroValue := strings.ToLower(strings.TrimSpace(distro))
packageValue := strings.ToLower(strings.TrimSpace(packageManager))
return packageValue == "" && (distroValue == "" || distroValue == "linux")
}
func packageManagerIconClass(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "apt":
return "fa-brands fa-debian"
case "pacman":
return "ti ti-brand-archlinux"
case "dnf", "yum", "zypper", "apk", "nix", "emerge":
return "ti ti-package"
default:
return "ti ti-package"
}
}
func packageManagerLabel(value string) string {
trimmed := strings.TrimSpace(value)
if trimmed == "" {
return "Unknown"
}
switch strings.ToLower(trimmed) {
case "apt":
return "APT"
case "dnf":
return "DNF"
case "yum":
return "YUM"
default:
return strings.ToUpper(trimmed[:1]) + strings.ToLower(trimmed[1:])
}
}
func icon(name string) template.HTML {
icons := map[string]string{
"dashboard": `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 13h7V4H4zm9 7h7v-9h-7zM4 20h7v-5H4zm9-9h7V4h-7z"/></svg>`,