feat: enhance Jira dashboard with advanced filtering and sprint details

- Updated `TODO.md` to mark several tasks as complete, including anomaly detection and sprint detail integration.
- Enhanced `VelocityChart` to support click events for sprint details, improving user interaction.
- Added `FilterBar` and `AnomalyDetectionPanel` components to `JiraDashboardPageClient` for advanced filtering capabilities.
- Implemented state management for selected sprints and modal display for detailed sprint information.
- Introduced new types for advanced filtering in `types.ts`, expanding the filtering options available in the analytics.
This commit is contained in:
Julien Froidefond
2025-09-19 10:13:48 +02:00
parent b7707d7651
commit 3dd6e0fd1c
17 changed files with 2879 additions and 68 deletions

View File

@@ -6,17 +6,26 @@ import { SprintVelocity } from '@/lib/types';
interface VelocityChartProps {
sprintHistory: SprintVelocity[];
className?: string;
onSprintClick?: (sprint: SprintVelocity) => void;
}
export function VelocityChart({ sprintHistory, className }: VelocityChartProps) {
export function VelocityChart({ sprintHistory, className, onSprintClick }: VelocityChartProps) {
// Préparer les données pour le graphique
const chartData = sprintHistory.map(sprint => ({
name: sprint.sprintName,
completed: sprint.completedPoints,
planned: sprint.plannedPoints,
completionRate: sprint.completionRate
completionRate: sprint.completionRate,
sprintData: sprint // Garder la référence au sprint original
}));
const handleBarClick = (data: unknown) => {
if (onSprintClick && data && typeof data === 'object' && data !== null && 'sprintData' in data) {
const typedData = data as { sprintData: SprintVelocity };
onSprintClick(typedData.sprintData);
}
};
const CustomTooltip = ({ active, payload, label }: {
active?: boolean;
payload?: Array<{ payload: { completed: number; planned: number; completionRate: number } }>;
@@ -40,6 +49,13 @@ export function VelocityChart({ sprintHistory, className }: VelocityChartProps)
<span>Taux de réussite:</span>
<span className="font-mono text-orange-500">{data.completionRate}%</span>
</div>
{onSprintClick && (
<div className="border-t border-[var(--border)] pt-2 mt-2">
<p className="text-xs text-[var(--muted-foreground)]">
🖱 Cliquez pour voir les détails
</p>
</div>
)}
</div>
</div>
);
@@ -50,7 +66,10 @@ export function VelocityChart({ sprintHistory, className }: VelocityChartProps)
return (
<div className={className}>
<ResponsiveContainer width="100%" height="100%">
<BarChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
<BarChart
data={chartData}
margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
>
<CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
<XAxis
dataKey="name"
@@ -63,13 +82,20 @@ export function VelocityChart({ sprintHistory, className }: VelocityChartProps)
/>
<Tooltip content={<CustomTooltip />} />
<Bar dataKey="planned" fill="var(--muted)" opacity={0.6} radius={[4, 4, 0, 0]} />
<Bar dataKey="completed" fill="hsl(142, 76%, 36%)" radius={[4, 4, 0, 0]}>
<Bar
dataKey="completed"
fill="hsl(142, 76%, 36%)"
radius={[4, 4, 0, 0]}
style={{ cursor: onSprintClick ? 'pointer' : 'default' }}
onClick={handleBarClick}
>
{chartData.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={entry.completionRate >= 80 ? 'hsl(142, 76%, 36%)' :
entry.completionRate >= 60 ? 'hsl(45, 93%, 47%)' :
'hsl(0, 84%, 60%)'}
style={{ cursor: onSprintClick ? 'pointer' : 'default' }}
/>
))}
</Bar>