diff options
-rw-r--r-- | .gopmfile | 5 | ||||
-rw-r--r-- | cmd/web.go | 5 | ||||
-rw-r--r-- | conf/app.ini | 4 | ||||
-rw-r--r-- | conf/locale/locale_en-US.ini | 11 | ||||
-rw-r--r-- | conf/locale/locale_zh-CN.ini | 11 | ||||
-rw-r--r-- | gogs.go | 2 | ||||
-rw-r--r-- | models/org.go | 94 | ||||
-rw-r--r-- | models/user.go | 10 | ||||
-rw-r--r-- | modules/middleware/context.go | 3 | ||||
-rw-r--r-- | modules/middleware/org.go | 23 | ||||
-rw-r--r-- | modules/middleware/repo.go | 2 | ||||
-rw-r--r-- | public/ng/css/gogs.css | 52 | ||||
-rw-r--r-- | public/ng/less/gogs/dashboard.less | 1 | ||||
-rw-r--r-- | public/ng/less/gogs/organization.less | 61 | ||||
-rw-r--r-- | public/ng/less/ui/label.less | 6 | ||||
-rw-r--r-- | routers/org/members.go | 95 | ||||
-rw-r--r-- | routers/repo/repo.go | 2 | ||||
-rw-r--r-- | templates/.VERSION | 2 | ||||
-rw-r--r-- | templates/org/header.tmpl | 16 | ||||
-rw-r--r-- | templates/org/home.tmpl | 9 | ||||
-rw-r--r-- | templates/org/invite.tmpl | 15 | ||||
-rw-r--r-- | templates/org/members.tmpl | 97 | ||||
-rw-r--r-- | templates/org/settings.tmpl | 130 | ||||
-rw-r--r-- | templates/user/dashboard/dashboard.tmpl | 2 |
24 files changed, 450 insertions, 208 deletions
@@ -11,14 +11,17 @@ github.com/codegangsta/cli = github.com/go-sql-driver/mysql = github.com/go-xorm/core = github.com/go-xorm/xorm = -github.com/gogits/cache = github.com/gogits/gfm = github.com/gogits/git = github.com/gogits/oauth2 = github.com/juju2013/goldap = github.com/lib/pq = +github.com/macaron-contrib/cache = +github.com/macaron-contrib/captcha = +github.com/macaron-contrib/csrf = github.com/macaron-contrib/i18n = github.com/macaron-contrib/session = +github.com/macaron-contrib/toolbox = github.com/nfnt/resize = [res] diff --git a/cmd/web.go b/cmd/web.go index 03704c64de..03e5e86066 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -232,6 +232,7 @@ func runWeb(*cli.Context) { m.Group("/:org", func(r *macaron.Router) { r.Get("/dashboard", user.Dashboard) r.Get("/members", org.Members) + r.Get("/members/action/:action", org.MembersAction) r.Get("/teams", org.Teams) r.Get("/teams/:team", org.SingleTeam) @@ -248,6 +249,10 @@ func runWeb(*cli.Context) { 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)) }, reqSignIn) // Repository routers. diff --git a/conf/app.ini b/conf/app.ini index ac1c6a3ba9..99ed628ec1 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -254,5 +254,5 @@ DRIVER = CONN = [i18n] -LANGS = en-US,zh-CN -NAMES = English,简体中文 +LANGS = en-US,zh-CN,de-DE +NAMES = English,简体中文,Deutsch diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini index d7b5c45a02..d44dca081b 100644 --- a/conf/locale/locale_en-US.ini +++ b/conf/locale/locale_en-US.ini @@ -250,6 +250,17 @@ settings.delete_account = Delete This Organization settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undo! settings.confirm_delete_account = Confirm Deletion +members.public = Public +members.public_helper = make private +members.private = Private +members.private_helper = make public +members.owner = Owner +members.member = Member +members.conceal = Conceal +members.remove = Remove +members.invite_desc = Start typing a username to invite a new member to %s: +members.invite_now = Invite Now + [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 2499e12154..b84aca3d9e 100644 --- a/conf/locale/locale_zh-CN.ini +++ b/conf/locale/locale_zh-CN.ini @@ -250,6 +250,17 @@ settings.delete_account = 删除当前组织 settings.delete_prompt = 删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>! settings.confirm_delete_account = 确认删除组织 +members.public = 公开成员 +members.public_helper = 设为私有 +members.private = 私有成员 +members.private_helper = 设为公开 +members.owner = 管理员 +members.member = 普通成员 +members.conceal = 隐藏身份 +members.remove = 移除成员 +members.invite_desc = 请输入被邀请到组织 %s 的用户名称: +members.invite_now = 立即邀请 + [action] create_repo = 创建了仓库 <a href="/%s">%s</a> commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a> @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.7.0814 Alpha" +const APP_VER = "0.4.7.0815 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/org.go b/models/org.go index edae828b54..b40b313bc3 100644 --- a/models/org.go +++ b/models/org.go @@ -59,6 +59,16 @@ func (org *User) GetMembers() error { return nil } +// AddMember adds new member to organization. +func (org *User) AddMember(uid int64) error { + return AddOrgUser(org.Id, uid) +} + +// RemoveMember removes member from organization. +func (org *User) RemoveMember(uid int64) error { + return RemoveOrgUser(org.Id, uid) +} + // CreateOrganization creates record of a new organization. func CreateOrganization(org, owner *User) (*User, error) { if !IsLegalName(org.Name) { @@ -241,8 +251,7 @@ func NewTeam(t *Team) error { } // Update organization number of teams. - rawSql := "UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?" - if _, err = sess.Exec(rawSql, t.OrgId); err != nil { + if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgId); err != nil { sess.Rollback() return err } @@ -270,8 +279,8 @@ func UpdateTeam(t *Team) error { // OrgUser represents an organization-user relation. type OrgUser struct { Id int64 - Uid int64 `xorm:"INDEX"` - OrgId int64 `xorm:"INDEX"` + Uid int64 `xorm:"INDEX UNIQUE(s)"` + OrgId int64 `xorm:"INDEX UNIQUE(s)"` IsPublic bool IsOwner bool NumTeam int @@ -289,6 +298,12 @@ func IsOrganizationMember(orgId, uid int64) bool { return has } +// IsPublicMembership returns ture if given user public his/her membership. +func IsPublicMembership(orgId, uid int64) bool { + has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("is_public=?", true).Get(new(OrgUser)) + return has +} + // GetOrgUsersByUserId returns all organization-user relations by user ID. func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) { ous := make([]*OrgUser, 0, 10) @@ -303,6 +318,77 @@ func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) { return ous, err } +// ChangeOrgUserStatus changes public or private membership status. +func ChangeOrgUserStatus(orgId, uid int64, public bool) error { + ou := new(OrgUser) + has, err := x.Where("uid=?", uid).And("org_id=?", orgId).Get(ou) + if err != nil { + return err + } else if !has { + return nil + } + + ou.IsPublic = public + _, err = x.Id(ou.Id).AllCols().Update(ou) + return err +} + +// AddOrgUser adds new user to given organization. +func AddOrgUser(orgId, uid int64) error { + if IsOrganizationMember(orgId, uid) { + return nil + } + + ou := &OrgUser{ + Uid: uid, + OrgId: orgId, + } + + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if _, err := sess.Insert(ou); err != nil { + sess.Rollback() + return err + } else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members + 1 WHERE id = ?", orgId); err != nil { + sess.Rollback() + return err + } + + return sess.Commit() +} + +// RemoveOrgUser removes user from given organization. +func RemoveOrgUser(orgId, uid int64) error { + ou := new(OrgUser) + + has, err := x.Where("uid=?", uid).And("org_id=?", orgId).Get(ou) + if err != nil { + return err + } else if !has { + return nil + } + + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if _, err := sess.Id(ou.Id).Delete(ou); err != nil { + sess.Rollback() + return err + } else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members - 1 WHERE id = ?", orgId); err != nil { + sess.Rollback() + return err + } + + return sess.Commit() +} + // ___________ ____ ___ // \__ ___/___ _____ _____ | | \______ ___________ // | |_/ __ \\__ \ / \| | / ___// __ \_ __ \ diff --git a/models/user.go b/models/user.go index f4526b51d1..757c290b9c 100644 --- a/models/user.go +++ b/models/user.go @@ -128,6 +128,16 @@ func (u *User) IsOrganization() bool { return u.Type == ORGANIZATION } +// IsUserOrgOwner returns true if user is in the owner team of given organization. +func (u *User) IsUserOrgOwner(orgId int64) bool { + return IsOrganizationOwner(orgId, u.Id) +} + +// IsPublicMember returns true if user public his/her membership in give organization. +func (u *User) IsPublicMember(orgId int64) bool { + return IsPublicMembership(orgId, u.Id) +} + // GetOrganizationCount returns count of membership of organization of user. func (u *User) GetOrganizationCount() (int64, error) { return x.Where("uid=?", u.Id).Count(new(OrgUser)) diff --git a/modules/middleware/context.go b/modules/middleware/context.go index aa1266d649..6ce0f6e1f7 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -68,7 +68,9 @@ type Context struct { Org struct { IsOwner bool IsMember bool + IsAdminTeam bool // In owner team or team that has admin permission level. Organization *models.User + OrgLink string } } @@ -181,7 +183,6 @@ func Contexter() macaron.Handler { Flash: f, Session: sess, } - // Compute current URL for real-time change language. link := ctx.Req.RequestURI i := strings.Index(link, "?") diff --git a/modules/middleware/org.go b/modules/middleware/org.go index 05316a518f..77e999a328 100644 --- a/modules/middleware/org.go +++ b/modules/middleware/org.go @@ -13,8 +13,9 @@ import ( func OrgAssignment(redirect bool, args ...bool) macaron.Handler { return func(ctx *Context) { var ( - requireMember bool - requireOwner bool + requireMember bool + requireOwner bool + requireAdminTeam bool ) if len(args) >= 1 { requireMember = args[0] @@ -22,6 +23,9 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler { if len(args) >= 2 { requireOwner = args[1] } + if len(args) >= 3 { + requireAdminTeam = args[2] + } orgName := ctx.Params(":org") @@ -43,13 +47,24 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler { ctx.Org.IsOwner = ctx.Org.Organization.IsOrgOwner(ctx.User.Id) if ctx.Org.IsOwner { ctx.Org.IsMember = true + ctx.Org.IsAdminTeam = true } else { - ctx.Org.IsMember = ctx.Org.Organization.IsOrgMember(ctx.User.Id) + if ctx.Org.Organization.IsOrgMember(ctx.User.Id) { + ctx.Org.IsMember = true + // TODO: ctx.Org.IsAdminTeam + } } } - if (requireMember && !ctx.Org.IsMember) || (requireOwner && !ctx.Org.IsOwner) { + if (requireMember && !ctx.Org.IsMember) || + (requireOwner && !ctx.Org.IsOwner) || + (requireAdminTeam && !ctx.Org.IsAdminTeam) { ctx.Handle(404, "OrgAssignment", err) return } + ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam + ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner + + ctx.Org.OrgLink = "/org/" + ctx.Org.Organization.Name + ctx.Data["OrgLink"] = ctx.Org.OrgLink } } diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index a028aab802..3db1932af0 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -146,6 +146,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { } ctx.Repo.GitRepo = gitRepo ctx.Repo.RepoLink = "/" + u.Name + "/" + repo.Name + ctx.Data["RepoLink"] = ctx.Repo.RepoLink tags, err := ctx.Repo.GitRepo.GetTags() if err != nil { @@ -157,7 +158,6 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { ctx.Data["Title"] = u.Name + "/" + repo.Name ctx.Data["Repository"] = repo ctx.Data["Owner"] = ctx.Repo.Repository.Owner - ctx.Data["RepoLink"] = ctx.Repo.RepoLink ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css index 93a5d2f8c9..e7a3a66f26 100644 --- a/public/ng/css/gogs.css +++ b/public/ng/css/gogs.css @@ -851,6 +851,7 @@ The dashboard page style margin-left: 1em; } #dashboard-news .push-news .news-content li img { + vertical-align: inherit; margin-bottom: -2px; } /* @@ -1691,6 +1692,30 @@ textarea#issue-add-content { #org-home-header { min-height: 100px; } +#org-header { + height: 48px; +} +#org-header .org-name { + padding-left: 10px; + font-size: 1.4em; + height: 50px; + line-height: 50px; + margin-bottom: 0; +} +#org-header > div > .menu-line > li.right > a { + font-size: 1.2em; + color: #444444; +} +#org-header > div > .menu-line > li.right > a:hover { + background-color: transparent; + color: #d9453d; +} +#org-header > div > .menu-line > li.right > a .octicon { + margin-right: 6px; +} +#org-header > div > .menu-line > li.right .current { + border-bottom: 2px solid #D26911; +} #org-home-header-info { padding-top: 10px; } @@ -1776,3 +1801,30 @@ textarea#issue-add-content { margin-bottom: 0; color: #777; } +#org-member-toolbar { + padding: 10px 0; +} +#org-member-list .org-member-item { + height: 50px; + line-height: 50px; + border-top: 1px solid #eee; + padding: 15px 20px; +} +#org-member-list .org-member-item .member-name { + padding-left: 15px; +} +#org-member-list .org-member-item ul { + list-style: none; +} +#org-member-list .org-member-item ul li { + text-align: center; + display: inline-block; +} +.invite-box { + padding: 50px 0; + min-height: 130px; + text-align: center; +} +.invite-box input { + width: 250px; +} diff --git a/public/ng/less/gogs/dashboard.less b/public/ng/less/gogs/dashboard.less index f8838ae6fd..6bf1150ba7 100644 --- a/public/ng/less/gogs/dashboard.less +++ b/public/ng/less/gogs/dashboard.less @@ -251,6 +251,7 @@ The dashboard page style .news-content li { margin-left: 1em; img { + vertical-align: inherit; margin-bottom: -2px; } } diff --git a/public/ng/less/gogs/organization.less b/public/ng/less/gogs/organization.less index ed8c05397a..cbdec3132e 100644 --- a/public/ng/less/gogs/organization.less +++ b/public/ng/less/gogs/organization.less @@ -9,6 +9,38 @@ #org-home-header { min-height: 100px; } +#org-header { + height: 48px; + .org-name { + padding-left: 10px; + font-size: 1.4em; + height: 50px; + line-height: 50px; + margin-bottom: 0; + } + > div { + > .menu-line { + > li { + &.right { + > a { + font-size: 1.2em; + color: @dashboardHeaderLinkColor; + &:hover { + background-color: transparent; + color: @dashboardHeaderLinkHoverColor; + } + .octicon { + margin-right: 6px; + } + } + .current { + border-bottom: 2px solid #D26911; + } + } + } + } + } +} #org-home-header-info { padding-top: 10px; h2 { @@ -93,4 +125,33 @@ margin-top: 0; margin-bottom: 0; color: #777; +} +#org-member-toolbar { + padding: 10px 0; +} +#org-member-list { + .org-member-item { + height: 50px; + line-height: 50px; + border-top: 1px solid #eee; + padding: 15px 20px; + .member-name { + padding-left: 15px; + } + ul { + list-style: none; + li { + text-align: center; + display: inline-block; + } + } + } +} +.invite-box { + padding: 50px 0; + min-height: 130px; + text-align: center; + input { + width: 250px; + } }
\ No newline at end of file diff --git a/public/ng/less/ui/label.less b/public/ng/less/ui/label.less index 1cf0a81d85..a2a8a67905 100644 --- a/public/ng/less/ui/label.less +++ b/public/ng/less/ui/label.less @@ -1,8 +1,8 @@ @import "var"; .label { - padding: 2px 6px; - color: @labelFontColor; + padding: 2px 6px; + color: @labelFontColor; } .label-red { @@ -30,7 +30,7 @@ } .label-radius{ - border-radius: .2em; + border-radius: .2em; } .label-link{ diff --git a/routers/org/members.go b/routers/org/members.go index ac278d4e6d..d98061765a 100644 --- a/routers/org/members.go +++ b/routers/org/members.go @@ -5,10 +5,101 @@ package org import ( + "github.com/Unknwon/com" + + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" ) +const ( + MEMBERS base.TplName = "org/members" + INVITE base.TplName = "org/invite" +) + func Members(ctx *middleware.Context) { - ctx.Data["Title"] = "Organization " + ctx.Params(":org") + " Members" - ctx.HTML(200, "org/members") + org := ctx.Org.Organization + ctx.Data["Title"] = org.Name + ctx.Data["PageIsOrgMembers"] = true + + if err := org.GetMembers(); err != nil { + ctx.Handle(500, "GetMembers", err) + return + } + ctx.Data["Members"] = org.Members + + ctx.HTML(200, MEMBERS) +} + +func MembersAction(ctx *middleware.Context) { + uid := com.StrTo(ctx.Query("uid")).MustInt64() + if uid == 0 { + ctx.Redirect(ctx.Org.OrgLink + "/members") + return + } + + org := ctx.Org.Organization + var err error + switch ctx.Params(":action") { + case "private": + if ctx.User.Id != uid && !ctx.Org.IsOwner { + ctx.Error(404) + return + } + err = models.ChangeOrgUserStatus(org.Id, uid, false) + case "public": + if ctx.User.Id != uid { + ctx.Error(404) + return + } + err = models.ChangeOrgUserStatus(org.Id, uid, true) + case "remove": + if !ctx.Org.IsOwner { + ctx.Error(404) + return + } + err = org.RemoveMember(uid) + } + + 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 + "/members") +} + +func Invitation(ctx *middleware.Context) { + org := ctx.Org.Organization + ctx.Data["Title"] = org.Name + ctx.Data["PageIsOrgMembers"] = true + + if ctx.Req.Method == "POST" { + uname := ctx.Query("uname") + u, err := models.GetUserByName(uname) + if err != nil { + if err == models.ErrUserNotExist { + ctx.Flash.Error(ctx.Tr("form.user_not_exist")) + ctx.Redirect(ctx.Org.OrgLink + "/invitations/new") + } else { + ctx.Handle(500, " GetUserByName", err) + } + return + } + + if err = org.AddMember(u.Id); err != nil { + ctx.Handle(500, " AddMember", err) + return + } + + log.Trace("New member added(%s): %s", org.Name, u.Name) + ctx.Redirect(ctx.Org.OrgLink + "/members") + return + } + + ctx.HTML(200, INVITE) } diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 3450ea76f7..7356f50330 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -227,7 +227,7 @@ func Action(ctx *middleware.Context) { } if err != nil { - log.Error(4, "repo.Action(%s): %v", ctx.Params(":action"), err) + log.Error(4, "Action(%s): %v", ctx.Params(":action"), err) ctx.JSON(200, map[string]interface{}{ "ok": false, "err": err.Error(), diff --git a/templates/.VERSION b/templates/.VERSION index f398e90110..906c01dc84 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.4.7.0814 Alpha
\ No newline at end of file +0.4.7.0815 Alpha
\ No newline at end of file diff --git a/templates/org/header.tmpl b/templates/org/header.tmpl new file mode 100644 index 0000000000..8566d0a3c5 --- /dev/null +++ b/templates/org/header.tmpl @@ -0,0 +1,16 @@ +<div class="org-header" id="org-header"> + <div class="container"> + <a class="text-black left" href="/org/{{.Org.LowerName}}"> + <img class="avatar-48 left" src="{{.Org.AvatarLink}}?s=100"> + <span class="org-name">{{.Org.FullName}}</span> + </a> + <ul class="menu menu-line container"> + <li class="right"> + <a {{if .PageIsOrgTeams}}class="current"{{end}} href="{{.OrgLink}}/teams"><i class="octicon octicon-jersey"></i> {{.i18n.Tr "org.teams"}} <span class="label label-gray label-radius">{{.Org.NumTeams}}</span></a> + </li> + <li class="right"> + <a {{if .PageIsOrgMembers}}class="current"{{end}} href="{{.OrgLink}}/members"><i class="octicon octicon-organization"></i> {{.i18n.Tr "org.people"}} <span class="label label-gray label-radius">{{.Org.NumMembers}}</span></a> + </li> + </ul> + </div> +</div>
\ No newline at end of file diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index 205318b0e9..d96624010f 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -17,7 +17,9 @@ <div class="container"> <div id="org-home-repo-list" class="left grid-2-3"> <div class="clear"> + {{if .IsAdminTeam}} <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> <div id="org-repo-list"> {{range .Repos}} @@ -45,9 +47,11 @@ <a href="/{{.Name}}"><img src="{{.AvatarLink}}"></a> {{end}} </div> + {{if .IsAdminTeam}} <div class="panel-footer"> - <a class="btn btn-medium btn-blue btn-link btn-radius" href="">{{.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> + {{end}} </div> <br> <div class="panel panel-radius"> @@ -65,9 +69,12 @@ {{end}} </ul> </div> + {{if .IsOrganizationOwner}} <div class="panel-footer"> <a class="btn btn-medium btn-blue btn-link btn-radius" href="/org/{{$.Org.LowerName}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a> </div> + + {{end}} </div> </div> </div> diff --git a/templates/org/invite.tmpl b/templates/org/invite.tmpl new file mode 100644 index 0000000000..400622fdd8 --- /dev/null +++ b/templates/org/invite.tmpl @@ -0,0 +1,15 @@ +{{template "ng/base/head" .}} +{{template "ng/base/header" .}} +{{template "org/header" .}} +<div class="container"> + <div class="invite-box"> + {{template "ng/base/alert" .}} + <h3>{{.i18n.Tr "org.members.invite_desc" .Org.FullName}}</h3> + <form action="{{.OrgLink}}/invitations/new" method="post"> + {{.CsrfTokenHtml}} + <input class="ipt ipt-large ipt-radius" name="uname" required> + <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "org.members.invite_now"}}</button> + </form> + </div> +</div> +{{template "ng/base/footer" .}}
\ No newline at end of file diff --git a/templates/org/members.tmpl b/templates/org/members.tmpl index ba14cb4cc9..bea4340ffb 100644 --- a/templates/org/members.tmpl +++ b/templates/org/members.tmpl @@ -1,56 +1,43 @@ -{{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 class="active"><a href="#"><i class="fa fa-users"></i>Members - <span class="label label-default">5</span></a> - </li> - <li><a href="#"><i class="fa fa-tags"></i>Teams - <span class="label label-default">2</span></a> - </li> - </ul> - <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> - <div id="org-nav-info"> - <h2 class="org-name">Organization Name</h2> - </div> - </div> - - </div> +{{template "ng/base/head" .}} +{{template "ng/base/header" .}} +{{template "org/header" .}} +<div class="container"> + {{template "ng/base/alert" .}} + <div class="clear" id="org-member-toolbar"> + {{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}} + </div> + <div id="org-member-list"> + {{range .Members}} + <div class="org-member-item"> + <img class="avatar-48 left" src="{{.AvatarLink}}?s=100"> + <a class="text-black" href="/{{.Name}}"><span class="member-name"><strong>{{.FullName}}</strong>({{.Name}})</span></a> + <ul class="grid-6-12 right"> + <li class="grid-1-3"> + {{ $isPublic := .IsPublicMember $.Org.Id}} + {{if $isPublic}} + {{$.i18n.Tr "org.members.public"}} + {{if eq $.SignedUser.Id .Id}}(<a href="{{$.OrgLink}}/members/action/private?uid={{.Id}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}} + {{else}} + {{$.i18n.Tr "org.members.private"}} + {{if eq $.SignedUser.Id .Id}}(<a href="{{$.OrgLink}}/members/action/public?uid={{.Id}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}} + {{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}} + {{end}} + </ul> + </div> + {{end}} + </div> </div> -<div id="body" class="container"> - <div id="org"> - <div id="org-members"> - <div class="member"> - <div class="avatar col-md-1"> - <img src="https://avatars3.githubusercontent.com/u/2142787?s=140" alt=""/> - </div> - <div class="name col-md-4"> - <a href="#"><strong>fuxiaohei</strong><span class="nick">傅小黑</span></a> - </div> - <div class="role col-md-2 pull-right"> - <strong>Member</strong> - </div> - <div class="status col-md-1 pull-right"> - <strong>Public</strong> - </div> - </div> - <div class="member"> - <div class="avatar col-md-1"> - <img src="https://avatars3.githubusercontent.com/u/2142787?s=140" alt=""/> - </div> - <div class="name col-md-4"> - <a href="#"><strong>fuxiaohei</strong><span class="nick">傅小黑</span></a> - </div> - <div class="role col-md-2 pull-right"> - <strong><i class="fa fa-user"></i>Owner</strong> - </div> - <div class="status col-md-1 pull-right"> - <i class="fa fa-lock"></i>Private - </div> - </div> - </div> - </div> -</div> -{{template "base/footer" .}} +{{template "ng/base/footer" .}}
\ No newline at end of file diff --git a/templates/org/settings.tmpl b/templates/org/settings.tmpl deleted file mode 100644 index fd0d6a1c14..0000000000 --- a/templates/org/settings.tmpl +++ /dev/null @@ -1,130 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -<div id="body-nav"> - <div class="container"> - <div class="btn-group pull-left" id="dashboard-switch"> - <button type="button" class="btn btn-default"> - <img src="{{.Org.AvatarLink}}?s=28" alt="user-avatar" title="username"> - {{.Org.Name}} - </button> - </div> - <ul class="nav nav-pills pull-right"> - <li><a href="/org/{{.Org.Name}}/dashboard/">News Feed</a></li> - <li><a href="/org/{{.Org.Name}}/dashboard/issues">Issues</a></li> - <li class="active"><a href="/org/{{.Org.Name}}/settings">Settings</a></li> - <!-- <li><a href="/pulls">Pull Requests</a></li> - <li><a href="/stars">Stars</a></li> --> - </ul> - </div> -</div> - -<div id="body" class="container" data-page="org"> - <div id="user-setting-nav" class="col-md-2 repo-setting-nav"> - <ul class="list-group"> - <li class="list-group-item active"><a href="#">Options</a></li> - </ul> - </div> - <div id="repo-setting-container" class="col-md-10"> - {{template "base/alert" .}} - <div class="panel panel-default"> - <div class="panel-heading"> - Organization Options - </div> - - <div class="panel-body"> - <form action="/org/{{.Org.Name}}/settings" method="post" class="form-horizontal"> - {{.CsrfTokenHtml}} - <input type="hidden" name="action" value="update"> - - <div class="form-group{{if .Err_DisplayName}} has-error has-feedback{{end}}"> - <label class="col-md-3 text-right" for="org-setting-name">Display Name</label> - <div class="col-md-9"> - <input class="form-control" name="display_name" value="{{.Org.FullName}}" title="" id="org-setting-name"/> - </div> - </div> - - <div class="form-group{{if .Err_Email}} has-error has-feedback{{end}}"> - <label class="col-md-3 text-right" for="org-email">Email</label> - <div class="col-md-9"> - <input class="form-control" name="email" value="{{.Org.Email}}" title="" id="org-email" type="email"/> - </div> - </div> - - <div class="form-group{{if .Err_Description}} has-error has-feedback{{end}}"> - <label class="col-md-3 text-right" for="org-desc">Description</label> - <div class="col-md-9"> - <textarea class="form-control" name="desc" id="org-desc" rows="3">{{.Org.Description}}</textarea> - </div> - </div> - - <div class="form-group{{if .Err_Website}} has-error has-feedback{{end}}"> - <label class="col-md-3 text-right" for="org-site">Official Site</label> - <div class="col-md-9"> - <input type="url" class="form-control" name="site" value="{{.Org.Website}}" id="org-site"/> - </div> - </div> - - <div class="form-group{{if .Err_Location}} has-error has-feedback{{end}}"> - <label class="col-md-3 text-right" for="org-location">Location</label> - <div class="col-md-9"> - <input class="form-control" name="location" value="{{.Org.Location}}" title="" id="org-location"/> - </div> - </div> - - <div class="form-group"> - <div class="col-md-9 col-md-offset-3"> - <button class="btn btn-primary" type="submit">Save Options</button> - </div> - </div> - </form> - </div> - </div> - - <div class="panel panel-warning"> - <div class="panel-heading"> - Danger Zone - </div> - <div class="panel-body"> - <button type="button" class="btn btn-default pull-right" href="#delete-org-modal" data-toggle="modal"> - Delete this organization - </button> - <dd> - <dt>Delete this organization</dt> - <dl>Once you delete this organization and all repositories in, there is no going back. Please be - certain. - </dl> - </dd> - - <div class="modal fade" id="delete-org-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" - aria-hidden="true"> - <div class="modal-dialog"> - <form action="/org/{{.Org.Name}}/settings/delete" method="post" - class="modal-content"> - {{.CsrfTokenHtml}} - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" - aria-hidden="true">×</button> - <h4 class="modal-title" id="myModalLabel">Delete organization</h4> - </div> - - <div class="modal-body"> - <div class="form-group"> - <label>Make sure your are owner of this organization. Please enter your password.<strong class="text-danger">*</strong></label> - <input name="password" class="form-control" type="password" placeholder="Type your account password" required="required"> - </div> - </div> - - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> - <button class="btn btn-danger btn-lg">I understand the consequences, delete this - organization - </button> - </div> - </form> - </div> - </div> - </div> - </div> - </div> -</div> -{{template "base/footer" .}} diff --git a/templates/user/dashboard/dashboard.tmpl b/templates/user/dashboard/dashboard.tmpl index c19c177e83..d0789b96d6 100644 --- a/templates/user/dashboard/dashboard.tmpl +++ b/templates/user/dashboard/dashboard.tmpl @@ -30,7 +30,7 @@ {{ $push := ActionContent2Commits .}} {{ $repoLink := .GetRepoLink}} {{range $push.Commits}} - <li><img src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="/{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> {{.Message}}</li> + <li><img class="avatar-16" src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="/{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> {{.Message}}</li> {{end}} </ul> </div> |