mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 12:54:53 -05:00
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