| @@ -11,7 +11,8 @@ import ( | |||
| type ContributorWithUserId struct { | |||
| git.Contributor | |||
| UserId int64 | |||
| UserId int64 | |||
| IsAdmin bool | |||
| } | |||
| func GetRepoKPIStats(repo *Repository) (*git.RepoKPIStats, error) { | |||
| @@ -144,6 +145,7 @@ func GetTop10Contributor(repoPath string) ([]ContributorWithUserId, error) { | |||
| contributorDistinctDict[user.Email] = ContributorWithUserId{ | |||
| contributor, | |||
| user.ID, | |||
| user.IsAdmin, | |||
| } | |||
| } else { | |||
| @@ -156,6 +158,7 @@ func GetTop10Contributor(repoPath string) ([]ContributorWithUserId, error) { | |||
| contributorDistinctDict[contributor.Email] = ContributorWithUserId{ | |||
| contributor, | |||
| -1, | |||
| false, | |||
| } | |||
| } else { | |||
| value.CommitCnt += contributor.CommitCnt | |||
| @@ -178,6 +178,7 @@ func GetObsListObject(jobName, parentDir string) ([]FileInfo, error) { | |||
| input := &obs.ListObjectsInput{} | |||
| input.Bucket = setting.Bucket | |||
| input.Prefix = strings.TrimPrefix(path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, parentDir), "/") | |||
| strPrefix := strings.Split(input.Prefix, "/") | |||
| output, err := ObsCli.ListObjects(input) | |||
| fileInfos := make([]FileInfo, 0) | |||
| if err == nil { | |||
| @@ -186,15 +187,29 @@ func GetObsListObject(jobName, parentDir string) ([]FileInfo, error) { | |||
| var isDir bool | |||
| var fileName,nextParentDir string | |||
| if strings.HasSuffix(val.Key, "/") { | |||
| //dirs in next level dir | |||
| if len(str1) - len(strPrefix) > 2 { | |||
| continue | |||
| } | |||
| fileName = str1[len(str1)-2] | |||
| isDir = true | |||
| nextParentDir = fileName | |||
| if fileName == parentDir || (fileName + "/") == setting.OutPutPath { | |||
| if parentDir == "" { | |||
| nextParentDir = fileName | |||
| } else { | |||
| nextParentDir = parentDir + "/" + fileName | |||
| } | |||
| if fileName == strPrefix[len(strPrefix)-1] || (fileName + "/") == setting.OutPutPath { | |||
| continue | |||
| } | |||
| } else { | |||
| //files in next level dir | |||
| if len(str1) - len(strPrefix) > 1 { | |||
| continue | |||
| } | |||
| fileName = str1[len(str1)-1] | |||
| isDir = false | |||
| nextParentDir = parentDir | |||
| } | |||
| fileInfo := FileInfo{ | |||
| @@ -0,0 +1,41 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
| <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
| viewBox="0 0 96 17.3" style="enable-background:new 0 0 96 17.3;" xml:space="preserve"> | |||
| <style type="text/css"> | |||
| .st0{fill:#5BB973;} | |||
| </style> | |||
| <g> | |||
| <path class="st0" d="M5.9,12.5l-1,3.8h-3L6.6,1.5H10l4.7,14.8h-3.1l-1-3.8H5.9z M6.5,10.2H10L9.6,8.5C9.4,7.8,9.1,7,8.9,6.1 | |||
| C8.7,5.3,8.5,4.5,8.3,3.7H8.2C8,4.5,7.8,5.3,7.6,6.2S7.2,7.8,6.9,8.5L6.5,10.2z"/> | |||
| <path class="st0" d="M19.5,1.5v14.8h-3V1.5H19.5z"/> | |||
| <path class="st0" d="M27.7,6.6v10.6h-2.1V6.6h-1.8v-2h1.8V0.3h2.1v4.3h1.7v2H27.7z M31.6,7.4c-0.2,0.9-0.5,1.8-0.8,2.7 | |||
| c-0.3,0.9-0.7,1.6-1.1,2.2c-0.1-0.1-0.2-0.2-0.4-0.3s-0.3-0.2-0.4-0.3c-0.2-0.1-0.3-0.2-0.5-0.3c-0.2-0.1-0.3-0.2-0.4-0.2 | |||
| c0.4-0.5,0.7-1.1,1-1.9s0.5-1.5,0.6-2.3L31.6,7.4z M34.6,5.8c0,0.9-0.1,1.9-0.3,2.9c-0.1,1-0.4,2-0.7,3s-0.8,2-1.4,2.9 | |||
| c-0.6,0.9-1.4,1.8-2.4,2.6c-0.1-0.1-0.2-0.2-0.3-0.4c-0.1-0.1-0.3-0.3-0.4-0.4c-0.1-0.1-0.3-0.3-0.4-0.4s-0.3-0.2-0.4-0.3 | |||
| c0.9-0.7,1.6-1.5,2.1-2.3c0.6-0.8,1-1.7,1.3-2.5c0.3-0.9,0.5-1.7,0.7-2.6s0.2-1.7,0.3-2.5h-2.7V3.7h2.7V0.5h2v3.2h3.7 | |||
| c0,0.1,0,0.3,0,0.4c0,0.1,0,0.2,0,0.3s0,0.2,0,0.3l-0.1,2.7l1.3-0.3c0.1,0.4,0.3,0.9,0.4,1.3c0.1,0.5,0.3,0.9,0.4,1.4 | |||
| c0.1,0.5,0.2,0.9,0.3,1.3c0.1,0.4,0.2,0.8,0.2,1.1L39,12.8c-0.1-0.5-0.2-1.1-0.3-1.8s-0.3-1.4-0.5-2.1c0,1.2-0.1,2.1-0.1,3 | |||
| c0,0.8-0.1,1.5-0.2,2.1c-0.1,0.6-0.1,1-0.2,1.4c-0.1,0.3-0.2,0.6-0.3,0.8c-0.2,0.3-0.4,0.5-0.7,0.7c-0.2,0.1-0.5,0.2-0.8,0.3 | |||
| C35.6,17,35.3,17,34.8,17s-0.9,0-1.3,0c0-0.3-0.1-0.6-0.2-1c-0.1-0.4-0.3-0.7-0.4-1c0.4,0,0.9,0.1,1.2,0.1c0.4,0,0.7,0,0.8,0 | |||
| c0.2,0,0.3,0,0.4-0.1c0.1,0,0.2-0.1,0.3-0.2c0.1-0.1,0.2-0.4,0.3-0.8c0.1-0.4,0.1-0.9,0.2-1.6s0.1-1.6,0.1-2.7 | |||
| c0-1.1,0.1-2.4,0.1-3.9H34.6z"/> | |||
| <path class="st0" d="M47.8,1.1C47.6,1.7,47.3,2.4,47,3c-0.3,0.6-0.6,1.2-0.9,1.9v12.4h-2.2v-9c-0.2,0.2-0.4,0.5-0.6,0.7 | |||
| S43,9.3,42.8,9.5c0-0.1-0.1-0.3-0.2-0.5c-0.1-0.2-0.2-0.4-0.3-0.6c-0.1-0.2-0.2-0.4-0.3-0.6s-0.2-0.4-0.3-0.5 | |||
| c0.4-0.4,0.8-0.9,1.2-1.4c0.4-0.5,0.8-1.1,1.1-1.6c0.4-0.6,0.7-1.2,1-1.8c0.3-0.6,0.6-1.3,0.8-1.9L47.8,1.1z M53.5,13.2v4h-2.2V5.3 | |||
| h-0.7c-0.4,0.7-0.7,1.3-1.1,1.9s-0.8,1.1-1.2,1.6c-0.1-0.1-0.2-0.2-0.3-0.4c-0.1-0.1-0.3-0.3-0.4-0.4S47.2,7.8,47,7.7 | |||
| c-0.2-0.1-0.3-0.2-0.4-0.3C47,6.9,47.4,6.5,47.8,6c0.4-0.5,0.7-1.1,1-1.7s0.6-1.2,0.9-1.8c0.3-0.6,0.5-1.3,0.7-1.9l2.1,0.5 | |||
| c-0.1,0.4-0.3,0.8-0.4,1.1s-0.3,0.7-0.5,1.1h7v2h-5.1v1.9h4.7v1.9h-4.7v2h4.9v2H53.5z"/> | |||
| <path class="st0" d="M69.3,11.3v6h-2.2v-6h-7V9.1h7V3.6H61V1.5h14.4v2.1h-6v5.5h7.1v2.2H69.3z M64.1,4.2c0.1,0.3,0.3,0.6,0.4,0.9 | |||
| s0.3,0.6,0.4,1c0.1,0.3,0.2,0.6,0.4,0.9c0.1,0.3,0.2,0.6,0.2,0.8l-2.1,0.6c0-0.2-0.1-0.5-0.2-0.8s-0.2-0.6-0.3-1 | |||
| c-0.1-0.3-0.2-0.7-0.4-1c-0.1-0.3-0.3-0.7-0.4-1L64.1,4.2z M74.6,4.7c-0.3,0.7-0.7,1.4-1,2.1c-0.3,0.7-0.7,1.2-1,1.7l-1.9-0.5 | |||
| c0.1-0.3,0.3-0.6,0.4-0.9s0.3-0.6,0.4-1c0.1-0.3,0.3-0.7,0.4-1c0.1-0.3,0.2-0.6,0.3-0.9L74.6,4.7z"/> | |||
| <path class="st0" d="M89.4,2c0.4,0.4,0.9,0.8,1.3,1.3c0.5,0.5,0.9,0.9,1.3,1.4s0.8,0.9,1.2,1.4c0.4,0.5,0.7,0.9,0.9,1.3l-1.8,1.3 | |||
| c-0.1-0.2-0.3-0.4-0.4-0.6c-0.2-0.2-0.3-0.5-0.5-0.7c-1.6,0.1-3,0.1-4.1,0.2c-1.2,0.1-2.1,0.1-3,0.2c-0.8,0-1.5,0.1-2,0.1 | |||
| s-1,0.1-1.3,0.1s-0.6,0.1-0.8,0.1c-0.2,0-0.4,0.1-0.5,0.1c0-0.1-0.1-0.2-0.1-0.4c-0.1-0.2-0.1-0.4-0.2-0.6 | |||
| c-0.1-0.2-0.1-0.4-0.2-0.6C79,6.3,78.9,6.2,78.9,6c0.3-0.1,0.6-0.2,0.9-0.5c0.3-0.3,0.7-0.6,1-1c0.4-0.4,0.7-0.8,1.1-1.2 | |||
| c0.4-0.4,0.7-0.9,1-1.3c0.3-0.4,0.6-0.8,0.8-1.2c0.2-0.4,0.4-0.6,0.5-0.8L86.4,1c-0.6,0.8-1.2,1.7-1.9,2.4s-1.4,1.5-2,2.2l7.4-0.2 | |||
| c-0.3-0.4-0.7-0.8-1.1-1.2c-0.4-0.4-0.7-0.7-1-1.1L89.4,2z M82.4,16.3v0.9h-2.2V9.3h12.2v7.9H90v-0.9H82.4z M82.4,14.2H90v-2.9 | |||
| h-7.6V14.2z"/> | |||
| </g> | |||
| </svg> | |||
| @@ -151,6 +151,15 @@ func GetProjectLatestStatistics(ctx *context.Context) { | |||
| for _, contributor := range contributors { | |||
| mode := repository.GetCollaboratorMode(contributor.UserId) | |||
| if mode == -1 { | |||
| if contributor.IsAdmin { | |||
| mode = int(models.AccessModeAdmin) | |||
| } | |||
| if contributor.UserId == repository.OwnerID { | |||
| mode = int(models.AccessModeOwner) | |||
| } | |||
| } | |||
| pr := models.GetPullCountByUserAndRepoId(repoIdInt, contributor.UserId) | |||
| userInfo := UserInfo{ | |||
| User: contributor.Committer, | |||
| @@ -245,6 +245,11 @@ func renderDirectory(ctx *context.Context, treeLink string) { | |||
| ctx.Data["ReadmeInList"] = true | |||
| ctx.Data["ReadmeExist"] = true | |||
| ctx.Data["FileIsSymlink"] = readmeFile.isSymlink | |||
| ctx.Data["ReadmeName"] = readmeFile.name | |||
| if ctx.Repo.CanEnableEditor() { | |||
| ctx.Data["CanEditFile"] = true | |||
| } | |||
| dataRc, err := readmeFile.blob.DataAsync() | |||
| if err != nil { | |||
| @@ -311,7 +311,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Head("/", func() string { | |||
| return "" | |||
| }) | |||
| m.Get("/", routers.Dashboard) | |||
| m.Get("/", routers.Home) | |||
| m.Get("/dashboard", routers.Dashboard) | |||
| m.Group("/explore", func() { | |||
| m.Get("", func(ctx *context.Context) { | |||
| @@ -615,6 +615,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| //reqRepoBlockChainWriter := context.RequireRepoWriter(models.UnitTypeBlockChain) | |||
| // ***** START: Organization ***** | |||
| m.Group("/org", func() { | |||
| m.Group("/:org", func() { | |||
| m.Get("/members", org.Members) | |||
| }, context.OrgAssignment()) | |||
| }) | |||
| m.Group("/org", func() { | |||
| m.Group("", func() { | |||
| m.Get("/create", org.Create) | |||
| @@ -625,7 +630,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/dashboard", user.Dashboard) | |||
| m.Get("/^:type(issues|pulls)$", user.Issues) | |||
| m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones) | |||
| m.Get("/members", org.Members) | |||
| //m.Get("/members", org.Members) | |||
| m.Post("/members/action/:action", org.MembersAction) | |||
| m.Get("/teams", org.Teams) | |||
| @@ -544,7 +544,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | |||
| if err := models.UpdateUserCols(u, "language"); err != nil { | |||
| log.Error(fmt.Sprintf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language)) | |||
| return setting.AppSubURL + "/" | |||
| return setting.AppSubURL + "/dashboard" | |||
| } | |||
| } else { | |||
| // Language setting of the user use the one previously set | |||
| @@ -562,7 +562,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | |||
| u.SetLastLogin() | |||
| if err := models.UpdateUserCols(u, "last_login_unix"); err != nil { | |||
| ctx.ServerError("UpdateUserCols", err) | |||
| return setting.AppSubURL + "/" | |||
| return setting.AppSubURL + "/dashboard" | |||
| } | |||
| if redirectTo := ctx.GetCookie("redirect_to"); len(redirectTo) > 0 && !util.IsExternalURL(redirectTo) { | |||
| @@ -574,9 +574,9 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | |||
| } | |||
| if obeyRedirect { | |||
| ctx.Redirect(setting.AppSubURL + "/") | |||
| ctx.Redirect(setting.AppSubURL + "/dashboard") | |||
| } | |||
| return setting.AppSubURL + "/" | |||
| return setting.AppSubURL + "/dashboard" | |||
| } | |||
| // SignInOAuth handles the OAuth2 login buttons | |||
| @@ -7,6 +7,14 @@ | |||
| <i class="sidebar icon"></i> | |||
| </div> | |||
| </div> | |||
| <div style="width:1px;background:#606266;height:80%;margin:auto 0.5rem"></div> | |||
| <div class="item brand" style="margin-left: 0.9rem;"> | |||
| <a href="/"> | |||
| <img class="ui mini image" style="height: 1.3rem;" src="{{StaticUrlPrefix}}/img/git-logo.svg"> | |||
| </a> | |||
| </div> | |||
| {{if .IsSigned}} | |||
| <a class="item {{if .PageIsDashboard}}active{{end}}" href="/dashboard">{{.i18n.Tr "index"}}</a> | |||
| @@ -38,11 +38,12 @@ | |||
| <div class="ui sixteen wide mobile six wide tablet five wide computer column"> | |||
| <h4 class="ui top attached header"> | |||
| <strong>{{.i18n.Tr "org.people"}}</strong> | |||
| {{if .IsOrganizationMember}} | |||
| <div class="ui right"> | |||
| <a class="text grey" href="{{.OrgLink}}/members">{{.Org.NumMembers}} {{svg "octicon-chevron-right" 16}}</a> | |||
| </div> | |||
| {{end}} | |||
| <div class="ui right"> | |||
| <a class="text grey" href="{{.OrgLink}}/members">{{.Org.NumMembers}} {{svg "octicon-chevron-right" 16}}</a> | |||
| </div> | |||
| <!-- {{if .IsOrganizationMember}} --> | |||
| <!-- {{end}} --> | |||
| </h4> | |||
| <div class="ui attached segment members"> | |||
| {{$isMember := .IsOrganizationMember}} | |||
| @@ -3,10 +3,10 @@ | |||
| <a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> | |||
| {{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | |||
| </a> | |||
| <a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members"> | |||
| {{svg "octicon-organization" 16}} {{$.i18n.Tr "org.people"}} | |||
| </a> | |||
| {{if or ($.IsOrganizationMember) ($.IsOrganizationOwner)}} | |||
| <a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members"> | |||
| {{svg "octicon-organization" 16}} {{$.i18n.Tr "org.people"}} | |||
| </a> | |||
| <a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams"> | |||
| {{svg "octicon-jersey" 16}} {{$.i18n.Tr "org.teams"}} | |||
| </a> | |||
| @@ -23,10 +23,10 @@ | |||
| {{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | |||
| </a> | |||
| {{end}} | |||
| <a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members"> | |||
| {{svg "octicon-organization" 16}} {{$.i18n.Tr "org.people"}} | |||
| </a> | |||
| {{if or ($.IsOrganizationMember) ($.IsOrganizationOwner)}} | |||
| <a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members"> | |||
| {{svg "octicon-organization" 16}} {{$.i18n.Tr "org.people"}} | |||
| </a> | |||
| <a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams"> | |||
| {{svg "octicon-jersey" 16}} {{$.i18n.Tr "org.teams"}} | |||
| </a> | |||
| @@ -34,6 +34,21 @@ | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{if .ReadmeInList}} | |||
| <div class="file-header-right"> | |||
| <div class="ui right file-actions"> | |||
| {{if .Repository.CanEnableEditor}} | |||
| {{if .CanEditFile}} | |||
| <a href="{{.RepoLink}}/_edit/{{EscapePound .BranchName}}/{{EscapePound .ReadmeName}}"><span class="btn-octicon poping up" data-content="{{.EditFileTooltip}}" data-position="bottom center" data-variation="tiny inverted">{{svg "octicon-pencil" 16}}</span></a> | |||
| {{else}} | |||
| <span class="btn-octicon poping up disabled" data-content="{{.EditFileTooltip}}" data-position="bottom center" data-variation="tiny inverted">{{svg "octicon-pencil" 16}}</span> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{if not .ReadmeInList}} | |||
| <div class="file-header-right"> | |||
| <div class="ui right file-actions"> | |||
| @@ -70,7 +70,7 @@ export default { | |||
| this.info.desc = el; | |||
| }, | |||
| getWeb() { | |||
| const el = $('a.link').text(); | |||
| const el = $('a.link.edit-link').text(); | |||
| this.info.index_web = el; | |||
| }, | |||
| getRepoName() { | |||
| @@ -298,7 +298,7 @@ display: block; | |||
| display: none; | |||
| position: absolute; | |||
| background-color: #ffffff; | |||
| min-width: 160px; | |||
| min-width: 180px; | |||
| z-index: 999; | |||
| border: 1px solid transparent; | |||
| border-color: #d4d4d5; | |||