-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement recent commits graph (#29210)
This is the implementation of Recent Commits page. This feature was mentioned on #18262. It adds another tab to Activity page called Recent Commits. Recent Commits tab shows number of commits since last year for the repository.
- Loading branch information
1 parent
0a426cc
commit d3982bc
Showing
9 changed files
with
233 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{{if .Permission.CanRead $.UnitTypeCode}} | ||
<div id="repo-recent-commits-chart" | ||
data-locale-loading-title="{{ctx.Locale.Tr "graphs.component_loading" (ctx.Locale.Tr "graphs.recent_commits.what")}}" | ||
data-locale-loading-title-failed="{{ctx.Locale.Tr "graphs.component_loading_failed" (ctx.Locale.Tr "graphs.recent_commits.what")}}" | ||
data-locale-loading-info="{{ctx.Locale.Tr "graphs.component_loading_info"}}" | ||
data-locale-component-failed-to-load="{{ctx.Locale.Tr "graphs.component_failed_to_load"}}" | ||
> | ||
</div> | ||
{{end}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<script> | ||
import {SvgIcon} from '../svg.js'; | ||
import { | ||
Chart, | ||
Tooltip, | ||
BarElement, | ||
LinearScale, | ||
TimeScale, | ||
} from 'chart.js'; | ||
import {GET} from '../modules/fetch.js'; | ||
import {Bar} from 'vue-chartjs'; | ||
import { | ||
startDaysBetween, | ||
firstStartDateAfterDate, | ||
fillEmptyStartDaysWithZeroes, | ||
} from '../utils/time.js'; | ||
import {chartJsColors} from '../utils/color.js'; | ||
import {sleep} from '../utils.js'; | ||
import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm'; | ||
const {pageData} = window.config; | ||
Chart.defaults.color = chartJsColors.text; | ||
Chart.defaults.borderColor = chartJsColors.border; | ||
Chart.register( | ||
TimeScale, | ||
LinearScale, | ||
BarElement, | ||
Tooltip, | ||
); | ||
export default { | ||
components: {Bar, SvgIcon}, | ||
props: { | ||
locale: { | ||
type: Object, | ||
required: true | ||
}, | ||
}, | ||
data: () => ({ | ||
isLoading: false, | ||
errorText: '', | ||
repoLink: pageData.repoLink || [], | ||
data: [], | ||
}), | ||
mounted() { | ||
this.fetchGraphData(); | ||
}, | ||
methods: { | ||
async fetchGraphData() { | ||
this.isLoading = true; | ||
try { | ||
let response; | ||
do { | ||
response = await GET(`${this.repoLink}/activity/recent-commits/data`); | ||
if (response.status === 202) { | ||
await sleep(1000); // wait for 1 second before retrying | ||
} | ||
} while (response.status === 202); | ||
if (response.ok) { | ||
const data = await response.json(); | ||
const start = Object.values(data)[0].week; | ||
const end = firstStartDateAfterDate(new Date()); | ||
const startDays = startDaysBetween(new Date(start), new Date(end)); | ||
this.data = fillEmptyStartDaysWithZeroes(startDays, data).slice(-52); | ||
this.errorText = ''; | ||
} else { | ||
this.errorText = response.statusText; | ||
} | ||
} catch (err) { | ||
this.errorText = err.message; | ||
} finally { | ||
this.isLoading = false; | ||
} | ||
}, | ||
toGraphData(data) { | ||
return { | ||
datasets: [ | ||
{ | ||
data: data.map((i) => ({x: i.week, y: i.commits})), | ||
label: 'Commits', | ||
backgroundColor: chartJsColors['commits'], | ||
borderWidth: 0, | ||
tension: 0.3, | ||
}, | ||
], | ||
}; | ||
}, | ||
getOptions() { | ||
return { | ||
responsive: true, | ||
maintainAspectRatio: false, | ||
animation: true, | ||
scales: { | ||
x: { | ||
type: 'time', | ||
grid: { | ||
display: false, | ||
}, | ||
time: { | ||
minUnit: 'week', | ||
}, | ||
ticks: { | ||
maxRotation: 0, | ||
maxTicksLimit: 52 | ||
}, | ||
}, | ||
y: { | ||
ticks: { | ||
maxTicksLimit: 6 | ||
}, | ||
}, | ||
}, | ||
}; | ||
}, | ||
}, | ||
}; | ||
</script> | ||
<template> | ||
<div> | ||
<div class="ui header gt-df gt-ac gt-sb"> | ||
{{ isLoading ? locale.loadingTitle : errorText ? locale.loadingTitleFailed: "Number of commits in the past year" }} | ||
</div> | ||
<div class="gt-df ui segment main-graph"> | ||
<div v-if="isLoading || errorText !== ''" class="gt-tc gt-m-auto"> | ||
<div v-if="isLoading"> | ||
<SvgIcon name="octicon-sync" class="gt-mr-3 job-status-rotate"/> | ||
{{ locale.loadingInfo }} | ||
</div> | ||
<div v-else class="text red"> | ||
<SvgIcon name="octicon-x-circle-fill"/> | ||
{{ errorText }} | ||
</div> | ||
</div> | ||
<Bar | ||
v-memo="data" v-if="data.length !== 0" | ||
:data="toGraphData(data)" :options="getOptions()" | ||
/> | ||
</div> | ||
</div> | ||
</template> | ||
<style scoped> | ||
.main-graph { | ||
height: 250px; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters