mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Expose fuzzy search for issues/pulls (#29701)
close #29685 --------- Signed-off-by: 6543 <6543@obermui.de> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
		| @@ -164,8 +164,8 @@ search = Search... | |||||||
| type_tooltip = Search type | type_tooltip = Search type | ||||||
| fuzzy = Fuzzy | fuzzy = Fuzzy | ||||||
| fuzzy_tooltip = Include results that also match the search term closely | fuzzy_tooltip = Include results that also match the search term closely | ||||||
| match = Match | exact = Exact | ||||||
| match_tooltip = Include only results that match the exact search term | exact_tooltip = Include only results that match the exact search term | ||||||
| repo_kind = Search repos... | repo_kind = Search repos... | ||||||
| user_kind = Search users... | user_kind = Search users... | ||||||
| org_kind = Search orgs... | org_kind = Search orgs... | ||||||
| @@ -179,6 +179,8 @@ branch_kind = Search branches... | |||||||
| commit_kind = Search commits... | commit_kind = Search commits... | ||||||
| runner_kind = Search runners... | runner_kind = Search runners... | ||||||
| no_results = No matching results found. | no_results = No matching results found. | ||||||
|  | issue_kind = Search issues... | ||||||
|  | pull_kind = Search pulls... | ||||||
| keyword_search_unavailable = Searching by keyword is currently not available. Please contact the site administrator. | keyword_search_unavailable = Searching by keyword is currently not available. Please contact the site administrator. | ||||||
|  |  | ||||||
| [aria] | [aria] | ||||||
|   | |||||||
| @@ -447,6 +447,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | |||||||
| 		User:       ctx.Doer, | 		User:       ctx.Doer, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	isFuzzy := ctx.FormBool("fuzzy") | ||||||
|  |  | ||||||
| 	// Search all repositories which | 	// Search all repositories which | ||||||
| 	// | 	// | ||||||
| 	// As user: | 	// As user: | ||||||
| @@ -546,7 +548,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | |||||||
| 	// USING FINAL STATE OF opts FOR A QUERY. | 	// USING FINAL STATE OF opts FOR A QUERY. | ||||||
| 	var issues issues_model.IssueList | 	var issues issues_model.IssueList | ||||||
| 	{ | 	{ | ||||||
| 		issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts)) | 		issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy( | ||||||
|  | 			func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy }, | ||||||
|  | 		)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("issueIDsFromSearch", err) | 			ctx.ServerError("issueIDsFromSearch", err) | ||||||
| 			return | 			return | ||||||
| @@ -567,7 +571,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | |||||||
| 	// ------------------------------- | 	// ------------------------------- | ||||||
| 	// Fill stats to post to ctx.Data. | 	// Fill stats to post to ctx.Data. | ||||||
| 	// ------------------------------- | 	// ------------------------------- | ||||||
| 	issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts)) | 	issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts).Copy( | ||||||
|  | 		func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy }, | ||||||
|  | 	)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("getUserIssueStats", err) | 		ctx.ServerError("getUserIssueStats", err) | ||||||
| 		return | 		return | ||||||
| @@ -621,6 +627,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | |||||||
| 	ctx.Data["SortType"] = sortType | 	ctx.Data["SortType"] = sortType | ||||||
| 	ctx.Data["IsShowClosed"] = isShowClosed | 	ctx.Data["IsShowClosed"] = isShowClosed | ||||||
| 	ctx.Data["SelectLabels"] = selectedLabels | 	ctx.Data["SelectLabels"] = selectedLabels | ||||||
|  | 	ctx.Data["IsFuzzy"] = isFuzzy | ||||||
|  |  | ||||||
| 	if isShowClosed { | 	if isShowClosed { | ||||||
| 		ctx.Data["State"] = "closed" | 		ctx.Data["State"] = "closed" | ||||||
| @@ -634,6 +641,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | |||||||
| 	pager.AddParamString("sort", sortType) | 	pager.AddParamString("sort", sortType) | ||||||
| 	pager.AddParamString("state", fmt.Sprint(ctx.Data["State"])) | 	pager.AddParamString("state", fmt.Sprint(ctx.Data["State"])) | ||||||
| 	pager.AddParamString("labels", selectedLabels) | 	pager.AddParamString("labels", selectedLabels) | ||||||
|  | 	pager.AddParamString("fuzzy", fmt.Sprintf("%v", isFuzzy)) | ||||||
| 	ctx.Data["Page"] = pager | 	ctx.Data["Page"] = pager | ||||||
|  |  | ||||||
| 	ctx.HTML(http.StatusOK, tplIssues) | 	ctx.HTML(http.StatusOK, tplIssues) | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ | |||||||
| {{/* IsFuzzy - state of the fuzzy search toggle */}} | {{/* IsFuzzy - state of the fuzzy search toggle */}} | ||||||
| <div class="ui small dropdown selection {{if .Disabled}} disabled{{end}}" data-tooltip-content="{{ctx.Locale.Tr "search.type_tooltip"}}"> | <div class="ui small dropdown selection {{if .Disabled}} disabled{{end}}" data-tooltip-content="{{ctx.Locale.Tr "search.type_tooltip"}}"> | ||||||
| 	<input name="fuzzy" type="hidden"{{if .Disabled}} disabled{{end}} value="{{.IsFuzzy}}">{{svg "octicon-triangle-down" 14 "dropdown icon"}} | 	<input name="fuzzy" type="hidden"{{if .Disabled}} disabled{{end}} value="{{.IsFuzzy}}">{{svg "octicon-triangle-down" 14 "dropdown icon"}} | ||||||
| 	<div class="text">{{if .IsFuzzy}}{{ctx.Locale.Tr "search.fuzzy"}}{{else}}{{ctx.Locale.Tr "search.match"}}{{end}}</div> | 	<div class="text">{{if .IsFuzzy}}{{ctx.Locale.Tr "search.fuzzy"}}{{else}}{{ctx.Locale.Tr "search.exact"}}{{end}}</div> | ||||||
| 	<div class="menu"> | 	<div class="menu"> | ||||||
| 		<div class="item" data-value="true" data-tooltip-content="{{ctx.Locale.Tr "search.fuzzy_tooltip"}}">{{ctx.Locale.Tr "search.fuzzy"}}</div> | 		<div class="item" data-value="true" data-tooltip-content="{{ctx.Locale.Tr "search.fuzzy_tooltip"}}">{{ctx.Locale.Tr "search.fuzzy"}}</div> | ||||||
| 		<div class="item" data-value="false" data-tooltip-content="{{ctx.Locale.Tr "search.match_tooltip"}}">{{ctx.Locale.Tr "search.match"}}</div> | 		<div class="item" data-value="false" data-tooltip-content="{{ctx.Locale.Tr "search.exact_tooltip"}}">{{ctx.Locale.Tr "search.exact"}}</div> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -6,29 +6,29 @@ | |||||||
| 		<div class="flex-container"> | 		<div class="flex-container"> | ||||||
| 			<div class="flex-container-nav"> | 			<div class="flex-container-nav"> | ||||||
| 				<div class="ui secondary vertical filter menu tw-bg-transparent"> | 				<div class="ui secondary vertical filter menu tw-bg-transparent"> | ||||||
| 					<a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 					<a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 						{{ctx.Locale.Tr "home.issues.in_your_repos"}} | 						{{ctx.Locale.Tr "home.issues.in_your_repos"}} | ||||||
| 						<strong>{{CountFmt .IssueStats.YourRepositoriesCount}}</strong> | 						<strong>{{CountFmt .IssueStats.YourRepositoriesCount}}</strong> | ||||||
| 					</a> | 					</a> | ||||||
| 					<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 					<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 						{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}} | 						{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}} | ||||||
| 						<strong>{{CountFmt .IssueStats.AssignCount}}</strong> | 						<strong>{{CountFmt .IssueStats.AssignCount}}</strong> | ||||||
| 					</a> | 					</a> | ||||||
| 					<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 					<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 						{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}} | 						{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}} | ||||||
| 						<strong>{{CountFmt .IssueStats.CreateCount}}</strong> | 						<strong>{{CountFmt .IssueStats.CreateCount}}</strong> | ||||||
| 					</a> | 					</a> | ||||||
| 					{{if .PageIsPulls}} | 					{{if .PageIsPulls}} | ||||||
| 						<a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 						<a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 							{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}} | 							{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}} | ||||||
| 							<strong>{{CountFmt .IssueStats.ReviewRequestedCount}}</strong> | 							<strong>{{CountFmt .IssueStats.ReviewRequestedCount}}</strong> | ||||||
| 						</a> | 						</a> | ||||||
| 						<a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 						<a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 							{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}} | 							{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}} | ||||||
| 							<strong>{{CountFmt .IssueStats.ReviewedCount}}</strong> | 							<strong>{{CountFmt .IssueStats.ReviewedCount}}</strong> | ||||||
| 						</a> | 						</a> | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 					<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> | 					<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 						{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}} | 						{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}} | ||||||
| 						<strong>{{CountFmt .IssueStats.MentionCount}}</strong> | 						<strong>{{CountFmt .IssueStats.MentionCount}}</strong> | ||||||
| 					</a> | 					</a> | ||||||
| @@ -37,11 +37,11 @@ | |||||||
| 			<div class="flex-container-main content"> | 			<div class="flex-container-main content"> | ||||||
| 				<div class="list-header"> | 				<div class="list-header"> | ||||||
| 					<div class="small-menu-items ui compact tiny menu list-header-toggle"> | 					<div class="small-menu-items ui compact tiny menu list-header-toggle"> | ||||||
| 						<a class="item{{if not .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}"> | 						<a class="item{{if not .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 							{{svg "octicon-issue-opened" 16 "tw-mr-2"}} | 							{{svg "octicon-issue-opened" 16 "tw-mr-2"}} | ||||||
| 							{{ctx.Locale.PrettyNumber .IssueStats.OpenCount}} {{ctx.Locale.Tr "repo.issues.open_title"}} | 							{{ctx.Locale.PrettyNumber .IssueStats.OpenCount}} {{ctx.Locale.Tr "repo.issues.open_title"}} | ||||||
| 						</a> | 						</a> | ||||||
| 						<a class="item{{if .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}"> | 						<a class="item{{if .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}"> | ||||||
| 							{{svg "octicon-issue-closed" 16 "tw-mr-2"}} | 							{{svg "octicon-issue-closed" 16 "tw-mr-2"}} | ||||||
| 							{{ctx.Locale.PrettyNumber .IssueStats.ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}} | 							{{ctx.Locale.PrettyNumber .IssueStats.ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}} | ||||||
| 						</a> | 						</a> | ||||||
| @@ -51,9 +51,11 @@ | |||||||
| 							<input type="hidden" name="type" value="{{$.ViewType}}"> | 							<input type="hidden" name="type" value="{{$.ViewType}}"> | ||||||
| 							<input type="hidden" name="sort" value="{{$.SortType}}"> | 							<input type="hidden" name="sort" value="{{$.SortType}}"> | ||||||
| 							<input type="hidden" name="state" value="{{$.State}}"> | 							<input type="hidden" name="state" value="{{$.State}}"> | ||||||
| 							{{template "shared/search/input" dict "Value" $.Keyword}} | 							{{if .PageIsPulls}} | ||||||
| 							<button id="issue-list-quick-goto" class="ui small icon button tw-hidden" data-tooltip-content="{{ctx.Locale.Tr "explore.go_to"}}">{{svg "octicon-hash"}}</button> | 								{{template "shared/search/combo_fuzzy" dict "Value" $.Keyword "IsFuzzy" $.IsFuzzy "Placeholder" (ctx.Locale.Tr "search.pull_kind") "Tooltip" (ctx.Locale.Tr "explorer.go")}} | ||||||
| 							{{template "shared/search/button"}} | 							{{else}} | ||||||
|  | 								{{template "shared/search/combo_fuzzy" dict "Value" $.Keyword "IsFuzzy" $.IsFuzzy "Placeholder" (ctx.Locale.Tr "search.issue_kind") "Tooltip" (ctx.Locale.Tr "explorer.go")}} | ||||||
|  | 							{{end}} | ||||||
| 						</div> | 						</div> | ||||||
| 					</form> | 					</form> | ||||||
| 					<!-- Sort --> | 					<!-- Sort --> | ||||||
| @@ -63,14 +65,14 @@ | |||||||
| 							{{svg "octicon-triangle-down" 14 "dropdown icon"}} | 							{{svg "octicon-triangle-down" 14 "dropdown icon"}} | ||||||
| 						</span> | 						</span> | ||||||
| 						<div class="menu"> | 						<div class="menu"> | ||||||
| 							<a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> | 							<a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> | ||||||
| 							<a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> | 							<a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> | ||||||
| 							<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> | 							<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> | ||||||
| 							<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> | 							<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> | ||||||
| 							<a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> | 							<a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> | ||||||
| 							<a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> | 							<a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> | ||||||
| 							<a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> | 							<a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> | ||||||
| 							<a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> | 							<a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 				</div> | 				</div> | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ textarea, | |||||||
|  |  | ||||||
| /* fix fomantic small dropdown having inconsistent padding with input */ | /* fix fomantic small dropdown having inconsistent padding with input */ | ||||||
| .ui.small.selection.dropdown { | .ui.small.selection.dropdown { | ||||||
|   padding: .67857143em 3.2em .67857143em 1em; |   padding: .67857143em 1.6em .67857143em 1em; | ||||||
| } | } | ||||||
|  |  | ||||||
| input:hover, | input:hover, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user