From 86442ad680c9cbbef25d42c025eb869054f2ae8b Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 17 Aug 2019 14:35:19 -0500 Subject: [PATCH 01/26] in progress changes for #7405, added ability to add cross-repo dependencies --- models/issue.go | 60 +++++++++--- models/issue_label.go | 13 +++ models/issue_test.go | 9 +- modules/indexer/issues/bleve.go | 16 ++- modules/indexer/issues/bleve_test.go | 2 +- modules/indexer/issues/db.go | 7 +- modules/indexer/issues/indexer.go | 11 +-- modules/indexer/issues/indexer_test.go | 16 +-- options/locale/locale_cs-CZ.ini | 1 - options/locale/locale_de-DE.ini | 1 - options/locale/locale_en-US.ini | 1 - options/locale/locale_es-ES.ini | 1 - options/locale/locale_fr-FR.ini | 1 - options/locale/locale_ja-JP.ini | 1 - options/locale/locale_lv-LV.ini | 1 - options/locale/locale_pt-BR.ini | 1 - options/locale/locale_ru-RU.ini | 1 - options/locale/locale_uk-UA.ini | 1 - options/locale/locale_zh-CN.ini | 1 - public/js/index.js | 2 +- routers/api/v1/api.go | 2 + routers/api/v1/repo/issue.go | 98 ++++++++++++++++++- routers/repo/issue.go | 2 +- routers/repo/issue_dependency.go | 6 -- .../repo/issue/view_content/sidebar.tmpl | 8 +- templates/swagger/v1_json.tmpl | 43 ++++++++ 26 files changed, 244 insertions(+), 62 deletions(-) diff --git a/models/issue.go b/models/issue.go index 7561083e0fc69..328f15407af9d 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1747,8 +1747,8 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen } // SearchIssueIDsByKeyword search issues on database -func SearchIssueIDsByKeyword(kw string, repoID int64, limit, start int) (int64, []int64, error) { - var repoCond = builder.Eq{"repo_id": repoID} +func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int64, []int64, error) { + var repoCond = builder.In("repo_id", repoIDs) var subQuery = builder.Select("id").From("issue").Where(repoCond) var cond = builder.And( repoCond, @@ -1820,33 +1820,69 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix util.TimeStamp, doer *User) return sess.Commit() } +// DependencyInfo represents high level information about an issue which is a dependency of another issue. +type DependencyInfo struct { + ID int64 `xorm:"id"` + RepoID int64 `xorm:"repo_id"` + Index int64 `xorm:"index"` + IsClosed bool `xorm:"is_closed"` + Title string `xorm:"name"` + RepoLink string `xorm:"-"` +} + // Get Blocked By Dependencies, aka all issues this issue is blocked by. -func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*Issue, err error) { - return issueDeps, e. - Table("issue_dependency"). - Select("issue.*"). +func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { + err = e.Table("issue_dependency"). + Select("issue.id, issue.repo_id, issue.index, issue.is_closed, issue.name"). Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) + + if err != nil { + return nil, err + } + + for i := 0; i < len(issueDeps); i++ { + repo, err := GetRepositoryByID(issueDeps[i].RepoID) + if err != nil { + return nil, err + } + issueDeps[i].RepoLink = repo.Link() + } + + return issueDeps, nil } // Get Blocking Dependencies, aka all issues this issue blocks. -func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*Issue, err error) { - return issueDeps, e. - Table("issue_dependency"). - Select("issue.*"). +func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { + err = e.Table("issue_dependency"). + Select("issue.id, issue.repo_id, issue.index, issue.is_closed, issue.name"). Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) + + if err != nil { + return nil, err + } + + for i := 0; i < len(issueDeps); i++ { + repo, err := GetRepositoryByID(issueDeps[i].RepoID) + if err != nil { + return nil, err + } + issueDeps[i].RepoLink = repo.Link() + } + + return issueDeps, nil } // BlockedByDependencies finds all Dependencies an issue is blocked by -func (issue *Issue) BlockedByDependencies() ([]*Issue, error) { +func (issue *Issue) BlockedByDependencies() ([]*DependencyInfo, error) { return issue.getBlockedByDependencies(x) } // BlockingDependencies returns all blocking dependencies, aka all other issues a given issue blocks -func (issue *Issue) BlockingDependencies() ([]*Issue, error) { +func (issue *Issue) BlockingDependencies() ([]*DependencyInfo, error) { return issue.getBlockingDependencies(x) } diff --git a/models/issue_label.go b/models/issue_label.go index 7af6060f87cd7..e3e4d87f0e2e6 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -217,6 +217,19 @@ func GetLabelIDsInRepoByNames(repoID int64, labelNames []string) ([]int64, error Find(&labelIDs) } +// GetLabelIDsInReposByNames returns a list of labelIDs by names in one of the given +// repositories. +// it silently ignores label names that do not belong to the repository. +func GetLabelIDsInReposByNames(repoIDs []int64, labelNames []string) ([]int64, error) { + labelIDs := make([]int64, 0, len(labelNames)) + return labelIDs, x.Table("label"). + In("repo_id", repoIDs). + In("name", labelNames). + Asc("name"). + Cols("id"). + Find(&labelIDs) +} + // GetLabelInRepoByID returns a label by ID in given repository. func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) { return getLabelInRepoByID(x, repoID, labelID) diff --git a/models/issue_test.go b/models/issue_test.go index 1a7e45ae02bda..b469da5359846 100644 --- a/models/issue_test.go +++ b/models/issue_test.go @@ -298,24 +298,23 @@ func TestIssue_loadTotalTimes(t *testing.T) { func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { assert.NoError(t, PrepareTestDatabase()) - - total, ids, err := SearchIssueIDsByKeyword("issue2", 1, 10, 0) + total, ids, err := SearchIssueIDsByKeyword("issue2", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{2}, ids) - total, ids, err = SearchIssueIDsByKeyword("first", 1, 10, 0) + total, ids, err = SearchIssueIDsByKeyword("first", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) - total, ids, err = SearchIssueIDsByKeyword("for", 1, 10, 0) + total, ids, err = SearchIssueIDsByKeyword("for", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 4, total) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) // issue1's comment id 2 - total, ids, err = SearchIssueIDsByKeyword("good", 1, 10, 0) + total, ids, err = SearchIssueIDsByKeyword("good", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) diff --git a/modules/indexer/issues/bleve.go b/modules/indexer/issues/bleve.go index 36279198b86b0..24443e54a343b 100644 --- a/modules/indexer/issues/bleve.go +++ b/modules/indexer/issues/bleve.go @@ -218,9 +218,18 @@ func (b *BleveIndexer) Delete(ids ...int64) error { // Search searches for issues by given conditions. // Returns the matching issue IDs -func (b *BleveIndexer) Search(keyword string, repoID int64, limit, start int) (*SearchResult, error) { +func (b *BleveIndexer) Search(keyword string, repoIDs []int64, limit, start int) (*SearchResult, error) { + var repoQueriesP []*query.NumericRangeQuery + for _, repoID := range repoIDs { + repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "RepoID")) + } + repoQueries := make([]query.Query, len(repoQueriesP)) + for i, v := range repoQueriesP { + repoQueries[i] = query.Query(v) + } + indexerQuery := bleve.NewConjunctionQuery( - numericEqualityQuery(repoID, "RepoID"), + bleve.NewDisjunctionQuery(repoQueries...), bleve.NewDisjunctionQuery( newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer), newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer), @@ -242,8 +251,7 @@ func (b *BleveIndexer) Search(keyword string, repoID int64, limit, start int) (* return nil, err } ret.Hits = append(ret.Hits, Match{ - ID: id, - RepoID: repoID, + ID: id, }) } return &ret, nil diff --git a/modules/indexer/issues/bleve_test.go b/modules/indexer/issues/bleve_test.go index 8ec274566fa31..94d935d89da5a 100644 --- a/modules/indexer/issues/bleve_test.go +++ b/modules/indexer/issues/bleve_test.go @@ -76,7 +76,7 @@ func TestBleveIndexAndSearch(t *testing.T) { ) for _, kw := range keywords { - res, err := indexer.Search(kw.Keyword, 2, 10, 0) + res, err := indexer.Search(kw.Keyword, []int64{2}, 10, 0) assert.NoError(t, err) var ids = make([]int64, 0, len(res.Hits)) diff --git a/modules/indexer/issues/db.go b/modules/indexer/issues/db.go index 6e7f0c1a6e1f0..7d4e3894712ae 100644 --- a/modules/indexer/issues/db.go +++ b/modules/indexer/issues/db.go @@ -26,8 +26,8 @@ func (db *DBIndexer) Delete(ids ...int64) error { } // Search dummy function -func (db *DBIndexer) Search(kw string, repoID int64, limit, start int) (*SearchResult, error) { - total, ids, err := models.SearchIssueIDsByKeyword(kw, repoID, limit, start) +func (db *DBIndexer) Search(kw string, repoIDs []int64, limit, start int) (*SearchResult, error) { + total, ids, err := models.SearchIssueIDsByKeyword(kw, repoIDs, limit, start) if err != nil { return nil, err } @@ -37,8 +37,7 @@ func (db *DBIndexer) Search(kw string, repoID int64, limit, start int) (*SearchR } for _, id := range ids { result.Hits = append(result.Hits, Match{ - ID: id, - RepoID: repoID, + ID: id, }) } return &result, nil diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index df8bfd6305912..8353e697b494f 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -26,9 +26,8 @@ type IndexerData struct { // Match represents on search result type Match struct { - ID int64 `json:"id"` - RepoID int64 `json:"repo_id"` - Score float64 `json:"score"` + ID int64 `json:"id"` + Score float64 `json:"score"` } // SearchResult represents search results @@ -42,7 +41,7 @@ type Indexer interface { Init() (bool, error) Index(issue []*IndexerData) error Delete(ids ...int64) error - Search(kw string, repoID int64, limit, start int) (*SearchResult, error) + Search(kw string, repoIDs []int64, limit, start int) (*SearchResult, error) } var ( @@ -195,9 +194,9 @@ func DeleteRepoIssueIndexer(repo *models.Repository) { } // SearchIssuesByKeyword search issue ids by keywords and repo id -func SearchIssuesByKeyword(repoID int64, keyword string) ([]int64, error) { +func SearchIssuesByKeyword(repoIDs []int64, keyword string) ([]int64, error) { var issueIDs []int64 - res, err := issueIndexer.Search(keyword, repoID, 1000, 0) + res, err := issueIndexer.Search(keyword, repoIDs, 1000, 0) if err != nil { return nil, err } diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 59a7beed47d62..f531a5c9026ac 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -38,19 +38,19 @@ func TestBleveSearchIssues(t *testing.T) { time.Sleep(5 * time.Second) - ids, err := SearchIssuesByKeyword(1, "issue2") + ids, err := SearchIssuesByKeyword([]int64{1}, "issue2") assert.NoError(t, err) assert.EqualValues(t, []int64{2}, ids) - ids, err = SearchIssuesByKeyword(1, "first") + ids, err = SearchIssuesByKeyword([]int64{1}, "first") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) - ids, err = SearchIssuesByKeyword(1, "for") + ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) - ids, err = SearchIssuesByKeyword(1, "good") + ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) } @@ -63,19 +63,19 @@ func TestDBSearchIssues(t *testing.T) { fatalTestError("Error InitIssueIndexer: %v\n", err) } - ids, err := SearchIssuesByKeyword(1, "issue2") + ids, err := SearchIssuesByKeyword([]int64{1}, "issue2") assert.NoError(t, err) assert.EqualValues(t, []int64{2}, ids) - ids, err = SearchIssuesByKeyword(1, "first") + ids, err = SearchIssuesByKeyword([]int64{1}, "first") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) - ids, err = SearchIssuesByKeyword(1, "for") + ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) - ids, err = SearchIssuesByKeyword(1, "good") + ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) assert.EqualValues(t, []int64{1}, ids) } diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 6df290baecf12..76ec13d4038d9 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -909,7 +909,6 @@ issues.dependency.add_error_dep_issue_not_exist=Související úkol neexistuje. issues.dependency.add_error_dep_not_exist=Závislost neexistuje. issues.dependency.add_error_dep_exists=Závislost již existuje. issues.dependency.add_error_cannot_create_circular=Nemůžete vytvořit závislost dvou úkolů, které se vzájemně blokují. -issues.dependency.add_error_dep_not_same_repo=Oba úkoly musí být ve stejném repozitáři. issues.review.self.approval=Nemůžete schválit svůj požadavek na natažení. issues.review.self.rejection=Nemůžete požadovat změny ve svém vlastním požadavku na natažení. issues.review.approve=schválil tyto změny %s diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 29158c3aad8db..f6ade84fb469b 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=Abhängiges Issue existiert nich issues.dependency.add_error_dep_not_exist=Abhängigkeit existiert nicht. issues.dependency.add_error_dep_exists=Abhängigkeit existiert bereits. issues.dependency.add_error_cannot_create_circular=Du kannst keine Abhängigkeit erstellen, bei welcher sich zwei Issues gegenseitig blockieren. -issues.dependency.add_error_dep_not_same_repo=Beide Issues müssen sich im selben Repository befinden. issues.review.self.approval=Du kannst keine Änderungen an deinem eigenen Pull-Request genehmigen. issues.review.self.rejection=Du kannst keine Änderungen an deinem eigenen Pull-Request anfragen. issues.review.approve=hat die Änderungen %s genehmigt diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0df7cdf7e0d09..176c4972fe3cf 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -933,7 +933,6 @@ issues.dependency.add_error_dep_issue_not_exist = Dependent issue does not exist issues.dependency.add_error_dep_not_exist = Dependency does not exist. issues.dependency.add_error_dep_exists = Dependency already exists. issues.dependency.add_error_cannot_create_circular = You cannot create a dependency with two issues blocking each other. -issues.dependency.add_error_dep_not_same_repo = Both issues must be in the same repository. issues.review.self.approval = You cannot approve your own pull request. issues.review.self.rejection = You cannot request changes on your own pull request. issues.review.approve = "approved these changes %s" diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 359ddf86c0837..057482bf29c15 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=Incidencia dependiente no existe issues.dependency.add_error_dep_not_exist=La dependencia no existe. issues.dependency.add_error_dep_exists=La dependencia ya existe. issues.dependency.add_error_cannot_create_circular=No puede crear una depenciena con dos issues que se estan bloqueando mutuamente. -issues.dependency.add_error_dep_not_same_repo=Ambas incidencias deben estar en el mismo repositorio. issues.review.self.approval=No puede aprobar su propio pull request. issues.review.self.rejection=No puede sugerir cambios en su propio pull request. issues.review.approve=aprobado estos cambios %s diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 4b61c5a55a59f..c16d2c97e585e 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=Le ticket dépendant n'existe pa issues.dependency.add_error_dep_not_exist=La dépendance n'existe pas. issues.dependency.add_error_dep_exists=La dépendance existe déjà. issues.dependency.add_error_cannot_create_circular=Vous ne pouvez pas créer une dépendance avec deux tickets qui se bloquent l'un l'autre. -issues.dependency.add_error_dep_not_same_repo=Les deux tickets doivent être dans le même dépôt. issues.review.self.approval=Vous ne pouvez approuver vos propres demandes d'ajout. issues.review.self.rejection=Vous ne pouvez demander de changements sur vos propres demandes de changement. issues.review.approve=ces changements ont été approuvés %s diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 2575879bd980a..dca8be7887ba4 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=依存先の課題が存在し issues.dependency.add_error_dep_not_exist=依存関係が存在していません。 issues.dependency.add_error_dep_exists=依存関係は既に設定済みです。 issues.dependency.add_error_cannot_create_circular=2つの課題が互いにブロックする依存関係は作成できません。 -issues.dependency.add_error_dep_not_same_repo=両方とも同じリポジトリの課題にする必要があります。 issues.review.self.approval=自分のプルリクエストを承認することはできません。 issues.review.self.rejection=自分のプルリクエストに対して修正を要求することはできません。 issues.review.approve=が変更を承認 %s diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 9cb62c70103ad..79af901e6909b 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -931,7 +931,6 @@ issues.dependency.add_error_dep_issue_not_exist=Atkarīgā problēma neeksistē. issues.dependency.add_error_dep_not_exist=Atkarība neeksistē. issues.dependency.add_error_dep_exists=Atkarība jau ir pievienota. issues.dependency.add_error_cannot_create_circular=Nav iespējams veidot atkarību, kur divas problēmas bloķētu viena otru. -issues.dependency.add_error_dep_not_same_repo=Abām problēmām ir jābūt no viena repozitorija. issues.review.self.approval=Nevar apstiprināt savu izmaiņu pieprasījumi. issues.review.self.rejection=Nevar pieprasīt izmaiņas savam izmaiņu pieprasījumam. issues.review.approve=apstiprināja izmaiņas %s diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 716aec22b6d0b..57c3c93ad872d 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=Issue dependente não existe. issues.dependency.add_error_dep_not_exist=Dependência não existe. issues.dependency.add_error_dep_exists=Dependência já existe. issues.dependency.add_error_cannot_create_circular=Você não pode criar uma dependência com duas issues bloqueando uma a outra. -issues.dependency.add_error_dep_not_same_repo=Ambas as issues devem estar no mesmo repositório. issues.review.self.approval=Você não pode aprovar o seu próprio pull request. issues.review.self.rejection=Você não pode solicitar alterações em seu próprio pull request. issues.review.approve=aprovou estas alterações %s diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 4c84dd1201979..79a94fd082502 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -900,7 +900,6 @@ issues.dependency.add_error_dep_issue_not_exist=Зависимая задача issues.dependency.add_error_dep_not_exist=Зависимости не существует. issues.dependency.add_error_dep_exists=Зависимость уже существует. issues.dependency.add_error_cannot_create_circular=Вы не можете создать зависимость с двумя задачами, блокирующими друг друга. -issues.dependency.add_error_dep_not_same_repo=Обе задачи должны находиться в одном репозитории. issues.review.self.approval=Вы не можете одобрить собственный Pull Request. issues.review.self.rejection=Невозможно запрашивать изменения своего Pull Request'а. issues.review.approve=одобрил(а) эти изменения %s diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 5368d13a96fda..75c0b60ada6b0 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -802,7 +802,6 @@ issues.dependency.add_error_dep_issue_not_exist=Залежність для пр issues.dependency.add_error_dep_not_exist=Залежність не існує. issues.dependency.add_error_dep_exists=Залежність уже існує. issues.dependency.add_error_cannot_create_circular=Ви не можете створити залежність з двома проблемами, які блокують одна одну. -issues.dependency.add_error_dep_not_same_repo=Обидві проблеми повинні бути в одному репозиторії. issues.review.self.approval=Ви не можете схвалити власний пулл-реквест. issues.review.self.rejection=Ви не можете надіслати запит на зміну на власний пулл-реквест. issues.review.approve=зміни затверджено %s diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 80cd498480c3d..eda62e4af7dee 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -932,7 +932,6 @@ issues.dependency.add_error_dep_issue_not_exist=依赖项不存在。 issues.dependency.add_error_dep_not_exist=依赖项不存在。 issues.dependency.add_error_dep_exists=依赖项已存在。 issues.dependency.add_error_cannot_create_circular=您不能创建依赖, 使得两个工单相互阻止。 -issues.dependency.add_error_dep_not_same_repo=这两个工单必须在同一仓库。 issues.review.self.approval=您不能批准您自己的合并请求。 issues.review.self.rejection=您不能请求对您自己的合并请求进行更改。 issues.review.approve=已于 %s 批准这些更改 diff --git a/public/js/index.js b/public/js/index.js index 90412756f108c..4a21f7027b24f 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -3077,7 +3077,7 @@ function initIssueList() { $('#new-dependency-drop-list') .dropdown({ apiSettings: { - url: suburl + '/api/v1/repos/' + repolink + '/issues?q={query}', + url: suburl + '/api/v1/repos/issues/search?q={query}', onResponse: function(response) { const filteredResponse = {'success': true, 'results': []}; const currIssueId = $('#new-dependency-drop-list').data('issue-id'); diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index cd308fce51824..17d02d5328873 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -602,6 +602,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/search", repo.Search) }) + m.Get("/repos/issues/search", repo.SearchIssues) + m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID) m.Group("/repos", func() { diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index daaa3d59856aa..db1525e8cd12f 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -21,6 +21,102 @@ import ( api "code.gitea.io/gitea/modules/structs" ) +// SearchIssues searches for issues across the repositories that the user has access to +func SearchIssues(ctx *context.APIContext) { + // swagger:operation GET /repos/issues/search issue issueSearchIssues + // --- + // summary: Search for issues across the repositories that the user has access to + // produces: + // - application/json + // parameters: + // - name: state + // in: query + // description: whether issue is open or closed + // type: string + // - name: labels + // in: query + // description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded + // type: string + // - name: page + // in: query + // description: page number of requested issues + // type: integer + // - name: q + // in: query + // description: search string + // type: string + // responses: + // "200": + // "$ref": "#/responses/IssueList" + var ( + repoIDs []int64 + err error + ) + + repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User.ID) + if err != nil { + ctx.Error(500, "FindUserAccessibleRepoIDs", err) + return + } + + var isClosed util.OptionalBool + switch ctx.Query("state") { + case "closed": + isClosed = util.OptionalBoolTrue + case "all": + isClosed = util.OptionalBoolNone + default: + isClosed = util.OptionalBoolFalse + } + + var issues []*models.Issue + + keyword := strings.Trim(ctx.Query("q"), " ") + if strings.IndexByte(keyword, 0) >= 0 { + keyword = "" + } + var issueIDs []int64 + var labelIDs []int64 + if len(keyword) > 0 { + issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) + } + + if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 { + labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted) + if err != nil { + ctx.Error(500, "GetLabelIDsInRepoByNames", err) + return + } + } + + // Only fetch the issues if we either don't have a keyword or the search returned issues + // This would otherwise return all issues if no issues were found by the search. + if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { + issues, err = models.Issues(&models.IssuesOptions{ + RepoIDs: repoIDs, + Page: ctx.QueryInt("page"), + PageSize: setting.UI.IssuePagingNum, + IsClosed: isClosed, + IssueIDs: issueIDs, + LabelIDs: labelIDs, + }) + } + + if err != nil { + ctx.Error(500, "Issues", err) + return + } + + apiIssues := make([]*api.Issue, len(issues)) + for i := range issues { + apiIssues[i] = issues[i].APIFormat() + } + + //TODO need to find # issues in all the repos in repoIDs? + ctx.SetLinkHeader(0, setting.UI.IssuePagingNum) + ctx.JSON(200, &apiIssues) +} + // ListIssues list the issues of a repository func ListIssues(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/issues issue issueListIssues @@ -78,7 +174,7 @@ func ListIssues(ctx *context.APIContext) { var labelIDs []int64 var err error if len(keyword) > 0 { - issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx.Repo.Repository.ID, keyword) + issueIDs, err = issue_indexer.SearchIssuesByKeyword([]int64{ctx.Repo.Repository.ID}, keyword) } if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 { diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 72e0357e6cf87..28ef2a1694930 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -144,7 +144,7 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB var issueIDs []int64 if len(keyword) > 0 { - issueIDs, err = issue_indexer.SearchIssuesByKeyword(repo.ID, keyword) + issueIDs, err = issue_indexer.SearchIssuesByKeyword([]int64{repo.ID}, keyword) if err != nil { ctx.ServerError("issueIndexer.Search", err) return diff --git a/routers/repo/issue_dependency.go b/routers/repo/issue_dependency.go index 730271126d98d..38d3aafd79094 100644 --- a/routers/repo/issue_dependency.go +++ b/routers/repo/issue_dependency.go @@ -39,12 +39,6 @@ func AddDependency(ctx *context.Context) { return } - // Check if both issues are in the same repo - if issue.RepoID != dep.RepoID { - ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo")) - return - } - // Check if issue and dependency is the same if dep.Index == issueIndex { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue")) diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index e50ac0a4b126b..588e51ca3dadd 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -276,7 +276,9 @@ {{range .BlockingDependencies}}
#{{.Index}}
- {{.Title}} + + {{if eq .RepoID $.Repository.ID}}{{.Title}}{{else}}{{.Title}} ({{.RepoLink}}){{end}} +
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
#{{.Index}}
-
{{.Title}} + + {{if eq .RepoID $.Repository.ID}}{{.Title}}{{else}}{{.Title}} ({{.RepoLink}}){{end}} +
{{if and $.CanCreateIssueDependencies (not $.IsArchived)}} Date: Sat, 17 Aug 2019 15:14:30 -0500 Subject: [PATCH 02/26] removed unused repolink var --- public/js/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/js/index.js b/public/js/index.js index 0966af77bbaf1..f21bb9e214184 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -3069,7 +3069,6 @@ function deleteDependencyModal(id, type) { } function initIssueList() { - const repolink = $('#repolink').val(); $('#new-dependency-drop-list') .dropdown({ apiSettings: { From 6647aa8cabbfc80016d7579502e71c8ba581f591 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sun, 18 Aug 2019 15:47:06 -0500 Subject: [PATCH 03/26] fixed query that was breaking ci tests; fixed check in issue dependency add so that the id of the issue and dependency is checked rather than the indexes --- models/issue.go | 4 ++-- routers/repo/issue_dependency.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/models/issue.go b/models/issue.go index 4b1a0116570eb..e794c095ef9ea 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1834,7 +1834,7 @@ type DependencyInfo struct { // Get Blocked By Dependencies, aka all issues this issue is blocked by. func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { err = e.Table("issue_dependency"). - Select("issue.id, issue.repo_id, issue.index, issue.is_closed, issue.name"). + Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) @@ -1857,7 +1857,7 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI // Get Blocking Dependencies, aka all issues this issue blocks. func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { err = e.Table("issue_dependency"). - Select("issue.id, issue.repo_id, issue.index, issue.is_closed, issue.name"). + Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) diff --git a/routers/repo/issue_dependency.go b/routers/repo/issue_dependency.go index 38d3aafd79094..8bbea90a79a29 100644 --- a/routers/repo/issue_dependency.go +++ b/routers/repo/issue_dependency.go @@ -40,7 +40,7 @@ func AddDependency(ctx *context.Context) { } // Check if issue and dependency is the same - if dep.Index == issueIndex { + if dep.ID == issue.ID { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue")) return } From f1bae29d9bedd3059ab8947c6b7089e092ebc819 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Mon, 19 Aug 2019 06:26:31 -0500 Subject: [PATCH 04/26] reverted removal of string in local files becasue these are done via crowdin, not updated manually --- options/locale/locale_cs-CZ.ini | 1 + options/locale/locale_de-DE.ini | 1 + options/locale/locale_en-US.ini | 1 + options/locale/locale_es-ES.ini | 1 + options/locale/locale_fr-FR.ini | 1 + options/locale/locale_ja-JP.ini | 1 + options/locale/locale_lv-LV.ini | 1 + options/locale/locale_pt-BR.ini | 1 + options/locale/locale_ru-RU.ini | 1 + options/locale/locale_uk-UA.ini | 1 + options/locale/locale_zh-CN.ini | 1 + 11 files changed, 11 insertions(+) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 444764da4c598..e609219a5e3b5 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -908,6 +908,7 @@ issues.dependency.add_error_dep_issue_not_exist=Související úkol neexistuje. issues.dependency.add_error_dep_not_exist=Závislost neexistuje. issues.dependency.add_error_dep_exists=Závislost již existuje. issues.dependency.add_error_cannot_create_circular=Nemůžete vytvořit závislost dvou úkolů, které se vzájemně blokují. +issues.dependency.add_error_dep_not_same_repo=Oba úkoly musí být ve stejném repozitáři. issues.review.self.approval=Nemůžete schválit svůj požadavek na natažení. issues.review.self.rejection=Nemůžete požadovat změny ve svém vlastním požadavku na natažení. issues.review.approve=schválil tyto změny %s diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 60ffaf6fcf00a..89cd8b7607982 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=Abhängiges Issue existiert nich issues.dependency.add_error_dep_not_exist=Abhängigkeit existiert nicht. issues.dependency.add_error_dep_exists=Abhängigkeit existiert bereits. issues.dependency.add_error_cannot_create_circular=Du kannst keine Abhängigkeit erstellen, bei welcher sich zwei Issues gegenseitig blockieren. +issues.dependency.add_error_dep_not_same_repo=Beide Issues müssen sich im selben Repository befinden. issues.review.self.approval=Du kannst keine Änderungen an deinem eigenen Pull-Request genehmigen. issues.review.self.rejection=Du kannst keine Änderungen an deinem eigenen Pull-Request anfragen. issues.review.approve=hat die Änderungen %s genehmigt diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9f8f2948f44b7..fb86d54903756 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -933,6 +933,7 @@ issues.dependency.add_error_dep_issue_not_exist = Dependent issue does not exist issues.dependency.add_error_dep_not_exist = Dependency does not exist. issues.dependency.add_error_dep_exists = Dependency already exists. issues.dependency.add_error_cannot_create_circular = You cannot create a dependency with two issues blocking each other. +issues.dependency.add_error_dep_not_same_repo = Both issues must be in the same repository. issues.review.self.approval = You cannot approve your own pull request. issues.review.self.rejection = You cannot request changes on your own pull request. issues.review.approve = "approved these changes %s" diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 41caa50a0e8ed..91395fc5851e9 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=Incidencia dependiente no existe issues.dependency.add_error_dep_not_exist=La dependencia no existe. issues.dependency.add_error_dep_exists=La dependencia ya existe. issues.dependency.add_error_cannot_create_circular=No puede crear una depenciena con dos issues que se estan bloqueando mutuamente. +issues.dependency.add_error_dep_not_same_repo=Ambas incidencias deben estar en el mismo repositorio. issues.review.self.approval=No puede aprobar su propio pull request. issues.review.self.rejection=No puede sugerir cambios en su propio pull request. issues.review.approve=aprobado estos cambios %s diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 3b4ad56b913fa..53f28ac11e58c 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=Le ticket dépendant n'existe pa issues.dependency.add_error_dep_not_exist=La dépendance n'existe pas. issues.dependency.add_error_dep_exists=La dépendance existe déjà. issues.dependency.add_error_cannot_create_circular=Vous ne pouvez pas créer une dépendance avec deux tickets qui se bloquent l'un l'autre. +issues.dependency.add_error_dep_not_same_repo=Les deux tickets doivent être dans le même dépôt. issues.review.self.approval=Vous ne pouvez approuver vos propres demandes d'ajout. issues.review.self.rejection=Vous ne pouvez demander de changements sur vos propres demandes de changement. issues.review.approve=ces changements ont été approuvés %s diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index cbc0101a5c68e..97ca59ee1542f 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=依存先の課題が存在し issues.dependency.add_error_dep_not_exist=依存関係が存在していません。 issues.dependency.add_error_dep_exists=依存関係は既に設定済みです。 issues.dependency.add_error_cannot_create_circular=2つの課題が互いにブロックする依存関係は作成できません。 +issues.dependency.add_error_dep_not_same_repo=両方とも同じリポジトリの課題にする必要があります。 issues.review.self.approval=自分のプルリクエストを承認することはできません。 issues.review.self.rejection=自分のプルリクエストに対して修正を要求することはできません。 issues.review.approve=が変更を承認 %s diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 405253d150e06..130c2465b6145 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -930,6 +930,7 @@ issues.dependency.add_error_dep_issue_not_exist=Atkarīgā problēma neeksistē. issues.dependency.add_error_dep_not_exist=Atkarība neeksistē. issues.dependency.add_error_dep_exists=Atkarība jau ir pievienota. issues.dependency.add_error_cannot_create_circular=Nav iespējams veidot atkarību, kur divas problēmas bloķētu viena otru. +issues.dependency.add_error_dep_not_same_repo=Abām problēmām ir jābūt no viena repozitorija. issues.review.self.approval=Nevar apstiprināt savu izmaiņu pieprasījumi. issues.review.self.rejection=Nevar pieprasīt izmaiņas savam izmaiņu pieprasījumam. issues.review.approve=apstiprināja izmaiņas %s diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index f4354cf6a301a..b15c315f87f48 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=Issue dependente não existe. issues.dependency.add_error_dep_not_exist=Dependência não existe. issues.dependency.add_error_dep_exists=Dependência já existe. issues.dependency.add_error_cannot_create_circular=Você não pode criar uma dependência com duas issues bloqueando uma a outra. +issues.dependency.add_error_dep_not_same_repo=Ambas as issues devem estar no mesmo repositório. issues.review.self.approval=Você não pode aprovar o seu próprio pull request. issues.review.self.rejection=Você não pode solicitar alterações em seu próprio pull request. issues.review.approve=aprovou estas alterações %s diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 79a94fd082502..4c84dd1201979 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -900,6 +900,7 @@ issues.dependency.add_error_dep_issue_not_exist=Зависимая задача issues.dependency.add_error_dep_not_exist=Зависимости не существует. issues.dependency.add_error_dep_exists=Зависимость уже существует. issues.dependency.add_error_cannot_create_circular=Вы не можете создать зависимость с двумя задачами, блокирующими друг друга. +issues.dependency.add_error_dep_not_same_repo=Обе задачи должны находиться в одном репозитории. issues.review.self.approval=Вы не можете одобрить собственный Pull Request. issues.review.self.rejection=Невозможно запрашивать изменения своего Pull Request'а. issues.review.approve=одобрил(а) эти изменения %s diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 75c0b60ada6b0..5368d13a96fda 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -802,6 +802,7 @@ issues.dependency.add_error_dep_issue_not_exist=Залежність для пр issues.dependency.add_error_dep_not_exist=Залежність не існує. issues.dependency.add_error_dep_exists=Залежність уже існує. issues.dependency.add_error_cannot_create_circular=Ви не можете створити залежність з двома проблемами, які блокують одна одну. +issues.dependency.add_error_dep_not_same_repo=Обидві проблеми повинні бути в одному репозиторії. issues.review.self.approval=Ви не можете схвалити власний пулл-реквест. issues.review.self.rejection=Ви не можете надіслати запит на зміну на власний пулл-реквест. issues.review.approve=зміни затверджено %s diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 67a271fa889b3..f5236bf575ed9 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -931,6 +931,7 @@ issues.dependency.add_error_dep_issue_not_exist=依赖项不存在。 issues.dependency.add_error_dep_not_exist=依赖项不存在。 issues.dependency.add_error_dep_exists=依赖项已存在。 issues.dependency.add_error_cannot_create_circular=您不能创建依赖, 使得两个工单相互阻止。 +issues.dependency.add_error_dep_not_same_repo=这两个工单必须在同一仓库。 issues.review.self.approval=您不能批准您自己的合并请求。 issues.review.self.rejection=您不能请求对您自己的合并请求进行更改。 issues.review.approve=已于 %s 批准这些更改 From 935eae4609156b22b725a04a83d764149eb9b6de Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Mon, 19 Aug 2019 20:15:17 -0500 Subject: [PATCH 05/26] removed 'Select("issue.*")' from getBlockedByDependencies and getBlockingDependencies based on comments in PR review --- models/issue.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/models/issue.go b/models/issue.go index e794c095ef9ea..65a4f0d9d1a10 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1834,7 +1834,6 @@ type DependencyInfo struct { // Get Blocked By Dependencies, aka all issues this issue is blocked by. func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { err = e.Table("issue_dependency"). - Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) @@ -1857,7 +1856,6 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI // Get Blocking Dependencies, aka all issues this issue blocks. func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { err = e.Table("issue_dependency"). - Select("issue.*"). Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) From 0473eca99e7ec84e78dce5a37f04846c94a4d3b5 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Wed, 21 Aug 2019 05:51:57 -0500 Subject: [PATCH 06/26] changed getBlockedByDependencies and getBlockingDependencies to use a more xorm-like query, also updated the sidebar as a result --- models/issue.go | 31 +++++++------------ .../repo/issue/view_content/sidebar.tmpl | 20 ++++++------ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/models/issue.go b/models/issue.go index 65a4f0d9d1a10..7b248223dc9ac 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1823,18 +1823,16 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us // DependencyInfo represents high level information about an issue which is a dependency of another issue. type DependencyInfo struct { - ID int64 `xorm:"id"` - RepoID int64 `xorm:"repo_id"` - Index int64 `xorm:"index"` - IsClosed bool `xorm:"is_closed"` - Title string `xorm:"name"` - RepoLink string `xorm:"-"` + Issue `xorm:"extends"` + Repository `xorm:"extends"` + RepoLink string `xorm:"-"` } // Get Blocked By Dependencies, aka all issues this issue is blocked by. func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { - err = e.Table("issue_dependency"). - Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). + err = e.Table("issue"). + Join("INNER", "repository", "repository.id = issue.repo_id"). + Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) @@ -1843,11 +1841,7 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI } for i := 0; i < len(issueDeps); i++ { - repo, err := GetRepositoryByID(issueDeps[i].RepoID) - if err != nil { - return nil, err - } - issueDeps[i].RepoLink = repo.Link() + issueDeps[i].RepoLink = issueDeps[i].Repository.Link() } return issueDeps, nil @@ -1855,8 +1849,9 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI // Get Blocking Dependencies, aka all issues this issue blocks. func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { - err = e.Table("issue_dependency"). - Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). + err = e.Table("issue"). + Join("INNER", "repository", "repository.id = issue.repo_id"). + Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) @@ -1865,11 +1860,7 @@ func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyIn } for i := 0; i < len(issueDeps); i++ { - repo, err := GetRepositoryByID(issueDeps[i].RepoID) - if err != nil { - return nil, err - } - issueDeps[i].RepoLink = repo.Link() + issueDeps[i].RepoLink = issueDeps[i].Repository.Link() } return issueDeps, nil diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 588e51ca3dadd..c27eceb079d4b 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -274,14 +274,14 @@
{{range .BlockingDependencies}} -
-
#{{.Index}}
-
- {{if eq .RepoID $.Repository.ID}}{{.Title}}{{else}}{{.Title}} ({{.RepoLink}}){{end}} +
+
#{{.Issue.Index}}
+
+ {{if eq .Issue.RepoID $.Repository.ID}}{{.Issue.Title}}{{else}}{{.Issue.Title}} ({{.RepoLink}}){{end}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - @@ -302,14 +302,14 @@
{{range .BlockedByDependencies}} -
-
#{{.Index}}
- - {{if eq .RepoID $.Repository.ID}}{{.Title}}{{else}}{{.Title}} ({{.RepoLink}}){{end}} +
+
#{{.Issue.Index}}
+
+ {{if eq .Issue.RepoID $.Repository.ID}}{{.Issue.Title}}{{else}}{{.Issue.Title}} ({{.RepoLink}}){{end}}
{{if and $.CanCreateIssueDependencies (not $.IsArchived)}} - From 52f0e19551106d73a1f1bf0ed0ea7132e3ef33d9 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 24 Aug 2019 14:44:31 -0500 Subject: [PATCH 07/26] simplified the getBlockingDependencies and getBlockedByDependencies methods; changed the sidebar to show the dependencies in a different format where you can see the name of the repository --- models/issue.go | 27 +++---------------- .../repo/issue/view_content/sidebar.tmpl | 14 ++++------ 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/models/issue.go b/models/issue.go index 7b248223dc9ac..ee08c0b95fb17 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1825,45 +1825,26 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us type DependencyInfo struct { Issue `xorm:"extends"` Repository `xorm:"extends"` - RepoLink string `xorm:"-"` } // Get Blocked By Dependencies, aka all issues this issue is blocked by. func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { - err = e.Table("issue"). + return issueDeps, e. + Table("issue"). Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id"). Where("issue_id = ?", issue.ID). Find(&issueDeps) - - if err != nil { - return nil, err - } - - for i := 0; i < len(issueDeps); i++ { - issueDeps[i].RepoLink = issueDeps[i].Repository.Link() - } - - return issueDeps, nil } // Get Blocking Dependencies, aka all issues this issue blocks. func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { - err = e.Table("issue"). + return issueDeps, e. + Table("issue"). Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id"). Where("dependency_id = ?", issue.ID). Find(&issueDeps) - - if err != nil { - return nil, err - } - - for i := 0; i < len(issueDeps); i++ { - issueDeps[i].RepoLink = issueDeps[i].Repository.Link() - } - - return issueDeps, nil } // BlockedByDependencies finds all Dependencies an issue is blocked by diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index c27eceb079d4b..41e4f53893c35 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -275,10 +275,8 @@
{{range .BlockingDependencies}}
-
#{{.Issue.Index}}
- - {{if eq .Issue.RepoID $.Repository.ID}}{{.Issue.Title}}{{else}}{{.Issue.Title}} ({{.RepoLink}}){{end}} - +
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
+ {{.Issue.Title}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} {{range .BlockedByDependencies}}
-
#{{.Issue.Index}}
-
- {{if eq .Issue.RepoID $.Repository.ID}}{{.Issue.Title}}{{else}}{{.Issue.Title}} ({{.RepoLink}}){{end}} - +
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
+ {{.Issue.Title}}
- {{if and $.CanCreateIssueDependencies (not $.IsArchived)}} + {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} From 0b9e67bd62b6705d47cd6dfb042e17fa913a3822 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sun, 25 Aug 2019 15:16:56 -0500 Subject: [PATCH 08/26] made some changes to the issue view in the dependencies (issue name on top, repo full name on separate line). Change view of issue in the dependency search results (also showing the full repo name on separate line) --- models/issue.go | 7 +++++++ modules/structs/issue.go | 7 +++++++ public/js/index.js | 3 ++- templates/repo/issue/view_content/sidebar.tmpl | 8 ++++---- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/models/issue.go b/models/issue.go index ee08c0b95fb17..f3e7ee15c0dab 100644 --- a/models/issue.go +++ b/models/issue.go @@ -377,6 +377,13 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue { Updated: issue.UpdatedUnix.AsTime(), } + if issue.Repo != nil { + apiIssue.Repo = &api.RepositoryMeta{ + ID: issue.Repo.ID, + FullName: issue.Repo.FullName(), + } + } + if issue.ClosedUnix != 0 { apiIssue.Closed = issue.ClosedUnix.AsTimePtr() } diff --git a/modules/structs/issue.go b/modules/structs/issue.go index 58fd7344b4f27..b8c925e512923 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -26,6 +26,12 @@ type PullRequestMeta struct { Merged *time.Time `json:"merged_at"` } +// RepositoryMeta basic repository information +type RepositoryMeta struct { + ID int64 `json:"id"` + FullName string `json:"full_name"` +} + // Issue represents an issue in a repository // swagger:model type Issue struct { @@ -57,6 +63,7 @@ type Issue struct { Deadline *time.Time `json:"due_date"` PullRequest *PullRequestMeta `json:"pull_request"` + Repo *RepositoryMeta `json:"repository"` } // ListIssueOption list issue options diff --git a/public/js/index.js b/public/js/index.js index f21bb9e214184..d6149e2bc69f6 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -3083,7 +3083,8 @@ function initIssueList() { return; } filteredResponse.results.push({ - 'name' : '#' + issue.number + ' ' + htmlEncode(issue.title), + 'name' : htmlEncode(issue.title) + '
' + + htmlEncode(issue.repository.full_name) + '#' + issue.number + '
', 'value' : issue.id }); }); diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 41e4f53893c35..cedcaae3a4e77 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -275,12 +275,12 @@
{{range .BlockingDependencies}}
-
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
{{.Issue.Title}} +
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} + data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted=""> {{end}} @@ -301,12 +301,12 @@
{{range .BlockedByDependencies}}
-
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
{{.Issue.Title}} +
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} + data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted=""> {{end}} From b426606e94981857fb7245d8a121552f8c29f4c2 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Mon, 2 Sep 2019 14:26:29 -0500 Subject: [PATCH 09/26] replace call to FindUserAccessibleRepoIDs with SearchRepositoryByName. The former was hardcoded to use isPrivate = false on the repo search, but this code needed it to be true. The SearchRepositoryByName method is used more in the code including on the user's dashboard --- routers/api/v1/repo/issue.go | 39 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index fbf9143ff96b8..eb3035270355a 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" @@ -49,15 +50,34 @@ func SearchIssues(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/IssueList" - var ( - repoIDs []int64 - err error - ) - repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User.ID) - if err != nil { - ctx.Error(500, "FindUserAccessibleRepoIDs", err) - return + // find repos user can access + repoIDs := make([]int64, 0) + for page := 1; ; page++ { + repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{ + Page: page, + PageSize: models.RepositoryListDefaultPageSize, + Private: true, + Keyword: "", + OwnerID: ctx.User.ID, + TopicOnly: false, + Collaborate: util.OptionalBoolNone, + UserIsAdmin: ctx.IsUserSiteAdmin(), + UserID: ctx.Data["SignedUserID"].(int64), + OrderBy: models.SearchOrderByID, + }) + if err != nil { + ctx.Error(500, "SearchRepositoryByName", err) + return + } + + if len(repos) == 0 { + break + } + log.Trace("Processing next %d repos of %d", len(repos), count) + for _, repo := range repos { + repoIDs = append(repoIDs, repo.ID) + } } var isClosed util.OptionalBool @@ -78,7 +98,8 @@ func SearchIssues(ctx *context.APIContext) { } var issueIDs []int64 var labelIDs []int64 - if len(keyword) > 0 { + var err error + if len(keyword) > 0 && len(repoIDs) > 0 { issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) } From 2f257d019937a9cadebcd4bdece1b82f33974628 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Mon, 2 Sep 2019 22:12:54 -0500 Subject: [PATCH 10/26] some more tweaks to the layout of the issues when showing dependencies and in the search box when you add new dependencies --- public/js/index.js | 4 ++-- templates/repo/issue/view_content/sidebar.tmpl | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/public/js/index.js b/public/js/index.js index d6149e2bc69f6..8ff093d07b6bb 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -3083,8 +3083,8 @@ function initIssueList() { return; } filteredResponse.results.push({ - 'name' : htmlEncode(issue.title) + '
' + - htmlEncode(issue.repository.full_name) + '#' + issue.number + '
', + 'name' : '#' + issue.number + ' ' + htmlEncode(issue.title) + + '
' + htmlEncode(issue.repository.full_name) + '
', 'value' : issue.id }); }); diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index cedcaae3a4e77..cc20e0ad84013 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -275,8 +275,9 @@
{{range .BlockingDependencies}}
+ #{{.Issue.Index}} {{.Issue.Title}} -
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
+
{{.Repository.OwnerName}}/{{.Repository.Name}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} {{range .BlockedByDependencies}}
+ #{{.Issue.Index}} {{.Issue.Title}} -
{{.Repository.OwnerName}}/{{.Repository.Name}}#{{.Issue.Index}}
+
{{.Repository.OwnerName}}/{{.Repository.Name}}
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} Date: Sat, 7 Sep 2019 21:16:17 -0500 Subject: [PATCH 11/26] added Name to the RepositoryMeta struct --- models/issue.go | 1 + modules/structs/issue.go | 1 + 2 files changed, 2 insertions(+) diff --git a/models/issue.go b/models/issue.go index 99bc297824cd1..d94764c8c6454 100644 --- a/models/issue.go +++ b/models/issue.go @@ -380,6 +380,7 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue { if issue.Repo != nil { apiIssue.Repo = &api.RepositoryMeta{ ID: issue.Repo.ID, + Name: issue.Repo.Name, FullName: issue.Repo.FullName(), } } diff --git a/modules/structs/issue.go b/modules/structs/issue.go index b8c925e512923..bd39f9ea444b0 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -29,6 +29,7 @@ type PullRequestMeta struct { // RepositoryMeta basic repository information type RepositoryMeta struct { ID int64 `json:"id"` + Name string `json:"name"` FullName string `json:"full_name"` } From 6d741b7e6e8aae8b7efd9fd5dda41a47d4d61eb4 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 7 Sep 2019 21:23:48 -0500 Subject: [PATCH 12/26] updated swagger doc --- templates/swagger/v1_json.tmpl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 81ff952ac940d..44288b901b784 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -9036,6 +9036,9 @@ "pull_request": { "$ref": "#/definitions/PullRequestMeta" }, + "repository": { + "$ref": "#/definitions/RepositoryMeta" + }, "state": { "$ref": "#/definitions/StateType" }, @@ -9916,6 +9919,26 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "RepositoryMeta": { + "description": "RepositoryMeta basic repository information", + "type": "object", + "properties": { + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "SearchResults": { "description": "SearchResults results of a successful search", "type": "object", From cf015b66805712a149718c97c07206f2d561fe99 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 7 Sep 2019 21:55:32 -0500 Subject: [PATCH 13/26] fixed total count for link header on SearchIssues --- routers/api/v1/repo/issue.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 9f4ef8212940c..2e53d90ac61f6 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -52,6 +52,7 @@ func SearchIssues(ctx *context.APIContext) { // find repos user can access repoIDs := make([]int64, 0) + issueCount := 0 for page := 1; ; page++ { repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{ Page: page, @@ -75,6 +76,7 @@ func SearchIssues(ctx *context.APIContext) { } log.Trace("Processing next %d repos of %d", len(repos), count) for _, repo := range repos { + issueCount += repo.NumIssues repoIDs = append(repoIDs, repo.ID) } } @@ -133,8 +135,7 @@ func SearchIssues(ctx *context.APIContext) { apiIssues[i] = issues[i].APIFormat() } - //TODO need to find # issues in all the repos in repoIDs? - ctx.SetLinkHeader(0, setting.UI.IssuePagingNum) + ctx.SetLinkHeader(issueCount, setting.UI.IssuePagingNum) ctx.JSON(200, &apiIssues) } From e630aa7d8a1db88ee4f8a317d1d16a91ce6ee3ca Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 7 Sep 2019 22:02:41 -0500 Subject: [PATCH 14/26] fixed indentation --- templates/repo/issue/view_content/sidebar.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index cc20e0ad84013..b984e474f36fe 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -281,7 +281,7 @@
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} + data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted=""> {{end}} @@ -308,7 +308,7 @@
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} + data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted=""> {{end}} From deb2ff314256f7e4a222f642821ba509f6501754 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Wed, 25 Sep 2019 22:18:27 -0500 Subject: [PATCH 15/26] fixed aligment of remove icon on dependencies in issue sidebar --- public/css/index.css | 3 +++ templates/repo/issue/view_content/sidebar.tmpl | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index 1da2399c461b8..3f253cb06d765 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -78,6 +78,7 @@ a{cursor:pointer} .ui.form .ui.button{font-weight:400} .ui.floating.label{z-index:10} .ui.transparent.label{background-color:transparent} +.ui.nopadding{padding:0} .ui.menu,.ui.segment,.ui.vertical.menu{box-shadow:none} .ui .menu:not(.vertical) .item>.button.compact{padding:.58928571em 1.125em} .ui .menu:not(.vertical) .item>.button.small{font-size:.92857143rem} @@ -151,6 +152,8 @@ a{cursor:pointer} .ui .border.yellow{border-color:#fbbd08!important} .ui .border.gold{border-color:#a1882b!important} .ui .branch-tag-choice{line-height:20px} +i.icon.nopadding{padding: 0} +i.icon.nomargin{margin: 0} @media only screen and (max-width:767px){.ui.pagination.menu .item.navigation span.navigation_label,.ui.pagination.menu .item:not(.active):not(.navigation){display:none} } .file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)} diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 001a9f8913e78..23bce27e01c24 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -278,11 +278,11 @@ #{{.Issue.Index}} {{.Issue.Title}}
{{.Repository.OwnerName}}/{{.Repository.Name}}
-
+
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{end}}
@@ -305,11 +305,11 @@ #{{.Issue.Index}} {{.Issue.Title}}
{{.Repository.OwnerName}}/{{.Repository.Name}}
-
+
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{end}}
From b7cd0f5ae98761dbeccf103d3735808d7a8c0486 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Fri, 27 Sep 2019 21:52:39 -0500 Subject: [PATCH 16/26] removed unnecessary nil check (unnecessary because issue.loadRepo is called prior to this block) --- models/issue.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/models/issue.go b/models/issue.go index f23d50de24e0e..030066ba33a43 100644 --- a/models/issue.go +++ b/models/issue.go @@ -377,12 +377,10 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue { Updated: issue.UpdatedUnix.AsTime(), } - if issue.Repo != nil { - apiIssue.Repo = &api.RepositoryMeta{ - ID: issue.Repo.ID, - Name: issue.Repo.Name, - FullName: issue.Repo.FullName(), - } + apiIssue.Repo = &api.RepositoryMeta{ + ID: issue.Repo.ID, + Name: issue.Repo.Name, + FullName: issue.Repo.FullName(), } if issue.ClosedUnix != 0 { From a707ea7a977326fc98509d5d73eac32f3b77ee93 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Fri, 27 Sep 2019 22:03:26 -0500 Subject: [PATCH 17/26] reverting .css change, somehow missed or forgot that less is used --- public/css/index.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index 3f253cb06d765..1da2399c461b8 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -78,7 +78,6 @@ a{cursor:pointer} .ui.form .ui.button{font-weight:400} .ui.floating.label{z-index:10} .ui.transparent.label{background-color:transparent} -.ui.nopadding{padding:0} .ui.menu,.ui.segment,.ui.vertical.menu{box-shadow:none} .ui .menu:not(.vertical) .item>.button.compact{padding:.58928571em 1.125em} .ui .menu:not(.vertical) .item>.button.small{font-size:.92857143rem} @@ -152,8 +151,6 @@ a{cursor:pointer} .ui .border.yellow{border-color:#fbbd08!important} .ui .border.gold{border-color:#a1882b!important} .ui .branch-tag-choice{line-height:20px} -i.icon.nopadding{padding: 0} -i.icon.nomargin{margin: 0} @media only screen and (max-width:767px){.ui.pagination.menu .item.navigation span.navigation_label,.ui.pagination.menu .item:not(.active):not(.navigation){display:none} } .file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)} From 25c40a40e8944a8374f8c5b60a92aabfa5b9d1a2 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Fri, 27 Sep 2019 22:20:37 -0500 Subject: [PATCH 18/26] updated less file and generated css; updated sidebar template with styles to line up delete and issue index --- public/css/index.css | 3 +++ public/less/_base.less | 12 ++++++++++++ templates/repo/issue/view_content/sidebar.tmpl | 4 ++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index 1da2399c461b8..9cd9273e7f499 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -78,6 +78,7 @@ a{cursor:pointer} .ui.form .ui.button{font-weight:400} .ui.floating.label{z-index:10} .ui.transparent.label{background-color:transparent} +.ui.nopadding{padding:0} .ui.menu,.ui.segment,.ui.vertical.menu{box-shadow:none} .ui .menu:not(.vertical) .item>.button.compact{padding:.58928571em 1.125em} .ui .menu:not(.vertical) .item>.button.small{font-size:.92857143rem} @@ -109,6 +110,8 @@ a{cursor:pointer} .ui .text.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block} .ui .text.thin{font-weight:400} .ui .text.middle{vertical-align:middle} +.ui .text.nopadding{padding:0} +.ui .text.nomargin{margin:0} .ui .message{text-align:center} .ui.bottom.attached.message{font-weight:700;text-align:left;color:#000} .ui.bottom.attached.message .pull-right{color:#000} diff --git a/public/less/_base.less b/public/less/_base.less index e295be368dfd3..79a3347f9967a 100644 --- a/public/less/_base.less +++ b/public/less/_base.less @@ -321,6 +321,10 @@ code, background-color: transparent; } + &.nopadding { + padding: 0; + } + &.menu, &.vertical.menu, &.segment { @@ -453,6 +457,14 @@ code, &.middle { vertical-align: middle; } + + &.nopadding { + padding: 0; + } + + &.nomargin { + margin: 0; + } } .message { diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 23bce27e01c24..1d21e77501bc5 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -282,7 +282,7 @@ {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{end}}
@@ -309,7 +309,7 @@ {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{end}}
From 3a9028f67bd60681a703ac51465b2fa6e9770e26 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Fri, 27 Sep 2019 22:27:13 -0500 Subject: [PATCH 19/26] added ordering to the blocked by/depends on queries --- models/issue.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/models/issue.go b/models/issue.go index 030066ba33a43..a2228295fd347 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1899,6 +1899,7 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id"). Where("issue_id = ?", issue.ID). + OrderBy("repository.id, issue.id ASC"). Find(&issueDeps) } @@ -1909,6 +1910,7 @@ func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyIn Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id"). Where("dependency_id = ?", issue.ID). + OrderBy("repository.id, issue.id ASC"). Find(&issueDeps) } From 9dd2fc0fe03db88958fce67d56eec35370b933b9 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 5 Oct 2019 22:17:16 -0500 Subject: [PATCH 20/26] fixed sorting in issue dependency search and the depends on/blocks views to show issues from the current repo first, then by created date descending; added a "all cross repository dependencies" setting to allow this feature to be turned off, if turned off, the issue dependency search will work the way it did before (restricted to the current repository) --- custom/conf/app.ini.sample | 2 ++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + models/issue.go | 15 +++++++--- models/pull.go | 2 +- modules/setting/service.go | 2 ++ public/js/index.js | 9 +++++- routers/api/v1/repo/issue.go | 28 ++++++++++++------- routers/repo/issue.go | 3 ++ .../repo/issue/view_content/sidebar.tmpl | 2 ++ templates/swagger/v1_json.tmpl | 7 +++++ 10 files changed, 55 insertions(+), 16 deletions(-) diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 9bfddc97e8f25..271a623aee8a7 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -420,6 +420,8 @@ DEFAULT_ORG_MEMBER_VISIBLE = false ; Default value for EnableDependencies ; Repositories will use dependencies by default depending on this setting DEFAULT_ENABLE_DEPENDENCIES = true +; The issue dependency search will show issues from all repositories where the user is granted access or only issues from the current repository depending on this setting. +ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true ; Enable heatmap on users profiles. ENABLE_USER_HEATMAP = true ; Enable Timetracking diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 60d7341f241ab..63730ca8a27f5 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -246,6 +246,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. - `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net. - `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default. +- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to have the issue dependency search show issues from all repositories where the user is granted access. - `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles. - `EMAIL_DOMAIN_WHITELIST`: **\**: If non-empty, list of domain names that can only be used to register on this instance. diff --git a/models/issue.go b/models/issue.go index a2228295fd347..da6b2c3811798 100644 --- a/models/issue.go +++ b/models/issue.go @@ -9,6 +9,7 @@ import ( "path" "regexp" "sort" + "strconv" "strings" "code.gitea.io/gitea/modules/base" @@ -1343,11 +1344,13 @@ type IssuesOptions struct { LabelIDs []int64 SortType string IssueIDs []int64 + // prioritize issues from this repo + PriorityRepoID int64 } // sortIssuesSession sort an issues-related session based on the provided // sortType string -func sortIssuesSession(sess *xorm.Session, sortType string) { +func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64) { switch sortType { case "oldest": sess.Asc("issue.created_unix") @@ -1365,6 +1368,8 @@ func sortIssuesSession(sess *xorm.Session, sortType string) { sess.Asc("issue.deadline_unix") case "farduedate": sess.Desc("issue.deadline_unix") + case "priorityrepo": + sess.OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 ELSE 2 END, issue.created_unix DESC") default: sess.Desc("issue.created_unix") } @@ -1462,7 +1467,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) { defer sess.Close() opts.setupSession(sess) - sortIssuesSession(sess, opts.SortType) + sortIssuesSession(sess, opts.SortType, opts.PriorityRepoID) issues := make([]*Issue, 0, setting.UI.IssuePagingNum) if err := sess.Find(&issues); err != nil { @@ -1899,7 +1904,8 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id"). Where("issue_id = ?", issue.ID). - OrderBy("repository.id, issue.id ASC"). + //sort by repo id then created date, with the issues of the same repo at the beginning of the list + OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC"). Find(&issueDeps) } @@ -1910,7 +1916,8 @@ func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyIn Join("INNER", "repository", "repository.id = issue.repo_id"). Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id"). Where("dependency_id = ?", issue.ID). - OrderBy("repository.id, issue.id ASC"). + //sort by repo id then created date, with the issues of the same repo at the beginning of the list + OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC"). Find(&issueDeps) } diff --git a/models/pull.go b/models/pull.go index 2f7218f4157e3..bc7b27e22798c 100644 --- a/models/pull.go +++ b/models/pull.go @@ -781,7 +781,7 @@ func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, prs := make([]*PullRequest, 0, ItemsPerPage) findSession, err := listPullRequestStatement(baseRepoID, opts) - sortIssuesSession(findSession, opts.SortType) + sortIssuesSession(findSession, opts.SortType, 0) if err != nil { log.Error("listPullRequestStatement: %v", err) return nil, maxResults, err diff --git a/modules/setting/service.go b/modules/setting/service.go index 905b1326f78d6..6b197718578d3 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -38,6 +38,7 @@ var Service struct { EnableTimetracking bool DefaultEnableTimetracking bool DefaultEnableDependencies bool + AllowCrossRepositoryDependencies bool DefaultAllowOnlyContributorsToTrackTime bool NoReplyAddress string EnableUserHeatmap bool @@ -77,6 +78,7 @@ func newService() { Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true) } Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true) + Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true) Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true) Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) diff --git a/public/js/index.js b/public/js/index.js index dadbf03580b97..b6d71279c20c1 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -3096,10 +3096,17 @@ function deleteDependencyModal(id, type) { } function initIssueList() { + const repolink = $('#repolink').val(); + const repoId = $('#repoId').val(); + const crossRepoSearch = $('#crossRepoSearch').val(); + let issueSearchUrl = suburl + '/api/v1/repos/' + repolink + '/issues?q={query}'; + if (crossRepoSearch === 'true') { + issueSearchUrl = suburl + '/api/v1/repos/issues/search?q={query}&priority_repo_id=' + repoId; + } $('#new-dependency-drop-list') .dropdown({ apiSettings: { - url: suburl + '/api/v1/repos/issues/search?q={query}', + url: issueSearchUrl, onResponse: function(response) { const filteredResponse = {'success': true, 'results': []}; const currIssueId = $('#new-dependency-drop-list').data('issue-id'); diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index ffcc8eea79781..3024c9b41ecce 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -47,17 +47,22 @@ func SearchIssues(ctx *context.APIContext) { // in: query // description: search string // type: string + // - name: priority_repo_id + // in: query + // description: repository to prioritize in the results + // type: integer + // format: int64 // responses: // "200": // "$ref": "#/responses/IssueList" - // find repos user can access + // find repos user can access (for issue search) repoIDs := make([]int64, 0) issueCount := 0 for page := 1; ; page++ { repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{ Page: page, - PageSize: models.RepositoryListDefaultPageSize, + PageSize: 15, Private: true, Keyword: "", OwnerID: ctx.User.ID, @@ -65,7 +70,7 @@ func SearchIssues(ctx *context.APIContext) { Collaborate: util.OptionalBoolNone, UserIsAdmin: ctx.IsUserSiteAdmin(), UserID: ctx.Data["SignedUserID"].(int64), - OrderBy: models.SearchOrderByID, + OrderBy: models.SearchOrderByRecentUpdated, }) if err != nil { ctx.Error(500, "SearchRepositoryByName", err) @@ -105,7 +110,8 @@ func SearchIssues(ctx *context.APIContext) { issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) } - if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 { + splitted := strings.Split(ctx.Query("labels"), ",") + if len(splitted) > 0 { labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted) if err != nil { ctx.Error(500, "GetLabelIDsInRepoByNames", err) @@ -117,12 +123,14 @@ func SearchIssues(ctx *context.APIContext) { // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { issues, err = models.Issues(&models.IssuesOptions{ - RepoIDs: repoIDs, - Page: ctx.QueryInt("page"), - PageSize: setting.UI.IssuePagingNum, - IsClosed: isClosed, - IssueIDs: issueIDs, - LabelIDs: labelIDs, + RepoIDs: repoIDs, + Page: ctx.QueryInt("page"), + PageSize: setting.UI.IssuePagingNum, + IsClosed: isClosed, + IssueIDs: issueIDs, + LabelIDs: labelIDs, + SortType: "priorityrepo", + PriorityRepoID: ctx.QueryInt64("priority_repo_id"), }) } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 611898f69df48..80f95ef54d9e0 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -777,6 +777,9 @@ func ViewIssue(ctx *context.Context) { // Check if the user can use the dependencies ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User) + // check if dependencies can be created across repositories + ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies + // Render comments and and fetch participants. participants[0] = issue.Poster for _, comment = range issue.Comments { diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 1d21e77501bc5..637d4ad04aef0 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -426,6 +426,8 @@
{{if and .CanCreateIssueDependencies (not .Repository.IsArchived)}} + + diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 1690134684d1c..00be71798c21e 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1081,6 +1081,13 @@ "description": "search string", "name": "q", "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "repository to prioritize in the results", + "name": "priority_repo_id", + "in": "query" } ], "responses": { From 03273654b3da618552f166c8effe3cf22a6ef05e Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sat, 5 Oct 2019 22:26:37 -0500 Subject: [PATCH 21/26] re-applied my swagger changes after merge --- templates/swagger/v1_json.tmpl | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index d8750d8bcce46..237c871581a17 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1111,6 +1111,56 @@ } } }, + "/repos/issues/search": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Search for issues across the repositories that the user has access to", + "operationId": "issueSearchIssues", + "parameters": [ + { + "type": "string", + "description": "whether issue is open or closed", + "name": "state", + "in": "query" + }, + { + "type": "string", + "description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", + "name": "labels", + "in": "query" + }, + { + "type": "integer", + "description": "page number of requested issues", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "search string", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "repository to prioritize in the results", + "name": "priority_repo_id", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + } + } + } + }, "/repos/migrate": { "post": { "consumes": [ @@ -9143,6 +9193,9 @@ "pull_request": { "$ref": "#/definitions/PullRequestMeta" }, + "repository": { + "$ref": "#/definitions/RepositoryMeta" + }, "state": { "$ref": "#/definitions/StateType" }, @@ -10036,6 +10089,26 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "RepositoryMeta": { + "description": "RepositoryMeta basic repository information", + "type": "object", + "properties": { + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "SearchResults": { "description": "SearchResults results of a successful search", "type": "object", From 17b78884b77341bddeb4081f175b962d0690260b Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Sun, 6 Oct 2019 15:14:00 -0500 Subject: [PATCH 22/26] fixed split string condition in issue search --- routers/api/v1/repo/issue.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index ccef61b7bfe7f..8725f6a6ea304 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -111,8 +111,8 @@ func SearchIssues(ctx *context.APIContext) { issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) } - splitted := strings.Split(ctx.Query("labels"), ",") - if len(splitted) > 0 { + labels := ctx.Query("labels") + if splitted := strings.Split(labels, ","); labels != "" && len(splitted) > 0 { labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted) if err != nil { ctx.Error(500, "GetLabelIDsInRepoByNames", err) From 690442c87ccca3527a7f3a95114d0b07cbe99319 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Mon, 7 Oct 2019 22:17:08 -0500 Subject: [PATCH 23/26] changed ALLOW_CROSS_REPOSITORY_DEPENDENCIES description to sound more global than just the issue dependency search; returning 400 in the cross repo issue search api method if not enabled; fixed bug where the issue count did not respect the state parameter --- custom/conf/app.ini.sample | 2 +- .../doc/advanced/config-cheat-sheet.en-us.md | 2 +- routers/api/v1/repo/issue.go | 34 +++++++++++++------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 271a623aee8a7..54f1a332fe0df 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -420,7 +420,7 @@ DEFAULT_ORG_MEMBER_VISIBLE = false ; Default value for EnableDependencies ; Repositories will use dependencies by default depending on this setting DEFAULT_ENABLE_DEPENDENCIES = true -; The issue dependency search will show issues from all repositories where the user is granted access or only issues from the current repository depending on this setting. +; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting. ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true ; Enable heatmap on users profiles. ENABLE_USER_HEATMAP = true diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 9b00eea221446..11767fcb26d46 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -246,7 +246,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. - `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net. - `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default. -- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to have the issue dependency search show issues from all repositories where the user is granted access. +- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access. - `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles. - `EMAIL_DOMAIN_WHITELIST`: **\**: If non-empty, list of domain names that can only be used to register on this instance. diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 8725f6a6ea304..50162b0a91c6f 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -57,6 +57,21 @@ func SearchIssues(ctx *context.APIContext) { // "200": // "$ref": "#/responses/IssueList" + if !setting.Service.AllowCrossRepositoryDependencies { + ctx.Error(400, "CrossRepositoryDependenciesNotEnabled", "cross repository dependencies are not enabled") + return + } + + var isClosed util.OptionalBool + switch ctx.Query("state") { + case "closed": + isClosed = util.OptionalBoolTrue + case "all": + isClosed = util.OptionalBoolNone + default: + isClosed = util.OptionalBoolFalse + } + // find repos user can access (for issue search) repoIDs := make([]int64, 0) issueCount := 0 @@ -83,21 +98,18 @@ func SearchIssues(ctx *context.APIContext) { } log.Trace("Processing next %d repos of %d", len(repos), count) for _, repo := range repos { - issueCount += repo.NumIssues + switch isClosed { + case util.OptionalBoolTrue: + issueCount += repo.NumClosedIssues + case util.OptionalBoolFalse: + issueCount += repo.NumOpenIssues + case util.OptionalBoolNone: + issueCount += repo.NumIssues + } repoIDs = append(repoIDs, repo.ID) } } - var isClosed util.OptionalBool - switch ctx.Query("state") { - case "closed": - isClosed = util.OptionalBoolTrue - case "all": - isClosed = util.OptionalBoolNone - default: - isClosed = util.OptionalBoolFalse - } - var issues []*models.Issue keyword := strings.Trim(ctx.Query("q"), " ") From c77a9501d03c7792ce1188a5f6675db4732bc8b5 Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Fri, 25 Oct 2019 22:00:29 -0500 Subject: [PATCH 24/26] when adding a dependency to an issue, added a check to make sure the issue and dependency are in the same repo if cross repo dependencies is not enabled --- routers/api/v1/repo/issue.go | 6 ------ routers/repo/issue_dependency.go | 7 +++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 6e5e5672719f3..dd9ab61cc2835 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -56,12 +56,6 @@ func SearchIssues(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/IssueList" - - if !setting.Service.AllowCrossRepositoryDependencies { - ctx.Error(400, "CrossRepositoryDependenciesNotEnabled", "cross repository dependencies are not enabled") - return - } - var isClosed util.OptionalBool switch ctx.Query("state") { case "closed": diff --git a/routers/repo/issue_dependency.go b/routers/repo/issue_dependency.go index 8bbea90a79a29..6b11f0cdf1530 100644 --- a/routers/repo/issue_dependency.go +++ b/routers/repo/issue_dependency.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" ) // AddDependency adds new dependencies @@ -39,6 +40,12 @@ func AddDependency(ctx *context.Context) { return } + // Check if both issues are in the same repo if cross repository dependencies is not enabled + if issue.RepoID != dep.RepoID && !setting.Service.AllowCrossRepositoryDependencies { + ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo")) + return + } + // Check if issue and dependency is the same if dep.ID == issue.ID { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue")) From 1d8bd097c5c183e0458e4642f2b580bfec801acd Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Wed, 30 Oct 2019 21:59:07 -0500 Subject: [PATCH 25/26] updated sortIssuesSession call in PullRequests, another commit moved this method from pull.go to pull_list.go so I had to re-apply my change here --- models/pull_list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/pull_list.go b/models/pull_list.go index 4ec6fdde3b525..2c2f53f4a1591 100644 --- a/models/pull_list.go +++ b/models/pull_list.go @@ -87,7 +87,7 @@ func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, prs := make([]*PullRequest, 0, ItemsPerPage) findSession, err := listPullRequestStatement(baseRepoID, opts) - sortIssuesSession(findSession, opts.SortType) + sortIssuesSession(findSession, opts.SortType, 0) if err != nil { log.Error("listPullRequestStatement: %v", err) return nil, maxResults, err From 22c5dd294b707547c65adc5f993e8c24f1fbaaac Mon Sep 17 00:00:00 2001 From: Brad Albright Date: Wed, 30 Oct 2019 22:16:10 -0500 Subject: [PATCH 26/26] fixed incorrect setting of user id parameter in search repos call --- routers/api/v1/repo/issue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index e6bdf866788f4..fe5862ea5e452 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -78,7 +78,7 @@ func SearchIssues(ctx *context.APIContext) { TopicOnly: false, Collaborate: util.OptionalBoolNone, UserIsAdmin: ctx.IsUserSiteAdmin(), - UserID: ctx.Data["SignedUserID"].(int64), + UserID: ctx.User.ID, OrderBy: models.SearchOrderByRecentUpdated, }) if err != nil {