mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-10 00:26:14 +02:00
Add archived repository filters to global code search
This commit is contained in:
1 parent
4f9f0fc4b8
commit
4034e6d709
11 files changed
+215
-13
No files matched your search
@@ -97,7 +97,7 @@ func UpdateIndexerStatus(ctx context.Context, repo *Repository, indexerType Repo
|
|||||||
return fmt.Errorf("UpdateIndexerStatus: Unable to getIndexerStatus for repo: %s Error: %w", repo.FullName(), err)
|
return fmt.Errorf("UpdateIndexerStatus: Unable to getIndexerStatus for repo: %s Error: %w", repo.FullName(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(status.CommitSha) == 0 {
|
if status.ID == 0 {
|
||||||
status.CommitSha = sha
|
status.CommitSha = sha
|
||||||
if err := db.Insert(ctx, status); err != nil {
|
if err := db.Insert(ctx, status); err != nil {
|
||||||
return fmt.Errorf("UpdateIndexerStatus: Unable to insert repoIndexerStatus for repo: %s Sha: %s Error: %w", repo.FullName(), sha, err)
|
return fmt.Errorf("UpdateIndexerStatus: Unable to insert repoIndexerStatus for repo: %s Sha: %s Error: %w", repo.FullName(), sha, err)
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
|
|||||||
// RepoIndexerData data stored in the repo indexer
|
// RepoIndexerData data stored in the repo indexer
|
||||||
type RepoIndexerData struct {
|
type RepoIndexerData struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
|
Archived bool
|
||||||
CommitID string
|
CommitID string
|
||||||
Content string
|
Content string
|
||||||
Filename string
|
Filename string
|
||||||
@@ -71,7 +72,7 @@ const (
|
|||||||
filenameIndexerAnalyzer = "filenameIndexerAnalyzer"
|
filenameIndexerAnalyzer = "filenameIndexerAnalyzer"
|
||||||
filenameIndexerTokenizer = "filenameIndexerTokenizer"
|
filenameIndexerTokenizer = "filenameIndexerTokenizer"
|
||||||
repoIndexerDocType = "repoIndexerDocType"
|
repoIndexerDocType = "repoIndexerDocType"
|
||||||
repoIndexerLatestVersion = 9
|
repoIndexerLatestVersion = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
// generateBleveIndexMapping generates a bleve index mapping for the repo indexer
|
// generateBleveIndexMapping generates a bleve index mapping for the repo indexer
|
||||||
@@ -81,6 +82,10 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
|
|||||||
numericFieldMapping.IncludeInAll = false
|
numericFieldMapping.IncludeInAll = false
|
||||||
docMapping.AddFieldMappingsAt("RepoID", numericFieldMapping)
|
docMapping.AddFieldMappingsAt("RepoID", numericFieldMapping)
|
||||||
|
|
||||||
|
boolFieldMapping := bleve.NewBooleanFieldMapping()
|
||||||
|
boolFieldMapping.IncludeInAll = false
|
||||||
|
docMapping.AddFieldMappingsAt("Archived", boolFieldMapping)
|
||||||
|
|
||||||
textFieldMapping := bleve.NewTextFieldMapping()
|
textFieldMapping := bleve.NewTextFieldMapping()
|
||||||
textFieldMapping.IncludeInAll = false
|
textFieldMapping.IncludeInAll = false
|
||||||
docMapping.AddFieldMappingsAt("Content", textFieldMapping)
|
docMapping.AddFieldMappingsAt("Content", textFieldMapping)
|
||||||
@@ -195,6 +200,7 @@ func (b *Indexer) addUpdate(ctx context.Context, catFileBatch git.CatFileBatch,
|
|||||||
id := internal.FilenameIndexerID(repo.ID, update.Filename)
|
id := internal.FilenameIndexerID(repo.ID, update.Filename)
|
||||||
return batch.Index(id, &RepoIndexerData{
|
return batch.Index(id, &RepoIndexerData{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
|
Archived: repo.IsArchived,
|
||||||
CommitID: commitSha,
|
CommitID: commitSha,
|
||||||
Filename: update.Filename,
|
Filename: update.Filename,
|
||||||
Content: string(charset.ToUTF8DropErrors(fileContents)),
|
Content: string(charset.ToUTF8DropErrors(fileContents)),
|
||||||
@@ -298,6 +304,13 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
|
|||||||
indexerQuery = keywordQuery
|
indexerQuery = keywordQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.Archived.Has() {
|
||||||
|
indexerQuery = bleve.NewConjunctionQuery(
|
||||||
|
indexerQuery,
|
||||||
|
inner_bleve.BoolFieldQuery(opts.Archived.Value(), "Archived"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Save for reuse without language filter
|
// Save for reuse without language filter
|
||||||
facetQuery := indexerQuery
|
facetQuery := indexerQuery
|
||||||
if len(opts.Language) > 0 {
|
if len(opts.Language) > 0 {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
esRepoIndexerLatestVersion = 3
|
esRepoIndexerLatestVersion = 4
|
||||||
// multi-match-types, currently only 2 types are used
|
// multi-match-types, currently only 2 types are used
|
||||||
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
|
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
|
||||||
esMultiMatchTypeBestFields = "best_fields"
|
esMultiMatchTypeBestFields = "best_fields"
|
||||||
@@ -100,6 +100,10 @@ const (
|
|||||||
"type": "long",
|
"type": "long",
|
||||||
"index": true
|
"index": true
|
||||||
},
|
},
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean",
|
||||||
|
"index": true
|
||||||
|
},
|
||||||
"filename": {
|
"filename": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"term_vector": "with_positions_offsets",
|
"term_vector": "with_positions_offsets",
|
||||||
@@ -185,6 +189,7 @@ func (b *Indexer) addUpdate(ctx context.Context, catFileBatch git.CatFileBatch,
|
|||||||
Id(id).
|
Id(id).
|
||||||
Doc(map[string]any{
|
Doc(map[string]any{
|
||||||
"repo_id": repo.ID,
|
"repo_id": repo.ID,
|
||||||
|
"archived": repo.IsArchived,
|
||||||
"filename": update.Filename,
|
"filename": update.Filename,
|
||||||
"content": string(charset.ToUTF8DropErrors(fileContents)),
|
"content": string(charset.ToUTF8DropErrors(fileContents)),
|
||||||
"commit_id": sha,
|
"commit_id": sha,
|
||||||
@@ -377,6 +382,9 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
|
|||||||
repoQuery := elastic.NewTermsQuery("repo_id", repoStrs...)
|
repoQuery := elastic.NewTermsQuery("repo_id", repoStrs...)
|
||||||
query = query.Must(repoQuery)
|
query = query.Must(repoQuery)
|
||||||
}
|
}
|
||||||
|
if opts.Archived.Has() {
|
||||||
|
query = query.Must(elastic.NewTermQuery("archived", opts.Archived.Value()))
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
start, pageSize = opts.GetSkipTake()
|
start, pageSize = opts.GetSkipTake()
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
indexer_module "code.gitea.io/gitea/modules/indexer"
|
indexer_module "code.gitea.io/gitea/modules/indexer"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/bleve"
|
"code.gitea.io/gitea/modules/indexer/code/bleve"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/elasticsearch"
|
"code.gitea.io/gitea/modules/indexer/code/elasticsearch"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||||
|
"code.gitea.io/gitea/modules/optional"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/test"
|
"code.gitea.io/gitea/modules/test"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
@@ -280,6 +282,110 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
|
|||||||
|
|
||||||
assert.NoError(t, tearDownRepositoryIndexes(t.Context(), indexer))
|
assert.NoError(t, tearDownRepositoryIndexes(t.Context(), indexer))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run(name+"_archived_filter", func(t *testing.T) {
|
||||||
|
assert.NoError(t, setupRepositoryIndexes(t.Context(), indexer))
|
||||||
|
t.Cleanup(func() {
|
||||||
|
assert.NoError(t, tearDownRepositoryIndexes(context.Background(), indexer))
|
||||||
|
})
|
||||||
|
|
||||||
|
repo1, err := repo_model.GetRepositoryByID(t.Context(), 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
repo62, err := repo_model.GetRepositoryByID(t.Context(), 62)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
originalRepo1Archived := repo1.IsArchived
|
||||||
|
originalRepo62Archived := repo62.IsArchived
|
||||||
|
t.Cleanup(func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
require.NoError(t, repo_model.SetArchiveRepoState(ctx, repo1, originalRepo1Archived))
|
||||||
|
require.NoError(t, repo_model.SetArchiveRepoState(ctx, repo62, originalRepo62Archived))
|
||||||
|
require.NoError(t, repo_model.UpdateIndexerStatus(ctx, repo1, repo_model.RepoIndexerTypeCode, ""))
|
||||||
|
require.NoError(t, repo_model.UpdateIndexerStatus(ctx, repo62, repo_model.RepoIndexerTypeCode, ""))
|
||||||
|
require.NoError(t, index(ctx, indexer, repo1.ID))
|
||||||
|
require.NoError(t, index(ctx, indexer, repo62.ID))
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, repo_model.SetArchiveRepoState(t.Context(), repo1, false))
|
||||||
|
require.NoError(t, repo_model.SetArchiveRepoState(t.Context(), repo62, true))
|
||||||
|
require.NoError(t, repo_model.UpdateIndexerStatus(t.Context(), repo1, repo_model.RepoIndexerTypeCode, ""))
|
||||||
|
require.NoError(t, repo_model.UpdateIndexerStatus(t.Context(), repo62, repo_model.RepoIndexerTypeCode, ""))
|
||||||
|
require.NoError(t, index(t.Context(), indexer, repo1.ID))
|
||||||
|
require.NoError(t, index(t.Context(), indexer, repo62.ID))
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
keyword string
|
||||||
|
archived optional.Option[bool]
|
||||||
|
total int64
|
||||||
|
filenames []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "exclude_archived_repo_results",
|
||||||
|
keyword: "cucumber",
|
||||||
|
archived: optional.Some(false),
|
||||||
|
total: 0,
|
||||||
|
filenames: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "include_archived_repo_results",
|
||||||
|
keyword: "cucumber",
|
||||||
|
archived: optional.None[bool](),
|
||||||
|
total: 2,
|
||||||
|
filenames: []string{"cucumber.md", "avocado.md"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only_archived_repo_results",
|
||||||
|
keyword: "cucumber",
|
||||||
|
archived: optional.Some(true),
|
||||||
|
total: 2,
|
||||||
|
filenames: []string{"cucumber.md", "avocado.md"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "exclude_keeps_non_archived_repo_results",
|
||||||
|
keyword: "Description",
|
||||||
|
archived: optional.Some(false),
|
||||||
|
total: 1,
|
||||||
|
filenames: []string{"README.md"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "include_keeps_non_archived_repo_results",
|
||||||
|
keyword: "Description",
|
||||||
|
archived: optional.None[bool](),
|
||||||
|
total: 1,
|
||||||
|
filenames: []string{"README.md"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only_excludes_non_archived_repo_results",
|
||||||
|
keyword: "Description",
|
||||||
|
archived: optional.Some(true),
|
||||||
|
total: 0,
|
||||||
|
filenames: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
total, res, _, err := indexer.Search(t.Context(), &internal.SearchOptions{
|
||||||
|
Keyword: tc.keyword,
|
||||||
|
SearchMode: indexer_module.SearchModeWords,
|
||||||
|
Archived: tc.archived,
|
||||||
|
Paginator: &db.ListOptions{
|
||||||
|
Page: 1,
|
||||||
|
PageSize: 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tc.total, total)
|
||||||
|
|
||||||
|
filenames := make([]string, 0, len(res))
|
||||||
|
for _, hit := range res {
|
||||||
|
filenames = append(filenames, hit.Filename)
|
||||||
|
}
|
||||||
|
assert.Equal(t, tc.filenames, filenames)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBleveIndexAndSearch(t *testing.T) {
|
func TestBleveIndexAndSearch(t *testing.T) {
|
||||||
@@ -332,6 +438,13 @@ func tearDownRepositoryIndexes(ctx context.Context, indexer internal.Indexer) er
|
|||||||
if err := indexer.Delete(ctx, repoID); err != nil {
|
if err := indexer.Delete(ctx, repoID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
repo, err := repo_model.GetRepositoryByID(ctx, repoID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := repo_model.UpdateIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/indexer"
|
"code.gitea.io/gitea/modules/indexer"
|
||||||
"code.gitea.io/gitea/modules/indexer/internal"
|
"code.gitea.io/gitea/modules/indexer/internal"
|
||||||
|
"code.gitea.io/gitea/modules/optional"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Indexer defines an interface to index and search code contents
|
// Indexer defines an interface to index and search code contents
|
||||||
@@ -28,6 +29,7 @@ type SearchOptions struct {
|
|||||||
Language string
|
Language string
|
||||||
|
|
||||||
SearchMode indexer.SearchModeType
|
SearchMode indexer.SearchModeType
|
||||||
|
Archived optional.Option[bool]
|
||||||
|
|
||||||
db.Paginator
|
db.Paginator
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,8 @@
|
|||||||
"search.type_tooltip": "Search type",
|
"search.type_tooltip": "Search type",
|
||||||
"search.fuzzy": "Fuzzy",
|
"search.fuzzy": "Fuzzy",
|
||||||
"search.fuzzy_tooltip": "Include results that closely match the search term",
|
"search.fuzzy_tooltip": "Include results that closely match the search term",
|
||||||
|
"search.code_archived_filter.all": "Archived and not archived",
|
||||||
|
"search.code_archived_filter.not_archived": "Not Archived",
|
||||||
"search.words": "Words",
|
"search.words": "Words",
|
||||||
"search.words_tooltip": "Include only results that match the search term words",
|
"search.words_tooltip": "Include only results that match the search term words",
|
||||||
"search.regexp": "Regexp",
|
"search.regexp": "Regexp",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
unit_model "code.gitea.io/gitea/models/unit"
|
unit_model "code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
code_indexer "code.gitea.io/gitea/modules/indexer/code"
|
||||||
"code.gitea.io/gitea/modules/label"
|
"code.gitea.io/gitea/modules/label"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/optional"
|
"code.gitea.io/gitea/modules/optional"
|
||||||
@@ -1014,6 +1015,12 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
|
|||||||
if err := actions_service.CleanRepoScheduleTasks(ctx, repo); err != nil {
|
if err := actions_service.CleanRepoScheduleTasks(ctx, repo); err != nil {
|
||||||
log.Error("CleanRepoScheduleTasks for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
log.Error("CleanRepoScheduleTasks for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
}
|
}
|
||||||
|
if setting.Indexer.RepoIndexerEnabled {
|
||||||
|
if err := repo_model.UpdateIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode, ""); err != nil {
|
||||||
|
log.Error("Reset code indexer status for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
|
}
|
||||||
|
code_indexer.UpdateRepoIndexer(repo)
|
||||||
|
}
|
||||||
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
} else {
|
} else {
|
||||||
if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil {
|
if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil {
|
||||||
@@ -1026,6 +1033,12 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
|
|||||||
log.Error("DetectAndHandleSchedules for un-archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
log.Error("DetectAndHandleSchedules for un-archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if setting.Indexer.RepoIndexerEnabled {
|
||||||
|
if err := repo_model.UpdateIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode, ""); err != nil {
|
||||||
|
log.Error("Reset code indexer status for un-archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
|
}
|
||||||
|
code_indexer.UpdateRepoIndexer(repo)
|
||||||
|
}
|
||||||
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
code_indexer "code.gitea.io/gitea/modules/indexer/code"
|
code_indexer "code.gitea.io/gitea/modules/indexer/code"
|
||||||
|
"code.gitea.io/gitea/modules/optional"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
"code.gitea.io/gitea/routers/common"
|
"code.gitea.io/gitea/routers/common"
|
||||||
@@ -19,8 +20,27 @@ import (
|
|||||||
const (
|
const (
|
||||||
// tplExploreCode explore code page template
|
// tplExploreCode explore code page template
|
||||||
tplExploreCode templates.TplName = "explore/code"
|
tplExploreCode templates.TplName = "explore/code"
|
||||||
|
|
||||||
|
archivedModeExclude = "exclude"
|
||||||
|
archivedModeInclude = "include"
|
||||||
|
archivedModeOnly = "only"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func parseArchivedMode(value string) (string, optional.Option[bool]) {
|
||||||
|
switch value {
|
||||||
|
case archivedModeInclude:
|
||||||
|
return archivedModeInclude, optional.None[bool]()
|
||||||
|
case "":
|
||||||
|
return archivedModeInclude, optional.None[bool]()
|
||||||
|
case archivedModeOnly:
|
||||||
|
return archivedModeOnly, optional.Some(true)
|
||||||
|
case archivedModeExclude:
|
||||||
|
return archivedModeExclude, optional.Some(false)
|
||||||
|
default:
|
||||||
|
return archivedModeInclude, optional.None[bool]()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Code render explore code page
|
// Code render explore code page
|
||||||
func Code(ctx *context.Context) {
|
func Code(ctx *context.Context) {
|
||||||
if !setting.Indexer.RepoIndexerEnabled || setting.Service.Explore.DisableCodePage {
|
if !setting.Indexer.RepoIndexerEnabled || setting.Service.Explore.DisableCodePage {
|
||||||
@@ -36,6 +56,10 @@ func Code(ctx *context.Context) {
|
|||||||
ctx.Data["PageIsExploreCode"] = true
|
ctx.Data["PageIsExploreCode"] = true
|
||||||
ctx.Data["PageIsViewCode"] = true
|
ctx.Data["PageIsViewCode"] = true
|
||||||
|
|
||||||
|
archivedMode, archivedFilter := parseArchivedMode(ctx.FormTrim("archived"))
|
||||||
|
ctx.Data["ArchivedMode"] = archivedMode
|
||||||
|
ctx.Data["IsArchived"] = archivedFilter
|
||||||
|
|
||||||
prepareSearch := common.PrepareCodeSearch(ctx)
|
prepareSearch := common.PrepareCodeSearch(ctx)
|
||||||
if prepareSearch.Keyword == "" {
|
if prepareSearch.Keyword == "" {
|
||||||
ctx.HTML(http.StatusOK, tplExploreCode)
|
ctx.HTML(http.StatusOK, tplExploreCode)
|
||||||
@@ -77,6 +101,7 @@ func Code(ctx *context.Context) {
|
|||||||
Keyword: prepareSearch.Keyword,
|
Keyword: prepareSearch.Keyword,
|
||||||
SearchMode: prepareSearch.SearchMode,
|
SearchMode: prepareSearch.SearchMode,
|
||||||
Language: prepareSearch.Language,
|
Language: prepareSearch.Language,
|
||||||
|
Archived: archivedFilter,
|
||||||
Paginator: &db.ListOptions{
|
Paginator: &db.ListOptions{
|
||||||
Page: page,
|
Page: page,
|
||||||
PageSize: setting.UI.RepoSearchPagingNum,
|
PageSize: setting.UI.RepoSearchPagingNum,
|
||||||
|
|||||||
@@ -962,6 +962,12 @@ func handleSettingsPostArchive(ctx *context.Context) {
|
|||||||
|
|
||||||
// update issue indexer
|
// update issue indexer
|
||||||
issue_indexer.UpdateRepoIndexer(ctx, repo.ID)
|
issue_indexer.UpdateRepoIndexer(ctx, repo.ID)
|
||||||
|
if setting.Indexer.RepoIndexerEnabled {
|
||||||
|
if err := repo_model.UpdateIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode, ""); err != nil {
|
||||||
|
log.Error("Reset code indexer status for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
|
}
|
||||||
|
code.UpdateRepoIndexer(repo)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.archive.success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.archive.success"))
|
||||||
|
|
||||||
@@ -991,6 +997,12 @@ func handleSettingsPostUnarchive(ctx *context.Context) {
|
|||||||
|
|
||||||
// update issue indexer
|
// update issue indexer
|
||||||
issue_indexer.UpdateRepoIndexer(ctx, repo.ID)
|
issue_indexer.UpdateRepoIndexer(ctx, repo.ID)
|
||||||
|
if setting.Indexer.RepoIndexerEnabled {
|
||||||
|
if err := repo_model.UpdateIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode, ""); err != nil {
|
||||||
|
log.Error("Reset code indexer status for un-archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
|
||||||
|
}
|
||||||
|
code.UpdateRepoIndexer(repo)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.unarchive.success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.unarchive.success"))
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="flex-text-block tw-flex-wrap">
|
<div class="flex-text-block tw-flex-wrap">
|
||||||
{{range $term := .SearchResultLanguages}}
|
{{range $term := .SearchResultLanguages}}
|
||||||
<a class="ui {{if eq $.Language $term.Language}}primary{{end}} basic label tw-m-0"
|
<a class="ui {{if eq $.Language $term.Language}}primary{{end}} basic label tw-m-0"
|
||||||
href="?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}&search_mode={{$.SelectedSearchMode}}">
|
href="?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}{{if $.SelectedSearchMode}}&search_mode={{$.SelectedSearchMode}}{{end}}{{if $.ArchivedMode}}&archived={{$.ArchivedMode}}{{end}}">
|
||||||
<i class="color-icon tw-mr-2" style="background-color: {{$term.Color}}"></i>
|
<i class="color-icon tw-mr-2" style="background-color: {{$term.Color}}"></i>
|
||||||
{{$term.Language}}
|
{{$term.Language}}
|
||||||
<div class="detail">{{$term.Count}}</div>
|
<div class="detail">{{$term.Count}}</div>
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
<form class="ui form ignore-dirty">
|
<div class="ui small secondary filter menu">
|
||||||
{{template "shared/search/combo" (dict
|
<form id="repo-search-form" class="ui form ignore-dirty tw-flex-1 tw-flex tw-items-center tw-gap-x-2">
|
||||||
"Disabled" .CodeIndexerUnavailable
|
{{if .Language}}<input type="hidden" name="l" value="{{.Language}}">{{end}}
|
||||||
"Value" .Keyword
|
<div class="tw-flex-1">
|
||||||
"Placeholder" (ctx.Locale.Tr "search.code_kind")
|
{{template "shared/search/combo" (dict
|
||||||
"SearchModes" .SearchModes
|
"Disabled" .CodeIndexerUnavailable
|
||||||
"SelectedSearchMode" .SelectedSearchMode
|
"Value" .Keyword
|
||||||
)}}
|
"Placeholder" (ctx.Locale.Tr "search.code_kind")
|
||||||
</form>
|
"SearchModes" .SearchModes
|
||||||
|
"SelectedSearchMode" .SelectedSearchMode
|
||||||
|
)}}
|
||||||
|
</div>
|
||||||
|
<div class="item ui small dropdown jump">
|
||||||
|
<span class="text">{{ctx.Locale.Tr "filter_title"}}</span>
|
||||||
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
|
<div class="menu flex-items-menu">
|
||||||
|
<label class="item"><input type="radio" name="archived" {{if eq .ArchivedMode "include"}}checked{{end}} value="include"> {{ctx.Locale.Tr "search.code_archived_filter.all"}}</label>
|
||||||
|
<label class="item"><input type="radio" name="archived" {{if eq .ArchivedMode "exclude"}}checked{{end}} value="exclude"> {{ctx.Locale.Tr "search.code_archived_filter.not_archived"}}</label>
|
||||||
|
<label class="item"><input type="radio" name="archived" {{if .IsArchived.Value}}checked{{end}} value="only"> {{ctx.Locale.Tr "filter.is_archived"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div class="ui list">
|
<div class="ui list">
|
||||||
{{template "base/alert" .}}
|
{{template "base/alert" .}}
|
||||||
|
|||||||
Reference in new issue
Block a user