Merge branch 'ci-trends'

This commit is contained in:
Santinova Dashboard Automation
2026-08-20 17:56:30 +02:00
5 changed files with 88 additions and 6 deletions

View File

@@ -12,8 +12,11 @@ import {
CheckCircle2,
XCircle,
Loader2,
TrendingDown,
TrendingUp,
Minus,
} from 'lucide-react';
import { getGiteaRepos, getGiteaCommits, getGiteaWorkflowRuns } from '../utils/api';
import { getGiteaRepos, getGiteaCommits, getGiteaWorkflowRuns, getGiteaWorkflowSummary } from '../utils/api';
function formatDate(dateStr) {
if (!dateStr) return 'N/A';
@@ -49,6 +52,7 @@ export default function GiteaPage() {
const [selectedRepo, setSelectedRepo] = useState(null);
const [commits, setCommits] = useState([]);
const [workflowRuns, setWorkflowRuns] = useState([]);
const [workflowSummary, setWorkflowSummary] = useState(null);
const [loadingCommits, setLoadingCommits] = useState(false);
const fetchRepos = async () => {
@@ -68,16 +72,19 @@ export default function GiteaPage() {
setSelectedRepo(fullName);
try {
const [owner, repo] = fullName.split('/');
const [commitsResponse, runsResponse] = await Promise.all([
const [commitsResponse, runsResponse, summaryResponse] = await Promise.all([
getGiteaCommits(owner, repo),
getGiteaWorkflowRuns(owner, repo),
getGiteaWorkflowSummary(owner, repo),
]);
setCommits(commitsResponse.data);
setWorkflowRuns(runsResponse.data);
setWorkflowSummary(summaryResponse.data);
} catch (err) {
console.error('Erreur chargement commits:', err);
setCommits([]);
setWorkflowRuns([]);
setWorkflowSummary(null);
} finally {
setLoadingCommits(false);
}
@@ -218,7 +225,15 @@ export default function GiteaPage() {
{workflowRuns.length === 0 ? (
<p className="text-sm text-gray-500">Aucune validation CI trouvée pour ce dépôt.</p>
) : (
<div className="space-y-2">
<>
{workflowSummary?.sampleSize > 0 && (
<div className="grid grid-cols-3 gap-2 mb-3 text-xs">
<div className="rounded bg-dark-700/70 p-2"><p className="text-gray-500">Succès</p><p className="font-semibold text-emerald-300">{workflowSummary.successRate}%</p></div>
<div className="rounded bg-dark-700/70 p-2"><p className="text-gray-500">Médiane</p><p className="font-semibold text-gray-200">{formatDuration(workflowSummary.medianDurationSeconds)}</p></div>
<div className="rounded bg-dark-700/70 p-2"><p className={`font-semibold flex items-center gap-1 ${workflowSummary.trend === 'faster' ? 'text-emerald-300' : workflowSummary.trend === 'slower' ? 'text-red-300' : 'text-gray-300'}`}>{workflowSummary.trend === 'faster' ? <TrendingDown className="w-3 h-3" /> : workflowSummary.trend === 'slower' ? <TrendingUp className="w-3 h-3" /> : <Minus className="w-3 h-3" />}{workflowSummary.changePercent === null ? 'N/A' : `${Math.abs(workflowSummary.changePercent)}%`}</p></div>
</div>
)}
<div className="space-y-2">
{workflowRuns.slice(0, 5).map((run) => (
<div key={run.id} className="flex items-center justify-between gap-3 text-xs">
<div className="min-w-0">
@@ -231,7 +246,8 @@ export default function GiteaPage() {
</div>
</div>
))}
</div>
</div>
</>
)}
</div>
{commits.map((commit, idx) => (

View File

@@ -61,6 +61,8 @@ export const getGiteaCommits = (owner, repo) =>
api.get(`/gitea/repos/${owner}/${repo}/commits`);
export const getGiteaWorkflowRuns = (owner, repo) =>
api.get(`/gitea/repos/${owner}/${repo}/actions/runs`);
export const getGiteaWorkflowSummary = (owner, repo) =>
api.get(`/gitea/repos/${owner}/${repo}/actions/summary`);
// Docker
export const getContainers = () => api.get('/docker/containers');