| <!-- |
| Copyright 2022 The Go Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style |
| license that can be found in the LICENSE file. |
| --> |
| {{define "task_list"}} |
| {{$workflow := .Workflow}} |
| <table class="TaskList"> |
| <thead> |
| <tr class="TaskList-item TaskList-itemHeader"> |
| <th class="TaskList-itemHeaderCol TaskList-itemExpand"></th> |
| <th class="TaskList-itemHeaderCol TaskList-itemState">State</th> |
| <th class="TaskList-itemHeaderCol TaskList-itemName">Name</th> |
| <th class="TaskList-itemHeaderCol TaskList-itemStarted">Started</th> |
| <th class="TaskList-itemHeaderCol TaskList-itemUpdated">Updated</th> |
| <th class="TaskList-itemHeaderCol TaskList-itemResult">Result</th> |
| <th class="TaskList-itemHeaderCol TaskList-itemActions">Actions</th> |
| </tr> |
| </thead> |
| <tbody> |
| {{range .Tasks}} |
| {{- /*gotype: golang.org/x/build/internal/relui/db.TasksForWorkflowSortedRow*/ -}} |
| {{$resultDetail := unmarshalResultDetail .Result.String}} |
| <tr class="TaskList-item TaskList-itemSummary TaskList-expandableItem"> |
| <td class="TaskList-itemCol TaskList-itemExpand"> |
| <span class="TaskList-itemExpandClosed"> |
| <img |
| class="TaskList-itemExpandControl" |
| alt="unfold more" |
| src="{{baseLink "/static/images/chevron_right_black_24dp.svg"}}" /> |
| </span> |
| <span class="TaskList-ItemExpandOpened"> |
| <img |
| class="TaskList-itemExpandControl" |
| alt="unfold less" |
| src="{{baseLink "/static/images/expand_more_black_24dp.svg"}}" /> |
| </span> |
| </td> |
| <td class="TaskList-itemCol TaskList-itemState"> |
| {{if .Error.Valid}} |
| <img class="TaskList-itemStateIcon" alt="error" src="{{baseLink "/static/images/error_red_24dp.svg"}}" /> |
| {{else if .Finished}} |
| <img |
| class="TaskList-itemStateIcon" |
| alt="finished" |
| src="{{baseLink "/static/images/check_circle_green_24dp.svg"}}" /> |
| {{else if .Started}} |
| <img |
| class="TaskList-itemStateIcon" |
| alt="started" |
| src="{{baseLink "/static/images/pending_yellow_24dp.svg"}}" /> |
| {{else}} |
| <img |
| class="TaskList-itemStateIcon" |
| alt="pending" |
| src="{{baseLink "/static/images/pending_grey_24dp.svg"}}" /> |
| {{end}} |
| </td> |
| <td class="TaskList-itemCol TaskList-itemName"> |
| {{.Name}} |
| </td> |
| <td class="TaskList-itemCol TaskList-itemStarted"> |
| {{.CreatedAt.UTC.Format "Mon Jan _2 2006 15:04:05"}} |
| </td> |
| <td class="TaskList-itemCol TaskList-itemUpdated"> |
| {{.MostRecentUpdate.UTC.Format "Mon Jan _2 2006 15:04:05"}} |
| </td> |
| <td class="TaskList-itemCol TaskList-itemResult"> |
| {{if .ApprovedAt.Valid}} |
| Approved |
| {{else}} |
| {{$resultDetail.Kind}} |
| {{end}} |
| </td> |
| <td class="TaskList-itemCol TaskList-itemAction"> |
| {{if .Error.Valid}} |
| <div class="TaskList-retryTask"> |
| <form |
| action="{{baseLink (printf "/workflows/%s/tasks/%s/retry" $workflow.ID .Name)}}" |
| method="post"> |
| <input type="hidden" id="workflow.id" name="workflow.id" value="{{$workflow.ID}}" /> |
| <input |
| class="Button Button--small" |
| name="task.reset" |
| type="submit" |
| value="Retry" |
| onclick="return this.form.reportValidity() && confirm('This will retry the task.\n\nReady to proceed?')" /> |
| </form> |
| </div> |
| {{else if and (not .ApprovedAt.Valid) (.ReadyForApproval)}} |
| <div class="TaskList-approveTask"> |
| <form |
| action="{{baseLink (printf "/workflows/%s/tasks/%s/approve" $workflow.ID .Name)}}" |
| method="post"> |
| <input type="hidden" id="workflow.id" name="workflow.id" value="{{$workflow.ID}}" /> |
| <input |
| class="Button Button--small" |
| name="task.approve" |
| type="submit" |
| value="Approve" |
| onclick="return this.form.reportValidity() && confirm('This will mark the task approved and resume the workflow.\n\nReady to proceed?')" /> |
| </form> |
| </div> |
| {{end}} |
| </td> |
| </tr> |
| <tr class="TaskList-itemLogsRow"> |
| <td class="TaskList-itemLogs" colspan="5"> |
| {{if .Error.Valid}} |
| <div class="TaskList-itemLogLine TaskList-itemLogLineError"> |
| {{- .Error.Value -}} |
| </div> |
| {{end}} |
| {{if .ApprovedAt.Valid}} |
| <div class="TaskList-itemLogLine TaskList-itemLogLineApproved"> |
| {{- printf "Approved at: %s" (.ApprovedAt.Value.UTC.Format "2006/01/02 15:04:05") -}} |
| </div> |
| {{end}} |
| {{range $log := index $.TaskLogs .Name}} |
| <div class="TaskList-itemLogLine"> |
| {{- printf "%s %s" ($log.CreatedAt.UTC.Format "2006/01/02 15:04:05") $log.Body -}} |
| </div> |
| {{end}} |
| {{if and .Result.Valid (ne .Result.String "null")}} |
| <div class="TaskList-itemLogLine"> |
| {{- .Result.String -}} |
| </div> |
| {{end}} |
| </td> |
| <td class="TaskList-itemResultDetail" colspan="2"> |
| {{with $resultDetail}} |
| {{template "itemResult" $resultDetail}} |
| {{end}} |
| </td> |
| </tr> |
| {{end}} |
| </tbody> |
| </table> |
| {{end}} |
| |
| {{define "itemResult"}} |
| {{- /*gotype: golang.org/x/build/internal/relui.resultDetail*/ -}} |
| {{if eq .Kind "Artifact"}} |
| <dl class="TaskList-itemResultDetailList"> |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| Name |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition"> |
| {{with .Artifact.Target}} |
| {{.Name}} |
| {{else}} |
| {{.Artifact.Filename}} |
| {{end}} |
| </dd> |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| Filename |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition"> |
| {{.Artifact.Filename}} |
| </dd> |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| Scratch |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition"> |
| {{.Artifact.Scratch}} |
| </dd> |
| </dl> |
| {{else if eq .Kind "Outputs"}} |
| {{range $key, $value := .Outputs}} |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| {{$key}} |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition TaskList-itemResultDefinition--nested"></dd> |
| {{template "itemResult" $value}} |
| {{end}} |
| {{else if eq .Kind "JSON"}} |
| {{range $key, $value := .JSON}} |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| {{$key}} |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition"> |
| {{$value}} |
| </dd> |
| {{end}} |
| {{else if eq .Kind "String"}} |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| String |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition TaskList-itemResultDefinition--string"> |
| <pre class="TaskList-preString">{{.String}}</pre> |
| </dd> |
| {{else if eq .Kind "Slice"}} |
| {{with .Slice}} |
| {{if eq (index . 0).Kind "Artifact"}} |
| <dt class="TaskList-itemResultTerm"> |
| <div class="TaskList-itemResultTermContent"> |
| Filenames |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition"> |
| {{range $detail := .}} |
| {{with $detail.Artifact}} |
| <div class="TaskList-itemResultArtifact"> |
| <div class="TaskList-itemResultArtifactName"> |
| {{if .Filename}} |
| {{.Filename}} |
| {{else if .Target}} |
| {{.Target.Name}} |
| {{else}} |
| {{pathBase .Scratch}} |
| {{end}} |
| </div> |
| <div class="TaskList-itemResultArtifactSize">{{prettySize .Size}}</div> |
| </div> |
| {{end}} |
| {{end}} |
| </dd> |
| {{else}} |
| <dt class="TaskList-itemResultTerm TaskList-itemResultTerm--nested"> |
| <div class="TaskList-itemResultTermContent"> |
| Slice |
| </div> |
| </dt> |
| <dd class="TaskList-itemResultDefinition TaskList-itemResultDefinition--nested"></dd> |
| {{range $value := .}} |
| {{template "itemResult" $value}} |
| {{end}} |
| {{end}} |
| {{end}} |
| {{else if eq .Kind "Number"}} |
| {{.Number}} |
| {{else if eq .Kind "Boolean"}} |
| <dd class="TaskList-itemResultDefinition TaskList-itemResultDefinition--string"> |
| {{.Boolean}} |
| </dd> |
| {{else}} |
| {{with .}} |
| {{.Unknown}} |
| {{else}} |
| <dd class="TaskList-itemResultDefinition TaskList-itemResultDefinition--string"> |
| None |
| </dd> |
| {{end}} |
| {{end}} |
| {{end}} |