P2R-02 slice 1: host-detail sub-tab skeleton
Extract header/vitals/sub-tabs into a host_chrome partial that every host-detail tab page renders. Sources / Schedules / Repo go from inert divs to real <a> links backed by stub pages that share the chrome and a 'coming next' body — slices 2/3/4 fill them in. Also re-establishes the version indicator (host_schedule_version vs agent's applied_schedule_version) in the header. Drops the legacy fat-schedule list/edit templates that referenced fields removed by the P2 redesign (Manual / Paths / RetentionPolicy on Schedule); the new templates land in slice 3.
This commit is contained in:
@@ -1,38 +1,83 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
stdhttp "net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"gitea.dcglab.co.uk/steve/restic-manager/internal/store"
|
||||
)
|
||||
|
||||
// ui_schedules.go — HTML form-driven schedule CRUD.
|
||||
//
|
||||
// Stubbed during the P2 redesign template rewrite. Phase 4 of the
|
||||
// redesign rebuilds the schedule editor against the new slim shape
|
||||
// (cron + source-group multi-select + enabled), the source-group
|
||||
// list/edit pages, and the repo-maintenance tab. Until then these
|
||||
// routes return 501; the dashboard's host-row "View →" link is the
|
||||
// only operator entry point that still works.
|
||||
// ui_schedules.go — HTML form-driven schedule CRUD against the slim
|
||||
// shape (cron + source-group multi-select + enabled). The list view
|
||||
// is live as of slice 1 of P2R-02; the new/edit/delete/run handlers
|
||||
// land in slice 3.
|
||||
|
||||
// hostSchedulesPage is the data the schedules-tab template renders.
|
||||
type hostSchedulesPage struct {
|
||||
hostChromeData
|
||||
}
|
||||
|
||||
func (s *Server) handleUISchedulesList(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
u := s.requireUIUser(w, r)
|
||||
if u == nil {
|
||||
return
|
||||
}
|
||||
host, ok := s.loadHostForUI(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
view := s.baseView(u, "dashboard")
|
||||
view.Title = host.Name + " schedules · restic-manager"
|
||||
view.Page = hostSchedulesPage{
|
||||
hostChromeData: s.loadHostChrome(r, *host, "schedules", "schedules"),
|
||||
}
|
||||
if err := s.deps.UI.Render(w, "host_schedules", view); err != nil {
|
||||
slog.Error("ui: render host_schedules", "err", err)
|
||||
stdhttp.Error(w, "internal", stdhttp.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleUIScheduleNewGet(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
stdhttp.Error(w, "schedule editor lands in P2R-02 slice 3", stdhttp.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (s *Server) handleUIScheduleEditGet(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
stdhttp.Error(w, "schedule editor lands in P2R-02 slice 3", stdhttp.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (s *Server) handleUIScheduleSave(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
stdhttp.Error(w, "schedule editor lands in P2R-02 slice 3", stdhttp.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (s *Server) handleUIScheduleDelete(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
stdhttp.Error(w, "schedule editor lands in P2R-02 slice 3", stdhttp.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (s *Server) handleUIScheduleRun(w stdhttp.ResponseWriter, r *stdhttp.Request) {
|
||||
stdhttp.Error(w, "schedules UI is being rebuilt — see P2 redesign Phase 4", stdhttp.StatusNotImplemented)
|
||||
stdhttp.Error(w, "schedule editor lands in P2R-02 slice 3", stdhttp.StatusNotImplemented)
|
||||
}
|
||||
|
||||
// loadHostForUI is a small helper shared across the host-detail tab
|
||||
// handlers — fetches the host by URL param, writing the appropriate
|
||||
// 404/500 + returning ok=false on failure.
|
||||
func (s *Server) loadHostForUI(w stdhttp.ResponseWriter, r *stdhttp.Request) (*store.Host, bool) {
|
||||
hostID := chi.URLParam(r, "id")
|
||||
if hostID == "" {
|
||||
stdhttp.NotFound(w, r)
|
||||
return nil, false
|
||||
}
|
||||
host, err := s.deps.Store.GetHost(r.Context(), hostID)
|
||||
if err != nil {
|
||||
if errors.Is(err, store.ErrNotFound) {
|
||||
stdhttp.NotFound(w, r)
|
||||
return nil, false
|
||||
}
|
||||
slog.Error("ui host tab: get host", "host_id", hostID, "err", err)
|
||||
stdhttp.Error(w, "internal", stdhttp.StatusInternalServerError)
|
||||
return nil, false
|
||||
}
|
||||
return host, true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user