aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHesterG <hestergong@gmail.com>2023-06-21 12:25:14 +0800
committerGitHub <noreply@github.com>2023-06-21 04:25:14 +0000
commit1454f9dafc681875d8f6a429b80e27de62f4040e (patch)
treea450eb8e78cb5f7add2d2aee48b2841874b63647
parente79ff5056043f25a77c50847a228826bc7cdaf61 (diff)
downloadgitea-1454f9dafc681875d8f6a429b80e27de62f4040e.tar.gz
gitea-1454f9dafc681875d8f6a429b80e27de62f4040e.zip
Add actor and status dropdowns to run list (#25118)
Part of #25042 1. Added actor and status dropdowns first in case something is offtrack and PR is too large. 2. Also added "No results matched." and "The workflow has no runs yet.", and "No results matched." will show if there is no filter results and there is no workflows (with [reference to github action](https://github.com/go-gitea/gitea/actions/workflows/files-changed.yml?query=actor%3AGiteaBot)) Demo: https://github.com/go-gitea/gitea/assets/17645053/6e76292c-4c1f-450d-8b48-99944cfc920c TODOs: - [x] Get available status (same as those in `aggregateJobStatus`) instead of getting from database - [x] Use `JOIN` to get actors, actors order by name - [x] Make self on top
-rw-r--r--models/actions/run_list.go35
-rw-r--r--options/locale/locale_en-US.ini6
-rw-r--r--routers/web/repo/actions/actions.go24
-rw-r--r--routers/web/repo/helper.go2
-rw-r--r--routers/web/repo/helper_test.go6
-rw-r--r--routers/web/repo/issue.go6
-rw-r--r--routers/web/repo/pull.go2
-rw-r--r--routers/web/repo/release.go4
-rw-r--r--templates/package/shared/list.tmpl2
-rw-r--r--templates/repo/actions/list.tmpl46
-rw-r--r--templates/repo/actions/runs_list.tmpl6
-rw-r--r--web_src/css/repo.css7
12 files changed, 127 insertions, 19 deletions
diff --git a/models/actions/run_list.go b/models/actions/run_list.go
index 56de8eb916..29ab193d57 100644
--- a/models/actions/run_list.go
+++ b/models/actions/run_list.go
@@ -71,6 +71,7 @@ type FindRunOptions struct {
WorkflowFileName string
TriggerUserID int64
Approved bool // not util.OptionalBool, it works only when it's true
+ Status Status
}
func (opts FindRunOptions) toConds() builder.Cond {
@@ -90,6 +91,9 @@ func (opts FindRunOptions) toConds() builder.Cond {
if opts.Approved {
cond = cond.And(builder.Gt{"approved_by": 0})
}
+ if opts.Status > StatusUnknown {
+ cond = cond.And(builder.Eq{"status": opts.Status})
+ }
return cond
}
@@ -106,3 +110,34 @@ func FindRuns(ctx context.Context, opts FindRunOptions) (RunList, int64, error)
func CountRuns(ctx context.Context, opts FindRunOptions) (int64, error) {
return db.GetEngine(ctx).Where(opts.toConds()).Count(new(ActionRun))
}
+
+type StatusInfo struct {
+ Status int
+ DisplayedStatus string
+}
+
+// GetStatusInfoList returns a slice of StatusInfo
+func GetStatusInfoList(ctx context.Context) []StatusInfo {
+ // same as those in aggregateJobStatus
+ allStatus := []Status{StatusSuccess, StatusFailure, StatusWaiting, StatusRunning}
+ statusInfoList := make([]StatusInfo, 0, 4)
+ for _, s := range allStatus {
+ statusInfoList = append(statusInfoList, StatusInfo{
+ Status: int(s),
+ DisplayedStatus: s.String(),
+ })
+ }
+ return statusInfoList
+}
+
+// GetActors returns a slice of Actors
+func GetActors(ctx context.Context, repoID int64) ([]*user_model.User, error) {
+ actors := make([]*user_model.User, 0, 10)
+
+ return actors, db.GetEngine(ctx).Where(builder.In("id", builder.Select("`action_run`.trigger_user_id").From("`action_run`").
+ GroupBy("`action_run`.trigger_user_id").
+ Where(builder.Eq{"`action_run`.repo_id": repoID}))).
+ Cols("id", "name", "full_name", "avatar", "avatar_email", "use_custom_avatar").
+ OrderBy(user_model.GetOrderByName()).
+ Find(&actors)
+}
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 0cf8810702..234b898fc1 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -3460,6 +3460,12 @@ runs.commit = Commit
runs.pushed_by = Pushed by
runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s
runs.no_matching_runner_helper = No matching runner: %s
+runs.actor = Actor
+runs.status = Status
+runs.actors_no_select = All actors
+runs.status_no_select = All status
+runs.no_results = No results matched.
+runs.no_runs = The workflow has no runs yet.
need_approval_desc = Need approval to run workflows for fork pull request.
diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go
index 10acb46854..e1e07b5a72 100644
--- a/routers/web/repo/actions/actions.go
+++ b/routers/web/repo/actions/actions.go
@@ -5,6 +5,7 @@ package actions
import (
"bytes"
+ "fmt"
"net/http"
actions_model "code.gitea.io/gitea/models/actions"
@@ -16,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/web/repo"
"code.gitea.io/gitea/services/convert"
"github.com/nektos/act/pkg/model"
@@ -125,7 +127,16 @@ func List(ctx *context.Context) {
}
workflow := ctx.FormString("workflow")
+ actorID := ctx.FormInt64("actor")
+ status := ctx.FormInt("status")
ctx.Data["CurWorkflow"] = workflow
+ // if status or actor query param is not given to frontend href, (href="/<repoLink>/actions")
+ // they will be 0 by default, which indicates get all status or actors
+ ctx.Data["CurActor"] = actorID
+ ctx.Data["CurStatus"] = status
+ if actorID > 0 || status > int(actions_model.StatusUnknown) {
+ ctx.Data["IsFiltered"] = true
+ }
opts := actions_model.FindRunOptions{
ListOptions: db.ListOptions{
@@ -134,6 +145,8 @@ func List(ctx *context.Context) {
},
RepoID: ctx.Repo.Repository.ID,
WorkflowFileName: workflow,
+ TriggerUserID: actorID,
+ Status: actions_model.Status(status),
}
runs, total, err := actions_model.FindRuns(ctx, opts)
@@ -153,9 +166,20 @@ func List(ctx *context.Context) {
ctx.Data["Runs"] = runs
+ actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+ ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx, actors)
+
+ ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
+
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("workflow", workflow)
+ pager.AddParamString("actor", fmt.Sprint(actorID))
+ pager.AddParamString("status", fmt.Sprint(status))
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplListActions)
diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go
index 6f9ca4874b..fb5ada1bdb 100644
--- a/routers/web/repo/helper.go
+++ b/routers/web/repo/helper.go
@@ -10,7 +10,7 @@ import (
"code.gitea.io/gitea/modules/context"
)
-func makeSelfOnTop(ctx *context.Context, users []*user.User) []*user.User {
+func MakeSelfOnTop(ctx *context.Context, users []*user.User) []*user.User {
if ctx.Doer != nil {
sort.Slice(users, func(i, j int) bool {
if users[i].ID == users[j].ID {
diff --git a/routers/web/repo/helper_test.go b/routers/web/repo/helper_test.go
index e9ab44fe69..226e2e81f4 100644
--- a/routers/web/repo/helper_test.go
+++ b/routers/web/repo/helper_test.go
@@ -13,15 +13,15 @@ import (
)
func TestMakeSelfOnTop(t *testing.T) {
- users := makeSelfOnTop(&context.Context{}, []*user.User{{ID: 2}, {ID: 1}})
+ users := MakeSelfOnTop(&context.Context{}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
- users = makeSelfOnTop(&context.Context{Doer: &user.User{ID: 1}}, []*user.User{{ID: 2}, {ID: 1}})
+ users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 1}}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 1, users[0].ID)
- users = makeSelfOnTop(&context.Context{Doer: &user.User{ID: 2}}, []*user.User{{ID: 2}, {ID: 1}})
+ users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 2}}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 49ba753a7d..a9ce1cc1e7 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -312,7 +312,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = makeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
@@ -508,7 +508,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *repo_model.R
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = makeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
handleTeamMentions(ctx)
}
@@ -3487,7 +3487,7 @@ func IssuePosters(ctx *context.Context) {
}
}
- posters = makeSelfOnTop(ctx, posters)
+ posters = MakeSelfOnTop(ctx, posters)
resp := &userSearchResponse{}
resp.Results = make([]*userSearchInfo, len(posters))
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 309e61cf6e..ef9d5856da 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -809,7 +809,7 @@ func ViewPullFiles(ctx *context.Context) {
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = makeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index afba1f18bf..5fddddb344 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -349,7 +349,7 @@ func NewRelease(ctx *context.Context) {
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = makeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
upload.AddUploadContext(ctx, "release")
ctx.HTML(http.StatusOK, tplReleaseNew)
@@ -517,7 +517,7 @@ func EditRelease(ctx *context.Context) {
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = makeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.HTML(http.StatusOK, tplReleaseNew)
}
diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl
index 707fbe357f..5ac5baf0f1 100644
--- a/templates/package/shared/list.tmpl
+++ b/templates/package/shared/list.tmpl
@@ -38,7 +38,7 @@
{{else}}
{{if not .HasPackages}}
<div class="empty center">
- {{svg "octicon-package" 32}}
+ {{svg "octicon-package" 48}}
<h2>{{.locale.Tr "packages.empty"}}</h2>
{{if and .Repository .CanWritePackages}}
{{$packagesUrl := URLJoin .Owner.HomeLink "-" "packages"}}
diff --git a/templates/repo/actions/list.tmpl b/templates/repo/actions/list.tmpl
index ca97b67faa..46cbb34670 100644
--- a/templates/repo/actions/list.tmpl
+++ b/templates/repo/actions/list.tmpl
@@ -1,14 +1,14 @@
{{template "base/head" .}}
-<div class="page-content repository">
+<div class="page-content repository actions">
{{template "repo/header" .}}
<div class="ui container">
<div class="ui stackable grid">
<div class="four wide column">
<div class="ui fluid vertical menu">
- <a class="item{{if not $.CurWorkflow}} active{{end}}" href="{{$.Link}}">{{.locale.Tr "actions.runs.all_workflows"}}</a>
+ <a class="item{{if not $.CurWorkflow}} active{{end}}" href="{{$.Link}}?actor={{$.CurActor}}&status={{$.CurStatus}}">{{.locale.Tr "actions.runs.all_workflows"}}</a>
<div class="divider"></div>
{{range .workflows}}
- <a class="item{{if eq .Entry.Name $.CurWorkflow}} active{{end}}" href="{{$.Link}}?workflow={{.Entry.Name}}">{{.Entry.Name}}
+ <a class="item{{if eq .Entry.Name $.CurWorkflow}} active{{end}}" href="{{$.Link}}?workflow={{.Entry.Name}}&actor={{$.CurActor}}&status={{$.CurStatus}}">{{.Entry.Name}}
{{if .ErrMsg}}
<span data-tooltip-content="{{.ErrMsg}}">
{{svg "octicon-alert" 16 "text red"}}
@@ -19,6 +19,46 @@
</div>
</div>
<div class="twelve wide column content">
+ <div class="ui secondary filter stackable menu gt-je">
+ <!-- Actor -->
+ <div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item">
+ <span class="text">{{.locale.Tr "actions.runs.actor"}}</span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search"}}</i>
+ <input type="text" placeholder="{{.locale.Tr "actions.runs.actor"}}">
+ </div>
+ <a class="item{{if not $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&status={{$.CurStatus}}&actor=0">
+ {{.locale.Tr "actions.runs.actors_no_select"}}
+ </a>
+ {{range .Actors}}
+ <a class="item{{if eq .ID $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{.ID}}&status={{$.CurStatus}}">
+ {{avatar $.Context . 20}} {{.GetDisplayName}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ <!-- Status -->
+ <div class="ui dropdown jump item">
+ <span class="text">{{.locale.Tr "actions.runs.status"}}</span>
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="menu">
+ <div class="ui icon search input">
+ <i class="icon">{{svg "octicon-search"}}</i>
+ <input type="text" placeholder="{{.locale.Tr "actions.runs.status"}}">
+ </div>
+ <a class="item{{if not $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status=0">
+ {{.locale.Tr "actions.runs.status_no_select"}}
+ </a>
+ {{range .StatusInfoList}}
+ <a class="item{{if eq .Status $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}">
+ {{.DisplayedStatus}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ </div>
{{template "repo/actions/runs_list" .}}
</div>
</div>
diff --git a/templates/repo/actions/runs_list.tmpl b/templates/repo/actions/runs_list.tmpl
index 5f444f31f9..bfd5aabe55 100644
--- a/templates/repo/actions/runs_list.tmpl
+++ b/templates/repo/actions/runs_list.tmpl
@@ -1,4 +1,10 @@
<div class="issue list gt-m-0">
+ {{if eq (len .Runs) 0}}
+ <div class="empty center">
+ {{svg "octicon-no-entry" 48}}
+ <h2>{{if $.IsFiltered}}{{.locale.Tr "actions.runs.no_results"}}{{else}}{{.locale.Tr "actions.runs.no_runs"}}{{end}}</h2>
+ </div>
+ {{end}}
{{range .Runs}}
<li class="item gt-df gt-py-4">
<div class="issue-item-left issue-item-icon gt-df gt-items-start">
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index 150254569d..fa97393421 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -1877,15 +1877,12 @@
flex: 1
}
-.repository.packages .empty {
+.repository.packages .empty,
+.repository.actions .empty {
padding-top: 70px;
padding-bottom: 100px;
}
-.repository.packages .empty .svg {
- height: 48px;
-}
-
.repository.packages .file-size {
white-space: nowrap;
}