summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUnknwon <joe2010xtmf@163.com>2014-08-16 16:21:17 +0800
committerUnknwon <joe2010xtmf@163.com>2014-08-16 16:21:17 +0800
commitbba707de36d9bfbdb3001e3e89fac0c072aa14e9 (patch)
tree2b3ee7fc662baea04cecdf14b8a2758c108f83cc
parent78add502d71dca43bb59ab9ad91745c64d0bf74d (diff)
downloadgitea-bba707de36d9bfbdb3001e3e89fac0c072aa14e9.tar.gz
gitea-bba707de36d9bfbdb3001e3e89fac0c072aa14e9.zip
Finish team list, create new team, join/leave team page
-rw-r--r--cmd/web.go5
-rw-r--r--conf/locale/locale_en-US.ini19
-rw-r--r--conf/locale/locale_zh-CN.ini19
-rw-r--r--gogs.go2
-rw-r--r--models/org.go306
-rw-r--r--modules/auth/org.go2
-rw-r--r--modules/middleware/context.go2
-rw-r--r--modules/middleware/org.go26
-rw-r--r--public/ng/css/gogs.css35
-rw-r--r--public/ng/less/gogs/organization.less42
-rw-r--r--public/ng/less/gogs/repository.less1
-rw-r--r--routers/org/members.go22
-rw-r--r--routers/org/org.go2
-rw-r--r--routers/org/teams.go100
-rw-r--r--routers/user/auth.go11
-rw-r--r--templates/.VERSION2
-rw-r--r--templates/org/base/header.tmpl (renamed from templates/org/header.tmpl)0
-rw-r--r--templates/org/home.tmpl13
-rw-r--r--templates/org/member/invite.tmpl (renamed from templates/org/invite.tmpl)2
-rw-r--r--templates/org/member/members.tmpl (renamed from templates/org/members.tmpl)30
-rw-r--r--templates/org/settings/delete.tmpl1
-rw-r--r--templates/org/settings/options.tmpl1
-rw-r--r--templates/org/team/new.tmpl48
-rw-r--r--templates/org/team/teams.tmpl42
-rw-r--r--templates/org/team_new.tmpl79
-rw-r--r--templates/org/teams.tmpl58
-rw-r--r--templates/repo/create.tmpl4
-rw-r--r--templates/user/auth/activate.tmpl (renamed from templates/user/activate.tmpl)0
-rw-r--r--templates/user/auth/forgot_passwd.tmpl (renamed from templates/user/forgot_passwd.tmpl)0
-rw-r--r--templates/user/auth/reset_passwd.tmpl (renamed from templates/user/reset_passwd.tmpl)0
-rw-r--r--templates/user/auth/signin.tmpl (renamed from templates/user/signin.tmpl)0
-rw-r--r--templates/user/auth/signup.tmpl (renamed from templates/user/signup.tmpl)0
-rw-r--r--templates/user/stars.tmpl17
33 files changed, 533 insertions, 358 deletions
diff --git a/cmd/web.go b/cmd/web.go
index 03e5e86066..064a0358f9 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -236,6 +236,7 @@ func runWeb(*cli.Context) {
r.Get("/teams", org.Teams)
r.Get("/teams/:team", org.SingleTeam)
+ r.Get("/teams/:team/action/:action", org.TeamsAction)
}, middleware.OrgAssignment(true, true))
m.Group("/:org", func(r *macaron.Router) {
@@ -248,11 +249,9 @@ func runWeb(*cli.Context) {
r.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
r.Route("/delete", "GET,POST", org.SettingsDelete)
})
- }, middleware.OrgAssignment(true, true, true))
- m.Group("/:org", func(r *macaron.Router) {
r.Route("/invitations/new", "GET,POST", org.Invitation)
- }, middleware.OrgAssignment(true, false, false, true))
+ }, middleware.OrgAssignment(true, true, true))
}, reqSignIn)
// Repository routers.
diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini
index d44dca081b..4e191dca40 100644
--- a/conf/locale/locale_en-US.ini
+++ b/conf/locale/locale_en-US.ini
@@ -79,6 +79,7 @@ Retype = Re-type password
SSHTitle = SSH key name
HttpsUrl = HTTPS URL
PayloadUrl = Payload URL
+TeamName = Team name
require_error = ` cannot be empty.`
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
@@ -94,16 +95,19 @@ password_not_match = Password and re-type password are not same.
username_been_taken = Username has been already taken.
repo_name_been_taken = Repository name has been already taken.
org_name_been_taken = Organization name has been already taken.
+team_name_been_taken = Team name has been already taken.
email_been_used = E-mail address has been already used.
ssh_key_been_used = Public key name has been used.
illegal_username = Your username contains illegal characters.
illegal_repo_name = Repository name contains illegal characters.
illegal_org_name = Organization name contains illegal characters.
+illegal_team_name = Team name contains illegal characters.
username_password_incorrect = Username or password is not correct.
enterred_invalid_repo_name = Please make sure you entered repository name is correct.
enterred_invalid_owner_name = Please make sure you entered owner name is correct.
enterred_invalid_password = Please make sure you entered password is correct.
user_not_exist = Given user does not exist.
+last_org_owner = The user to remove is the last member in owner team. There must be another owner.
invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
auth_failed = Authentication failed: %v
@@ -237,6 +241,11 @@ lower_members = members
lower_repositories = repositories
create_new_team = Create New Team
org_desc = Description
+team_name = Team Name
+team_desc = Description
+team_name_helper = You'll use this name to mention this team in conversations.
+team_desc_helper = What is this team all about?
+team_permission_desc = What permission level should this team have?
settings = Settings
settings.options = Options
@@ -258,9 +267,19 @@ members.owner = Owner
members.member = Member
members.conceal = Conceal
members.remove = Remove
+members.leave = Leave
members.invite_desc = Start typing a username to invite a new member to %s:
members.invite_now = Invite Now
+teams.join = Join
+teams.leave = Leave
+teams.read_access = Read Access
+teams.read_access_helper = This team will be able to view and clone its repositories.
+teams.write_access = Write Access
+teams.write_access_helper = This team will be able to read its repositories, as well as push to them.
+teams.admin_access = Admin Access
+teams.admin_access_helper = This team will be able to push/pull to its repositories, as well as add other collaborators to them.
+
[action]
create_repo = created repository <a href="/%s">%s</a>
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
diff --git a/conf/locale/locale_zh-CN.ini b/conf/locale/locale_zh-CN.ini
index b84aca3d9e..e3607d8e6e 100644
--- a/conf/locale/locale_zh-CN.ini
+++ b/conf/locale/locale_zh-CN.ini
@@ -79,6 +79,7 @@ Retype = 确认密码
SSHTitle = SSH 密钥名称
HttpsUrl = HTTPS URL 地址
PayloadUrl = 推送地址
+TeamName = 团队名称
require_error = 不能为空。
alpha_dash_error = 必须为英文字母、阿拉伯数字或横线(-_)。
@@ -94,16 +95,19 @@ password_not_match = 密码与确认密码未匹配。
username_been_taken = 用户名已经被占用。
repo_name_been_taken = 仓库名称已经被占用。
org_name_been_taken = 组织名称已经被占用。
+team_name_been_taken = 团队名称已经被占用。
email_been_used = 邮箱地址已经被使用。
ssh_key_been_used = SSH 密钥已经被使用。
illegal_username = 您的用户名包含非法字符。
illegal_repo_name = 仓库名称包含非法字符。
illegal_org_name = 组织名称包含非法字符。
+illegal_team_name = 团队名称包含非法字符。
username_password_incorrect = 用户名或密码不正确。
enterred_invalid_repo_name = 请检查您输入的仓库名称是正确。
enterred_invalid_owner_name = 请检查您输入的新所有者用户名是否正确。
enterred_invalid_password = 请检查您输入的密码是否正确。
user_not_exist = 被操作的用户不存在!
+last_org_owner = 被移除用户为最后一位管理员。请添加一位新的管理员再进行移除成员操作!
invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
auth_failed = 授权验证失败:%v
@@ -237,6 +241,11 @@ lower_members = 名成员
lower_repositories = 个仓库
create_new_team = 创建新的团队
org_desc = 组织描述
+team_name = 团队名称
+team_desc = 团队描述
+team_name_helper = 您可以使用该名称来通知改组全体成员。
+team_desc_helper = 一句话描述这个团队是做什么的。
+team_permission_desc = 请选择该团队所具有的权限等级:
settings = 组织设置
settings.options = 基本设置
@@ -258,9 +267,19 @@ members.owner = 管理员
members.member = 普通成员
members.conceal = 隐藏身份
members.remove = 移除成员
+members.leave = 离开组织
members.invite_desc = 请输入被邀请到组织 %s 的用户名称:
members.invite_now = 立即邀请
+teams.join = 加入团队
+teams.leave = 离开团队
+teams.read_access = 读取权限
+teams.read_access_helper = 这个团队将拥有查看和克隆所属仓库的权限。
+teams.write_access = 写入权限
+teams.write_access_helper = 这个团队将拥有查看、克隆和推送所属仓库的权限。
+teams.admin_access = 管理权限
+teams.admin_access_helper = 这个团队将拥有查看、克隆、推送和添加其他组织成员到团队的权限。
+
[action]
create_repo = 创建了仓库 <a href="/%s">%s</a>
commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
diff --git a/gogs.go b/gogs.go
index 6a9ded37d5..f20f0a10d0 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.4.7.0815 Alpha"
+const APP_VER = "0.4.7.0816 Alpha"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/org.go b/models/org.go
index b40b313bc3..b810422280 100644
--- a/models/org.go
+++ b/models/org.go
@@ -15,6 +15,9 @@ import (
var (
ErrOrgNotExist = errors.New("Organization does not exist")
ErrTeamAlreadyExist = errors.New("Team already exist")
+ ErrTeamNotExist = errors.New("Team does not exist")
+ ErrTeamNameIllegal = errors.New("Team name contains illegal characters")
+ ErrLastOrgOwner = errors.New("The user to remove is the last member in owner team")
)
// IsOrgOwner returns true if given user is in the owner team.
@@ -27,14 +30,14 @@ func (org *User) IsOrgMember(uid int64) bool {
return IsOrganizationMember(org.Id, uid)
}
+// GetTeam returns named team of organization.
+func (org *User) GetTeam(name string) (*Team, error) {
+ return GetTeam(org.Id, name)
+}
+
// GetOwnerTeam returns owner team of organization.
func (org *User) GetOwnerTeam() (*Team, error) {
- t := &Team{
- OrgId: org.Id,
- Name: OWNER_TEAM,
- }
- _, err := x.Get(t)
- return t, err
+ return org.GetTeam(OWNER_TEAM)
}
// GetTeams returns all teams that belong to organization.
@@ -179,96 +182,6 @@ func DeleteOrganization(org *User) (err error) {
return sess.Commit()
}
-// ___________
-// \__ ___/___ _____ _____
-// | |_/ __ \\__ \ / \
-// | |\ ___/ / __ \| Y Y \
-// |____| \___ >____ /__|_| /
-// \/ \/ \/
-
-type AuthorizeType int
-
-const (
- ORG_READABLE AuthorizeType = iota + 1
- ORG_WRITABLE
- ORG_ADMIN
-)
-
-const OWNER_TEAM = "Owners"
-
-// Team represents a organization team.
-type Team struct {
- Id int64
- OrgId int64 `xorm:"INDEX"`
- LowerName string
- Name string
- Description string
- Authorize AuthorizeType
- RepoIds string `xorm:"TEXT"`
- NumMembers int
- NumRepos int
- Members []*User `xorm:"-"`
-}
-
-// IsTeamMember returns true if given user is a member of team.
-func (t *Team) IsMember(uid int64) bool {
- return IsTeamMember(t.OrgId, t.Id, uid)
-}
-
-// GetMembers returns all members in given team of organization.
-func (t *Team) GetMembers() (err error) {
- t.Members, err = GetTeamMembers(t.OrgId, t.Id)
- return err
-}
-
-// NewTeam creates a record of new team.
-// It's caller's responsibility to assign organization ID.
-func NewTeam(t *Team) error {
- has, err := x.Id(t.OrgId).Get(new(User))
- if err != nil {
- return err
- } else if !has {
- return ErrOrgNotExist
- }
-
- t.LowerName = strings.ToLower(t.Name)
- has, err = x.Where("org_id=?", t.OrgId).And("lower_name=?", t.LowerName).Get(new(Team))
- if err != nil {
- return err
- } else if has {
- return ErrTeamAlreadyExist
- }
-
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
- return err
- }
-
- if _, err = sess.Insert(t); err != nil {
- sess.Rollback()
- return err
- }
-
- // Update organization number of teams.
- if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgId); err != nil {
- sess.Rollback()
- return err
- }
- return sess.Commit()
-}
-
-// UpdateTeam updates information of team.
-func UpdateTeam(t *Team) error {
- if len(t.Description) > 255 {
- t.Description = t.Description[:255]
- }
-
- t.LowerName = strings.ToLower(t.Name)
- _, err := x.Id(t.Id).AllCols().Update(t)
- return err
-}
-
// ________ ____ ___
// \_____ \_______ ____ | | \______ ___________
// / | \_ __ \/ ___\| | / ___// __ \_ __ \
@@ -372,6 +285,21 @@ func RemoveOrgUser(orgId, uid int64) error {
return nil
}
+ // Check if the user to delete is the last member in owner team.
+ if IsOrganizationOwner(orgId, uid) {
+ org, err := GetUserById(orgId)
+ if err != nil {
+ return err
+ }
+ t, err := org.GetOwnerTeam()
+ if err != nil {
+ return err
+ }
+ if t.NumMembers == 1 {
+ return ErrLastOrgOwner
+ }
+ }
+
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
@@ -389,6 +317,127 @@ func RemoveOrgUser(orgId, uid int64) error {
return sess.Commit()
}
+// ___________
+// \__ ___/___ _____ _____
+// | |_/ __ \\__ \ / \
+// | |\ ___/ / __ \| Y Y \
+// |____| \___ >____ /__|_| /
+// \/ \/ \/
+
+type AuthorizeType int
+
+const (
+ ORG_READABLE AuthorizeType = iota + 1
+ ORG_WRITABLE
+ ORG_ADMIN
+)
+
+const OWNER_TEAM = "Owners"
+
+// Team represents a organization team.
+type Team struct {
+ Id int64
+ OrgId int64 `xorm:"INDEX"`
+ LowerName string
+ Name string
+ Description string
+ Authorize AuthorizeType
+ RepoIds string `xorm:"TEXT"`
+ NumMembers int
+ NumRepos int
+ Members []*User `xorm:"-"`
+}
+
+// IsTeamMember returns true if given user is a member of team.
+func (t *Team) IsMember(uid int64) bool {
+ return IsTeamMember(t.OrgId, t.Id, uid)
+}
+
+// GetMembers returns all members in given team of organization.
+func (t *Team) GetMembers() (err error) {
+ t.Members, err = GetTeamMembers(t.OrgId, t.Id)
+ return err
+}
+
+// NewTeam creates a record of new team.
+// It's caller's responsibility to assign organization ID.
+func NewTeam(t *Team) error {
+ if !IsLegalName(t.Name) {
+ return ErrTeamNameIllegal
+ }
+
+ has, err := x.Id(t.OrgId).Get(new(User))
+ if err != nil {
+ return err
+ } else if !has {
+ return ErrOrgNotExist
+ }
+
+ t.LowerName = strings.ToLower(t.Name)
+ has, err = x.Where("org_id=?", t.OrgId).And("lower_name=?", t.LowerName).Get(new(Team))
+ if err != nil {
+ return err
+ } else if has {
+ return ErrTeamAlreadyExist
+ }
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err = sess.Begin(); err != nil {
+ return err
+ }
+
+ if _, err = sess.Insert(t); err != nil {
+ sess.Rollback()
+ return err
+ }
+
+ // Update organization number of teams.
+ if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgId); err != nil {
+ sess.Rollback()
+ return err
+ }
+ return sess.Commit()
+}
+
+// GetTeam returns team by given team name and organization.
+func GetTeam(orgId int64, name string) (*Team, error) {
+ t := &Team{
+ OrgId: orgId,
+ LowerName: strings.ToLower(name),
+ }
+ has, err := x.Get(t)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, ErrTeamNotExist
+ }
+ return t, nil
+}
+
+// GetTeamById returns team by given ID.
+func GetTeamById(teamId int64) (*Team, error) {
+ t := new(Team)
+ has, err := x.Id(teamId).Get(t)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, ErrTeamNotExist
+ }
+ return t, nil
+}
+
+// UpdateTeam updates information of team.
+func UpdateTeam(t *Team) error {
+ if len(t.Description) > 255 {
+ t.Description = t.Description[:255]
+ }
+
+ t.LowerName = strings.ToLower(t.Name)
+ _, err := x.Id(t.Id).AllCols().Update(t)
+ return err
+}
+
// ___________ ____ ___
// \__ ___/___ _____ _____ | | \______ ___________
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
@@ -427,3 +476,68 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
}
return us, nil
}
+
+// AddTeamMember adds new member to given team of given organization.
+func AddTeamMember(orgId, teamId, uid int64) error {
+ if !IsOrganizationMember(orgId, uid) || IsTeamMember(orgId, teamId, uid) {
+ return nil
+ }
+
+ // We can use raw SQL here but we also want to vertify there is a such team.
+ t, err := GetTeamById(teamId)
+ if err != nil {
+ return err
+ }
+ t.NumMembers++
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err = sess.Begin(); err != nil {
+ return err
+ }
+
+ tu := &TeamUser{
+ Uid: uid,
+ OrgId: orgId,
+ TeamId: teamId,
+ }
+
+ if _, err = sess.Insert(tu); err != nil {
+ sess.Rollback()
+ return err
+ } else if _, err = sess.Id(t.Id).Update(t); err != nil {
+ sess.Rollback()
+ return err
+ }
+
+ return sess.Commit()
+}
+
+// RemoveMember removes member from given team of given organization.
+func RemoveMember(orgId, teamId, uid int64) error {
+ if !IsTeamMember(orgId, teamId, uid) {
+ return nil
+ }
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return err
+ }
+
+ tu := &TeamUser{
+ Uid: uid,
+ OrgId: orgId,
+ TeamId: teamId,
+ }
+
+ if _, err := sess.Delete(tu); err != nil {
+ sess.Rollback()
+ return err
+ } else if _, err = sess.Exec("UPDATE `team` SET num_members = num_members - 1 WHERE id = ?", teamId); err != nil {
+ sess.Rollback()
+ return err
+ }
+
+ return sess.Commit()
+}
diff --git a/modules/auth/org.go b/modules/auth/org.go
index 9598e6f834..6183e8c826 100644
--- a/modules/auth/org.go
+++ b/modules/auth/org.go
@@ -49,7 +49,7 @@ func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs *binding.Erro
// \/ \/ \/
type CreateTeamForm struct {
- TeamName string `form:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
+ TeamName string `form:"team_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Permission string `form:"permission"`
}
diff --git a/modules/middleware/context.go b/modules/middleware/context.go
index 6ce0f6e1f7..80975e999e 100644
--- a/modules/middleware/context.go
+++ b/modules/middleware/context.go
@@ -71,6 +71,8 @@ type Context struct {
IsAdminTeam bool // In owner team or team that has admin permission level.
Organization *models.User
OrgLink string
+
+ Team *models.Team
}
}
diff --git a/modules/middleware/org.go b/modules/middleware/org.go
index 77e999a328..c85221a5ab 100644
--- a/modules/middleware/org.go
+++ b/modules/middleware/org.go
@@ -41,15 +41,16 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
}
return
}
- ctx.Data["Org"] = ctx.Org.Organization
+ org := ctx.Org.Organization
+ ctx.Data["Org"] = org
if ctx.IsSigned {
- ctx.Org.IsOwner = ctx.Org.Organization.IsOrgOwner(ctx.User.Id)
+ ctx.Org.IsOwner = org.IsOrgOwner(ctx.User.Id)
if ctx.Org.IsOwner {
ctx.Org.IsMember = true
ctx.Org.IsAdminTeam = true
} else {
- if ctx.Org.Organization.IsOrgMember(ctx.User.Id) {
+ if org.IsOrgMember(ctx.User.Id) {
ctx.Org.IsMember = true
// TODO: ctx.Org.IsAdminTeam
}
@@ -64,7 +65,24 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
- ctx.Org.OrgLink = "/org/" + ctx.Org.Organization.Name
+ ctx.Org.OrgLink = "/org/" + org.Name
ctx.Data["OrgLink"] = ctx.Org.OrgLink
+
+ // Team.
+ teamName := ctx.Params(":team")
+ if len(teamName) > 0 {
+ ctx.Org.Team, err = org.GetTeam(teamName)
+ if err != nil {
+ if err == models.ErrTeamNotExist {
+ ctx.Handle(404, "GetTeam", err)
+ } else if redirect {
+ ctx.Redirect("/")
+ } else {
+ ctx.Handle(500, "GetTeam", err)
+ }
+ return
+ }
+ ctx.Data["Team"] = ctx.Org.Team
+ }
}
}
diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css
index 6b400df28c..3d784fab21 100644
--- a/public/ng/css/gogs.css
+++ b/public/ng/css/gogs.css
@@ -1172,28 +1172,34 @@ The register and sign-in page style
width: 520px;
}
/* repository create */
+#team-create-form,
#repo-migrate-form,
#repo-create-form {
width: 800px;
margin: 60px auto auto auto;
background: white;
}
+#team-create-form h2,
#repo-migrate-form h2,
#repo-create-form h2 {
margin: .5em 1em;
}
+#team-create-form .field,
#repo-migrate-form .field,
#repo-create-form .field {
margin: 1.2em 0 2em 0;
}
+#team-create-form .ipt,
#repo-migrate-form .ipt,
#repo-create-form .ipt {
width: 540px;
}
+#team-create-form textarea,
#repo-migrate-form textarea,
#repo-create-form textarea {
height: 120px;
}
+#team-create-form .avatar,
#repo-migrate-form .avatar,
#repo-create-form .avatar {
vertical-align: middle;
@@ -1201,6 +1207,7 @@ The register and sign-in page style
width: 28px;
height: 28px;
}
+#team-create-form:hover,
#repo-migrate-form:hover,
#repo-create-form:hover {
box-shadow: 0px 0px 6px #CCC;
@@ -1681,6 +1688,9 @@ textarea#issue-add-content {
box-sizing: border-box;
height: 120px;
}
+.org-header-alert .alert {
+ margin-top: 10px;
+}
.org-header {
padding: 16px 0;
background-color: #FFF;
@@ -1767,10 +1777,10 @@ textarea#issue-add-content {
.org-sidebar .panel-footer {
padding: .8em 1.2em;
}
-#org-member-avatar-group {
+.org-sidebar .member-avatar-group {
padding: 15px;
}
-#org-member-avatar-group img {
+.org-sidebar .member-avatar-group img {
width: 59px;
height: 59px;
border-radius: 3px;
@@ -1801,13 +1811,14 @@ textarea#issue-add-content {
margin-bottom: 0;
color: #777;
}
-#org-member-toolbar {
+.org-toolbar {
padding: 10px 0;
+ border-bottom: 1px solid #eee;
}
#org-member-list .org-member-item {
height: 50px;
line-height: 50px;
- border-top: 1px solid #eee;
+ border-bottom: 1px solid #eee;
padding: 15px 20px;
}
#org-member-list .org-member-item .member-name {
@@ -1832,3 +1843,19 @@ textarea#issue-add-content {
#org-member-list-block {
padding-top: 2px;
}
+.org-team-list .org-team-list-item {
+ float: left;
+ padding: 15px;
+ width: 555px;
+}
+.org-team-list .org-team-list-item .member-avatar-group {
+ padding: 5px 15px;
+}
+.org-team-list .org-team-list-item .member-avatar-group img {
+ width: 38px;
+ height: 38px;
+ border-radius: 3px;
+}
+#team-create-form .note {
+ margin-left: 153px;
+}
diff --git a/public/ng/less/gogs/organization.less b/public/ng/less/gogs/organization.less
index 3805829532..e8063f2328 100644
--- a/public/ng/less/gogs/organization.less
+++ b/public/ng/less/gogs/organization.less
@@ -1,3 +1,6 @@
+.org-header-alert .alert {
+ margin-top: 10px;
+}
.org-header {
padding: 16px 0;
background-color: #FFF;
@@ -91,13 +94,13 @@
.panel-footer {
padding: .8em 1.2em;
}
-}
-#org-member-avatar-group {
- padding: 15px;
- img {
- width: 59px;
- height: 59px;
- border-radius: 3px;
+ .member-avatar-group {
+ padding: 15px;
+ img {
+ width: 59px;
+ height: 59px;
+ border-radius: 3px;
+ }
}
}
#org-home-team-list {
@@ -126,14 +129,15 @@
margin-bottom: 0;
color: #777;
}
-#org-member-toolbar {
+.org-toolbar {
padding: 10px 0;
+ border-bottom: 1px solid #eee;
}
#org-member-list {
.org-member-item {
height: 50px;
line-height: 50px;
- border-top: 1px solid #eee;
+ border-bottom: 1px solid #eee;
padding: 15px 20px;
.member-name {
padding-left: 15px;
@@ -158,4 +162,24 @@
}
#org-member-list-block {
padding-top: 2px;
+}
+.org-team-list {
+ .org-team-list-item {
+ float: left;
+ padding: 15px;
+ width: 555px;
+ .member-avatar-group {
+ padding: 5px 15px;
+ img {
+ width: 38px;
+ height: 38px;
+ border-radius: 3px;
+ }
+ }
+ }
+}
+#team-create-form {
+ .note {
+ margin-left: 153px;
+ }
} \ No newline at end of file
diff --git a/public/ng/less/gogs/repository.less b/public/ng/less/gogs/repository.less
index 0aa19a04a9..8f9a97fa02 100644
--- a/public/ng/less/gogs/repository.less
+++ b/public/ng/less/gogs/repository.less
@@ -310,6 +310,7 @@ border-top-right-radius: .25em;
}
/* repository create */
+#team-create-form,
#repo-migrate-form,
#repo-create-form {
width: 800px;
diff --git a/routers/org/members.go b/routers/org/members.go
index d98061765a..1e249e8be2 100644
--- a/routers/org/members.go
+++ b/routers/org/members.go
@@ -14,13 +14,13 @@ import (
)
const (
- MEMBERS base.TplName = "org/members"
- INVITE base.TplName = "org/invite"
+ MEMBERS base.TplName = "org/member/members"
+ MEMBER_INVITE base.TplName = "org/member/invite"
)
func Members(ctx *middleware.Context) {
org := ctx.Org.Organization
- ctx.Data["Title"] = org.Name
+ ctx.Data["Title"] = org.FullName
ctx.Data["PageIsOrgMembers"] = true
if err := org.GetMembers(); err != nil {
@@ -60,6 +60,18 @@ func MembersAction(ctx *middleware.Context) {
return
}
err = org.RemoveMember(uid)
+ if err == models.ErrLastOrgOwner {
+ ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
+ ctx.Redirect(ctx.Org.OrgLink + "/members")
+ return
+ }
+ case "leave":
+ err = org.RemoveMember(ctx.User.Id)
+ if err == models.ErrLastOrgOwner {
+ ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
+ ctx.Redirect(ctx.Org.OrgLink + "/members")
+ return
+ }
}
if err != nil {
@@ -75,7 +87,7 @@ func MembersAction(ctx *middleware.Context) {
func Invitation(ctx *middleware.Context) {
org := ctx.Org.Organization
- ctx.Data["Title"] = org.Name
+ ctx.Data["Title"] = org.FullName
ctx.Data["PageIsOrgMembers"] = true
if ctx.Req.Method == "POST" {
@@ -101,5 +113,5 @@ func Invitation(ctx *middleware.Context) {
return
}
- ctx.HTML(200, INVITE)
+ ctx.HTML(200, MEMBER_INVITE)
}
diff --git a/routers/org/org.go b/routers/org/org.go
index 254ba8148f..27ccf02d3f 100644
--- a/routers/org/org.go
+++ b/routers/org/org.go
@@ -19,7 +19,7 @@ const (
func Home(ctx *middleware.Context) {
org := ctx.Org.Organization
- ctx.Data["Title"] = org.Name
+ ctx.Data["Title"] = org.FullName
repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id))
if err != nil {
diff --git a/routers/org/teams.go b/routers/org/teams.go
index d494ddc04d..bc12a97160 100644
--- a/routers/org/teams.go
+++ b/routers/org/teams.go
@@ -13,31 +13,22 @@ import (
)
const (
- TEAMS base.TplName = "org/teams"
- TEAM_NEW base.TplName = "org/team_new"
+ TEAMS base.TplName = "org/team/teams"
+ TEAM_NEW base.TplName = "org/team/new"
)
func Teams(ctx *middleware.Context) {
- ctx.Data["Title"] = "Organization " + ctx.Params(":org") + " Teams"
+ org := ctx.Org.Organization
+ ctx.Data["Title"] = org.FullName
+ ctx.Data["PageIsOrgTeams"] = true
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.Teams(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.Teams(GetUserByName)", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- if err = org.GetTeams(); err != nil {
- ctx.Handle(500, "org.Teams(GetTeams)", err)
+ if err := org.GetTeams(); err != nil {
+ ctx.Handle(500, "GetTeams", err)
return
}
for _, t := range org.Teams {
- if err = t.GetMembers(); err != nil {
- ctx.Handle(500, "org.Home(GetMembers)", err)
+ if err := t.GetMembers(); err != nil {
+ ctx.Handle(500, "GetMembers", err)
return
}
}
@@ -46,44 +37,39 @@ func Teams(ctx *middleware.Context) {
ctx.HTML(200, TEAMS)
}
-func NewTeam(ctx *middleware.Context) {
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.NewTeam(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.NewTeam(GetUserByName)", err)
- }
- return
+func TeamsAction(ctx *middleware.Context) {
+ var err error
+ switch ctx.Params(":action") {
+ case "join":
+ err = models.AddTeamMember(ctx.Org.Organization.Id, ctx.Org.Team.Id, ctx.User.Id)
+ case "leave":
+ err = models.RemoveMember(ctx.Org.Organization.Id, ctx.Org.Team.Id, ctx.User.Id)
}
- ctx.Data["Org"] = org
- // Check ownership of organization.
- if !org.IsOrgOwner(ctx.User.Id) {
- ctx.Error(403)
+ if err != nil {
+ log.Error(4, "Action(%s): %v", ctx.Params(":action"), err)
+ ctx.JSON(200, map[string]interface{}{
+ "ok": false,
+ "err": err.Error(),
+ })
return
}
+ ctx.Redirect(ctx.Org.OrgLink + "/teams")
+}
+func NewTeam(ctx *middleware.Context) {
+ ctx.Data["Title"] = ctx.Org.Organization.FullName
+ ctx.Data["PageIsOrgTeams"] = true
+ ctx.Data["PageIsOrgTeamsNew"] = true
+ ctx.Data["Team"] = &models.Team{}
ctx.HTML(200, TEAM_NEW)
}
func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.NewTeamPost(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.NewTeamPost(GetUserByName)", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- // Check ownership of organization.
- if !org.IsOrgOwner(ctx.User.Id) {
- ctx.Error(403)
- return
- }
+ ctx.Data["Title"] = ctx.Org.Organization.FullName
+ ctx.Data["PageIsOrgTeams"] = true
+ ctx.Data["PageIsOrgTeamsNew"] = true
+ ctx.Data["Team"] = &models.Team{}
if ctx.HasError() {
ctx.HTML(200, TEAM_NEW)
@@ -104,23 +90,29 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
return
}
+ org := ctx.Org.Organization
+
t := &models.Team{
OrgId: org.Id,
Name: form.TeamName,
Description: form.Description,
Authorize: auth,
}
- if err = models.NewTeam(t); err != nil {
- if err == models.ErrTeamAlreadyExist {
+ if err := models.NewTeam(t); err != nil {
+ switch err {
+ case models.ErrTeamNameIllegal:
+ ctx.Data["Err_TeamName"] = true
+ ctx.RenderWithErr(ctx.Tr("form.illegal_team_name"), TEAM_NEW, &form)
+ case models.ErrTeamAlreadyExist:
ctx.Data["Err_TeamName"] = true
- ctx.RenderWithErr("Team name has already been used", TEAM_NEW, &form)
- } else {
- ctx.Handle(500, "org.NewTeamPost(NewTeam)", err)
+ ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), TEAM_NEW, &form)
+ default:
+ ctx.Handle(500, "NewTeam", err)
}
return
}
- log.Trace("%s Team created: %s/%s", ctx.Req.RequestURI, org.Name, t.Name)
- ctx.Redirect("/org/" + org.LowerName + "/teams/" + t.LowerName)
+ log.Trace("Team created: %s/%s", org.Name, t.Name)
+ ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
}
func EditTeam(ctx *middleware.Context) {
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 404b22f24d..231ee66279 100644
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -20,12 +20,11 @@ import (
)
const (
- SIGNIN base.TplName = "user/signin"
- SIGNUP base.TplName = "user/signup"
- DELETE base.TplName = "user/delete"
- ACTIVATE base.TplName = "user/activate"
- FORGOT_PASSWORD base.TplName = "user/forgot_passwd"
- RESET_PASSWORD base.TplName = "user/reset_passwd"
+ SIGNIN base.TplName = "user/auth/signin"
+ SIGNUP base.TplName = "user/auth/signup"
+ ACTIVATE base.TplName = "user/auth/activate"
+ FORGOT_PASSWORD base.TplName = "user/auth/forgot_passwd"
+ RESET_PASSWORD base.TplName = "user/auth/reset_passwd"
)
func SignIn(ctx *middleware.Context) {
diff --git a/templates/.VERSION b/templates/.VERSION
index 906c01dc84..48fe58b179 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.4.7.0815 Alpha \ No newline at end of file
+0.4.7.0816 Alpha \ No newline at end of file
diff --git a/templates/org/header.tmpl b/templates/org/base/header.tmpl
index 8566d0a3c5..8566d0a3c5 100644
--- a/templates/org/header.tmpl
+++ b/templates/org/base/header.tmpl
diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl
index d96624010f..afd695ec7d 100644
--- a/templates/org/home.tmpl
+++ b/templates/org/home.tmpl
@@ -4,7 +4,10 @@
<div class="container clear">
<img class="avatar-100 left" src="{{.Org.AvatarLink}}?s=140"/>
<div id="org-home-header-info">
- <h2>{{.Org.FullName}} <a class="text-grey" href="/org/{{.Org.LowerName}}/settings"><span class="octicon octicon-gear"></span></a></h2>
+ <h2>
+ {{.Org.FullName}}
+ {{if .IsOrganizationOwner}}<a class="text-grey" href="{{.OrgLink}}/settings"><span class="octicon octicon-gear"></span></a>{{end}}
+ </h2>
{{if .Org.Description}}<p>{{.Org.Description}}</p>{{end}}
<ul class="text-grey">
{{if .Org.Location}}<li><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></li>{{end}}
@@ -17,7 +20,7 @@
<div class="container">
<div id="org-home-repo-list" class="left grid-2-3">
<div class="clear">
- {{if .IsAdminTeam}}
+ {{if .IsOrganizationOwner}}
<a class="btn btn-green btn-large btn-link btn-radius right" href="/repo/create?org={{.Org.Id}}"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "new_repo"}}</a>
{{end}}
</div>
@@ -42,12 +45,12 @@
<a class="text-grey right" href="/org/{{.Org.LowerName}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a>
<strong>{{.i18n.Tr "org.people"}}</strong>
</div>
- <div class="panel-body" id="org-member-avatar-group">
+ <div class="panel-body member-avatar-group">
{{range .Members}}
- <a href="/{{.Name}}"><img src="{{.AvatarLink}}"></a>
+ <a href="/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
{{end}}
</div>
- {{if .IsAdminTeam}}
+ {{if .IsOrganizationOwner}}
<div class="panel-footer">
<a class="btn btn-medium btn-blue btn-link btn-radius" href="/org/{{.Org.LowerName}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a>
</div>
diff --git a/templates/org/invite.tmpl b/templates/org/member/invite.tmpl
index b9901aeb48..bff1b98b4c 100644
--- a/templates/org/invite.tmpl
+++ b/templates/org/member/invite.tmpl
@@ -1,6 +1,6 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
-{{template "org/header" .}}
+{{template "org/base/header" .}}
<div class="container">
<div class="invite-box" id="invite-box">
{{template "ng/base/alert" .}}
diff --git a/templates/org/members.tmpl b/templates/org/member/members.tmpl
index bea4340ffb..3ab92bbfc0 100644
--- a/templates/org/members.tmpl
+++ b/templates/org/member/members.tmpl
@@ -1,9 +1,11 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
-{{template "org/header" .}}
+{{template "org/base/header" .}}
<div class="container">
- {{template "ng/base/alert" .}}
- <div class="clear" id="org-member-toolbar">
+ <div class="org-header-alert">
+ {{template "ng/base/alert" .}}
+ </div>
+ <div class="org-toolbar clear">
{{if .IsAdminTeam}}
<a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/invitations/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.invite_someone"}}</a>
{{end}}
@@ -25,15 +27,19 @@
{{end}}
</li>
<li class="grid-1-4">{{if .IsUserOrgOwner $.Org.Id}}<strong>{{$.i18n.Tr "org.members.owner"}}</strong>{{else}}{{$.i18n.Tr "org.members.member"}}{{end}}</li>
- {{if $.IsOrganizationOwner}}
- <li class="grid-1-6 right">
- <a class="btn btn-red btn-link btn-radius" href="{{$.OrgLink}}/members/action/remove?uid={{.Id}}">{{$.i18n.Tr "org.members.remove"}}</a>
- </li>
- {{if $isPublic}}
- <li class="grid-1-6 right">
- <a class="btn btn-blue btn-link btn-radius" href="{{$.OrgLink}}/members/action/private?uid={{.Id}}">{{$.i18n.Tr "org.members.conceal"}}</a>
- </li>
- {{end}}
+ {{if eq $.SignedUser.Id .Id}}
+ <li class="grid-1-6 right">
+ <a class="btn btn-red btn-link btn-radius" href="{{$.OrgLink}}/members/action/leave?uid={{.Id}}">{{$.i18n.Tr "org.members.leave"}}</a>
+ </li>
+ {{else if $.IsOrganizationOwner}}
+ <li class="grid-1-6 right">
+ <a class="btn btn-red btn-link btn-radius" href="{{$.OrgLink}}/members/action/remove?uid={{.Id}}">{{$.i18n.Tr "org.members.remove"}}</a>
+ </li>
+ {{if $isPublic}}
+ <li class="grid-1-6 right">
+ <a class="btn btn-blue btn-link btn-radius" href="{{$.OrgLink}}/members/action/private?uid={{.Id}}">{{$.i18n.Tr "org.members.conceal"}}</a>
+ </li>
+ {{end}}
{{end}}
</ul>
</div>
diff --git a/templates/org/settings/delete.tmpl b/templates/org/settings/delete.tmpl
index 7e24f85144..828389d6ff 100644
--- a/templates/org/settings/delete.tmpl
+++ b/templates/org/settings/delete.tmpl
@@ -1,5 +1,6 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
+{{template "org/header" .}}
<div id="setting-wrapper" class="main-wrapper">
<div id="org-setting" class="container clear">
{{template "org/settings/nav" .}}
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl
index 7548ad5aef..c5c6a7e221 100644
--- a/templates/org/settings/options.tmpl
+++ b/templates/org/settings/options.tmpl
@@ -1,5 +1,6 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
+{{template "org/header" .}}
<div id="setting-wrapper" class="main-wrapper">
<div id="org-setting" class="container clear">
{{template "org/settings/nav" .}}
diff --git a/templates/org/team/new.tmpl b/templates/org/team/new.tmpl
new file mode 100644
index 0000000000..f02512e052
--- /dev/null
+++ b/templates/org/team/new.tmpl
@@ -0,0 +1,48 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+{{template "org/base/header" .}}
+<div id="repo-wrapper">
+ <form id="team-create-form" class="form form-align panel panel-radius" action="{{.OrgLink}}/teams/new" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="panel-header">
+ <h2>{{.i18n.Tr "org.create_new_team"}}</h2>
+ </div>
+ <div class="panel-content">
+ {{template "ng/base/alert" .}}
+ <div class="field">
+ <label class="req" for="team-name">{{.i18n.Tr "org.team_name"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_TeamName}}ipt-error{{end}}" id="team-name" name="team_name" value="{{.team_name}}" required />
+ <span class="form-label"></span>
+ <span class="help">{{.i18n.Tr "org.team_name_helper"}}</span>
+ </div>
+ <div class="field">
+ <label for="desc">{{.i18n.Tr "org.team_desc"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc" value="{{.desc}}" />
+ <span class="form-label"></span>
+ <span class="help">{{.i18n.Tr "org.team_desc_helper"}}</span>
+ </div>
+ <div class="field">
+ <h4 class="text-center">{{.i18n.Tr "org.team_permission_desc"}}</h4>
+ <label></label>
+ <input name="permission" type="radio" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.Authorize 1)}}checked{{end}}> {{.i18n.Tr "org.teams.read_access"}}
+ <label></label>
+ <p class="text-grey note">{{.i18n.Tr "org.teams.read_access_helper"}}</p>
+ <label></label>
+ <input name="permission" type="radio" value="write" {{if eq .Team.Authorize 2}}checked{{end}}> {{.i18n.Tr "org.teams.write_access"}}
+ <label></label>
+ <p class="text-grey note">{{.i18n.Tr "org.teams.write_access_helper"}}</p>
+ <label></label>
+ <input name="permission" type="radio" value="admin" {{if eq .Team.Authorize 3}}checked{{end}}> {{.i18n.Tr "org.teams.admin_access"}}
+ <label></label>
+ <p class="text-grey note">{{.i18n.Tr "org.teams.admin_access_helper"}}</p>
+ </div>
+ <hr>
+ <div class="field">
+ <label></label>
+ <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_new_team"}}</button>
+ <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{.OrgLink}}/teams"><strong>{{.i18n.Tr "cancel"}}</strong></a>
+ </div>
+ </div>
+ </form>
+</div>
+{{template "ng/base/footer" .}} \ No newline at end of file
diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl
new file mode 100644
index 0000000000..3e0846d652
--- /dev/null
+++ b/templates/org/team/teams.tmpl
@@ -0,0 +1,42 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+{{template "org/base/header" .}}
+<div class="container">
+ <div class="org-header-alert">
+ {{template "ng/base/alert" .}}
+ </div>
+ <div class="org-toolbar clear">
+ {{if .IsAdminTeam}}
+ <a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/teams/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.create_new_team"}}</a>
+ {{end}}
+ </div>
+ <div class="org-team-list">
+ {{range .Teams}}
+ <div class="org-team-list-item">
+ <div class="panel panel-radius">
+ <div class="panel-header">
+ {{if .IsMember $.SignedUser.Id}}
+ <a class="btn btn-small btn-red btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave">{{$.i18n.Tr "org.teams.leave"}}</a>
+ {{else}}
+ <a class="btn btn-small btn-blue btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/join">{{$.i18n.Tr "org.teams.join"}}</a>
+ {{end}}
+ <a class="text-black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
+ </div>
+ {{if .NumMembers}}
+ <div class="panel-body member-avatar-group">
+ {{range .Members}}
+ <a href="/{{.Name}}" title="{{.Name}}">
+ <img src="{{.AvatarLink}}">
+ </a>
+ {{end}}
+ </div>
+ {{end}}
+ <div class="panel-footer">
+ <p class="team-meta">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+</div>
+{{template "ng/base/footer" .}} \ No newline at end of file
diff --git a/templates/org/team_new.tmpl b/templates/org/team_new.tmpl
deleted file mode 100644
index 0936ec29b3..0000000000
--- a/templates/org/team_new.tmpl
+++ /dev/null
@@ -1,79 +0,0 @@
-{{template "base/head" .}}
-{{template "base/navbar" .}}
-<div id="body-nav" class="org-nav org-nav-auto">
- <div class="container clearfix">
- <div id="org-nav-wrapper">
- <ul class="nav nav-pills pull-right">
- <li><a href="/org/{{.Org.Name}}/members"><i class="fa fa-users"></i>Members
- <span class="label label-default">{{.Org.NumMembers}}</span></a>
- </li>
- <li class="active"><a href="/org/{{.Org.Name}}/teams"><i class="fa fa-tags"></i>Teams
- <span class="label label-default">{{.Org.NumTeams}}</span></a>
- </li>
- </ul>
- <img class="pull-left org-small-logo" src="{{.Org.AvatarLink}}?s=140" alt="" width="60"/>
- <div id="org-nav-info">
- <h2 class="org-name">{{.Org.FullName}}</h2>
- </div>
- </div>
- </div>
-</div>
-
-<div id="body" class="container">
- <div id="org">
- <form action="/org/{{.Org.Name}}/teams/new" method="post" id="org-teams-create" class="form-horizontal card">
- {{.CsrfTokenHtml}}
- <h3>Create new team</h3>
- {{template "base/alert" .}}
- <div class="form-group{{if .Err_TeamName}} has-error has-feedback{{end}}">
- <label class="col-md-2 control-label">Team Name<strong class="text-danger">*</strong></label>
- <div class="col-md-8">
- <input name="name" type="text" class="form-control" placeholder="Type your team name" value="{{.name}}" required="required">
- <span class="help-block">You'll use this name to mention this team in conversations.</span>
- </div>
- </div>
-
- <div class="form-group{{if .Err_Description}} has-error has-feedback{{end}}">
- <label class="col-md-2 control-label">Description</label>
- <div class="col-md-8">
- <input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value="{{.desc}}">
- </div>
- </div>
-
- <div class="form-group{{if .Err_Permission}} has-error has-feedback{{end}}">
- <label class="col-md-2 control-label">Permission</label>
- <div class="col-md-8">
- <div class="radio">
- <label>
- <input type="radio" name="permission" value="read" checked="">
- <strong>Read Access</strong>
- </label>
- <p>This team will be able to view and clone its repositories.</p>
- </div>
- <div class="radio">
- <label>
- <input type="radio" name="permission" value="write">
- <strong>Write Access</strong>
- </label>
- <p>This team will be able to read its repositories, as well as push to them.</p>
- </div>
- <div class="radio">
- <label>
- <input type="radio" name="permission" value="admin">
- <strong>Admin Access</strong>
- </label>
- <p>This team will be able to push/pull to its repositories, as well as add other collaborators to them.</p>
- </div>
- </div>
- </div>
- <hr/>
- <div class="form-group">
- <label class="col-md-2">&nbsp;</label>
- <div class="col-md-8">
- <button class="btn btn-primary">Create team</button>
- </div>
- </div>
- </form>
- </div>
-</div>
-{{template "base/footer" .}}
diff --git a/templates/org/teams.tmpl b/templates/org/teams.tmpl
deleted file mode 100644
index 90ee209c0a..0000000000
--- a/templates/org/teams.tmpl
+++ /dev/null
@@ -1,58 +0,0 @@
-{{template "base/head" .}}
-{{template "base/navbar" .}}
-<div id="body-nav" class="org-nav org-nav-auto">
- <div class="container clearfix">
- <div id="org-nav-wrapper">
- <ul class="nav nav-pills pull-right">
- <li><a href="/org/{{.Org.Name}}/members"><i class="fa fa-users"></i>Members
- <span class="label label-default">{{.Org.NumMembers}}</span></a>
- </li>
- <li class="active"><a href="/org/{{.Org.Name}}/teams"><i class="fa fa-tags"></i>Teams
- <span class="label label-default">{{.Org.NumTeams}}</span></a>
- </li>
- </ul>
- <img class="pull-left org-small-logo" src="{{.Org.AvatarLink}}?s=140" alt="" width="60"/>
- <div id="org-nav-info">
- <h2 class="org-name">{{.Org.FullName}}</h2>
- </div>
- </div>
- </div>
-</div>
-
-<div id="body" class="container">
- <div id="org">
- <div id="org-teams">
- <div id="org-teams-action">
- <div class="col-md-12">
- <a href="/org/{{.Org.Name}}/teams/new"><button class="btn btn-success"><i class="fa fa-plus-square"></i>New Team</button></a>
- <hr/>
- </div>
- </div>
- {{range .Teams}}
- <div class="org-team col-md-6">
- <div class="panel panel-default">
- <h2 class="panel-heading org-team-name"><a href="/org/{{$.Org.Name}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a></h2>
- <div class="panel-body">
- <p class="org-team-meta">{{.NumMembers}} members · {{.NumRepos}} repositories</p>
- <p class="org-team-members">
- {{range .Members}}
- <a href="/user/{{.LowerName}}">
- <img class="img-thumbnail" src="{{.AvatarLink}}?s=60" alt=""/>
- </a>
- {{end}}
- </p>
- </div>
- <div class="panel-footer">
- {{if .IsMember $.SignedUser.Id}}
- <a class="pull-right btn btn-danger" href="/org/{{$.Org.Name}}/teams/{{.LowerName}}?action=leave">Leave</a>
- {{else}}
- <a class="pull-right btn btn-default" href="/org/{{$.Org.Name}}/teams/{{.LowerName}}?action=join">Join</a>
- {{end}}
- </div>
- </div>
- </div>
- {{end}}
- </div>
- </div>
-</div>
-{{template "base/footer" .}}
diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl
index b5a8ea4e47..6baa6d31e0 100644
--- a/templates/repo/create.tmpl
+++ b/templates/repo/create.tmpl
@@ -3,7 +3,9 @@
<div id="repo-wrapper">
<form id="repo-create-form" class="form form-align panel panel-radius" action="/repo/create" method="post">
{{.CsrfTokenHtml}}
- <div class="panel-header"><h2>{{.i18n.Tr "new_repo"}}</h2></div>
+ <div class="panel-header">
+ <h2>{{.i18n.Tr "new_repo"}}</h2>
+ </div>
<div class="panel-content">
{{template "ng/base/alert" .}}
<div class="field">
diff --git a/templates/user/activate.tmpl b/templates/user/auth/activate.tmpl
index acdad9e80b..acdad9e80b 100644
--- a/templates/user/activate.tmpl
+++ b/templates/user/auth/activate.tmpl
diff --git a/templates/user/forgot_passwd.tmpl b/templates/user/auth/forgot_passwd.tmpl
index 3b5512673b..3b5512673b 100644
--- a/templates/user/forgot_passwd.tmpl
+++ b/templates/user/auth/forgot_passwd.tmpl
diff --git a/templates/user/reset_passwd.tmpl b/templates/user/auth/reset_passwd.tmpl
index d17abde2ba..d17abde2ba 100644
--- a/templates/user/reset_passwd.tmpl
+++ b/templates/user/auth/reset_passwd.tmpl
diff --git a/templates/user/signin.tmpl b/templates/user/auth/signin.tmpl
index c2f6ef877a..c2f6ef877a 100644
--- a/templates/user/signin.tmpl
+++ b/templates/user/auth/signin.tmpl
diff --git a/templates/user/signup.tmpl b/templates/user/auth/signup.tmpl
index b4736a07ce..b4736a07ce 100644
--- a/templates/user/signup.tmpl
+++ b/templates/user/auth/signup.tmpl
diff --git a/templates/user/stars.tmpl b/templates/user/stars.tmpl
deleted file mode 100644
index 253efd6eec..0000000000
--- a/templates/user/stars.tmpl
+++ /dev/null
@@ -1,17 +0,0 @@
-{{template "base/head" .}}
-{{template "base/navbar" .}}
-<div id="body-nav">
- <div class="container">
- <ul class="nav nav-pills pull-right">
- <li><a href="/">Feed</a></li>
- <li><a href="/issues">Issues</a></li>
- <li><a href="/pulls">Pull Requests</a></li>
- <li class="active"><a href="/stars">Stars</a></li>
- </ul>
- <h3>Stars</h3>
- </div>
-</div>
-<div id="body" class="container" data-page="user">
- {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
-</div>
-{{template "base/footer" .}} \ No newline at end of file