110 lines
2.5 KiB
Go
110 lines
2.5 KiB
Go
package api
|
|
|
|
import (
|
|
"embed"
|
|
"html/template"
|
|
"net/http"
|
|
"time"
|
|
|
|
"reanimator/internal/domain"
|
|
"reanimator/internal/repository/registry"
|
|
"reanimator/internal/repository/tickets"
|
|
"reanimator/internal/repository/timeline"
|
|
)
|
|
|
|
//go:embed ui_assets.tmpl
|
|
var uiTemplates embed.FS
|
|
|
|
var assetTemplate = template.Must(template.New("asset").Funcs(template.FuncMap{
|
|
"formatTime": func(t time.Time) string {
|
|
return t.UTC().Format("2006-01-02 15:04:05 UTC")
|
|
},
|
|
"formatTimePtr": func(t *time.Time) string {
|
|
if t == nil {
|
|
return "—"
|
|
}
|
|
return t.UTC().Format("2006-01-02 15:04:05 UTC")
|
|
},
|
|
}).ParseFS(uiTemplates, "ui_assets.tmpl"))
|
|
|
|
type UIDependencies struct {
|
|
Assets *registry.AssetRepository
|
|
Installations *registry.InstallationRepository
|
|
Timeline *timeline.EventRepository
|
|
Tickets *tickets.TicketRepository
|
|
}
|
|
|
|
type uiHandlers struct {
|
|
deps UIDependencies
|
|
}
|
|
|
|
func RegisterUIRoutes(mux *http.ServeMux, deps UIDependencies) {
|
|
h := uiHandlers{deps: deps}
|
|
mux.HandleFunc("/ui/assets/", h.handleAssetPage)
|
|
}
|
|
|
|
type assetPageData struct {
|
|
Asset domain.Asset
|
|
Components []domain.Component
|
|
Events []domain.TimelineEvent
|
|
Tickets []domain.Ticket
|
|
}
|
|
|
|
func (h uiHandlers) handleAssetPage(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
id, ok := parseID(r.URL.Path, "/ui/assets/")
|
|
if !ok {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
asset, err := h.deps.Assets.Get(r.Context(), id)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
components := []domain.Component{}
|
|
if h.deps.Installations != nil {
|
|
components, err = h.deps.Installations.ListCurrentComponentsByAsset(r.Context(), id)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
events := []domain.TimelineEvent{}
|
|
if h.deps.Timeline != nil {
|
|
items, _, err := h.deps.Timeline.List(r.Context(), "asset", id, 100, nil)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
events = items
|
|
}
|
|
|
|
tickets := []domain.Ticket{}
|
|
if h.deps.Tickets != nil {
|
|
items, err := h.deps.Tickets.ListByAsset(r.Context(), id)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
tickets = items
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
if err := assetTemplate.Execute(w, assetPageData{
|
|
Asset: asset,
|
|
Components: components,
|
|
Events: events,
|
|
Tickets: tickets,
|
|
}); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|