feat(dashboard): add sensitive data toggle to flow chart

Add an eye toggle in the flow section header that masks sensitive node
labels (users, tokens, nodes, groups, channels) in the Sankey while keeping
model names visible. Masking only rewrites display text; nodes stay distinct
via their key so graph structure, links, and highlighting are unaffected.
This commit is contained in:
CaIon
2026-06-20 22:09:04 +08:00
parent 8ad83bf62f
commit 5e86644649
10 changed files with 119 additions and 9 deletions
+46 -9
View File
@@ -18,11 +18,18 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useCallback, useMemo, lazy, Suspense } from 'react'
import { getRouteApi, useNavigate } from '@tanstack/react-router'
import { Eye, EyeOff } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
import { ROLE } from '@/lib/roles'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { SectionPageLayout } from '@/components/layout'
import { FadeIn } from '@/components/page-transition'
import { ModelsChartPreferences } from './components/models/models-chart-preferences'
@@ -179,6 +186,7 @@ export function Dashboard() {
}
}
)
const [flowSensitiveVisible, setFlowSensitiveVisible] = useState(true)
const handleFilterChange = useCallback((filters: DashboardFilters) => {
setModelFilters(filters)
@@ -242,14 +250,40 @@ export function Dashboard() {
) : null
const flowActions =
activeSection === 'flow' ? (
<ModelsFilter
preferences={chartPreferences}
currentFilters={modelFilters}
onFilterChange={handleFilterChange}
onReset={handleResetFilters}
titleKey='Flow Filters'
descriptionKey='Filter the traffic flow view by time range and user.'
/>
<>
<Tooltip>
<TooltipTrigger
render={
<Button
variant='ghost'
size='icon'
onClick={() => setFlowSensitiveVisible((prev) => !prev)}
aria-label={
flowSensitiveVisible
? t('Hide sensitive data')
: t('Show sensitive data')
}
className='text-muted-foreground hover:text-foreground size-8'
/>
}
>
{flowSensitiveVisible ? <Eye /> : <EyeOff />}
</TooltipTrigger>
<TooltipContent>
{flowSensitiveVisible
? t('Hide sensitive data')
: t('Show sensitive data')}
</TooltipContent>
</Tooltip>
<ModelsFilter
preferences={chartPreferences}
currentFilters={modelFilters}
onFilterChange={handleFilterChange}
onReset={handleResetFilters}
titleKey='Flow Filters'
descriptionKey='Filter the traffic flow view by time range and user.'
/>
</>
) : null
const sectionActions = modelActions ?? flowActions
@@ -339,7 +373,10 @@ export function Dashboard() {
{activeSection === 'flow' && (
<FadeIn>
<Suspense fallback={<ModelChartsFallback />}>
<LazyFlowCharts filters={modelFilters} />
<LazyFlowCharts
filters={modelFilters}
sensitiveVisible={flowSensitiveVisible}
/>
</Suspense>
</FadeIn>
)}