mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-04 15:06:37 +08:00
a11y 收尾:主题级对比度根因修复(indigo-500→600)+12 处控件 accessible name+4 处 heading-order,7 页复扫全 0 违规;基准 total_issues 保持 8
Result: {"status":"keep","total_issues":8,"eslint_errors":0,"eslint_problems":0,"eslint_warnings":0,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_exhaustive":0,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_total":0,"golint_test_usetesting":0,"golint_total":8,"golint_usestdlibvars":0,"golint_vetx_total":0,"golint_wastedassign":0,"measure_s":85,"tsc_errors":0,"vitest_failed":0,"vitest_total":126}
This commit is contained in:
@@ -189,9 +189,9 @@ export function CacheManager({ refreshTrigger }: CacheManagerProps) {
|
||||
<div className='grid grid-cols-1 lg:grid-cols-5 gap-6'>
|
||||
{/* 左边:状态区 (2/5 cols) */}
|
||||
<div className='lg:col-span-2 space-y-4'>
|
||||
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider'>
|
||||
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider'>
|
||||
{t('runtimeStatus')}
|
||||
</h4>
|
||||
</p>
|
||||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
|
||||
{/* 已占空间 */}
|
||||
<div className='p-4 rounded-xl border border-border/40 bg-background/30 backdrop-blur-xs hover:border-primary/20 transition-all duration-300'>
|
||||
@@ -240,9 +240,9 @@ export function CacheManager({ refreshTrigger }: CacheManagerProps) {
|
||||
|
||||
{/* 右边:配置区 (3/5 cols) */}
|
||||
<div className='lg:col-span-3 border-t lg:border-t-0 lg:border-l border-border/40 pt-6 lg:pt-0 lg:pl-6 space-y-4'>
|
||||
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider'>
|
||||
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider'>
|
||||
{t('policyConfig')}
|
||||
</h4>
|
||||
</p>
|
||||
<form onSubmit={handleSaveConfig} className='space-y-4'>
|
||||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
|
||||
<div className='space-y-1.5'>
|
||||
|
||||
@@ -165,7 +165,7 @@ export function SQLConsole({ dbType, onClose }: SQLConsoleProps) {
|
||||
{t('quickTemplates')}
|
||||
</span>
|
||||
<Select onValueChange={handlePresetSQLChange}>
|
||||
<SelectTrigger className='h-7 w-[180px] text-[11px] bg-background'>
|
||||
<SelectTrigger aria-label={t('selectPresetSQL')} className='h-7 w-[180px] text-[11px] bg-background'>
|
||||
<SelectValue placeholder={t('selectPresetSQL')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
||||
@@ -140,7 +140,7 @@ export function TableBrowser({
|
||||
<Skeleton className='h-8 w-48' />
|
||||
) : (
|
||||
<Select value={selectedTable} onValueChange={handleTableChange}>
|
||||
<SelectTrigger className='h-8 w-[200px] text-xs bg-background border-border/40'>
|
||||
<SelectTrigger aria-label={t('selectTable')} className='h-8 w-[200px] text-xs bg-background border-border/40'>
|
||||
<SelectValue placeholder={t('selectTable')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className='max-h-[300px]'>
|
||||
|
||||
@@ -231,6 +231,7 @@ export function AccessAnalytics() {
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
className='size-8'
|
||||
aria-label={t('refresh')}
|
||||
onClick={fetchAnalytics}
|
||||
disabled={loading}
|
||||
>
|
||||
|
||||
@@ -434,6 +434,7 @@ export function EventsTab() {
|
||||
onCheckedChange={() =>
|
||||
toggleEventMutation.mutate(event.id)
|
||||
}
|
||||
aria-label={t('colStatus')}
|
||||
className='scale-75'
|
||||
/>
|
||||
</TableCell>
|
||||
@@ -448,6 +449,7 @@ export function EventsTab() {
|
||||
<Button
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
aria-label={t('configure')}
|
||||
className='h-6 w-6 text-muted-foreground hover:text-foreground'
|
||||
onClick={() => handleEditEventClick(event)}
|
||||
>
|
||||
@@ -466,6 +468,7 @@ export function EventsTab() {
|
||||
<Button
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
aria-label={t('delete')}
|
||||
className='h-6 w-6 text-muted-foreground hover:text-destructive hover:bg-destructive/10'
|
||||
disabled={deleteEventMutation.isPending}
|
||||
onClick={() => setDeleteTarget(event)}
|
||||
|
||||
@@ -311,7 +311,7 @@ export function OpenFlareOpsSettings() {
|
||||
value={fields.geoip_provider}
|
||||
onValueChange={(value) => updateField('geoip_provider', value)}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectTrigger aria-label={t('geo.mode')}>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -443,8 +443,9 @@ export function OpenFlareOpsSettings() {
|
||||
</p>
|
||||
</div>
|
||||
<div className='space-y-1.5'>
|
||||
<Label>{t('discovery.command')}</Label>
|
||||
<Label htmlFor='discovery-command'>{t('discovery.command')}</Label>
|
||||
<Textarea
|
||||
id='discovery-command'
|
||||
readOnly
|
||||
value={discoveryCommand || t('discovery.commandHint')}
|
||||
className='min-h-24 font-mono text-xs'
|
||||
@@ -542,7 +543,7 @@ export function OpenFlareOpsSettings() {
|
||||
updateField('uptime_kuma_monitor_scope', value)
|
||||
}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectTrigger aria-label={t('kuma.scope')}>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -644,8 +645,9 @@ function FieldInput({
|
||||
}) {
|
||||
return (
|
||||
<div className='space-y-1.5'>
|
||||
<Label>{label}</Label>
|
||||
<Label htmlFor={`field-${label}`}>{label}</Label>
|
||||
<Input
|
||||
id={`field-${label}`}
|
||||
type={type}
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
@@ -677,7 +679,7 @@ function ToggleRow({
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<Switch checked={checked} onCheckedChange={onChange} />
|
||||
<Switch checked={checked} onCheckedChange={onChange} aria-label={label} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -378,9 +378,9 @@ export function TaskManager() {
|
||||
<div className='space-y-2'>
|
||||
<div className='flex items-start justify-between'>
|
||||
<div className='space-y-1'>
|
||||
<h3 className='font-semibold text-base tracking-tight'>
|
||||
<p className='font-semibold text-base tracking-tight'>
|
||||
{task.name}
|
||||
</h3>
|
||||
</p>
|
||||
<p className='text-xs text-muted-foreground leading-relaxed line-clamp-2 min-h-[36px]'>
|
||||
{task.description}
|
||||
</p>
|
||||
|
||||
@@ -104,9 +104,9 @@ export function UserDetailSheet({
|
||||
|
||||
<div className='p-6 space-y-6'>
|
||||
<div className='space-y-4'>
|
||||
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
|
||||
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
|
||||
{t('personalInfo')}
|
||||
</h4>
|
||||
</p>
|
||||
<div className='rounded-lg border divide-y bg-background/50'>
|
||||
<div className='flex items-center justify-between gap-4 p-3.5 text-sm'>
|
||||
<span className='flex items-center gap-2 text-[10px] text-muted-foreground'>
|
||||
@@ -167,9 +167,9 @@ export function UserDetailSheet({
|
||||
</div>
|
||||
|
||||
<div className='space-y-4'>
|
||||
<h4 className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
|
||||
<p className='text-xs font-semibold text-muted-foreground uppercase tracking-wider px-1'>
|
||||
{t('systemRecords')}
|
||||
</h4>
|
||||
</p>
|
||||
<div className='rounded-lg border divide-y bg-background/50'>
|
||||
<div className='flex items-center justify-between p-3.5 text-sm'>
|
||||
<span className='text-[10px]'>
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
--card-foreground: oklch(0.141 0.005 285.823);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.141 0.005 285.823);
|
||||
--primary: oklch(58.5% 51% 277.117);
|
||||
/* indigo-600: 亮色下与 primary-foreground(#fafafa) 对比度 ~6.8,满足 WCAG AA;indigo-500 仅 4.27 */
|
||||
--primary: oklch(51.1% 0.262 276.966);
|
||||
--primary-foreground: oklch(98.5% 0% 0);
|
||||
--secondary: oklch(0.967 0.001 286.375);
|
||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
||||
|
||||
@@ -238,7 +238,7 @@ export function UserFileManager() {
|
||||
<Upload className='size-10' />
|
||||
</div>
|
||||
<div className='space-y-1'>
|
||||
<h3 className='font-semibold text-sm'>{t('noFiles')}</h3>
|
||||
<p className='font-semibold text-sm'>{t('noFiles')}</p>
|
||||
<p className='text-xs text-muted-foreground max-w-xs'>
|
||||
{debouncedKeyword ? t('noMatchingFiles') : t('uploadFirstFile')}
|
||||
</p>
|
||||
|
||||
@@ -1237,7 +1237,8 @@
|
||||
"fetchFailed": "Failed to fetch analytics",
|
||||
"requestVolume": "Requests",
|
||||
"requestCount": "Request count",
|
||||
"countTimes": "{count} ({percent}%)"
|
||||
"countTimes": "{count} ({percent}%)",
|
||||
"refresh": "Refresh"
|
||||
},
|
||||
"appLogs": {
|
||||
"loading": "Loading...",
|
||||
@@ -1461,4 +1462,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1237,7 +1237,8 @@
|
||||
"fetchFailed": "获取数据统计失败",
|
||||
"requestVolume": "请求量",
|
||||
"requestCount": "请求次数",
|
||||
"countTimes": "{count} 次 ({percent}%)"
|
||||
"countTimes": "{count} 次 ({percent}%)",
|
||||
"refresh": "刷新"
|
||||
},
|
||||
"appLogs": {
|
||||
"loading": "加载中...",
|
||||
@@ -1461,4 +1462,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user