feat: add Top Attacking IPs chart component and integrate into CrowdSec configuration page
- Implemented TopAttackingIPsChart component for visualizing top attacking IPs. - Created hooks for fetching CrowdSec dashboard data including summary, timeline, top IPs, scenarios, and alerts. - Added tests for the new hooks to ensure data fetching works as expected. - Updated translation files for new dashboard terms in multiple languages. - Refactored CrowdSecConfig page to include a tabbed interface for configuration and dashboard views. - Added end-to-end tests for CrowdSec dashboard functionality including tab navigation, data display, and interaction with time range and refresh features.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { isAxiosError } from 'axios'
|
||||
import { Shield, ShieldOff, Trash2, Search, AlertTriangle, ExternalLink } from 'lucide-react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { lazy, Suspense, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate, Link } from 'react-router-dom'
|
||||
|
||||
@@ -15,11 +15,15 @@ import { ConfigReloadOverlay } from '../components/LoadingStates'
|
||||
import { Button } from '../components/ui/Button'
|
||||
import { Card } from '../components/ui/Card'
|
||||
import { Input } from '../components/ui/Input'
|
||||
import { Skeleton } from '../components/ui/Skeleton'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/Tabs'
|
||||
import { CROWDSEC_PRESETS, type CrowdsecPreset } from '../data/crowdsecPresets'
|
||||
import { useConsoleStatus, useEnrollConsole, useClearConsoleEnrollment } from '../hooks/useConsoleEnrollment'
|
||||
import { buildCrowdsecExportFilename, downloadCrowdsecExport, promptCrowdsecFilename } from '../utils/crowdsecExport'
|
||||
import { toast } from '../utils/toast'
|
||||
|
||||
const CrowdSecDashboard = lazy(() => import('../components/crowdsec/CrowdSecDashboard'))
|
||||
|
||||
export default function CrowdSecConfig() {
|
||||
const { t } = useTranslation()
|
||||
const { data: status, isLoading, error } = useQuery({ queryKey: ['security-status'], queryFn: getSecurityStatus })
|
||||
@@ -557,6 +561,20 @@ export default function CrowdSecConfig() {
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-2xl font-bold">{t('crowdsecConfig.title')}</h1>
|
||||
|
||||
<Tabs defaultValue="config">
|
||||
<TabsList>
|
||||
<TabsTrigger value="config">{t('security.crowdsec.tabs.config', 'Configuration')}</TabsTrigger>
|
||||
<TabsTrigger value="dashboard">{t('security.crowdsec.tabs.dashboard', 'Dashboard')}</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="dashboard" className="mt-4">
|
||||
<Suspense fallback={<div className="space-y-4"><Skeleton className="h-24 w-full" /><Skeleton className="h-64 w-full" /></div>}>
|
||||
<CrowdSecDashboard />
|
||||
</Suspense>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="config" className="mt-4">
|
||||
|
||||
{/* CrowdSec Bouncer API Key - moved from Security Dashboard */}
|
||||
{status.cerberus?.enabled && status.crowdsec.enabled && (
|
||||
<CrowdSecBouncerKeyDisplay />
|
||||
@@ -1221,6 +1239,9 @@ export default function CrowdSecConfig() {
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
{/* Ban IP Modal */}
|
||||
|
||||
Reference in New Issue
Block a user