Skip to content

Commit 2b02d49

Browse files
Added new feature to calculate Advance Analysis with PAT only for more insights.
1 parent d904719 commit 2b02d49

4 files changed

Lines changed: 440 additions & 15 deletions

File tree

src/context/AppContext.jsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createContext, useContext, useState, useCallback, useEffect, useMemo } from 'react'
2-
import { fetchOrg, fetchRepos, fetchContributors, fetchIssues, fetchRateLimit } from '../services/github'
2+
import { fetchOrg, fetchRepos, fetchContributors, fetchIssues, fetchRateLimit, fetchPulls } from '../services/github'
33
import { buildAnalyticalModel, getTopRepositories } from '../services/analytics'
44

55
const Ctx = createContext(null)
@@ -29,12 +29,14 @@ export function AppProvider({ children }) {
2929
const [orgs, setOrgs] = useState([])
3030
const [model, setModel] = useState(null)
3131
const [issuesData, setIssuesData] = useState({})
32+
const [pullsData, setPullsData] = useState({})
3233
const [rateLimit, setRateLimit] = useState(getStoredRateLimit)
3334
const [loading, setLoading] = useState(false)
3435
const [loadMsg, setLoadMsg] = useState('')
3536
const [govLoading, setGovLoading] = useState(false)
3637
const [error, setError] = useState('')
3738
const [totalRepo, setTotalRepo] = useState(0)
39+
const [advanceAnalyticsLoading, setAdvanceAnalyticsLoading] = useState(false);
3840

3941
useEffect(() => {
4042
const handler = e => {
@@ -151,6 +153,24 @@ export function AppProvider({ children }) {
151153
setGovLoading(false)
152154
}, [model, pat, govLoading])
153155

156+
// Advanced analytics — parallel batches of 5 (Section 3.2.5)
157+
const runAdvanceAnalytics = useCallback(async () => {
158+
if (!model || advanceAnalyticsLoading) return
159+
setAdvanceAnalyticsLoading(true)
160+
const map = {}
161+
const repos = model.totalRepos;
162+
163+
// Batches of 5 using Promise.allSettled
164+
for (let i = 0; i < repos.length; i += 5) {
165+
const batch = repos.slice(i, i + 5)
166+
await Promise.allSettled(batch.map(async repo => {
167+
map[`${repo.orgLogin}/${repo.name}`] = await fetchPulls(repo.orgLogin, repo.name, pat)
168+
}))
169+
}
170+
setPullsData(map)
171+
setAdvanceAnalyticsLoading(false)
172+
}, [model, pat, advanceAnalyticsLoading])
173+
154174
const STALE_DAYS = 90
155175

156176
const staleRepoStats = useMemo(() => {
@@ -187,9 +207,9 @@ export function AppProvider({ children }) {
187207

188208
return (
189209
<Ctx.Provider value={{
190-
pat, savePat, orgs, model, issuesData,
210+
pat, savePat, orgs, model, issuesData, pullsData,
191211
rateLimit, loading, loadMsg, govLoading, error, totalRepo,
192-
explore, runAudit, setError, refreshRateLimit, staleRepoStats,
212+
explore, runAudit, runAdvanceAnalytics, setError, refreshRateLimit, staleRepoStats, advanceAnalyticsLoading
193213
}}>
194214
{children}
195215
</Ctx.Provider>

src/hooks/useSortedData.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,52 @@ export function useSortedData(data = [], defaultKey = 'healthScore', defaultDir
2020

2121
return { sorted, sortConfig: cfg, onSort }
2222
}
23+
24+
25+
export function useAdvancedMetrics(pulls = []) {
26+
return useMemo(() => {
27+
if (!pulls.length) {
28+
return {
29+
avgMergeDays: 0,
30+
acceptanceRate: 0,
31+
merged: 0,
32+
rejected: 0
33+
}
34+
}
35+
36+
const mergedPRs = pulls.filter(pr => pr.merged_at)
37+
38+
const rejectedPRs = pulls.filter(
39+
pr => pr.state === 'closed' && !pr.merged_at
40+
)
41+
42+
const totalMergeTime = mergedPRs.reduce((sum, pr) => {
43+
return (
44+
sum +
45+
(new Date(pr.merged_at).getTime() -
46+
new Date(pr.created_at).getTime())
47+
)
48+
}, 0)
49+
50+
const avgMergeDays =
51+
mergedPRs.length === 0
52+
? 0
53+
: totalMergeTime /
54+
mergedPRs.length /
55+
(1000 * 60 * 60 * 24)
56+
57+
const acceptanceRate =
58+
mergedPRs.length + rejectedPRs.length === 0
59+
? 0
60+
: (mergedPRs.length /
61+
(mergedPRs.length + rejectedPRs.length)) *
62+
100
63+
64+
return {
65+
avgMergeDays,
66+
acceptanceRate,
67+
merged: mergedPRs.length,
68+
rejected: rejectedPRs.length
69+
}
70+
}, [pulls])
71+
}

0 commit comments

Comments
 (0)