From 2838fbb254ae36aa5b7a9a669a1f89a94df5d88e Mon Sep 17 00:00:00 2001 From: Alex Rakoczy Date: Tue, 14 Jun 2022 19:14:51 -0400 Subject: [PATCH] internal/relui: simplify rendering of homepage This refactors the homepage rendering to use a nested template for each task row. This will help simplify the template as we add more complex layout to the outputs of workflows and tasks. Updates golang/go#51797 Updates golang/go#40279 For golang/go#53382 Change-Id: I85a86b82bdc79c7fb4e837d884af922c7028295d Reviewed-on: https://go-review.googlesource.com/c/build/+/412176 Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov TryBot-Result: Gopher Robot Run-TryBot: Alex Rakoczy --- internal/relui/templates/home.html | 92 ++------------------- internal/relui/templates/layout.html | 4 +- internal/relui/templates/new_workflow.html | 2 + internal/relui/templates/task_list.html | 94 ++++++++++++++++++++++ internal/relui/web.go | 59 +++++++++----- 5 files changed, 145 insertions(+), 106 deletions(-) create mode 100644 internal/relui/templates/task_list.html diff --git a/internal/relui/templates/home.html b/internal/relui/templates/home.html index d5534f1ab..e160560a4 100644 --- a/internal/relui/templates/home.html +++ b/internal/relui/templates/home.html @@ -3,6 +3,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> +{{template "layout" .}} + {{define "content"}}
@@ -10,7 +12,9 @@

Workflows

New
    - {{range $workflow := .Workflows}} + {{range $wfid := .WorkflowIDs}} + {{$detail := index $.WorkflowDetails $wfid}} + {{$workflow := $detail.Workflow}}
  • {{$workflow.Name.String}} @@ -19,8 +23,8 @@

    {{if not (or $workflow.Finished $workflow.Error)}}
    -
    - + +
    @@ -60,87 +64,7 @@

    Tasks

    - - - - - - - - - - - - - {{$tasks := index $.WorkflowTasks $workflow.ID}} - {{range $task := $tasks}} - - - - - - - - - - - - - - - {{end}} -
    StateNameStartedUpdatedResultActions
    - - unfold more - - - unfold less - - - {{if $task.Error.Valid}} - error - {{else if $task.Finished}} - finished - {{else}} - pending - {{end}} - - {{$task.Name}} - - {{$task.CreatedAt.UTC.Format "Mon Jan _2 2006 15:04:05"}} - - {{$task.UpdatedAt.UTC.Format "Mon Jan _2 2006 15:04:05"}} - - {{$task.Result.String}} - - {{if $task.Error.Valid}} -
    -
    - - -
    -
    - {{end}} - {{if and (not $task.Finished) (hasPrefix $task.Name "APPROVE-")}} -
    -
    - - -
    -
    - {{end}} -
    - {{if $task.Error.Valid}} -
    - {{- $task.Error.Value -}} -
    - {{end}} - {{range $log := $.Logs $workflow.ID $task.Name}} -
    - {{- $log.CreatedAt.UTC.Format "2006/01/02 15:04:05"}} {{$log.Body -}} -
    - {{end}} -
    + {{template "task_list" $detail}}
  • {{end}}
diff --git a/internal/relui/templates/layout.html b/internal/relui/templates/layout.html index 9cc777ebb..a8be183ca 100644 --- a/internal/relui/templates/layout.html +++ b/internal/relui/templates/layout.html @@ -3,6 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> +{{define "layout"}} {{.SiteHeader.Title}} @@ -16,7 +17,8 @@

{{.SiteHeader.Title}}

- {{template "content" .}} + {{block "content" .}}{{end}}
+{{end}} diff --git a/internal/relui/templates/new_workflow.html b/internal/relui/templates/new_workflow.html index 4810a8f2b..c0a0a447a 100644 --- a/internal/relui/templates/new_workflow.html +++ b/internal/relui/templates/new_workflow.html @@ -3,6 +3,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> +{{template "layout" .}} + {{define "content"}}

New Go Release

diff --git a/internal/relui/templates/task_list.html b/internal/relui/templates/task_list.html new file mode 100644 index 000000000..428fa36b5 --- /dev/null +++ b/internal/relui/templates/task_list.html @@ -0,0 +1,94 @@ + +{{define "task_list"}} + {{$workflow := .Workflow}} + + + + + + + + + + + + + {{range $task := .Tasks}} + + + + + + + + + + + + + + + {{end}} +
StateNameStartedUpdatedResultActions
+ + unfold more + + + unfold less + + + {{if $task.Error.Valid}} + error + {{else if $task.Finished}} + finished + {{else}} + pending + {{end}} + + {{$task.Name}} + + {{$task.CreatedAt.UTC.Format "Mon Jan _2 2006 15:04:05"}} + + {{$task.UpdatedAt.UTC.Format "Mon Jan _2 2006 15:04:05"}} + + {{$task.Result.String}} + + {{if $task.Error.Valid}} +
+
+ + +
+
+ {{end}} + {{if and (not $task.Finished) (hasPrefix $task.Name "APPROVE-")}} +
+
+ + +
+
+ {{end}} +
+ {{if $task.Error.Valid}} +
+ {{- $task.Error.Value -}} +
+ {{end}} + {{range $log := index $.TaskLogs $task.Name}} +
+ {{- $log.CreatedAt.UTC.Format "2006/01/02 15:04:05"}} {{$log.Body -}} +
+ {{end}} +
+{{end}} diff --git a/internal/relui/web.go b/internal/relui/web.go index c6acad40a..8c765c1a6 100644 --- a/internal/relui/web.go +++ b/internal/relui/web.go @@ -59,6 +59,7 @@ type Server struct { // mux used if baseURL is set bm *http.ServeMux + templates *template.Template homeTmpl *template.Template newWorkflowTmpl *template.Template } @@ -79,9 +80,9 @@ func NewServer(p *pgxpool.Pool, w *Worker, baseURL *url.URL, header SiteHeader) "baseLink": s.BaseLink, "hasPrefix": strings.HasPrefix, } - layout := template.Must(template.New("layout.html").Funcs(helpers).ParseFS(templates, "templates/layout.html")) - s.homeTmpl = template.Must(template.Must(layout.Clone()).Funcs(helpers).ParseFS(templates, "templates/home.html")) - s.newWorkflowTmpl = template.Must(template.Must(layout.Clone()).Funcs(helpers).ParseFS(templates, "templates/new_workflow.html")) + s.templates = template.Must(template.New("").Funcs(helpers).ParseFS(templates, "templates/*.html")) + s.homeTmpl = s.mustLookup("home.html") + s.newWorkflowTmpl = s.mustLookup("new_workflow.html") s.m.POST("/workflows/:id/stop", s.stopWorkflowHandler) s.m.POST("/workflows/:id/tasks/:name/retry", s.retryTaskHandler) s.m.POST("/workflows/:id/tasks/:name/approve", s.approveTaskHandler) @@ -98,6 +99,14 @@ func NewServer(p *pgxpool.Pool, w *Worker, baseURL *url.URL, header SiteHeader) return s } +func (s *Server) mustLookup(name string) *template.Template { + t := template.Must(template.Must(s.templates.Clone()).ParseFS(templates, path.Join("templates", name))).Lookup(name) + if t == nil { + panic(fmt.Errorf("template %q not found", name)) + } + return t +} + func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { if s.bm != nil { s.bm.ServeHTTP(w, r) @@ -124,19 +133,18 @@ func (s *Server) BaseLink(target string) string { return u.String() } -type homeResponse struct { - SiteHeader SiteHeader - Workflows []db.Workflow - WorkflowTasks map[uuid.UUID][]db.Task - TaskLogs map[uuid.UUID]map[string][]db.TaskLog +type workflowDetail struct { + Workflow db.Workflow + Tasks []db.Task + // TaskLogs is a map of all logs for a db.Task, keyed on + // (db.Task).Name + TaskLogs map[string][]db.TaskLog } -func (h *homeResponse) Logs(workflow uuid.UUID, task string) []db.TaskLog { - t := h.TaskLogs[workflow] - if t == nil { - return nil - } - return t[task] +type homeResponse struct { + SiteHeader SiteHeader + WorkflowIDs []uuid.UUID + WorkflowDetails map[uuid.UUID]*workflowDetail } func (h *homeResponse) WorkflowParams(wf db.Workflow) map[string]string { @@ -172,22 +180,31 @@ func (s *Server) buildHomeResponse(ctx context.Context) (*homeResponse, error) { if err != nil { return nil, err } - wfTasks := make(map[uuid.UUID][]db.Task, len(ws)) + hr := &homeResponse{ + SiteHeader: s.header, + WorkflowDetails: make(map[uuid.UUID]*workflowDetail), + } + for _, w := range ws { + hr.WorkflowIDs = append(hr.WorkflowIDs, w.ID) + hr.WorkflowDetails[w.ID] = &workflowDetail{Workflow: w} + } for _, t := range tasks { - wfTasks[t.WorkflowID] = append(wfTasks[t.WorkflowID], t) + wd := hr.WorkflowDetails[t.WorkflowID] + wd.Tasks = append(hr.WorkflowDetails[t.WorkflowID].Tasks, t) + wd.TaskLogs = make(map[string][]db.TaskLog) } tlogs, err := q.TaskLogs(ctx) if err != nil { return nil, err } - wftlogs := make(map[uuid.UUID]map[string][]db.TaskLog) for _, l := range tlogs { - if wftlogs[l.WorkflowID] == nil { - wftlogs[l.WorkflowID] = make(map[string][]db.TaskLog) + wd := hr.WorkflowDetails[l.WorkflowID] + if wd.TaskLogs == nil { + wd.TaskLogs = make(map[string][]db.TaskLog) } - wftlogs[l.WorkflowID][l.TaskName] = append(wftlogs[l.WorkflowID][l.TaskName], l) + wd.TaskLogs[l.TaskName] = append(wd.TaskLogs[l.TaskName], l) } - return &homeResponse{SiteHeader: s.header, Workflows: ws, WorkflowTasks: wfTasks, TaskLogs: wftlogs}, nil + return hr, nil } type newWorkflowResponse struct {