Browse Source

Fix all the bugs in issues and pulls on dashboard (#943)

* fix all the bugs in issues and pulls on dashboard

* small fix and refactor

* add method getRepoIDs for IssueList
Lunny Xiao 2 years ago
parent
commit
847527fd6d
4 changed files with 120 additions and 67 deletions
  1. 59 0
      models/issue.go
  2. 28 0
      models/user.go
  3. 32 66
      routers/user/home.go
  4. 1 1
      templates/user/dashboard/issues.tmpl

+ 59 - 0
models/issue.go

@@ -1399,3 +1399,62 @@ func updateIssue(e Engine, issue *Issue) error {
1399 1399
 func UpdateIssue(issue *Issue) error {
1400 1400
 	return updateIssue(x, issue)
1401 1401
 }
1402
+
1403
+// IssueList defines a list of issues
1404
+type IssueList []*Issue
1405
+
1406
+func (issues IssueList) getRepoIDs() []int64 {
1407
+	repoIDs := make([]int64, 0, len(issues))
1408
+	for _, issue := range issues {
1409
+		var has bool
1410
+		for _, repoID := range repoIDs {
1411
+			if repoID == issue.RepoID {
1412
+				has = true
1413
+				break
1414
+			}
1415
+		}
1416
+		if !has {
1417
+			repoIDs = append(repoIDs, issue.RepoID)
1418
+		}
1419
+	}
1420
+	return repoIDs
1421
+}
1422
+
1423
+func (issues IssueList) loadRepositories(e Engine) ([]*Repository, error) {
1424
+	if len(issues) == 0 {
1425
+		return nil, nil
1426
+	}
1427
+
1428
+	repoIDs := issues.getRepoIDs()
1429
+	rows, err := e.
1430
+		Where("id > 0").
1431
+		In("id", repoIDs).
1432
+		Rows(new(Repository))
1433
+	if err != nil {
1434
+		return nil, fmt.Errorf("find repository: %v", err)
1435
+	}
1436
+	defer rows.Close()
1437
+
1438
+	repositories := make([]*Repository, 0, len(repoIDs))
1439
+	repoMaps := make(map[int64]*Repository, len(repoIDs))
1440
+	for rows.Next() {
1441
+		var repo Repository
1442
+		err = rows.Scan(&repo)
1443
+		if err != nil {
1444
+			return nil, fmt.Errorf("find repository: %v", err)
1445
+		}
1446
+
1447
+		repositories = append(repositories, &repo)
1448
+		repoMaps[repo.ID] = &repo
1449
+	}
1450
+
1451
+	for _, issue := range issues {
1452
+		issue.Repo = repoMaps[issue.RepoID]
1453
+	}
1454
+	return repositories, nil
1455
+}
1456
+
1457
+// LoadRepositories loads issues' all repositories
1458
+func (issues IssueList) LoadRepositories() ([]*Repository, error) {
1459
+	return issues.loadRepositories(x)
1460
+}

+ 28 - 0
models/user.go

@@ -500,6 +500,34 @@ func (u *User) GetRepositories(page, pageSize int) (err error) {
500 500
 	return err
501 501
 }
502 502
 
503
+// GetRepositoryIDs returns repositories IDs where user owned
504
+func (u *User) GetRepositoryIDs() ([]int64, error) {
505
+	var ids []int64
506
+	return ids, x.Table("repository").Cols("id").Where("owner_id = ?", u.ID).Find(&ids)
507
+}
508
+
509
+// GetOrgRepositoryIDs returns repositories IDs where user's team owned
510
+func (u *User) GetOrgRepositoryIDs() ([]int64, error) {
511
+	var ids []int64
512
+	return ids, x.Table("repository").
513
+		Cols("repository.id").
514
+		Join("INNER", "team_user", "repository.owner_id = team_user.org_id AND team_user.uid = ?", u.ID).
515
+		GroupBy("repository.id").Find(&ids)
516
+}
517
+
518
+// GetAccessRepoIDs returns all repsitories IDs where user's or user is a team member orgnizations
519
+func (u *User) GetAccessRepoIDs() ([]int64, error) {
520
+	ids, err := u.GetRepositoryIDs()
521
+	if err != nil {
522
+		return nil, err
523
+	}
524
+	ids2, err := u.GetOrgRepositoryIDs()
525
+	if err != nil {
526
+		return nil, err
527
+	}
528
+	return append(ids, ids2...), nil
529
+}
530
+
503 531
 // GetMirrorRepositories returns mirror repositories that user owns, including private repositories.
504 532
 func (u *User) GetMirrorRepositories() ([]*Repository, error) {
505 533
 	return GetUserMirrorRepositories(u.ID)

+ 32 - 66
routers/user/home.go

@@ -214,48 +214,28 @@ func Issues(ctx *context.Context) {
214 214
 
215 215
 	// Get repositories.
216 216
 	var err error
217
-	var repos []*models.Repository
218
-	userRepoIDs := make([]int64, 0, len(repos))
217
+	var userRepoIDs []int64
219 218
 	if ctxUser.IsOrganization() {
220 219
 		env, err := ctxUser.AccessibleReposEnv(ctx.User.ID)
221 220
 		if err != nil {
222 221
 			ctx.Handle(500, "AccessibleReposEnv", err)
223 222
 			return
224 223
 		}
225
-		repos, err = env.Repos(1, ctxUser.NumRepos)
224
+		userRepoIDs, err = env.RepoIDs(1, ctxUser.NumRepos)
226 225
 		if err != nil {
227
-			ctx.Handle(500, "GetRepositories", err)
226
+			ctx.Handle(500, "env.RepoIDs", err)
228 227
 			return
229 228
 		}
230
-
231
-		for _, repo := range repos {
232
-			if (isPullList && repo.NumPulls == 0) ||
233
-				(!isPullList &&
234
-					(!repo.EnableUnit(models.UnitTypeIssues) || repo.NumIssues == 0)) {
235
-				continue
236
-			}
237
-
238
-			userRepoIDs = append(userRepoIDs, repo.ID)
239
-		}
240
-
241
-		if len(userRepoIDs) <= 0 {
242
-			userRepoIDs = []int64{-1}
243
-		}
244
-
245 229
 	} else {
246
-		if err := ctxUser.GetRepositories(1, ctx.User.NumRepos); err != nil {
247
-			ctx.Handle(500, "GetRepositories", err)
230
+		userRepoIDs, err = ctxUser.GetAccessRepoIDs()
231
+		if err != nil {
232
+			ctx.Handle(500, "ctxUser.GetAccessRepoIDs", err)
248 233
 			return
249 234
 		}
250
-		repos = ctxUser.Repos
235
+	}
251 236
 
252
-		for _, repo := range repos {
253
-			if (isPullList && repo.NumPulls == 0) ||
254
-				(!isPullList &&
255
-					(!repo.EnableUnit(models.UnitTypeIssues) || repo.NumIssues == 0)) {
256
-				continue
257
-			}
258
-		}
237
+	if len(userRepoIDs) <= 0 {
238
+		userRepoIDs = []int64{-1}
259 239
 	}
260 240
 
261 241
 	var issues []*models.Issue
@@ -309,55 +289,41 @@ func Issues(ctx *context.Context) {
309 289
 		return
310 290
 	}
311 291
 
312
-	showRepos := make([]*models.Repository, 0, len(issues))
313
-	showReposSet := make(map[int64]bool)
292
+	showRepos, err := models.IssueList(issues).LoadRepositories()
293
+	if err != nil {
294
+		ctx.Handle(500, "LoadRepositories", fmt.Errorf("%v", err))
295
+		return
296
+	}
314 297
 
315 298
 	if repoID > 0 {
316
-		repo, err := models.GetRepositoryByID(repoID)
317
-		if err != nil {
318
-			ctx.Handle(500, "GetRepositoryByID", fmt.Errorf("[#%d]%v", repoID, err))
319
-			return
299
+		var theRepo *models.Repository
300
+		for _, repo := range showRepos {
301
+			if repo.ID == repoID {
302
+				theRepo = repo
303
+				break
304
+			}
320 305
 		}
321 306
 
322
-		if err = repo.GetOwner(); err != nil {
323
-			ctx.Handle(500, "GetOwner", fmt.Errorf("[#%d]%v", repoID, err))
324
-			return
307
+		if theRepo == nil {
308
+			theRepo, err = models.GetRepositoryByID(repoID)
309
+			if err != nil {
310
+				ctx.Handle(500, "GetRepositoryByID", fmt.Errorf("[#%d]%v", repoID, err))
311
+				return
312
+			}
313
+			showRepos = append(showRepos, theRepo)
325 314
 		}
326 315
 
327 316
 		// Check if user has access to given repository.
328
-		if !repo.IsOwnedBy(ctxUser.ID) && !repo.HasAccess(ctxUser) {
317
+		if !theRepo.IsOwnedBy(ctxUser.ID) && !theRepo.HasAccess(ctxUser) {
329 318
 			ctx.Handle(404, "Issues", fmt.Errorf("#%d", repoID))
330 319
 			return
331 320
 		}
332
-
333
-		showReposSet[repoID] = true
334
-		showRepos = append(showRepos, repo)
335 321
 	}
336 322
 
337
-	for _, issue := range issues {
338
-		// Get Repository data.
339
-		issue.Repo, err = models.GetRepositoryByID(issue.RepoID)
340
-		if err != nil {
341
-			ctx.Handle(500, "GetRepositoryByID", fmt.Errorf("[#%d]%v", issue.RepoID, err))
342
-			return
343
-		}
344
-
345
-		// Get Owner data.
346
-		if err = issue.Repo.GetOwner(); err != nil {
347
-			ctx.Handle(500, "GetOwner", fmt.Errorf("[#%d]%v", issue.RepoID, err))
348
-			return
349
-		}
350
-
351
-		// Append repo to list of shown repos
352
-		if filterMode == models.FilterModeAll {
353
-			// Use a map to make sure we don't add the same Repository twice.
354
-			_, ok := showReposSet[issue.RepoID]
355
-			if !ok {
356
-				showReposSet[issue.RepoID] = true
357
-				// Append to list of shown Repositories.
358
-				showRepos = append(showRepos, issue.Repo)
359
-			}
360
-		}
323
+	err = models.RepositoryList(showRepos).LoadAttributes()
324
+	if err != nil {
325
+		ctx.Handle(500, "LoadAttributes", fmt.Errorf("%v", err))
326
+		return
361 327
 	}
362 328
 
363 329
 	issueStats := models.GetUserIssueStats(repoID, ctxUser.ID, userRepoIDs, filterMode, isPullList)

+ 1 - 1
templates/user/dashboard/issues.tmpl

@@ -23,7 +23,7 @@
23 23
 					{{range .Repos}}
24 24
 						<a class="{{if eq $.RepoID .ID}}ui basic blue button{{end}} repo name item" href="{{$.Link}}?type={{$.ViewType}}{{if not (eq $.RepoID .ID)}}&repo={{.ID}}{{end}}&sort={{$.SortType}}&state={{$.State}}">
25 25
 							<span class="text truncate">{{.FullName}}</span>
26
-							<div class="floating ui {{if $.IsShowClosed}}red{{else}}green{{end}} label">{{if $.IsShowClosed}}{{.NumClosedIssues}}{{else}}{{.NumOpenIssues}}{{end}}</div>
26
+							<div class="floating ui {{if $.IsShowClosed}}red{{else}}green{{end}} label">{{if $.IsShowClosed}}{{if $.PageIsPulls}}{{.NumClosedPulls}}{{else}}{{.NumClosedIssues}}{{end}}{{else}}{{if $.PageIsPulls}}{{.NumOpenPulls}}{{else}}{{.NumOpenIssues}}{{end}}{{end}}</div>
27 27
 						</a>
28 28
 					{{end}}
29 29
 				</div>