Team dashboards (#14159)
This commit is contained in:
		
							parent
							
								
									25f8970b2c
								
							
						
					
					
						commit
						40274b4a93
					
				
					 12 changed files with 148 additions and 47 deletions
				
			
		|  | @ -289,6 +289,7 @@ func (a *Action) GetIssueContent() string { | ||||||
| // GetFeedsOptions options for retrieving feeds
 | // GetFeedsOptions options for retrieving feeds
 | ||||||
| type GetFeedsOptions struct { | type GetFeedsOptions struct { | ||||||
| 	RequestedUser   *User // the user we want activity for
 | 	RequestedUser   *User // the user we want activity for
 | ||||||
|  | 	RequestedTeam   *Team // the team we want activity for
 | ||||||
| 	Actor           *User // the user viewing the activity
 | 	Actor           *User // the user viewing the activity
 | ||||||
| 	IncludePrivate  bool  // include private actions
 | 	IncludePrivate  bool  // include private actions
 | ||||||
| 	OnlyPerformedBy bool  // only actions performed by requested user
 | 	OnlyPerformedBy bool  // only actions performed by requested user
 | ||||||
|  | @ -357,6 +358,15 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if opts.RequestedTeam != nil { | ||||||
|  | 		env := opts.RequestedUser.AccessibleTeamReposEnv(opts.RequestedTeam) | ||||||
|  | 		teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("GetTeamRepositories: %v", err) | ||||||
|  | 		} | ||||||
|  | 		cond = cond.And(builder.In("repo_id", teamRepoIDs)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID}) | 	cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID}) | ||||||
| 
 | 
 | ||||||
| 	if opts.OnlyPerformedBy { | 	if opts.OnlyPerformedBy { | ||||||
|  |  | ||||||
|  | @ -746,6 +746,7 @@ type AccessibleReposEnvironment interface { | ||||||
| type accessibleReposEnv struct { | type accessibleReposEnv struct { | ||||||
| 	org     *User | 	org     *User | ||||||
| 	user    *User | 	user    *User | ||||||
|  | 	team    *Team | ||||||
| 	teamIDs []int64 | 	teamIDs []int64 | ||||||
| 	e       Engine | 	e       Engine | ||||||
| 	keyword string | 	keyword string | ||||||
|  | @ -782,16 +783,31 @@ func (org *User) accessibleReposEnv(e Engine, userID int64) (AccessibleReposEnvi | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org`
 | ||||||
|  | // that are accessible to the specified team.
 | ||||||
|  | func (org *User) AccessibleTeamReposEnv(team *Team) AccessibleReposEnvironment { | ||||||
|  | 	return &accessibleReposEnv{ | ||||||
|  | 		org:     org, | ||||||
|  | 		team:    team, | ||||||
|  | 		e:       x, | ||||||
|  | 		orderBy: SearchOrderByRecentUpdated, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (env *accessibleReposEnv) cond() builder.Cond { | func (env *accessibleReposEnv) cond() builder.Cond { | ||||||
| 	var cond = builder.NewCond() | 	var cond = builder.NewCond() | ||||||
| 	if env.user == nil || !env.user.IsRestricted { | 	if env.team != nil { | ||||||
| 		cond = cond.Or(builder.Eq{ | 		cond = cond.And(builder.Eq{"team_repo.team_id": env.team.ID}) | ||||||
| 			"`repository`.owner_id":   env.org.ID, | 	} else { | ||||||
| 			"`repository`.is_private": false, | 		if env.user == nil || !env.user.IsRestricted { | ||||||
| 		}) | 			cond = cond.Or(builder.Eq{ | ||||||
| 	} | 				"`repository`.owner_id":   env.org.ID, | ||||||
| 	if len(env.teamIDs) > 0 { | 				"`repository`.is_private": false, | ||||||
| 		cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs)) | 			}) | ||||||
|  | 		} | ||||||
|  | 		if len(env.teamIDs) > 0 { | ||||||
|  | 			cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs)) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	if env.keyword != "" { | 	if env.keyword != "" { | ||||||
| 		cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)}) | 		cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)}) | ||||||
|  |  | ||||||
|  | @ -138,6 +138,7 @@ type SearchRepoOptions struct { | ||||||
| 	Keyword         string | 	Keyword         string | ||||||
| 	OwnerID         int64 | 	OwnerID         int64 | ||||||
| 	PriorityOwnerID int64 | 	PriorityOwnerID int64 | ||||||
|  | 	TeamID          int64 | ||||||
| 	OrderBy         SearchOrderBy | 	OrderBy         SearchOrderBy | ||||||
| 	Private         bool // Include private repositories in results
 | 	Private         bool // Include private repositories in results
 | ||||||
| 	StarredByID     int64 | 	StarredByID     int64 | ||||||
|  | @ -294,6 +295,10 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | ||||||
| 		cond = cond.And(accessCond) | 		cond = cond.And(accessCond) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if opts.TeamID > 0 { | ||||||
|  | 		cond = cond.And(builder.In("`repository`.id", builder.Select("`team_repo`.repo_id").From("team_repo").Where(builder.Eq{"`team_repo`.team_id": opts.TeamID}))) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if opts.Keyword != "" { | 	if opts.Keyword != "" { | ||||||
| 		// separate keyword
 | 		// separate keyword
 | ||||||
| 		var subQueryCond = builder.NewCond() | 		var subQueryCond = builder.NewCond() | ||||||
|  |  | ||||||
|  | @ -17,6 +17,15 @@ type UserHeatmapData struct { | ||||||
| 
 | 
 | ||||||
| // GetUserHeatmapDataByUser returns an array of UserHeatmapData
 | // GetUserHeatmapDataByUser returns an array of UserHeatmapData
 | ||||||
| func GetUserHeatmapDataByUser(user *User, doer *User) ([]*UserHeatmapData, error) { | func GetUserHeatmapDataByUser(user *User, doer *User) ([]*UserHeatmapData, error) { | ||||||
|  | 	return getUserHeatmapData(user, nil, doer) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetUserHeatmapDataByUserTeam returns an array of UserHeatmapData
 | ||||||
|  | func GetUserHeatmapDataByUserTeam(user *User, team *Team, doer *User) ([]*UserHeatmapData, error) { | ||||||
|  | 	return getUserHeatmapData(user, team, doer) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getUserHeatmapData(user *User, team *Team, doer *User) ([]*UserHeatmapData, error) { | ||||||
| 	hdata := make([]*UserHeatmapData, 0) | 	hdata := make([]*UserHeatmapData, 0) | ||||||
| 
 | 
 | ||||||
| 	if !activityReadable(user, doer) { | 	if !activityReadable(user, doer) { | ||||||
|  | @ -39,6 +48,7 @@ func GetUserHeatmapDataByUser(user *User, doer *User) ([]*UserHeatmapData, error | ||||||
| 
 | 
 | ||||||
| 	cond, err := activityQueryCondition(GetFeedsOptions{ | 	cond, err := activityQueryCondition(GetFeedsOptions{ | ||||||
| 		RequestedUser:  user, | 		RequestedUser:  user, | ||||||
|  | 		RequestedTeam:  team, | ||||||
| 		Actor:          doer, | 		Actor:          doer, | ||||||
| 		IncludePrivate: true, // don't filter by private, as we already filter by repo access
 | 		IncludePrivate: true, // don't filter by private, as we already filter by repo access
 | ||||||
| 		IncludeDeleted: true, | 		IncludeDeleted: true, | ||||||
|  |  | ||||||
|  | @ -216,6 +216,7 @@ my_mirrors = My Mirrors | ||||||
| view_home = View %s | view_home = View %s | ||||||
| search_repos = Find a repository… | search_repos = Find a repository… | ||||||
| filter = Other Filters | filter = Other Filters | ||||||
|  | filter_by_team_repositories = Filter by team repositories | ||||||
| 
 | 
 | ||||||
| show_archived = Archived | show_archived = Archived | ||||||
| show_both_archived_unarchived = Showing both archived and unarchived | show_both_archived_unarchived = Showing both archived and unarchived | ||||||
|  |  | ||||||
|  | @ -70,6 +70,11 @@ func Search(ctx *context.APIContext) { | ||||||
| 	//   description: repo owner to prioritize in the results
 | 	//   description: repo owner to prioritize in the results
 | ||||||
| 	//   type: integer
 | 	//   type: integer
 | ||||||
| 	//   format: int64
 | 	//   format: int64
 | ||||||
|  | 	// - name: team_id
 | ||||||
|  | 	//   in: query
 | ||||||
|  | 	//   description: search only for repos that belong to the given team id
 | ||||||
|  | 	//   type: integer
 | ||||||
|  | 	//   format: int64
 | ||||||
| 	// - name: starredBy
 | 	// - name: starredBy
 | ||||||
| 	//   in: query
 | 	//   in: query
 | ||||||
| 	//   description: search only for repos that the user with the given id has starred
 | 	//   description: search only for repos that the user with the given id has starred
 | ||||||
|  | @ -131,6 +136,7 @@ func Search(ctx *context.APIContext) { | ||||||
| 		Keyword:            strings.Trim(ctx.Query("q"), " "), | 		Keyword:            strings.Trim(ctx.Query("q"), " "), | ||||||
| 		OwnerID:            ctx.QueryInt64("uid"), | 		OwnerID:            ctx.QueryInt64("uid"), | ||||||
| 		PriorityOwnerID:    ctx.QueryInt64("priority_owner_id"), | 		PriorityOwnerID:    ctx.QueryInt64("priority_owner_id"), | ||||||
|  | 		TeamID:             ctx.QueryInt64("team_id"), | ||||||
| 		TopicOnly:          ctx.QueryBool("topic"), | 		TopicOnly:          ctx.QueryBool("topic"), | ||||||
| 		Collaborate:        util.OptionalBoolNone, | 		Collaborate:        util.OptionalBoolNone, | ||||||
| 		Private:            ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), | 		Private:            ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), | ||||||
|  |  | ||||||
|  | @ -444,13 +444,15 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { | ||||||
| 
 | 
 | ||||||
| 		m.Group("/:org", func() { | 		m.Group("/:org", func() { | ||||||
| 			m.Get("/dashboard", user.Dashboard) | 			m.Get("/dashboard", user.Dashboard) | ||||||
|  | 			m.Get("/dashboard/:team", user.Dashboard) | ||||||
| 			m.Get("/^:type(issues|pulls)$", user.Issues) | 			m.Get("/^:type(issues|pulls)$", user.Issues) | ||||||
|  | 			m.Get("/^:type(issues|pulls)$/:team", user.Issues) | ||||||
| 			m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) | 			m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) | ||||||
|  | 			m.Get("/milestones/:team", reqMilestonesDashboardPageEnabled, user.Milestones) | ||||||
| 			m.Get("/members", org.Members) | 			m.Get("/members", org.Members) | ||||||
| 			m.Post("/members/action/:action", org.MembersAction) | 			m.Post("/members/action/:action", org.MembersAction) | ||||||
| 
 |  | ||||||
| 			m.Get("/teams", org.Teams) | 			m.Get("/teams", org.Teams) | ||||||
| 		}, context.OrgAssignment(true)) | 		}, context.OrgAssignment(true, false, true)) | ||||||
| 
 | 
 | ||||||
| 		m.Group("/:org", func() { | 		m.Group("/:org", func() { | ||||||
| 			m.Get("/teams/:team", org.TeamMembers) | 			m.Get("/teams/:team", org.TeamMembers) | ||||||
|  |  | ||||||
|  | @ -42,17 +42,8 @@ func getDashboardContextUser(ctx *context.Context) *models.User { | ||||||
| 	ctxUser := ctx.User | 	ctxUser := ctx.User | ||||||
| 	orgName := ctx.Params(":org") | 	orgName := ctx.Params(":org") | ||||||
| 	if len(orgName) > 0 { | 	if len(orgName) > 0 { | ||||||
| 		// Organization.
 | 		ctxUser = ctx.Org.Organization | ||||||
| 		org, err := models.GetUserByName(orgName) | 		ctx.Data["Teams"] = ctx.Org.Organization.Teams | ||||||
| 		if err != nil { |  | ||||||
| 			if models.IsErrUserNotExist(err) { |  | ||||||
| 				ctx.NotFound("GetUserByName", err) |  | ||||||
| 			} else { |  | ||||||
| 				ctx.ServerError("GetUserByName", err) |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		ctxUser = org |  | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["ContextUser"] = ctxUser | 	ctx.Data["ContextUser"] = ctxUser | ||||||
| 
 | 
 | ||||||
|  | @ -112,12 +103,13 @@ func Dashboard(ctx *context.Context) { | ||||||
| 	ctx.Data["PageIsDashboard"] = true | 	ctx.Data["PageIsDashboard"] = true | ||||||
| 	ctx.Data["PageIsNews"] = true | 	ctx.Data["PageIsNews"] = true | ||||||
| 	ctx.Data["SearchLimit"] = setting.UI.User.RepoPagingNum | 	ctx.Data["SearchLimit"] = setting.UI.User.RepoPagingNum | ||||||
|  | 
 | ||||||
| 	// no heatmap access for admins; GetUserHeatmapDataByUser ignores the calling user
 | 	// no heatmap access for admins; GetUserHeatmapDataByUser ignores the calling user
 | ||||||
| 	// so everyone would get the same empty heatmap
 | 	// so everyone would get the same empty heatmap
 | ||||||
| 	if setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate { | 	if setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate { | ||||||
| 		data, err := models.GetUserHeatmapDataByUser(ctxUser, ctx.User) | 		data, err := models.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.User) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("GetUserHeatmapDataByUser", err) | 			ctx.ServerError("GetUserHeatmapDataByUserTeam", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		ctx.Data["HeatmapData"] = data | 		ctx.Data["HeatmapData"] = data | ||||||
|  | @ -126,12 +118,16 @@ func Dashboard(ctx *context.Context) { | ||||||
| 	var err error | 	var err error | ||||||
| 	var mirrors []*models.Repository | 	var mirrors []*models.Repository | ||||||
| 	if ctxUser.IsOrganization() { | 	if ctxUser.IsOrganization() { | ||||||
| 		env, err := ctxUser.AccessibleReposEnv(ctx.User.ID) | 		var env models.AccessibleReposEnvironment | ||||||
| 		if err != nil { | 		if ctx.Org.Team != nil { | ||||||
| 			ctx.ServerError("AccessibleReposEnv", err) | 			env = ctxUser.AccessibleTeamReposEnv(ctx.Org.Team) | ||||||
| 			return | 		} else { | ||||||
|  | 			env, err = ctxUser.AccessibleReposEnv(ctx.User.ID) | ||||||
|  | 			if err != nil { | ||||||
|  | 				ctx.ServerError("AccessibleReposEnv", err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		mirrors, err = env.MirrorRepos() | 		mirrors, err = env.MirrorRepos() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("env.MirrorRepos", err) | 			ctx.ServerError("env.MirrorRepos", err) | ||||||
|  | @ -155,6 +151,7 @@ func Dashboard(ctx *context.Context) { | ||||||
| 
 | 
 | ||||||
| 	retrieveFeeds(ctx, models.GetFeedsOptions{ | 	retrieveFeeds(ctx, models.GetFeedsOptions{ | ||||||
| 		RequestedUser:   ctxUser, | 		RequestedUser:   ctxUser, | ||||||
|  | 		RequestedTeam:   ctx.Org.Team, | ||||||
| 		Actor:           ctx.User, | 		Actor:           ctx.User, | ||||||
| 		IncludePrivate:  true, | 		IncludePrivate:  true, | ||||||
| 		OnlyPerformedBy: false, | 		OnlyPerformedBy: false, | ||||||
|  | @ -183,16 +180,20 @@ func Milestones(ctx *context.Context) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var ( | 	repoOpts := models.SearchRepoOptions{ | ||||||
| 		repoOpts = models.SearchRepoOptions{ | 		Actor:         ctxUser, | ||||||
| 			Actor:         ctxUser, | 		OwnerID:       ctxUser.ID, | ||||||
| 			OwnerID:       ctxUser.ID, | 		Private:       true, | ||||||
| 			Private:       true, | 		AllPublic:     false,                 // Include also all public repositories of users and public organisations
 | ||||||
| 			AllPublic:     false,                 // Include also all public repositories of users and public organisations
 | 		AllLimited:    false,                 // Include also all public repositories of limited organisations
 | ||||||
| 			AllLimited:    false,                 // Include also all public repositories of limited organisations
 | 		HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones
 | ||||||
| 			HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones
 | 	} | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
|  | 	if ctxUser.IsOrganization() && ctx.Org.Team != nil { | ||||||
|  | 		repoOpts.TeamID = ctx.Org.Team.ID | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
| 		userRepoCond = models.SearchRepositoryCondition(&repoOpts) // all repo condition user could visit
 | 		userRepoCond = models.SearchRepositoryCondition(&repoOpts) // all repo condition user could visit
 | ||||||
| 		repoCond     = userRepoCond | 		repoCond     = userRepoCond | ||||||
| 		repoIDs      []int64 | 		repoIDs      []int64 | ||||||
|  | @ -412,10 +413,15 @@ func Issues(ctx *context.Context) { | ||||||
| 	var err error | 	var err error | ||||||
| 	var userRepoIDs []int64 | 	var userRepoIDs []int64 | ||||||
| 	if ctxUser.IsOrganization() { | 	if ctxUser.IsOrganization() { | ||||||
| 		env, err := ctxUser.AccessibleReposEnv(ctx.User.ID) | 		var env models.AccessibleReposEnvironment | ||||||
| 		if err != nil { | 		if ctx.Org.Team != nil { | ||||||
| 			ctx.ServerError("AccessibleReposEnv", err) | 			env = ctxUser.AccessibleTeamReposEnv(ctx.Org.Team) | ||||||
| 			return | 		} else { | ||||||
|  | 			env, err = ctxUser.AccessibleReposEnv(ctx.User.ID) | ||||||
|  | 			if err != nil { | ||||||
|  | 				ctx.ServerError("AccessibleReposEnv", err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		userRepoIDs, err = env.RepoIDs(1, ctxUser.NumRepos) | 		userRepoIDs, err = env.RepoIDs(1, ctxUser.NumRepos) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  |  | ||||||
|  | @ -2009,6 +2009,13 @@ | ||||||
|             "name": "priority_owner_id", |             "name": "priority_owner_id", | ||||||
|             "in": "query" |             "in": "query" | ||||||
|           }, |           }, | ||||||
|  |           { | ||||||
|  |             "type": "integer", | ||||||
|  |             "format": "int64", | ||||||
|  |             "description": "search only for repos that belong to the given team id", | ||||||
|  |             "name": "team_id", | ||||||
|  |             "in": "query" | ||||||
|  |           }, | ||||||
|           { |           { | ||||||
|             "type": "integer", |             "type": "integer", | ||||||
|             "format": "int64", |             "format": "int64", | ||||||
|  |  | ||||||
|  | @ -44,21 +44,51 @@ | ||||||
| 
 | 
 | ||||||
| 		{{if .ContextUser.IsOrganization}} | 		{{if .ContextUser.IsOrganization}} | ||||||
| 			<div class="right stackable menu"> | 			<div class="right stackable menu"> | ||||||
| 				<a class="{{if .PageIsNews}}active{{end}} item" style="margin-left: auto" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/dashboard"> | 				<div class="item"> | ||||||
|  | 					<div class="ui floating dropdown link jump"> | ||||||
|  | 						<span class="text"> | ||||||
|  | 							{{svg "octicon-people" 18}} | ||||||
|  | 							{{if .Team}} | ||||||
|  | 								{{.Team.Name}} | ||||||
|  | 							{{else}} | ||||||
|  | 								{{.i18n.Tr "org.teams"}} | ||||||
|  | 							{{end}} | ||||||
|  | 							{{svg "octicon-triangle-down" 14 "dropdown icon"}} | ||||||
|  | 						</span> | ||||||
|  | 						<div class="context user overflow menu" tabindex="-1"> | ||||||
|  | 							<div class="ui header"> | ||||||
|  | 								{{.i18n.Tr "home.filter_by_team_repositories"}} | ||||||
|  | 							</div> | ||||||
|  | 							<div class="scrolling menu items"> | ||||||
|  | 								<a class="{{if not $.Team}}active selected{{end}} item" title="{{.i18n.Tr "all"}}" href="{{AppSubUrl}}/org/{{$.Org.Name}}/{{if $.PageIsIssues}}issues{{else if $.PageIsPulls}}pulls{{else if $.PageIsMilestonesDashboard}}milestones{{else}}dashboard{{end}}"> | ||||||
|  | 									{{.i18n.Tr "all"}} | ||||||
|  | 								</a> | ||||||
|  | 								{{range .Org.Teams}} | ||||||
|  | 									{{if not .IncludesAllRepositories}} | ||||||
|  | 										<a class="{{if $.Team}}{{if eq $.Team.ID .ID}}active selected{{end}}{{end}} item" title="{{.Name}}" href="{{AppSubUrl}}/org/{{$.Org.Name}}/{{if $.PageIsIssues}}issues{{else if $.PageIsPulls}}pulls{{else if $.PageIsMilestonesDashboard}}milestones{{else}}dashboard{{end}}/{{.Name}}"> | ||||||
|  | 											{{.Name}} | ||||||
|  | 										</a> | ||||||
|  | 									{{end}} | ||||||
|  | 								{{end}} | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
|  | 				<a class="{{if .PageIsNews}}active{{end}} item" style="margin-left: auto" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/dashboard{{if .Team}}/{{.Team.Name}}{{end}}"> | ||||||
| 					{{svg "octicon-rss"}} {{.i18n.Tr "activities"}} | 					{{svg "octicon-rss"}} {{.i18n.Tr "activities"}} | ||||||
| 				</a> | 				</a> | ||||||
| 				{{if not .UnitIssuesGlobalDisabled}} | 				{{if not .UnitIssuesGlobalDisabled}} | ||||||
| 				<a class="{{if .PageIsIssues}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/issues"> | 				<a class="{{if .PageIsIssues}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/issues{{if .Team}}/{{.Team.Name}}{{end}}"> | ||||||
| 					{{svg "octicon-issue-opened"}} {{.i18n.Tr "issues"}} | 					{{svg "octicon-issue-opened"}} {{.i18n.Tr "issues"}} | ||||||
| 				</a> | 				</a> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 				{{if not .UnitPullsGlobalDisabled}} | 				{{if not .UnitPullsGlobalDisabled}} | ||||||
| 				<a class="{{if .PageIsPulls}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/pulls"> | 				<a class="{{if .PageIsPulls}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/pulls{{if .Team}}/{{.Team.Name}}{{end}}"> | ||||||
| 					{{svg "octicon-git-pull-request"}} {{.i18n.Tr "pull_requests"}} | 					{{svg "octicon-git-pull-request"}} {{.i18n.Tr "pull_requests"}} | ||||||
| 				</a> | 				</a> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 				{{if and .ShowMilestonesDashboardPage (not (and .UnitIssuesGlobalDisabled .UnitPullsGlobalDisabled))}} | 				{{if and .ShowMilestonesDashboardPage (not (and .UnitIssuesGlobalDisabled .UnitPullsGlobalDisabled))}} | ||||||
| 				<a class="{{if .PageIsMilestonesDashboard}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/milestones"> | 				<a class="{{if .PageIsMilestonesDashboard}}active{{end}} item" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}/milestones{{if .Team}}/{{.Team.Name}}{{end}}"> | ||||||
| 					{{svg "octicon-milestone"}} {{.i18n.Tr "milestones"}} | 					{{svg "octicon-milestone"}} {{.i18n.Tr "milestones"}} | ||||||
| 				</a> | 				</a> | ||||||
| 				{{end}} | 				{{end}} | ||||||
|  |  | ||||||
|  | @ -3,6 +3,9 @@ | ||||||
| 	:search-limit="searchLimit" | 	:search-limit="searchLimit" | ||||||
| 	:suburl="suburl" | 	:suburl="suburl" | ||||||
| 	:uid="uid" | 	:uid="uid" | ||||||
|  | 	{{if .Team}} | ||||||
|  | 	:team-id="{{.Team.ID}}" | ||||||
|  | 	{{end}} | ||||||
| 	:more-repos-link="'{{.ContextUser.HomeLink}}'" | 	:more-repos-link="'{{.ContextUser.HomeLink}}'" | ||||||
| 	{{if not .ContextUser.IsOrganization}} | 	{{if not .ContextUser.IsOrganization}} | ||||||
| 	:organizations="[ | 	:organizations="[ | ||||||
|  |  | ||||||
|  | @ -2755,6 +2755,11 @@ function initVueComponents() { | ||||||
|         type: Number, |         type: Number, | ||||||
|         required: true |         required: true | ||||||
|       }, |       }, | ||||||
|  |       teamId: { | ||||||
|  |         type: Number, | ||||||
|  |         required: false, | ||||||
|  |         default: 0 | ||||||
|  |       }, | ||||||
|       organizations: { |       organizations: { | ||||||
|         type: Array, |         type: Array, | ||||||
|         default: () => [], |         default: () => [], | ||||||
|  | @ -2853,7 +2858,7 @@ function initVueComponents() { | ||||||
|         return this.repos.length > 0 && this.repos.length < this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`]; |         return this.repos.length > 0 && this.repos.length < this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`]; | ||||||
|       }, |       }, | ||||||
|       searchURL() { |       searchURL() { | ||||||
|         return `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&q=${this.searchQuery |         return `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&team_id=${this.teamId}&q=${this.searchQuery | ||||||
|         }&page=${this.page}&limit=${this.searchLimit}&mode=${this.repoTypes[this.reposFilter].searchMode |         }&page=${this.page}&limit=${this.searchLimit}&mode=${this.repoTypes[this.reposFilter].searchMode | ||||||
|         }${this.reposFilter !== 'all' ? '&exclusive=1' : '' |         }${this.reposFilter !== 'all' ? '&exclusive=1' : '' | ||||||
|         }${this.archivedFilter === 'archived' ? '&archived=true' : ''}${this.archivedFilter === 'unarchived' ? '&archived=false' : '' |         }${this.archivedFilter === 'archived' ? '&archived=true' : ''}${this.archivedFilter === 'unarchived' ? '&archived=false' : '' | ||||||
|  | @ -3034,7 +3039,7 @@ function initVueComponents() { | ||||||
|         this.isLoading = true; |         this.isLoading = true; | ||||||
| 
 | 
 | ||||||
|         if (!this.reposTotalCount) { |         if (!this.reposTotalCount) { | ||||||
|           const totalCountSearchURL = `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&q=&page=1&mode=`; |           const totalCountSearchURL = `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`; | ||||||
|           $.getJSON(totalCountSearchURL, (_result, _textStatus, request) => { |           $.getJSON(totalCountSearchURL, (_result, _textStatus, request) => { | ||||||
|             self.reposTotalCount = request.getResponseHeader('X-Total-Count'); |             self.reposTotalCount = request.getResponseHeader('X-Total-Count'); | ||||||
|           }); |           }); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue