diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 2c92f40a17558..ff6a3f1b8e52a 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1915,8 +1915,9 @@ wiki.original_git_entry_tooltip = View original Git file instead of using friend activity = Activity activity.navbar.pulse = Pulse -activity.navbar.contributors = Contributors activity.navbar.code_frequency = Code Frequency +activity.navbar.contributors = Contributors +activity.navbar.recent_commits = Recent Commits activity.period.filter_label = Period: activity.period.daily = 1 day activity.period.halfweekly = 3 days @@ -2597,6 +2598,7 @@ component_loading_info = This might take a bit… component_failed_to_load = An unexpected error happened. code_frequency.what = code frequency contributors.what = contributions +recent_commits.what = recent commits [org] org_name_holder = Organization Name diff --git a/routers/web/repo/recent_commits.go b/routers/web/repo/recent_commits.go new file mode 100644 index 0000000000000..3507cb8752112 --- /dev/null +++ b/routers/web/repo/recent_commits.go @@ -0,0 +1,41 @@ +// 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 ( + tplRecentCommits base.TplName = "repo/activity" +) + +// RecentCommits renders the page to show recent commit frequency on repository +func RecentCommits(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("repo.activity.navbar.recent_commits") + + ctx.Data["PageIsActivity"] = true + ctx.Data["PageIsRecentCommits"] = true + ctx.PageData["repoLink"] = ctx.Repo.RepoLink + + ctx.HTML(http.StatusOK, tplRecentCommits) +} + +// RecentCommitsData returns JSON of recent commits data +func RecentCommitsData(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("RecentCommitsData", err) + } else { + ctx.JSON(http.StatusOK, contributorStats["total"].Weeks) + } +} diff --git a/routers/web/web.go b/routers/web/web.go index a76b444e4f43b..8505417c880be 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1402,6 +1402,10 @@ func registerRoutes(m *web.Route) { m.Get("", repo.CodeFrequency) m.Get("/data", repo.CodeFrequencyData) }) + m.Group("/recent-commits", func() { + m.Get("", repo.RecentCommits) + m.Get("/data", repo.RecentCommitsData) + }) }, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases)) m.Group("/activity_author_data", func() { diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl index 94f52b0e26386..a19fb662616db 100644 --- a/templates/repo/activity.tmpl +++ b/templates/repo/activity.tmpl @@ -9,6 +9,7 @@ {{if .PageIsPulse}}{{template "repo/pulse" .}}{{end}} {{if .PageIsContributors}}{{template "repo/contributors" .}}{{end}} {{if .PageIsCodeFrequency}}{{template "repo/code_frequency" .}}{{end}} + {{if .PageIsRecentCommits}}{{template "repo/recent_commits" .}}{{end}} diff --git a/templates/repo/navbar.tmpl b/templates/repo/navbar.tmpl index aa5021e73a70c..b2471dc17e7c0 100644 --- a/templates/repo/navbar.tmpl +++ b/templates/repo/navbar.tmpl @@ -8,4 +8,7 @@ {{ctx.Locale.Tr "repo.activity.navbar.code_frequency"}} + + {{ctx.Locale.Tr "repo.activity.navbar.recent_commits"}} + diff --git a/templates/repo/recent_commits.tmpl b/templates/repo/recent_commits.tmpl new file mode 100644 index 0000000000000..5c241d635cd90 --- /dev/null +++ b/templates/repo/recent_commits.tmpl @@ -0,0 +1,9 @@ +{{if .Permission.CanRead $.UnitTypeCode}} +
+
+{{end}} diff --git a/web_src/js/components/RepoRecentCommits.vue b/web_src/js/components/RepoRecentCommits.vue new file mode 100644 index 0000000000000..77697cd413f96 --- /dev/null +++ b/web_src/js/components/RepoRecentCommits.vue @@ -0,0 +1,149 @@ + + + diff --git a/web_src/js/features/recent-commits.js b/web_src/js/features/recent-commits.js new file mode 100644 index 0000000000000..ded10d39be49e --- /dev/null +++ b/web_src/js/features/recent-commits.js @@ -0,0 +1,21 @@ +import {createApp} from 'vue'; + +export async function initRepoRecentCommits() { + const el = document.getElementById('repo-recent-commits-chart'); + if (!el) return; + + const {default: RepoRecentCommits} = await import(/* webpackChunkName: "recent-commits-graph" */'../components/RepoRecentCommits.vue'); + try { + const View = createApp(RepoRecentCommits, { + locale: { + loadingTitle: el.getAttribute('data-locale-loading-title'), + loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), + loadingInfo: el.getAttribute('data-locale-loading-info'), + } + }); + View.mount(el); + } catch (err) { + console.error('RepoRecentCommits failed to load', err); + el.textContent = el.getAttribute('data-locale-component-failed-to-load'); + } +} diff --git a/web_src/js/index.js b/web_src/js/index.js index d9cfff408425c..b7f3ba99a0e95 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -85,6 +85,7 @@ import {initRepoIssueList} from './features/repo-issue-list.js'; import {initCommonIssueListQuickGoto} from './features/common-issue-list.js'; import {initRepoContributors} from './features/contributors.js'; import {initRepoCodeFrequency} from './features/code-frequency.js'; +import {initRepoRecentCommits} from './features/recent-commits.js'; import {initRepoDiffCommitBranchesAndTags} from './features/repo-diff-commit.js'; import {initDirAuto} from './modules/dirauto.js'; @@ -176,6 +177,7 @@ onDomReady(() => { initRepositoryActionView(); initRepoContributors(); initRepoCodeFrequency(); + initRepoRecentCommits(); initCommitStatuses(); initCaptcha();