Enhanced various settings components by adding 'min-w-0' class for better overflow handling and adjusting flex properties for improved alignment. Updated card and grid structures to ensure a cohesive user experience across the settings interface. Refined descriptions and layout in several settings tabs for better clarity and usability.
118 lines
4.4 KiB
TypeScript
118 lines
4.4 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
||
import { MonitorIcon } from 'lucide-react'
|
||
|
||
import { SettingRow } from '@/components/settings/setting-row'
|
||
import { SettingsCard } from '@/components/settings/settings-card'
|
||
import { SettingsFieldGroup } from '@/components/settings/settings-field-group'
|
||
import { Badge } from '@/components/reui/badge'
|
||
import { QueryState } from '@/components/query-state'
|
||
import { TOKEN_STORAGE_KEY } from '@/lib/api-client'
|
||
import { authSessionQueryOptions } from '@/queries/auth'
|
||
import {
|
||
Item,
|
||
ItemContent,
|
||
ItemDescription,
|
||
ItemGroup,
|
||
ItemMedia,
|
||
ItemTitle,
|
||
} from '@evobgp/ui/components/item'
|
||
|
||
const ROLE_LABELS: Record<string, string> = {
|
||
viewer: 'Просмотр',
|
||
editor: 'Редактор',
|
||
operator: 'Оператор',
|
||
node: 'Нода',
|
||
}
|
||
|
||
export function SessionSettingsTab() {
|
||
const hasStoredToken = Boolean(
|
||
typeof window !== 'undefined' && window.localStorage.getItem(TOKEN_STORAGE_KEY)?.trim(),
|
||
)
|
||
|
||
const sessionQ = useQuery({
|
||
...authSessionQueryOptions(),
|
||
enabled: hasStoredToken,
|
||
})
|
||
|
||
return (
|
||
<div className="flex flex-col gap-6">
|
||
<SettingsCard title="Текущая сессия" description="Проверка токена через GET /v1/auth/session">
|
||
<QueryState
|
||
data={sessionQ.data}
|
||
isLoading={sessionQ.isLoading && hasStoredToken}
|
||
isError={sessionQ.isError}
|
||
error={sessionQ.error}
|
||
empty={!hasStoredToken}
|
||
emptyTitle="Токен не задан"
|
||
emptyDescription="Сохраните API-токен во вкладке «Подключение»."
|
||
skeleton={<div className="h-24 px-5 py-4" />}
|
||
onRetry={() => sessionQ.refetch()}
|
||
>
|
||
{(session) => (
|
||
<ItemGroup className="gap-0">
|
||
<Item className="min-h-0 items-center gap-4 px-5 py-3.5">
|
||
<ItemMedia className="self-center!">
|
||
<Item className="bg-muted/60 border-background flex size-8 shrink-0 items-center justify-center border-2 p-0 shadow-[0_1px_3px_0_rgba(0,0,0,0.14)] [&_svg]:size-4 [&_svg]:opacity-60">
|
||
<MonitorIcon aria-hidden="true" />
|
||
</Item>
|
||
</ItemMedia>
|
||
|
||
<ItemContent className="min-w-0 justify-center gap-0.5 self-center">
|
||
<ItemTitle className="flex min-w-0 flex-wrap items-center gap-2 leading-5">
|
||
Этот браузер
|
||
<Badge variant="success-light" size="xs">
|
||
Активна
|
||
</Badge>
|
||
</ItemTitle>
|
||
<ItemDescription className="leading-5">
|
||
Tenant:{' '}
|
||
<code className="text-foreground font-mono text-xs break-all">
|
||
{session.tenant_id}
|
||
</code>
|
||
</ItemDescription>
|
||
</ItemContent>
|
||
</Item>
|
||
</ItemGroup>
|
||
)}
|
||
</QueryState>
|
||
</SettingsCard>
|
||
|
||
<SettingsCard title="Роль и доступ" description="Права текущего API-ключа">
|
||
<SettingsFieldGroup
|
||
legend="Роль"
|
||
description="Уровень доступа, определённый API-ключом."
|
||
>
|
||
<SettingRow
|
||
title="Роль"
|
||
description="Определяет доступ к операциям control plane и CRUD."
|
||
titleAddon={
|
||
sessionQ.data ? (
|
||
<Badge variant="info-light" size="sm">
|
||
{ROLE_LABELS[sessionQ.data.role] ?? sessionQ.data.role}
|
||
</Badge>
|
||
) : (
|
||
<Badge variant="outline" size="sm">
|
||
неизвестно
|
||
</Badge>
|
||
)
|
||
}
|
||
stacked
|
||
last
|
||
>
|
||
{sessionQ.data ? (
|
||
<p className="text-muted-foreground text-sm break-words">
|
||
Ключ с ролью <strong>{sessionQ.data.role}</strong> в tenant{' '}
|
||
<code className="font-mono text-xs break-all">{sessionQ.data.tenant_id}</code>.
|
||
</p>
|
||
) : (
|
||
<p className="text-muted-foreground text-sm">
|
||
Сохраните токен и дождитесь проверки сессии.
|
||
</p>
|
||
)}
|
||
</SettingRow>
|
||
</SettingsFieldGroup>
|
||
</SettingsCard>
|
||
</div>
|
||
)
|
||
}
|