mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Finish team list, create new team, join/leave team page
This commit is contained in:
		@@ -236,6 +236,7 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			r.Get("/teams", org.Teams)
 | 
								r.Get("/teams", org.Teams)
 | 
				
			||||||
			r.Get("/teams/:team", org.SingleTeam)
 | 
								r.Get("/teams/:team", org.SingleTeam)
 | 
				
			||||||
 | 
								r.Get("/teams/:team/action/:action", org.TeamsAction)
 | 
				
			||||||
		}, middleware.OrgAssignment(true, true))
 | 
							}, middleware.OrgAssignment(true, true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Group("/:org", func(r *macaron.Router) {
 | 
							m.Group("/:org", func(r *macaron.Router) {
 | 
				
			||||||
@@ -248,11 +249,9 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
				r.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
 | 
									r.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
 | 
				
			||||||
				r.Route("/delete", "GET,POST", org.SettingsDelete)
 | 
									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)
 | 
								r.Route("/invitations/new", "GET,POST", org.Invitation)
 | 
				
			||||||
		}, middleware.OrgAssignment(true, false, false, true))
 | 
							}, middleware.OrgAssignment(true, true, true))
 | 
				
			||||||
	}, reqSignIn)
 | 
						}, reqSignIn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Repository routers.
 | 
						// Repository routers.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,6 +79,7 @@ Retype = Re-type password
 | 
				
			|||||||
SSHTitle = SSH key name
 | 
					SSHTitle = SSH key name
 | 
				
			||||||
HttpsUrl = HTTPS URL
 | 
					HttpsUrl = HTTPS URL
 | 
				
			||||||
PayloadUrl = Payload URL
 | 
					PayloadUrl = Payload URL
 | 
				
			||||||
 | 
					TeamName = Team name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require_error = ` cannot be empty.`
 | 
					require_error = ` cannot be empty.`
 | 
				
			||||||
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
 | 
					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.
 | 
					username_been_taken = Username has been already taken.
 | 
				
			||||||
repo_name_been_taken = Repository name has been already taken.
 | 
					repo_name_been_taken = Repository name has been already taken.
 | 
				
			||||||
org_name_been_taken = Organization 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.
 | 
					email_been_used = E-mail address has been already used.
 | 
				
			||||||
ssh_key_been_used = Public key name has been used.
 | 
					ssh_key_been_used = Public key name has been used.
 | 
				
			||||||
illegal_username = Your username contains illegal characters.
 | 
					illegal_username = Your username contains illegal characters.
 | 
				
			||||||
illegal_repo_name = Repository name contains illegal characters.
 | 
					illegal_repo_name = Repository name contains illegal characters.
 | 
				
			||||||
illegal_org_name = Organization 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.
 | 
					username_password_incorrect = Username or password is not correct.
 | 
				
			||||||
enterred_invalid_repo_name = Please make sure you entered repository name is 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_owner_name = Please make sure you entered owner name is correct.
 | 
				
			||||||
enterred_invalid_password = Please make sure you entered password is correct.
 | 
					enterred_invalid_password = Please make sure you entered password is correct.
 | 
				
			||||||
user_not_exist = Given user does not exist.
 | 
					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
 | 
					invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
 | 
				
			||||||
auth_failed = Authentication failed: %v
 | 
					auth_failed = Authentication failed: %v
 | 
				
			||||||
@@ -237,6 +241,11 @@ lower_members = members
 | 
				
			|||||||
lower_repositories = repositories
 | 
					lower_repositories = repositories
 | 
				
			||||||
create_new_team = Create New Team
 | 
					create_new_team = Create New Team
 | 
				
			||||||
org_desc = Description
 | 
					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 = Settings
 | 
				
			||||||
settings.options = Options
 | 
					settings.options = Options
 | 
				
			||||||
@@ -258,9 +267,19 @@ members.owner = Owner
 | 
				
			|||||||
members.member = Member
 | 
					members.member = Member
 | 
				
			||||||
members.conceal = Conceal
 | 
					members.conceal = Conceal
 | 
				
			||||||
members.remove = Remove
 | 
					members.remove = Remove
 | 
				
			||||||
 | 
					members.leave = Leave
 | 
				
			||||||
members.invite_desc = Start typing a username to invite a new member to %s:
 | 
					members.invite_desc = Start typing a username to invite a new member to %s:
 | 
				
			||||||
members.invite_now = Invite Now
 | 
					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]
 | 
					[action]
 | 
				
			||||||
create_repo = created repository <a href="/%s">%s</a>
 | 
					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>
 | 
					commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,6 +79,7 @@ Retype = 确认密码
 | 
				
			|||||||
SSHTitle = SSH 密钥名称
 | 
					SSHTitle = SSH 密钥名称
 | 
				
			||||||
HttpsUrl = HTTPS URL 地址
 | 
					HttpsUrl = HTTPS URL 地址
 | 
				
			||||||
PayloadUrl = 推送地址
 | 
					PayloadUrl = 推送地址
 | 
				
			||||||
 | 
					TeamName = 团队名称
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require_error = 不能为空。
 | 
					require_error = 不能为空。
 | 
				
			||||||
alpha_dash_error = 必须为英文字母、阿拉伯数字或横线(-_)。
 | 
					alpha_dash_error = 必须为英文字母、阿拉伯数字或横线(-_)。
 | 
				
			||||||
@@ -94,16 +95,19 @@ password_not_match = 密码与确认密码未匹配。
 | 
				
			|||||||
username_been_taken = 用户名已经被占用。
 | 
					username_been_taken = 用户名已经被占用。
 | 
				
			||||||
repo_name_been_taken = 仓库名称已经被占用。
 | 
					repo_name_been_taken = 仓库名称已经被占用。
 | 
				
			||||||
org_name_been_taken = 组织名称已经被占用。
 | 
					org_name_been_taken = 组织名称已经被占用。
 | 
				
			||||||
 | 
					team_name_been_taken = 团队名称已经被占用。
 | 
				
			||||||
email_been_used = 邮箱地址已经被使用。
 | 
					email_been_used = 邮箱地址已经被使用。
 | 
				
			||||||
ssh_key_been_used = SSH 密钥已经被使用。
 | 
					ssh_key_been_used = SSH 密钥已经被使用。
 | 
				
			||||||
illegal_username = 您的用户名包含非法字符。
 | 
					illegal_username = 您的用户名包含非法字符。
 | 
				
			||||||
illegal_repo_name = 仓库名称包含非法字符。
 | 
					illegal_repo_name = 仓库名称包含非法字符。
 | 
				
			||||||
illegal_org_name = 组织名称包含非法字符。
 | 
					illegal_org_name = 组织名称包含非法字符。
 | 
				
			||||||
 | 
					illegal_team_name = 团队名称包含非法字符。
 | 
				
			||||||
username_password_incorrect = 用户名或密码不正确。
 | 
					username_password_incorrect = 用户名或密码不正确。
 | 
				
			||||||
enterred_invalid_repo_name = 请检查您输入的仓库名称是正确。
 | 
					enterred_invalid_repo_name = 请检查您输入的仓库名称是正确。
 | 
				
			||||||
enterred_invalid_owner_name = 请检查您输入的新所有者用户名是否正确。
 | 
					enterred_invalid_owner_name = 请检查您输入的新所有者用户名是否正确。
 | 
				
			||||||
enterred_invalid_password = 请检查您输入的密码是否正确。
 | 
					enterred_invalid_password = 请检查您输入的密码是否正确。
 | 
				
			||||||
user_not_exist = 被操作的用户不存在!
 | 
					user_not_exist = 被操作的用户不存在!
 | 
				
			||||||
 | 
					last_org_owner = 被移除用户为最后一位管理员。请添加一位新的管理员再进行移除成员操作!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
 | 
					invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
 | 
				
			||||||
auth_failed = 授权验证失败:%v
 | 
					auth_failed = 授权验证失败:%v
 | 
				
			||||||
@@ -237,6 +241,11 @@ lower_members = 名成员
 | 
				
			|||||||
lower_repositories = 个仓库
 | 
					lower_repositories = 个仓库
 | 
				
			||||||
create_new_team = 创建新的团队
 | 
					create_new_team = 创建新的团队
 | 
				
			||||||
org_desc = 组织描述
 | 
					org_desc = 组织描述
 | 
				
			||||||
 | 
					team_name = 团队名称
 | 
				
			||||||
 | 
					team_desc = 团队描述
 | 
				
			||||||
 | 
					team_name_helper = 您可以使用该名称来通知改组全体成员。
 | 
				
			||||||
 | 
					team_desc_helper = 一句话描述这个团队是做什么的。
 | 
				
			||||||
 | 
					team_permission_desc = 请选择该团队所具有的权限等级:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
settings = 组织设置
 | 
					settings = 组织设置
 | 
				
			||||||
settings.options = 基本设置
 | 
					settings.options = 基本设置
 | 
				
			||||||
@@ -258,9 +267,19 @@ members.owner = 管理员
 | 
				
			|||||||
members.member = 普通成员
 | 
					members.member = 普通成员
 | 
				
			||||||
members.conceal = 隐藏身份
 | 
					members.conceal = 隐藏身份
 | 
				
			||||||
members.remove = 移除成员
 | 
					members.remove = 移除成员
 | 
				
			||||||
 | 
					members.leave = 离开组织
 | 
				
			||||||
members.invite_desc = 请输入被邀请到组织 %s 的用户名称:
 | 
					members.invite_desc = 请输入被邀请到组织 %s 的用户名称:
 | 
				
			||||||
members.invite_now = 立即邀请
 | 
					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]
 | 
					[action]
 | 
				
			||||||
create_repo = 创建了仓库 <a href="/%s">%s</a>
 | 
					create_repo = 创建了仓库 <a href="/%s">%s</a>
 | 
				
			||||||
commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
 | 
					commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.4.7.0815 Alpha"
 | 
					const APP_VER = "0.4.7.0816 Alpha"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										306
									
								
								models/org.go
									
									
									
									
									
								
							
							
						
						
									
										306
									
								
								models/org.go
									
									
									
									
									
								
							@@ -15,6 +15,9 @@ import (
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	ErrOrgNotExist      = errors.New("Organization does not exist")
 | 
						ErrOrgNotExist      = errors.New("Organization does not exist")
 | 
				
			||||||
	ErrTeamAlreadyExist = errors.New("Team already 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.
 | 
					// 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)
 | 
						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.
 | 
					// GetOwnerTeam returns owner team of organization.
 | 
				
			||||||
func (org *User) GetOwnerTeam() (*Team, error) {
 | 
					func (org *User) GetOwnerTeam() (*Team, error) {
 | 
				
			||||||
	t := &Team{
 | 
						return org.GetTeam(OWNER_TEAM)
 | 
				
			||||||
		OrgId: org.Id,
 | 
					 | 
				
			||||||
		Name:  OWNER_TEAM,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err := x.Get(t)
 | 
					 | 
				
			||||||
	return t, err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTeams returns all teams that belong to organization.
 | 
					// GetTeams returns all teams that belong to organization.
 | 
				
			||||||
@@ -179,96 +182,6 @@ func DeleteOrganization(org *User) (err error) {
 | 
				
			|||||||
	return sess.Commit()
 | 
						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
 | 
							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()
 | 
						sess := x.NewSession()
 | 
				
			||||||
	defer sess.Close()
 | 
						defer sess.Close()
 | 
				
			||||||
	if err := sess.Begin(); err != nil {
 | 
						if err := sess.Begin(); err != nil {
 | 
				
			||||||
@@ -389,6 +317,127 @@ func RemoveOrgUser(orgId, uid int64) error {
 | 
				
			|||||||
	return sess.Commit()
 | 
						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
 | 
						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()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,7 @@ func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs *binding.Erro
 | 
				
			|||||||
//              \/     \/      \/
 | 
					//              \/     \/      \/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreateTeamForm struct {
 | 
					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)"`
 | 
						Description string `form:"desc" binding:"MaxSize(255)"`
 | 
				
			||||||
	Permission  string `form:"permission"`
 | 
						Permission  string `form:"permission"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,6 +71,8 @@ type Context struct {
 | 
				
			|||||||
		IsAdminTeam  bool // In owner team or team that has admin permission level.
 | 
							IsAdminTeam  bool // In owner team or team that has admin permission level.
 | 
				
			||||||
		Organization *models.User
 | 
							Organization *models.User
 | 
				
			||||||
		OrgLink      string
 | 
							OrgLink      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Team *models.Team
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,15 +41,16 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Data["Org"] = ctx.Org.Organization
 | 
							org := ctx.Org.Organization
 | 
				
			||||||
 | 
							ctx.Data["Org"] = org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ctx.IsSigned {
 | 
							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 {
 | 
								if ctx.Org.IsOwner {
 | 
				
			||||||
				ctx.Org.IsMember = true
 | 
									ctx.Org.IsMember = true
 | 
				
			||||||
				ctx.Org.IsAdminTeam = true
 | 
									ctx.Org.IsAdminTeam = true
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if ctx.Org.Organization.IsOrgMember(ctx.User.Id) {
 | 
									if org.IsOrgMember(ctx.User.Id) {
 | 
				
			||||||
					ctx.Org.IsMember = true
 | 
										ctx.Org.IsMember = true
 | 
				
			||||||
					// TODO: ctx.Org.IsAdminTeam
 | 
										// TODO: ctx.Org.IsAdminTeam
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -64,7 +65,24 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
		ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
							ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
				
			||||||
		ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 | 
							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
 | 
							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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1172,28 +1172,34 @@ The register and sign-in page style
 | 
				
			|||||||
  width: 520px;
 | 
					  width: 520px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* repository create */
 | 
					/* repository create */
 | 
				
			||||||
 | 
					#team-create-form,
 | 
				
			||||||
#repo-migrate-form,
 | 
					#repo-migrate-form,
 | 
				
			||||||
#repo-create-form {
 | 
					#repo-create-form {
 | 
				
			||||||
  width: 800px;
 | 
					  width: 800px;
 | 
				
			||||||
  margin: 60px auto auto auto;
 | 
					  margin: 60px auto auto auto;
 | 
				
			||||||
  background: white;
 | 
					  background: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form h2,
 | 
				
			||||||
#repo-migrate-form h2,
 | 
					#repo-migrate-form h2,
 | 
				
			||||||
#repo-create-form h2 {
 | 
					#repo-create-form h2 {
 | 
				
			||||||
  margin: .5em 1em;
 | 
					  margin: .5em 1em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form .field,
 | 
				
			||||||
#repo-migrate-form .field,
 | 
					#repo-migrate-form .field,
 | 
				
			||||||
#repo-create-form .field {
 | 
					#repo-create-form .field {
 | 
				
			||||||
  margin: 1.2em 0 2em 0;
 | 
					  margin: 1.2em 0 2em 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form .ipt,
 | 
				
			||||||
#repo-migrate-form .ipt,
 | 
					#repo-migrate-form .ipt,
 | 
				
			||||||
#repo-create-form .ipt {
 | 
					#repo-create-form .ipt {
 | 
				
			||||||
  width: 540px;
 | 
					  width: 540px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form textarea,
 | 
				
			||||||
#repo-migrate-form textarea,
 | 
					#repo-migrate-form textarea,
 | 
				
			||||||
#repo-create-form textarea {
 | 
					#repo-create-form textarea {
 | 
				
			||||||
  height: 120px;
 | 
					  height: 120px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form .avatar,
 | 
				
			||||||
#repo-migrate-form .avatar,
 | 
					#repo-migrate-form .avatar,
 | 
				
			||||||
#repo-create-form .avatar {
 | 
					#repo-create-form .avatar {
 | 
				
			||||||
  vertical-align: middle;
 | 
					  vertical-align: middle;
 | 
				
			||||||
@@ -1201,6 +1207,7 @@ The register and sign-in page style
 | 
				
			|||||||
  width: 28px;
 | 
					  width: 28px;
 | 
				
			||||||
  height: 28px;
 | 
					  height: 28px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-create-form:hover,
 | 
				
			||||||
#repo-migrate-form:hover,
 | 
					#repo-migrate-form:hover,
 | 
				
			||||||
#repo-create-form:hover {
 | 
					#repo-create-form:hover {
 | 
				
			||||||
  box-shadow: 0px 0px 6px #CCC;
 | 
					  box-shadow: 0px 0px 6px #CCC;
 | 
				
			||||||
@@ -1681,6 +1688,9 @@ textarea#issue-add-content {
 | 
				
			|||||||
  box-sizing: border-box;
 | 
					  box-sizing: border-box;
 | 
				
			||||||
  height: 120px;
 | 
					  height: 120px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.org-header-alert .alert {
 | 
				
			||||||
 | 
					  margin-top: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.org-header {
 | 
					.org-header {
 | 
				
			||||||
  padding: 16px 0;
 | 
					  padding: 16px 0;
 | 
				
			||||||
  background-color: #FFF;
 | 
					  background-color: #FFF;
 | 
				
			||||||
@@ -1767,10 +1777,10 @@ textarea#issue-add-content {
 | 
				
			|||||||
.org-sidebar .panel-footer {
 | 
					.org-sidebar .panel-footer {
 | 
				
			||||||
  padding: .8em 1.2em;
 | 
					  padding: .8em 1.2em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-avatar-group {
 | 
					.org-sidebar .member-avatar-group {
 | 
				
			||||||
  padding: 15px;
 | 
					  padding: 15px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-avatar-group img {
 | 
					.org-sidebar .member-avatar-group img {
 | 
				
			||||||
  width: 59px;
 | 
					  width: 59px;
 | 
				
			||||||
  height: 59px;
 | 
					  height: 59px;
 | 
				
			||||||
  border-radius: 3px;
 | 
					  border-radius: 3px;
 | 
				
			||||||
@@ -1801,13 +1811,14 @@ textarea#issue-add-content {
 | 
				
			|||||||
  margin-bottom: 0;
 | 
					  margin-bottom: 0;
 | 
				
			||||||
  color: #777;
 | 
					  color: #777;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-toolbar {
 | 
					.org-toolbar {
 | 
				
			||||||
  padding: 10px 0;
 | 
					  padding: 10px 0;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #eee;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-list .org-member-item {
 | 
					#org-member-list .org-member-item {
 | 
				
			||||||
  height: 50px;
 | 
					  height: 50px;
 | 
				
			||||||
  line-height: 50px;
 | 
					  line-height: 50px;
 | 
				
			||||||
  border-top: 1px solid #eee;
 | 
					  border-bottom: 1px solid #eee;
 | 
				
			||||||
  padding: 15px 20px;
 | 
					  padding: 15px 20px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-list .org-member-item .member-name {
 | 
					#org-member-list .org-member-item .member-name {
 | 
				
			||||||
@@ -1832,3 +1843,19 @@ textarea#issue-add-content {
 | 
				
			|||||||
#org-member-list-block {
 | 
					#org-member-list-block {
 | 
				
			||||||
  padding-top: 2px;
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					.org-header-alert .alert {
 | 
				
			||||||
 | 
						margin-top: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.org-header {
 | 
					.org-header {
 | 
				
			||||||
	padding: 16px 0;
 | 
						padding: 16px 0;
 | 
				
			||||||
	background-color: #FFF;
 | 
						background-color: #FFF;
 | 
				
			||||||
@@ -91,13 +94,13 @@
 | 
				
			|||||||
	.panel-footer {
 | 
						.panel-footer {
 | 
				
			||||||
		padding: .8em 1.2em;
 | 
							padding: .8em 1.2em;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
						.member-avatar-group {
 | 
				
			||||||
#org-member-avatar-group {
 | 
							padding: 15px;
 | 
				
			||||||
	padding: 15px;
 | 
							img {
 | 
				
			||||||
	img {
 | 
								width: 59px;
 | 
				
			||||||
		width: 59px;
 | 
								height: 59px;
 | 
				
			||||||
		height: 59px;
 | 
								border-radius: 3px;
 | 
				
			||||||
		border-radius: 3px;
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-home-team-list {
 | 
					#org-home-team-list {
 | 
				
			||||||
@@ -126,14 +129,15 @@
 | 
				
			|||||||
	margin-bottom: 0;
 | 
						margin-bottom: 0;
 | 
				
			||||||
	color: #777;
 | 
						color: #777;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-toolbar {
 | 
					.org-toolbar {
 | 
				
			||||||
	padding: 10px 0;
 | 
						padding: 10px 0;
 | 
				
			||||||
 | 
						border-bottom: 1px solid #eee;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#org-member-list {
 | 
					#org-member-list {
 | 
				
			||||||
	.org-member-item {
 | 
						.org-member-item {
 | 
				
			||||||
		height: 50px;
 | 
							height: 50px;
 | 
				
			||||||
		line-height: 50px;
 | 
							line-height: 50px;
 | 
				
			||||||
		border-top: 1px solid #eee;
 | 
							border-bottom: 1px solid #eee;
 | 
				
			||||||
		padding: 15px 20px;
 | 
							padding: 15px 20px;
 | 
				
			||||||
		.member-name {
 | 
							.member-name {
 | 
				
			||||||
			padding-left: 15px;
 | 
								padding-left: 15px;
 | 
				
			||||||
@@ -158,4 +162,24 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#org-member-list-block {
 | 
					#org-member-list-block {
 | 
				
			||||||
	padding-top: 2px;
 | 
						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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -310,6 +310,7 @@ border-top-right-radius: .25em;
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
/* repository create */
 | 
					/* repository create */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#team-create-form,
 | 
				
			||||||
#repo-migrate-form,
 | 
					#repo-migrate-form,
 | 
				
			||||||
#repo-create-form {
 | 
					#repo-create-form {
 | 
				
			||||||
	width: 800px;
 | 
						width: 800px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,13 +14,13 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	MEMBERS base.TplName = "org/members"
 | 
						MEMBERS       base.TplName = "org/member/members"
 | 
				
			||||||
	INVITE  base.TplName = "org/invite"
 | 
						MEMBER_INVITE base.TplName = "org/member/invite"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Members(ctx *middleware.Context) {
 | 
					func Members(ctx *middleware.Context) {
 | 
				
			||||||
	org := ctx.Org.Organization
 | 
						org := ctx.Org.Organization
 | 
				
			||||||
	ctx.Data["Title"] = org.Name
 | 
						ctx.Data["Title"] = org.FullName
 | 
				
			||||||
	ctx.Data["PageIsOrgMembers"] = true
 | 
						ctx.Data["PageIsOrgMembers"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := org.GetMembers(); err != nil {
 | 
						if err := org.GetMembers(); err != nil {
 | 
				
			||||||
@@ -60,6 +60,18 @@ func MembersAction(ctx *middleware.Context) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		err = org.RemoveMember(uid)
 | 
							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 {
 | 
						if err != nil {
 | 
				
			||||||
@@ -75,7 +87,7 @@ func MembersAction(ctx *middleware.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func Invitation(ctx *middleware.Context) {
 | 
					func Invitation(ctx *middleware.Context) {
 | 
				
			||||||
	org := ctx.Org.Organization
 | 
						org := ctx.Org.Organization
 | 
				
			||||||
	ctx.Data["Title"] = org.Name
 | 
						ctx.Data["Title"] = org.FullName
 | 
				
			||||||
	ctx.Data["PageIsOrgMembers"] = true
 | 
						ctx.Data["PageIsOrgMembers"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.Req.Method == "POST" {
 | 
						if ctx.Req.Method == "POST" {
 | 
				
			||||||
@@ -101,5 +113,5 @@ func Invitation(ctx *middleware.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.HTML(200, INVITE)
 | 
						ctx.HTML(200, MEMBER_INVITE)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func Home(ctx *middleware.Context) {
 | 
					func Home(ctx *middleware.Context) {
 | 
				
			||||||
	org := ctx.Org.Organization
 | 
						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))
 | 
						repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,31 +13,22 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	TEAMS    base.TplName = "org/teams"
 | 
						TEAMS    base.TplName = "org/team/teams"
 | 
				
			||||||
	TEAM_NEW base.TplName = "org/team_new"
 | 
						TEAM_NEW base.TplName = "org/team/new"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Teams(ctx *middleware.Context) {
 | 
					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 := org.GetTeams(); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
							ctx.Handle(500, "GetTeams", err)
 | 
				
			||||||
		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)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, t := range org.Teams {
 | 
						for _, t := range org.Teams {
 | 
				
			||||||
		if err = t.GetMembers(); err != nil {
 | 
							if err := t.GetMembers(); err != nil {
 | 
				
			||||||
			ctx.Handle(500, "org.Home(GetMembers)", err)
 | 
								ctx.Handle(500, "GetMembers", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -46,44 +37,39 @@ func Teams(ctx *middleware.Context) {
 | 
				
			|||||||
	ctx.HTML(200, TEAMS)
 | 
						ctx.HTML(200, TEAMS)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTeam(ctx *middleware.Context) {
 | 
					func TeamsAction(ctx *middleware.Context) {
 | 
				
			||||||
	org, err := models.GetUserByName(ctx.Params(":org"))
 | 
						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)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if err == models.ErrUserNotExist {
 | 
							log.Error(4, "Action(%s): %v", ctx.Params(":action"), err)
 | 
				
			||||||
			ctx.Handle(404, "org.NewTeam(GetUserByName)", err)
 | 
							ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		} else {
 | 
								"ok":  false,
 | 
				
			||||||
			ctx.Handle(500, "org.NewTeam(GetUserByName)", err)
 | 
								"err": err.Error(),
 | 
				
			||||||
		}
 | 
							})
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ctx.Data["Org"] = org
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check ownership of organization.
 | 
					 | 
				
			||||||
	if !org.IsOrgOwner(ctx.User.Id) {
 | 
					 | 
				
			||||||
		ctx.Error(403)
 | 
					 | 
				
			||||||
		return
 | 
							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)
 | 
						ctx.HTML(200, TEAM_NEW)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
					func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			||||||
	org, err := models.GetUserByName(ctx.Params(":org"))
 | 
						ctx.Data["Title"] = ctx.Org.Organization.FullName
 | 
				
			||||||
	if err != nil {
 | 
						ctx.Data["PageIsOrgTeams"] = true
 | 
				
			||||||
		if err == models.ErrUserNotExist {
 | 
						ctx.Data["PageIsOrgTeamsNew"] = true
 | 
				
			||||||
			ctx.Handle(404, "org.NewTeamPost(GetUserByName)", err)
 | 
						ctx.Data["Team"] = &models.Team{}
 | 
				
			||||||
		} 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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.HasError() {
 | 
						if ctx.HasError() {
 | 
				
			||||||
		ctx.HTML(200, TEAM_NEW)
 | 
							ctx.HTML(200, TEAM_NEW)
 | 
				
			||||||
@@ -104,23 +90,29 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						org := ctx.Org.Organization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t := &models.Team{
 | 
						t := &models.Team{
 | 
				
			||||||
		OrgId:       org.Id,
 | 
							OrgId:       org.Id,
 | 
				
			||||||
		Name:        form.TeamName,
 | 
							Name:        form.TeamName,
 | 
				
			||||||
		Description: form.Description,
 | 
							Description: form.Description,
 | 
				
			||||||
		Authorize:   auth,
 | 
							Authorize:   auth,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err = models.NewTeam(t); err != nil {
 | 
						if err := models.NewTeam(t); err != nil {
 | 
				
			||||||
		if err == models.ErrTeamAlreadyExist {
 | 
							switch err {
 | 
				
			||||||
 | 
							case models.ErrTeamNameIllegal:
 | 
				
			||||||
			ctx.Data["Err_TeamName"] = true
 | 
								ctx.Data["Err_TeamName"] = true
 | 
				
			||||||
			ctx.RenderWithErr("Team name has already been used", TEAM_NEW, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("form.illegal_team_name"), TEAM_NEW, &form)
 | 
				
			||||||
		} else {
 | 
							case models.ErrTeamAlreadyExist:
 | 
				
			||||||
			ctx.Handle(500, "org.NewTeamPost(NewTeam)", err)
 | 
								ctx.Data["Err_TeamName"] = true
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), TEAM_NEW, &form)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								ctx.Handle(500, "NewTeam", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	log.Trace("%s Team created: %s/%s", ctx.Req.RequestURI, org.Name, t.Name)
 | 
						log.Trace("Team created: %s/%s", org.Name, t.Name)
 | 
				
			||||||
	ctx.Redirect("/org/" + org.LowerName + "/teams/" + t.LowerName)
 | 
						ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EditTeam(ctx *middleware.Context) {
 | 
					func EditTeam(ctx *middleware.Context) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,12 +20,11 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	SIGNIN          base.TplName = "user/signin"
 | 
						SIGNIN          base.TplName = "user/auth/signin"
 | 
				
			||||||
	SIGNUP          base.TplName = "user/signup"
 | 
						SIGNUP          base.TplName = "user/auth/signup"
 | 
				
			||||||
	DELETE          base.TplName = "user/delete"
 | 
						ACTIVATE        base.TplName = "user/auth/activate"
 | 
				
			||||||
	ACTIVATE        base.TplName = "user/activate"
 | 
						FORGOT_PASSWORD base.TplName = "user/auth/forgot_passwd"
 | 
				
			||||||
	FORGOT_PASSWORD base.TplName = "user/forgot_passwd"
 | 
						RESET_PASSWORD  base.TplName = "user/auth/reset_passwd"
 | 
				
			||||||
	RESET_PASSWORD  base.TplName = "user/reset_passwd"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SignIn(ctx *middleware.Context) {
 | 
					func SignIn(ctx *middleware.Context) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.4.7.0815 Alpha
 | 
					0.4.7.0816 Alpha
 | 
				
			||||||
@@ -4,7 +4,10 @@
 | 
				
			|||||||
	<div class="container clear">
 | 
						<div class="container clear">
 | 
				
			||||||
		<img class="avatar-100 left" src="{{.Org.AvatarLink}}?s=140"/>
 | 
							<img class="avatar-100 left" src="{{.Org.AvatarLink}}?s=140"/>
 | 
				
			||||||
		<div id="org-home-header-info">
 | 
							<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}}
 | 
								{{if .Org.Description}}<p>{{.Org.Description}}</p>{{end}}
 | 
				
			||||||
            <ul class="text-grey">
 | 
					            <ul class="text-grey">
 | 
				
			||||||
                {{if .Org.Location}}<li><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></li>{{end}}
 | 
					                {{if .Org.Location}}<li><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></li>{{end}}
 | 
				
			||||||
@@ -17,7 +20,7 @@
 | 
				
			|||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
    <div id="org-home-repo-list" class="left grid-2-3">
 | 
					    <div id="org-home-repo-list" class="left grid-2-3">
 | 
				
			||||||
        <div class="clear">
 | 
					        <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>
 | 
					            <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}}
 | 
					        	{{end}}
 | 
				
			||||||
        </div>
 | 
					        </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>
 | 
						    			<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>
 | 
						    			<strong>{{.i18n.Tr "org.people"}}</strong>
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
	    		<div class="panel-body" id="org-member-avatar-group">
 | 
						    		<div class="panel-body member-avatar-group">
 | 
				
			||||||
	    			{{range .Members}}
 | 
						    			{{range .Members}}
 | 
				
			||||||
	    			<a href="/{{.Name}}"><img src="{{.AvatarLink}}"></a>
 | 
						    			<a href="/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
 | 
				
			||||||
	    			{{end}}
 | 
						    			{{end}}
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
	    		{{if .IsAdminTeam}}
 | 
						    		{{if .IsOrganizationOwner}}
 | 
				
			||||||
	    		<div class="panel-footer">
 | 
						    		<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>
 | 
						    			<a class="btn btn-medium btn-blue btn-link btn-radius" href="/org/{{.Org.LowerName}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a>
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{{template "ng/base/head" .}}
 | 
					{{template "ng/base/head" .}}
 | 
				
			||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
{{template "org/header" .}}
 | 
					{{template "org/base/header" .}}
 | 
				
			||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
	<div class="invite-box" id="invite-box">
 | 
						<div class="invite-box" id="invite-box">
 | 
				
			||||||
    	{{template "ng/base/alert" .}}
 | 
					    	{{template "ng/base/alert" .}}
 | 
				
			||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
{{template "ng/base/head" .}}
 | 
					{{template "ng/base/head" .}}
 | 
				
			||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
{{template "org/header" .}}
 | 
					{{template "org/base/header" .}}
 | 
				
			||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
	{{template "ng/base/alert" .}}
 | 
						<div class="org-header-alert">
 | 
				
			||||||
	<div class="clear" id="org-member-toolbar">
 | 
							{{template "ng/base/alert" .}}
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="org-toolbar clear">
 | 
				
			||||||
		{{if .IsAdminTeam}}
 | 
							{{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>
 | 
					        <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}}
 | 
							{{end}}
 | 
				
			||||||
@@ -25,15 +27,19 @@
 | 
				
			|||||||
				{{end}}
 | 
									{{end}}
 | 
				
			||||||
				</li>
 | 
									</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>
 | 
									<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}}
 | 
									{{if eq $.SignedUser.Id .Id}}
 | 
				
			||||||
				<li class="grid-1-6 right">
 | 
										<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>
 | 
											<a class="btn btn-red btn-link btn-radius" href="{{$.OrgLink}}/members/action/leave?uid={{.Id}}">{{$.i18n.Tr "org.members.leave"}}</a>
 | 
				
			||||||
				</li>
 | 
										</li>
 | 
				
			||||||
				{{if $isPublic}}
 | 
									{{else if $.IsOrganizationOwner}}
 | 
				
			||||||
				<li class="grid-1-6 right">
 | 
										<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>
 | 
											<a class="btn btn-red btn-link btn-radius" href="{{$.OrgLink}}/members/action/remove?uid={{.Id}}">{{$.i18n.Tr "org.members.remove"}}</a>
 | 
				
			||||||
				</li>
 | 
										</li>
 | 
				
			||||||
				{{end}}
 | 
										{{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}}
 | 
									{{end}}
 | 
				
			||||||
			</ul>
 | 
								</ul>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
{{template "ng/base/head" .}}
 | 
					{{template "ng/base/head" .}}
 | 
				
			||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
 | 
					{{template "org/header" .}}
 | 
				
			||||||
<div id="setting-wrapper" class="main-wrapper">
 | 
					<div id="setting-wrapper" class="main-wrapper">
 | 
				
			||||||
    <div id="org-setting" class="container clear">
 | 
					    <div id="org-setting" class="container clear">
 | 
				
			||||||
        {{template "org/settings/nav" .}}
 | 
					        {{template "org/settings/nav" .}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
{{template "ng/base/head" .}}
 | 
					{{template "ng/base/head" .}}
 | 
				
			||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
 | 
					{{template "org/header" .}}
 | 
				
			||||||
<div id="setting-wrapper" class="main-wrapper">
 | 
					<div id="setting-wrapper" class="main-wrapper">
 | 
				
			||||||
    <div id="org-setting" class="container clear">
 | 
					    <div id="org-setting" class="container clear">
 | 
				
			||||||
	        {{template "org/settings/nav" .}}
 | 
						        {{template "org/settings/nav" .}}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								templates/org/team/new.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								templates/org/team/new.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -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" .}}
 | 
				
			||||||
							
								
								
									
										42
									
								
								templates/org/team/teams.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								templates/org/team/teams.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -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" .}}
 | 
				
			||||||
@@ -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"> </label>
 | 
					 | 
				
			||||||
                <div class="col-md-8">
 | 
					 | 
				
			||||||
                    <button class="btn btn-primary">Create team</button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </form>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{{template "base/footer" .}}
 | 
					 | 
				
			||||||
@@ -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" .}}
 | 
					 | 
				
			||||||
@@ -3,7 +3,9 @@
 | 
				
			|||||||
<div id="repo-wrapper">
 | 
					<div id="repo-wrapper">
 | 
				
			||||||
    <form id="repo-create-form" class="form form-align panel panel-radius" action="/repo/create" method="post">
 | 
					    <form id="repo-create-form" class="form form-align panel panel-radius" action="/repo/create" method="post">
 | 
				
			||||||
        {{.CsrfTokenHtml}}
 | 
					        {{.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">
 | 
					        <div class="panel-content">
 | 
				
			||||||
            {{template "ng/base/alert" .}}
 | 
					            {{template "ng/base/alert" .}}
 | 
				
			||||||
            <div class="field">
 | 
					            <div class="field">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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" .}}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user