91 lines
2.0 KiB
Go
91 lines
2.0 KiB
Go
package panel
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
//go:embed templates static
|
|
var embeddedFS embed.FS
|
|
|
|
var templateFuncs = template.FuncMap{
|
|
"percent": func(count, max int) int {
|
|
if max <= 0 {
|
|
return 0
|
|
}
|
|
v := count * 100 / max
|
|
if v > 100 {
|
|
return 100
|
|
}
|
|
return v
|
|
},
|
|
"fmtMin": func(m int) string {
|
|
if m <= 0 {
|
|
return "—"
|
|
}
|
|
if m < 60 {
|
|
return fmt.Sprintf("%dm", m)
|
|
}
|
|
return fmt.Sprintf("%dh%dm", m/60, m%60)
|
|
},
|
|
"add": func(a, b int) int { return a + b },
|
|
// dict builds a map[string]any for passing multiple values to a sub-template.
|
|
"dict": func(pairs ...any) map[string]any {
|
|
m := make(map[string]any, len(pairs)/2)
|
|
for i := 0; i+1 < len(pairs); i += 2 {
|
|
k, _ := pairs[i].(string)
|
|
m[k] = pairs[i+1]
|
|
}
|
|
return m
|
|
},
|
|
"buttonClass": func(color string) string {
|
|
switch color {
|
|
case "secondary":
|
|
return "bg-gray-600"
|
|
case "success":
|
|
return "bg-green-600"
|
|
case "danger":
|
|
return "bg-red-600"
|
|
default:
|
|
return "bg-indigo-600"
|
|
}
|
|
},
|
|
"not": func(v bool) bool { return !v },
|
|
}
|
|
|
|
// StaticFS returns the file system to use for /static/* routes.
|
|
// In dev mode (PANEL_DEV=true), serves from disk for hot reload.
|
|
func StaticFS() http.FileSystem {
|
|
if os.Getenv("PANEL_DEV") == "true" {
|
|
return http.Dir("internal/panel/static")
|
|
}
|
|
sub, _ := fs.Sub(embeddedFS, "static")
|
|
return http.FS(sub)
|
|
}
|
|
|
|
// ParseTemplates parses a set of template files by name with global template functions.
|
|
// In dev mode templates are loaded from disk on every call (hot reload).
|
|
func ParseTemplates(names ...string) (*template.Template, error) {
|
|
var paths []string
|
|
for _, n := range names {
|
|
paths = append(paths, "templates/"+n)
|
|
}
|
|
base := template.New("").Funcs(templateFuncs)
|
|
if os.Getenv("PANEL_DEV") == "true" {
|
|
return base.ParseFiles(prependDir("internal/panel/", paths)...)
|
|
}
|
|
return base.ParseFS(embeddedFS, paths...)
|
|
}
|
|
|
|
func prependDir(dir string, paths []string) []string {
|
|
out := make([]string, len(paths))
|
|
for i, p := range paths {
|
|
out[i] = dir + p
|
|
}
|
|
return out
|
|
}
|