diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2024-12-10 11:38:22 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-10 11:38:22 +0800 |
commit | 90d20be5411a25e6e5e3ac25990265445ec71bc0 (patch) | |
tree | 61d16012572158e2a75f526e9be2645c3671e6e0 /templates | |
parent | 1b069dc94ace16168292e0f3c9889d1b356a7507 (diff) | |
download | gitea-90d20be5411a25e6e5e3ac25990265445ec71bc0.tar.gz gitea-90d20be5411a25e6e5e3ac25990265445ec71bc0.zip |
Refactor issue filter (labels, poster, assignee) (#32771)
Rewrite a lot of legacy strange code, remove duplicate code, remove
jquery, and make these filters reusable.
Let's forget the old code, new code affects:
* issue list open/close switch
* issue list filter (label, author, assignee)
* milestone list open/close switch
* milestone issue list filter (label, author, assignee)
* project view (label, assignee)
Diffstat (limited to 'templates')
-rw-r--r-- | templates/projects/view.tmpl | 84 | ||||
-rw-r--r-- | templates/repo/issue/filter_item_label.tmpl | 45 | ||||
-rw-r--r-- | templates/repo/issue/filter_item_user_assign.tmpl | 31 | ||||
-rw-r--r-- | templates/repo/issue/filter_item_user_fetch.tmpl | 23 | ||||
-rw-r--r-- | templates/repo/issue/filter_list.tmpl | 111 | ||||
-rw-r--r-- | templates/repo/issue/openclose.tmpl | 25 |
6 files changed, 147 insertions, 172 deletions
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index acaf45e8d2..966d3bf604 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -5,79 +5,19 @@ <h2 class="tw-mb-0 tw-flex-1 tw-break-anywhere">{{.Project.Title}}</h2> <div class="project-toolbar-right"> <div class="ui secondary filter menu labels"> - <!-- Label --> - <div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item label-filter"> - <span class="text"> - {{ctx.Locale.Tr "repo.issues.filter_label"}} - </span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} - <div class="menu"> - <div class="ui icon search input"> - <i class="icon">{{svg "octicon-search" 16}}</i> - <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_label"}}"> - </div> - <div class="ui checkbox compact archived-label-filter"> - <input name="archived" type="checkbox" - id="archived-filter-checkbox" - {{if .ShowArchivedLabels}}checked{{end}} - > - <label for="archived-filter-checkbox"> - {{ctx.Locale.Tr "repo.issues.label_archived_filter"}} - <i class="tw-ml-1" data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}> - {{svg "octicon-info"}} - </i> - </label> - </div> - <span class="info">{{ctx.Locale.Tr "repo.issues.filter_label_exclude"}}</span> - <div class="divider"></div> - <a class="{{if .AllLabels}}active selected {{end}}item" href="?assignee={{$.AssigneeID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_no_select"}}</a> - <a class="{{if .NoLabel}}active selected {{end}}item" href="?assignee={{$.AssigneeID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_select_no_label"}}</a> - {{$previousExclusiveScope := "_no_scope"}} - {{range .Labels}} - {{$exclusiveScope := .ExclusiveScope}} - {{if and (ne $previousExclusiveScope $exclusiveScope)}} - <div class="divider" data-scope="{{.ExclusiveScope}}"></div> - {{end}} - {{$previousExclusiveScope = $exclusiveScope}} - <a class="item label-filter-item tw-flex tw-items-center" data-label-id="{{.ID}}" data-scope="{{.ExclusiveScope}}" {{if .IsArchived}}data-is-archived{{end}} - href="?labels={{.QueryString}}&assignee={{$.AssigneeID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> - {{if .IsExcluded}} - {{svg "octicon-circle-slash"}} - {{else if .IsSelected}} - {{if $exclusiveScope}} - {{svg "octicon-dot-fill"}} - {{else}} - {{svg "octicon-check"}} - {{end}} - {{end}} - {{ctx.RenderUtils.RenderLabel .}} - <p class="tw-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p> - </a> - {{end}} - </div> - </div> + {{$queryLink := QueryBuild "?" "labels" .SelectLabels "assignee" $.AssigneeID "archived_labels" (Iif $.ShowArchivedLabels "true")}} - <!-- Assignee --> - <div class="ui {{if not .Assignees}}disabled{{end}} dropdown jump item"> - <span class="text"> - {{ctx.Locale.Tr "repo.issues.filter_assignee"}} - </span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} - <div class="menu"> - <div class="ui icon search input"> - <i class="icon">{{svg "octicon-search" 16}}</i> - <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignee"}}"> - </div> - <a class="{{if not .AssigneeID}}active selected {{end}}item" href="?labels={{.SelectLabels}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_select"}}</a> - <a class="{{if eq .AssigneeID -1}}active selected {{end}}item" href="?labels={{.SelectLabels}}&assignee=-1{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a> - <div class="divider"></div> - {{range .Assignees}} - <a class="{{if eq $.AssigneeID .ID}}active selected{{end}} item tw-flex" href="?labels={{$.SelectLabels}}&assignee={{.ID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> - {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}} - </a> - {{end}} - </div> - </div> + {{template "repo/issue/filter_item_label" dict "Labels" .Labels "QueryLink" $queryLink "SupportArchivedLabel" true}} + + {{template "repo/issue/filter_item_user_assign" dict + "QueryParamKey" "assignee" + "QueryLink" $queryLink + "UserSearchList" $.Assignees + "SelectedUserId" $.AssigneeID + "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") + "TextZeroValue" (ctx.Locale.Tr "repo.issues.filter_assginee_no_select") + "TextNegativeOne" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + }} </div> </div> {{if $canWriteProject}} diff --git a/templates/repo/issue/filter_item_label.tmpl b/templates/repo/issue/filter_item_label.tmpl new file mode 100644 index 0000000000..67bfab6fb0 --- /dev/null +++ b/templates/repo/issue/filter_item_label.tmpl @@ -0,0 +1,45 @@ +{{/* +* "labels" from query string (needed by JS) +* QueryLink +* Labels +* SupportArchivedLabel, if true, then it needs "archived_labels" from query string +*/}} +{{$queryLink := .QueryLink}} +<div class="item ui dropdown jump {{if not .Labels}}disabled{{end}} label-filter"> + <span class="text">{{ctx.Locale.Tr "repo.issues.filter_label"}}</span> + {{svg "octicon-triangle-down" 14 "dropdown icon"}} + <div class="menu flex-items-menu"> + <div class="ui icon search input"> + <i class="icon">{{svg "octicon-search" 16}}</i> + <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_label"}}"> + </div> + {{if .SupportArchivedLabel}}{{/* this checkbox has a hard dependency with the "labels" and "archived_label" query parameter */}} + <label class="label-filter-archived-toggle flex-text-block"> + <input type="checkbox"> {{ctx.Locale.Tr "repo.issues.label_archived_filter"}} + <span data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}>{{svg "octicon-info"}}</span> + </label> + {{end}} + <span class="info">{{ctx.Locale.Tr "repo.issues.filter_label_exclude"}}</span> + <div class="divider"></div> + <a class="item label-filter-query-default" href="{{QueryBuild $queryLink "labels" NIL}}">{{ctx.Locale.Tr "repo.issues.filter_label_no_select"}}</a> + <a class="item label-filter-query-not-set" href="{{QueryBuild $queryLink "labels" 0}}">{{ctx.Locale.Tr "repo.issues.filter_label_select_no_label"}}</a> + {{$previousExclusiveScope := "_no_scope"}} + {{range .Labels}} + {{$exclusiveScope := .ExclusiveScope}} + {{if and (ne $previousExclusiveScope $exclusiveScope)}} + <div class="divider" data-scope="{{.ExclusiveScope}}"></div> + {{end}} + {{$previousExclusiveScope = $exclusiveScope}} + <a class="item label-filter-query-item" data-label-id="{{.ID}}" data-scope="{{.ExclusiveScope}}" {{if .IsArchived}}data-is-archived{{end}} + href="{{QueryBuild $queryLink "labels" .QueryString}}"> + {{if .IsExcluded}} + {{svg "octicon-circle-slash"}} + {{else if .IsSelected}} + {{Iif $exclusiveScope (svg "octicon-dot-fill") (svg "octicon-check")}} + {{end}} + {{ctx.RenderUtils.RenderLabel .}} + <p class="tw-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p> + </a> + {{end}} + </div> +</div> diff --git a/templates/repo/issue/filter_item_user_assign.tmpl b/templates/repo/issue/filter_item_user_assign.tmpl new file mode 100644 index 0000000000..4f1db71d57 --- /dev/null +++ b/templates/repo/issue/filter_item_user_assign.tmpl @@ -0,0 +1,31 @@ +{{/* This is a user list for filter, the data is provided by a local variable assignment +* QueryParamKey: eg: "poster", "assignee" +* QueryLink +* UserSearchList +* SelectedUserId: 0 or empty means default, -1 means "no user is set" +* TextFilterTitle +* TextZeroValue: the text for "all issues" +* TextNegativeOne: the text for "issues with no assignee" +*/}} +{{$queryLink := .QueryLink}} +<div class="item ui dropdown jump {{if not .UserSearchList}}disabled{{end}}"> + {{$.TextFilterTitle}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} + <div class="menu"> + <div class="ui icon search input"> + <i class="icon">{{svg "octicon-search" 16}}</i> + <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_user_placeholder"}}"> + </div> + {{if $.TextZeroValue}} + <a class="item {{if not .SelectedUserId}}selected{{end}}" href="{{QueryBuild $queryLink $.QueryParamKey NIL}}">{{$.TextZeroValue}}</a> + {{end}} + {{if $.TextNegativeOne}} + <a class="item {{if eq .SelectedUserId -1}}selected{{end}}" href="{{QueryBuild $queryLink $.QueryParamKey -1}}">{{$.TextNegativeOne}}</a> + {{end}} + <div class="divider"></div> + {{range .UserSearchList}} + <a class="item {{if eq $.SelectedUserId .ID}}selected{{end}}" href="{{QueryBuild $queryLink $.QueryParamKey .ID}}"> + {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}} + </a> + {{end}} + </div> +</div> diff --git a/templates/repo/issue/filter_item_user_fetch.tmpl b/templates/repo/issue/filter_item_user_fetch.tmpl new file mode 100644 index 0000000000..cab128a787 --- /dev/null +++ b/templates/repo/issue/filter_item_user_fetch.tmpl @@ -0,0 +1,23 @@ +{{/* This is a user list for filter, the data is provided by a remote "fetch" request +* QueryParamKey: eg: "poster", "assignee" +* QueryLink +* UserSearchUrl +* SelectedUserId +* TextFilterTitle +*/}} +{{$queryLink := .QueryLink}} +<div class="item ui dropdown custom user-remote-search" data-tooltip-content="{{ctx.Locale.Tr "repo.user_search_tooltip"}}" + data-search-url="{{$.UserSearchUrl}}" + data-selected-user-id="{{$.SelectedUserId}}" + data-action-jump-url="{{QueryBuild $queryLink $.QueryParamKey NIL}}&{{$.QueryParamKey}}={username}" +> + {{$.TextFilterTitle}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} + <div class="menu"> + <div class="ui icon search input"> + <i class="icon">{{svg "octicon-search" 16}}</i> + <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_user_placeholder"}}"> + </div> + <a class="item" data-value="">{{ctx.Locale.Tr "repo.issues.filter_user_no_select"}}</a> + <a class="item item-from-input tw-hidden"></a> + </div> +</div> diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl index e686f1d60f..c78d23d51c 100644 --- a/templates/repo/issue/filter_list.tmpl +++ b/templates/repo/issue/filter_list.tmpl @@ -1,55 +1,6 @@ -{{$queryLink := QueryBuild "?" "q" $.Keyword "type" $.ViewType "sort" $.SortType "state" $.State "labels" $.SelectLabels "milestone" $.MilestoneID "project" $.ProjectID "assignee" $.AssigneeID "poster" $.PosterUsername "archived" (Iif $.ShowArchivedLabels NIL)}} -<!-- Label --> -<div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item label-filter"> - <span class="text"> - {{ctx.Locale.Tr "repo.issues.filter_label"}} - </span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} - <div class="menu"> - <div class="ui icon search input"> - <i class="icon">{{svg "octicon-search" 16}}</i> - <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_label"}}"> - </div> - <div class="ui checkbox compact archived-label-filter"> - <input name="archived" type="checkbox" - id="archived-filter-checkbox" - {{if .ShowArchivedLabels}}checked{{end}} - > - <label for="archived-filter-checkbox"> - {{ctx.Locale.Tr "repo.issues.label_archived_filter"}} - <i class="tw-ml-1" data-tooltip-content={{ctx.Locale.Tr "repo.issues.label_archive_tooltip"}}> - {{svg "octicon-info"}} - </i> - </label> - </div> - <span class="info">{{ctx.Locale.Tr "repo.issues.filter_label_exclude"}}</span> - <div class="divider"></div> - <a class="{{if .AllLabels}}active selected {{end}}item" href="{{QueryBuild $queryLink "labels" NIL}}">{{ctx.Locale.Tr "repo.issues.filter_label_no_select"}}</a> - <a class="{{if .NoLabel}}active selected {{end}}item" href="{{QueryBuild $queryLink "labels" 0}}">{{ctx.Locale.Tr "repo.issues.filter_label_select_no_label"}}</a> - {{$previousExclusiveScope := "_no_scope"}} - {{range .Labels}} - {{$exclusiveScope := .ExclusiveScope}} - {{if and (ne $previousExclusiveScope $exclusiveScope)}} - <div class="divider" data-scope="{{.ExclusiveScope}}"></div> - {{end}} - {{$previousExclusiveScope = $exclusiveScope}} - <a class="item label-filter-item tw-flex tw-items-center" data-label-id="{{.ID}}" data-scope="{{.ExclusiveScope}}" {{if .IsArchived}}data-is-archived{{end}} - href="{{QueryBuild $queryLink "labels" .QueryString}}"> - {{if .IsExcluded}} - {{svg "octicon-circle-slash"}} - {{else if .IsSelected}} - {{if $exclusiveScope}} - {{svg "octicon-dot-fill"}} - {{else}} - {{svg "octicon-check"}} - {{end}} - {{end}} - {{ctx.RenderUtils.RenderLabel .}} - <p class="tw-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p> - </a> - {{end}} - </div> -</div> +{{$queryLink := QueryBuild "?" "q" $.Keyword "type" $.ViewType "sort" $.SortType "state" $.State "labels" $.SelectLabels "milestone" $.MilestoneID "project" $.ProjectID "assignee" $.AssigneeID "poster" $.PosterUsername "archived_labels" (Iif $.ShowArchivedLabels "true")}} + +{{template "repo/issue/filter_item_label" dict "Labels" .Labels "QueryLink" $queryLink "SupportArchivedLabel" true}} {{if not .Milestone}} <!-- Milestone --> @@ -128,46 +79,24 @@ </div> </div> -<!-- Author --> -<div class="ui dropdown jump item user-remote-search" data-tooltip-content="{{ctx.Locale.Tr "repo.author_search_tooltip"}}" - data-search-url="{{if .Milestone}}{{$.RepoLink}}/issues/posters{{else}}{{$.Link}}/posters{{end}}" - data-selected-user-id="{{$.PosterID}}" - data-action-jump-url="{{QueryBuild $queryLink "poster" NIL}}&poster={username}" -> - <span class="text"> - {{ctx.Locale.Tr "repo.issues.filter_poster"}} - </span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} - <div class="menu"> - <div class="ui icon search input"> - <i class="icon">{{svg "octicon-search" 16}}</i> - <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_poster"}}"> - </div> - <a class="item" data-value="0">{{ctx.Locale.Tr "repo.issues.filter_poster_no_select"}}</a> - </div> -</div> +{{/* TODO: the UserSearchUrl is old logic but not right, milestone could also have "pull request" posters */}} +{{template "repo/issue/filter_item_user_fetch" dict + "QueryParamKey" "poster" + "QueryLink" $queryLink + "UserSearchUrl" (Iif .Milestone (print $.RepoLink "/issues/posters") (print $.Link "/posters")) + "SelectedUserId" $.PosterUserID + "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_poster") +}} -<!-- Assignee --> -<div class="ui {{if not .Assignees}}disabled{{end}} dropdown jump item"> - <span class="text"> - {{ctx.Locale.Tr "repo.issues.filter_assignee"}} - </span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} - <div class="menu"> - <div class="ui icon search input"> - <i class="icon">{{svg "octicon-search" 16}}</i> - <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignee"}}"> - </div> - <a class="{{if not .AssigneeID}}active selected {{end}}item" href="{{QueryBuild $queryLink "assignee" NIL}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_select"}}</a> - <a class="{{if eq .AssigneeID -1}}active selected {{end}}item" href="{{QueryBuild $queryLink "assignee" -1}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a> - <div class="divider"></div> - {{range .Assignees}} - <a class="{{if eq $.AssigneeID .ID}}active selected{{end}} item tw-flex" href="{{QueryBuild $queryLink "assignee" .ID}}"> - {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}} - </a> - {{end}} - </div> -</div> +{{template "repo/issue/filter_item_user_assign" dict + "QueryParamKey" "assignee" + "QueryLink" $queryLink + "UserSearchList" $.Assignees + "SelectedUserId" $.AssigneeID + "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") + "TextZeroValue" (ctx.Locale.Tr "repo.issues.filter_assginee_no_select") + "TextNegativeOne" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") +}} {{if .IsSigned}} <!-- Type --> diff --git a/templates/repo/issue/openclose.tmpl b/templates/repo/issue/openclose.tmpl index eb2d6e09ee..b9dd04a7db 100644 --- a/templates/repo/issue/openclose.tmpl +++ b/templates/repo/issue/openclose.tmpl @@ -1,16 +1,23 @@ +{{/* this tmpl is quite dirty, it should not mix unrelated things together .... need to split it in the future*/}} +{{$allStatesLink := ""}}{{$openLink := ""}}{{$closedLink := ""}} +{{if .PageIsMilestones}} + {{$allStatesLink = QueryBuild "?" "q" $.Keyword "sort" $.SortType "state" "all"}} +{{else}} + {{$allStatesLink = QueryBuild "?" "q" $.Keyword "type" $.ViewType "sort" $.SortType "state" "all" "labels" $.SelectLabels "milestone" $.MilestoneID "project" $.ProjectID "assignee" $.AssigneeID "poster" $.PosterUsername "archived_labels" (Iif $.ShowArchivedLabels "true")}} +{{end}} +{{$openLink = QueryBuild $allStatesLink "state" "open"}} +{{$closedLink = QueryBuild $allStatesLink "state" "closed"}} <div class="small-menu-items ui compact tiny menu"> - <a class="{{if eq .State "open"}}active {{end}}item" href="{{if eq .State "open"}}{{.AllStatesLink}}{{else}}{{.OpenLink}}{{end}}"> + <a class="{{if eq .State "open"}}active {{end}}item flex-text-inline" href="{{if eq .State "open"}}{{$allStatesLink}}{{else}}{{$openLink}}{{end}}"> {{if .PageIsMilestones}} - {{svg "octicon-milestone" 16 "tw-mr-2"}} - {{else if .PageIsPullList}} - {{svg "octicon-git-pull-request" 16 "tw-mr-2"}} + {{svg "octicon-milestone"}} {{else}} - {{svg "octicon-issue-opened" 16 "tw-mr-2"}} + {{Iif .PageIsPullList (svg "octicon-git-pull-request") (svg "octicon-issue-opened")}} {{end}} - {{ctx.Locale.PrettyNumber .OpenCount}} {{ctx.Locale.Tr "repo.issues.open_title"}} + {{ctx.Locale.PrettyNumber .OpenCount}} {{ctx.Locale.Tr "repo.issues.open_title"}} </a> - <a class="{{if eq .State "closed"}}active {{end}}item" href="{{if eq .State "closed"}}{{.AllStatesLink}}{{else}}{{.ClosedLink}}{{end}}"> - {{svg "octicon-check" 16 "tw-mr-2"}} - {{ctx.Locale.PrettyNumber .ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}} + <a class="{{if eq .State "closed"}}active {{end}}item flex-text-inline" href="{{if eq .State "closed"}}{{$allStatesLink}}{{else}}{{$closedLink}}{{end}}"> + {{svg "octicon-check"}} + {{ctx.Locale.PrettyNumber .ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}} </a> </div> |