Monorepo for Tangled tangled.org

appview: add page for single workflow

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li 798f1a3a 372731c8

verified
Changed files
+116
appview
pages
templates
repo
pipelines
pipelines
+13
appview/pages/pages.go
··· 963 963 return p.executeRepo("repo/pipelines/pipelines", w, params) 964 964 } 965 965 966 + type WorkflowParams struct { 967 + LoggedInUser *oauth.User 968 + RepoInfo repoinfo.RepoInfo 969 + Pipeline db.Pipeline 970 + Workflow string 971 + Active string 972 + } 973 + 974 + func (p *Pages) Workflow(w io.Writer, params WorkflowParams) error { 975 + params.Active = "pipelines" 976 + return p.executeRepo("repo/pipelines/workflow", w, params) 977 + } 978 + 966 979 func (p *Pages) Static() http.Handler { 967 980 if p.dev { 968 981 return http.StripPrefix("/static/", http.FileServer(http.Dir("appview/pages/static")))
+52
appview/pages/templates/repo/pipelines/workflow.html
··· 1 + {{ define "title" }} {{ .Workflow }} &middot; pipeline {{ .Pipeline.Id }} &middot; {{ .RepoInfo.FullName }}{{ end }} 2 + 3 + {{ define "extrameta" }} 4 + {{ $title := "pipelines"}} 5 + {{ $url := printf "https://tangled.sh/%s/pipelines" .RepoInfo.FullName }} 6 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} 7 + {{ end }} 8 + 9 + {{ define "repoContent" }} 10 + <section class="w-full grid grid-cols-1 md:grid-cols-4 gap-2 mt-2"> 11 + <div class="col-span-1"> 12 + {{ block "sidebar" . }} {{ end }} 13 + </div> 14 + <div class="col-span-1 md:col-span-3"> 15 + {{ block "logs" . }} {{ end }} 16 + </div> 17 + </section> 18 + {{ end }} 19 + 20 + {{ define "repoAfter" }} 21 + {{ end }} 22 + 23 + {{ define "sidebar" }} 24 + {{ $active := .Workflow }} 25 + {{ with .Pipeline }} 26 + <div class="rounded border border-gray-200 dark:border-gray-700"> 27 + {{ range $name, $all := .Statuses }} 28 + <div class="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700 {{if eq $name $active}}bg-gray-100/50 dark:bg-gray-700/50{{end}}"> 29 + {{ $lastStatus := $all.Latest }} 30 + {{ $kind := $lastStatus.Status.String }} 31 + 32 + {{ $t := .TimeTaken }} 33 + {{ $time := "" }} 34 + {{ if $t }} 35 + {{ $time = durationFmt $t }} 36 + {{ else }} 37 + {{ $time = printf "%s ago" (shortTimeFmt $.Created) }} 38 + {{ end }} 39 + 40 + <div id="left" class="flex items-center gap-2 flex-shrink-0"> 41 + {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 42 + {{ $name }} 43 + </div> 44 + <div id="right" class="flex items-center gap-2 flex-shrink-0"> 45 + <span class="font-bold">{{ $kind }}</span> 46 + <time>{{ $time }}</time> 47 + </div> 48 + </div> 49 + {{ end }} 50 + </div> 51 + {{ end }} 52 + {{ end }}
+51
appview/pipelines/pipelines.go
··· 86 86 Pipelines: ps, 87 87 }) 88 88 } 89 + 90 + func (p *Pipelines) Workflow(w http.ResponseWriter, r *http.Request) { 91 + user := p.oauth.GetUser(r) 92 + l := p.Logger.With("handler", "Workflow") 93 + 94 + f, err := p.repoResolver.Resolve(r) 95 + if err != nil { 96 + l.Error("failed to get repo and knot", "err", err) 97 + return 98 + } 99 + 100 + repoInfo := f.RepoInfo(user) 101 + 102 + pipelineId := chi.URLParam(r, "pipeline") 103 + if pipelineId == "" { 104 + l.Error("empty pipeline ID") 105 + return 106 + } 107 + 108 + workflow := chi.URLParam(r, "workflow") 109 + if pipelineId == "" { 110 + l.Error("empty workflow name") 111 + return 112 + } 113 + 114 + ps, err := db.GetPipelineStatuses( 115 + p.db, 116 + db.FilterEq("repo_owner", repoInfo.OwnerDid), 117 + db.FilterEq("repo_name", repoInfo.Name), 118 + db.FilterEq("knot", repoInfo.Knot), 119 + db.FilterEq("id", pipelineId), 120 + ) 121 + if err != nil { 122 + l.Error("failed to query db", "err", err) 123 + return 124 + } 125 + 126 + if len(ps) != 1 { 127 + l.Error("invalid number of pipelines", "len", len(ps)) 128 + return 129 + } 130 + 131 + singlePipeline := ps[0] 132 + 133 + p.pages.Workflow(w, pages.WorkflowParams{ 134 + LoggedInUser: user, 135 + RepoInfo: repoInfo, 136 + Pipeline: singlePipeline, 137 + Workflow: workflow, 138 + }) 139 + }