Skip to content

Commit

Permalink
Implement contributors graph (go-gitea#27882)
Browse files Browse the repository at this point in the history
Continuation of go-gitea#25439. Fixes go-gitea#847

Before:
<img width="1296" alt="image"
src="https://github.com/go-gitea/gitea/assets/32161460/24571ac8-b254-43c9-b178-97340f0dc8a9">

----
After:
<img width="1296" alt="image"
src="https://github.com/go-gitea/gitea/assets/32161460/c60b2459-9d10-4d42-8d83-d5ef0f45bf94">

---
#### Overview
This is the implementation of a requested feature: Contributors graph
(go-gitea#847)

It makes Activity page a multi-tab page and adds a new tab called
Contributors. Contributors tab shows the contribution graphs over time
since the repository existed. It also shows per user contribution graphs
for top 100 contributors. Top 100 is calculated based on the selected
contribution type (commits, additions or deletions).

---
#### Demo
(The demo is a bit old but still a good example to show off the main
features)

<video src="https://github.com/go-gitea/gitea/assets/32161460/9f68103f-8145-4cc2-94bc-5546daae7014" controls width="320" height="240">
  <a href="https://github.com/go-gitea/gitea/assets/32161460/9f68103f-8145-4cc2-94bc-5546daae7014">Download</a>
</video>


#### Features:

- Select contribution type (commits, additions or deletions)
- See overall and per user contribution graphs for the selected
contribution type
- Zoom and pan on graphs to see them in detail
- See top 100 contributors based on the selected contribution type and
selected time range
- Go directly to users' profile by clicking their name if they are
registered gitea users
- Cache the results so that when the same repository is visited again
fetching data will be faster


---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: hiifong <i@hiif.ong>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: yp05327 <576951401@qq.com>
  • Loading branch information
6 people committed Feb 20, 2024
1 parent 116205d commit 5d0c26d
Show file tree
Hide file tree
Showing 18 changed files with 1,330 additions and 230 deletions.
12 changes: 12 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,8 @@ wiki.page_name_desc = Enter a name for this Wiki page. Some special names are: '
wiki.original_git_entry_tooltip = View original Git file instead of using friendly link.

activity = Activity
activity.navbar.pulse = Pulse
activity.navbar.contributors = Contributors
activity.period.filter_label = Period:
activity.period.daily = 1 day
activity.period.halfweekly = 3 days
Expand Down Expand Up @@ -1977,6 +1979,16 @@ activity.git_stats_and_deletions = and
activity.git_stats_deletion_1 = %d deletion
activity.git_stats_deletion_n = %d deletions

contributors = Contributors
contributors.contribution_type.filter_label = Contribution type:
contributors.contribution_type.commits = Commits
contributors.contribution_type.additions = Additions
contributors.contribution_type.deletions = Deletions
contributors.loading_title = Loading contributions...
contributors.loading_title_failed = Could not load contributions
contributors.loading_info = This might take a bit…
contributors.component_failed_to_load = An unexpected error happened.

search = Search
search.search_repo = Search repository
search.type.tooltip = Search type
Expand Down
67 changes: 64 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
"add-asset-webpack-plugin": "2.0.1",
"ansi_up": "6.0.2",
"asciinema-player": "3.6.3",
"chart.js": "4.3.0",
"chartjs-adapter-dayjs-4": "1.0.4",
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.6",
"css-loader": "6.10.0",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
"esbuild-loader": "4.0.3",
Expand All @@ -46,6 +50,7 @@
"uint8-to-base64": "0.2.0",
"vue": "3.4.18",
"vue-bar-graph": "2.0.0",
"vue-chartjs": "5.3.0",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
"webpack": "5.90.1",
Expand Down
2 changes: 2 additions & 0 deletions routers/web/repo/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func Activity(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.activity")
ctx.Data["PageIsActivity"] = true

ctx.Data["PageIsPulse"] = true

ctx.Data["Period"] = ctx.Params("period")

timeUntil := time.Now()
Expand Down
44 changes: 44 additions & 0 deletions routers/web/repo/contributors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repo

import (
"errors"
"net/http"

"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
contributors_service "code.gitea.io/gitea/services/repository"
)

const (
tplContributors base.TplName = "repo/activity"
)

// Contributors render the page to show repository contributors graph
func Contributors(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.contributors")

ctx.Data["PageIsActivity"] = true
ctx.Data["PageIsContributors"] = true

ctx.PageData["contributionType"] = "commits"

ctx.PageData["repoLink"] = ctx.Repo.RepoLink

ctx.HTML(http.StatusOK, tplContributors)
}

// ContributorsData renders JSON of contributors along with their weekly commit statistics
func ContributorsData(ctx *context.Context) {
if contributorStats, err := contributors_service.GetContributorStats(ctx, ctx.Cache, ctx.Repo.Repository, ctx.Repo.CommitID); err != nil {
if errors.Is(err, contributors_service.ErrAwaitGeneration) {
ctx.Status(http.StatusAccepted)
return
}
ctx.ServerError("GetContributorStats", err)
} else {
ctx.JSON(http.StatusOK, contributorStats)
}
}
4 changes: 4 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,10 @@ func registerRoutes(m *web.Route) {
m.Group("/activity", func() {
m.Get("", repo.Activity)
m.Get("/{period}", repo.Activity)
m.Group("/contributors", func() {
m.Get("", repo.Contributors)
m.Get("/data", repo.ContributorsData)
})
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))

m.Group("/activity_author_data", func() {
Expand Down
Loading

0 comments on commit 5d0c26d

Please sign in to comment.