Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Find files in repo #15028

Merged
merged 36 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d83aecd
Create finding files page ui in repo page
rogerluo410 Mar 16, 2021
efe69d4
Modify router
rogerluo410 Mar 16, 2021
c4e3195
Get tree entries for find repo files.
rogerluo410 Mar 17, 2021
ea4110f
Conplete find files in repo.
rogerluo410 Mar 18, 2021
2d6a36b
Make fmt
rogerluo410 Mar 18, 2021
bbf1b6d
Merge branch 'master' into dev-find-file
rogerluo410 Mar 18, 2021
5ce4a6d
Update comment.
rogerluo410 Mar 18, 2021
5239d40
Move find files JS to individual file.
rogerluo410 Mar 19, 2021
09fe0f4
Fix go lint
rogerluo410 Mar 19, 2021
c7f622d
Update find repo files.
rogerluo410 Mar 23, 2021
6878f15
Merge branch 'master' into dev-find-file
rogerluo410 Mar 23, 2021
7d32375
gen swagger.
rogerluo410 Mar 23, 2021
ba6b069
gen swagger
rogerluo410 Mar 23, 2021
224c5d9
Add comment to redo ci
rogerluo410 Mar 23, 2021
4b90809
Add enry.IsVendor to exclude entries
rogerluo410 Mar 24, 2021
6661746
Merge branch 'master' into dev-find-file
rogerluo410 Nov 25, 2021
4e52afb
Make lint
rogerluo410 Nov 25, 2021
58802bd
Fix histroy conflicts
rogerluo410 Nov 25, 2021
1c5866d
Missing file
rogerluo410 Nov 25, 2021
a338737
Change HTML id naming style
rogerluo410 Nov 25, 2021
48dbb92
Merge branch 'master' into dev-find-file
rogerluo410 May 31, 2022
c34cd2f
Fix jquery $ variable not found issue
rogerluo410 May 31, 2022
22e79f5
Fix break too early when filtering.
rogerluo410 May 31, 2022
a1188ba
Fix id naming
rogerluo410 May 31, 2022
28951f9
revert package-lock.json
wxiaoguang Jun 7, 2022
12a9b8a
Merge branch 'main' into dev-find-file
wxiaoguang Jun 7, 2022
110afce
refactor
wxiaoguang Jun 7, 2022
02e17eb
fmt
wxiaoguang Jun 7, 2022
77ddc4d
fine tune HTML layout
wxiaoguang Jun 7, 2022
eaef506
Merge branch 'main' into dev-find-file
wxiaoguang Jun 7, 2022
c3b4e22
fine tune
wxiaoguang Jun 7, 2022
86116fe
Merge branch 'main' into dev-find-file
lunny Jun 8, 2022
7ac1f66
Apply suggestions from code review
wxiaoguang Jun 9, 2022
20b7325
add some comments
wxiaoguang Jun 9, 2022
65b69f2
use hidden instead of style, optimize strSubMatch for remaining chars
wxiaoguang Jun 9, 2022
5758ba3
Merge branch 'main' into dev-find-file
wxiaoguang Jun 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ delete_preexisting_label = Delete
delete_preexisting = Delete pre-existing files
delete_preexisting_content = Delete files in %s
delete_preexisting_success = Deleted unadopted files in %s
filter_repo_files_no_matching = No matching files found

transfer.accept = Accept Transfer
transfer.accept_desc = Transfer to "%s"
Expand Down Expand Up @@ -2576,6 +2577,7 @@ publish_release = `released <a href="%s/releases/tag/%s"> "%[4]s" </a> at <a hr
review_dismissed = `dismissed review from <b>%[4]s</b> for <a href="%[1]s/pulls/%[2]s">%[3]s#%[2]s</a>`
review_dismissed_reason = Reason:
create_branch = created branch <a href="%[1]s/src/branch/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a>
find_file = Go to file
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved

[tool]
ago = %s ago
Expand Down
64 changes: 64 additions & 0 deletions routers/repo/find.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package repo

import (
_ "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
)

const (
tplFindFiles base.TplName = "repo/find/files"
)

// render the page to find repository files
func FindFiles(ctx *context.Context) {
ctx.Data["PageIsFindFiles"] = true
ctx.Data["PageIsViewCode"] = true

branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
treeLink := branchLink

if len(ctx.Repo.TreePath) > 0 {
treeLink += "/" + ctx.Repo.TreePath
}

renderFiles(ctx, treeLink)

if ctx.Written() {
return
}

ctx.Data["RepoLink"] = ctx.Repo.RepoLink
ctx.Data["RepoName"] = ctx.Repo.Repository.Name
ctx.Data["TreeLink"] = treeLink

ctx.HTML(200, tplFindFiles)
}

func renderFiles(ctx *context.Context, treeLink string) {
tree, err := ctx.Repo.Commit.SubTree(ctx.Repo.TreePath)
if err != nil {
ctx.NotFoundOrServerError("Repo.Commit.SubTree", git.IsErrNotExist, err)
return
}

entries, err := tree.ListEntriesRecursive()
if err != nil {
ctx.ServerError("ListEntries", err)
return
}
entries.CustomSort(base.NaturalSortLess)

var fileEntries []*git.TreeEntry
for _, entry := range entries {
if !entry.IsDir() && !entry.IsSubModule() {
fileEntries = append(fileEntries, entry)
}
}
ctx.Data["Files"] = fileEntries
}
1 change: 1 addition & 0 deletions routers/routes/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ func RegisterRoutes(m *web.Route) {
m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists).
Get(ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff).
Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, bindIgnErr(auth.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost)
m.Get("/find/*", context.RepoRefByType(context.RepoRefBranch), repo.FindFiles)
}, context.RepoAssignment(), context.UnitTypes())

// Grouping for those endpoints that do require authentication
Expand Down
29 changes: 29 additions & 0 deletions templates/repo/find/files.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{template "base/head" .}}
<div class="page-content repository file list">
{{template "repo/header" .}}
<div class="ui container">
<div class="repo-title">
<a href="{{$.RepoLink}}">{{.RepoName}}</a>
<span class="mr-3 ml-3">/</span>
<input id="repo-file-find-input" type="text" style="border:none;outline:none;" autofocus="autofocus">
</div>
<table id="repo-find-files-table" class="ui single line table">
<tbody>
{{range $entry := .Files}}
<tr>
<td class="name four wide">
<span class="truncate">
{{svg (printf "octicon-%s" (EntryIcon $entry))}}
<a class="find-file-name" href="{{EscapePound $.TreeLink}}/{{EscapePound $entry.Name}}" title="{{$entry.Name}}">{{$entry.Name}}</a>
</span>
</td>
</tr>
{{end}}
</tbody>
</table>
<div id="no-hit-prompt" class="ui row center" style="margin-top: 60px;display:none;">
<h3>{{.i18n.Tr "repo.filter_repo_files_no_matching"}}</h3>
</div>
</div>
</div>
{{template "base/footer" .}}
5 changes: 5 additions & 0 deletions templates/repo/home.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
</a>
</div>
{{end}}
<div class="fitted item mx-0">
<a href="{{.BaseRepo.Link}}/find/{{.BranchName | EscapePound}}">
<button id="new-pull-request" class="ui compact basic button">{{.i18n.Tr "action.find_file"}}</button>
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
</a>
</div>
{{else}}
<div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div>
{{end}}
Expand Down
76 changes: 76 additions & 0 deletions web_src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,81 @@ function searchRepositories() {
});
}

function hitAllKeys(keys, entry) {
let i = 0;
let j = 0;
const hitIndexes = [];
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
while (i < keys.length) {
for (; j < entry.length; j++) {
if (keys[i] === entry[j]) {
hitIndexes.push(j);
j++;
break;
}
}
i++;
}

return hitIndexes;
}

function addHighLightToHit($a, entry, indexes) {
let highLightText = '';
for (let i = 0; i < entry.length; i++) {
if (indexes.includes(i)) {
highLightText += `<b>${entry[i]}</b>`;
} else {
highLightText += entry[i];
}
}
$a.html(highLightText);
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
}

function removeHighLight($a, entry) {
$a.text(entry.replace(/(<([^>]+)>)/ig, ''));
}

function filterRepoFiles(keys) {
if (keys.length > 0) {
let hit = false;
$('#repo-find-files-table tr').each(function() {
const entry = $(this).find('td:first').text();
const $a = $(this).find('td:first').find('a:first');
const keysTrim = keys.trim();
const entryTrim = entry.trim();
const hitIndexes = hitAllKeys(keysTrim, entryTrim);
if (hitIndexes.length > 0 && keysTrim.length === hitIndexes.length) {
addHighLightToHit($a, entryTrim, hitIndexes);
$(this).show();
hit = true;
} else {
removeHighLight($a, entryTrim);
$(this).hide();
}
});
if (hit) {
$('#no-hit-prompt').hide();
} else {
$('#no-hit-prompt').show();
}
} else {
// Remove all highlight
$('#repo-find-files-table tr').each(function() {
const entry = $(this).find('td:first').text();
const $a = $(this).find('td:first').find('a:first');
removeHighLight($a, entry.trim());
});
$('#no-hit-prompt').hide();
$('#repo-find-files-table tr').show();
}
}

function initFindFileInRepo() {
$('#repo-file-find-input').on('change paste keyup', () => {
filterRepoFiles($('#repo-file-find-input').val());
});
}

lunny marked this conversation as resolved.
Show resolved Hide resolved
function showCodeViewMenu() {
// Get clicked tr
const $code_tr = $('.code-view td.lines-code.active').parent();
Expand Down Expand Up @@ -2739,6 +2814,7 @@ $(document).ready(async () => {
initNotificationsTable();
initPullRequestMergeInstruction();
initReleaseEditor();
initFindFileInRepo();

const routes = {
'div.user.settings': initUserSettings,
Expand Down