Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0af37d55c4 | ||
|
|
78f2ecc246 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"pid": 52448,
|
"pid": 48400,
|
||||||
"version": "0.9.9",
|
"version": "0.9.9",
|
||||||
"socketPath": "\\\\.\\pipe\\codegraph-97b92efdcc5351da",
|
"socketPath": "\\\\.\\pipe\\codegraph-97b92efdcc5351da",
|
||||||
"startedAt": 1782969267595
|
"startedAt": 1783060842523
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ function DataGridPagination(props: DataGridPaginationProps): React.JSX.Element {
|
|||||||
{mergedProps.rowsPerPageLabel}
|
{mergedProps.rowsPerPageLabel}
|
||||||
</div>
|
</div>
|
||||||
<Select
|
<Select
|
||||||
|
items={mergedProps?.sizes?.map((size: number) => ({
|
||||||
|
value: `${size}`,
|
||||||
|
label: `${size}`,
|
||||||
|
}))}
|
||||||
value={`${pageSize}`}
|
value={`${pageSize}`}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
const newPageSize = Number(value)
|
const newPageSize = Number(value)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { createFileRoute, useSearch } from '@tanstack/react-router'
|
|||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import { AlertTriangle, Clock, Activity, Info, RefreshCw } from 'lucide-react'
|
import { AlertTriangle, Clock, Activity, Info, RefreshCw } from 'lucide-react'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { useState } from 'react'
|
import { useState, useMemo } from 'react'
|
||||||
|
|
||||||
import { Alert, AlertDescription, AlertTitle } from '@evobgp/ui/components/alert'
|
import { Alert, AlertDescription, AlertTitle } from '@evobgp/ui/components/alert'
|
||||||
import { Button } from '@evobgp/ui/components/button'
|
import { Button } from '@evobgp/ui/components/button'
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
SelectContent,
|
SelectContent,
|
||||||
SelectItem,
|
SelectItem,
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
} from '@evobgp/ui/components/select'
|
} from '@evobgp/ui/components/select'
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@evobgp/ui/components/tabs'
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@evobgp/ui/components/tabs'
|
||||||
import {
|
import {
|
||||||
@@ -367,6 +368,14 @@ function DiffTab({ revisions }: { revisions: import('@/types/api').RevisionRow[]
|
|||||||
const [a, setA] = useState('')
|
const [a, setA] = useState('')
|
||||||
const [b, setB] = useState('')
|
const [b, setB] = useState('')
|
||||||
const diffQ = useQuery(operationsDiffQueryOptions(a, b))
|
const diffQ = useQuery(operationsDiffQueryOptions(a, b))
|
||||||
|
const revisionItems = useMemo(
|
||||||
|
() =>
|
||||||
|
revisions.map((r) => ({
|
||||||
|
value: r.id,
|
||||||
|
label: `${r.id.slice(0, 12)}…`,
|
||||||
|
})),
|
||||||
|
[revisions],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
@@ -377,8 +386,10 @@ function DiffTab({ revisions }: { revisions: import('@/types/api').RevisionRow[]
|
|||||||
<div className="flex flex-wrap items-end gap-3">
|
<div className="flex flex-wrap items-end gap-3">
|
||||||
<div className="flex w-full max-w-xs flex-col gap-1">
|
<div className="flex w-full max-w-xs flex-col gap-1">
|
||||||
<span className="text-xs text-muted-foreground">Ревизия A</span>
|
<span className="text-xs text-muted-foreground">Ревизия A</span>
|
||||||
<Select value={a} onValueChange={(v) => v && setA(v)}>
|
<Select items={revisionItems} value={a} onValueChange={(v) => v && setA(v)}>
|
||||||
<SelectTrigger>{a ? a.slice(0, 12) + '…' : 'Выберите'}</SelectTrigger>
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Выберите" />
|
||||||
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{revisions.map((r) => (
|
{revisions.map((r) => (
|
||||||
<SelectItem key={r.id} value={r.id}>
|
<SelectItem key={r.id} value={r.id}>
|
||||||
@@ -390,8 +401,10 @@ function DiffTab({ revisions }: { revisions: import('@/types/api').RevisionRow[]
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full max-w-xs flex-col gap-1">
|
<div className="flex w-full max-w-xs flex-col gap-1">
|
||||||
<span className="text-xs text-muted-foreground">Ревизия B</span>
|
<span className="text-xs text-muted-foreground">Ревизия B</span>
|
||||||
<Select value={b} onValueChange={(v) => v && setB(v)}>
|
<Select items={revisionItems} value={b} onValueChange={(v) => v && setB(v)}>
|
||||||
<SelectTrigger>{b ? b.slice(0, 12) + '…' : 'Выберите'}</SelectTrigger>
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Выберите" />
|
||||||
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{revisions.map((r) => (
|
{revisions.map((r) => (
|
||||||
<SelectItem key={r.id} value={r.id}>
|
<SelectItem key={r.id} value={r.id}>
|
||||||
|
|||||||
@@ -4,7 +4,13 @@ import { useQuery } from '@tanstack/react-query'
|
|||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@evobgp/ui/components/card'
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@evobgp/ui/components/card'
|
||||||
import { Input } from '@evobgp/ui/components/input'
|
import { Input } from '@evobgp/ui/components/input'
|
||||||
import { Label } from '@evobgp/ui/components/label'
|
import { Label } from '@evobgp/ui/components/label'
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@evobgp/ui/components/select'
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '@evobgp/ui/components/select'
|
||||||
|
|
||||||
import { PageHeader } from '@/components/page-header'
|
import { PageHeader } from '@/components/page-header'
|
||||||
import { LoadingButton } from '@/components/loading-button'
|
import { LoadingButton } from '@/components/loading-button'
|
||||||
@@ -19,6 +25,12 @@ export const Route = createFileRoute('/_auth/settings')({
|
|||||||
component: SettingsComponent,
|
component: SettingsComponent,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const THEME_SELECT_ITEMS = [
|
||||||
|
{ value: 'light', label: 'Светлая' },
|
||||||
|
{ value: 'dark', label: 'Тёмная' },
|
||||||
|
{ value: 'system', label: 'Как в системе' },
|
||||||
|
] as const
|
||||||
|
|
||||||
function SettingsComponent() {
|
function SettingsComponent() {
|
||||||
const { data: session } = useQuery(authSessionQueryOptions())
|
const { data: session } = useQuery(authSessionQueryOptions())
|
||||||
const { theme, setTheme } = useTheme()
|
const { theme, setTheme } = useTheme()
|
||||||
@@ -84,8 +96,14 @@ function SettingsComponent() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-2">
|
<CardContent className="flex flex-col gap-2">
|
||||||
<Label htmlFor="theme-select">Тема</Label>
|
<Label htmlFor="theme-select">Тема</Label>
|
||||||
<Select value={theme ?? 'system'} onValueChange={(v) => v && setTheme(v)}>
|
<Select
|
||||||
<SelectTrigger id="theme-select" className="w-full max-w-xs" />
|
items={[...THEME_SELECT_ITEMS]}
|
||||||
|
value={theme ?? 'system'}
|
||||||
|
onValueChange={(v) => v && setTheme(v)}
|
||||||
|
>
|
||||||
|
<SelectTrigger id="theme-select" className="w-full max-w-xs">
|
||||||
|
<SelectValue placeholder="Выберите тему" />
|
||||||
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="light">Светлая</SelectItem>
|
<SelectItem value="light">Светлая</SelectItem>
|
||||||
<SelectItem value="dark">Тёмная</SelectItem>
|
<SelectItem value="dark">Тёмная</SelectItem>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
SelectContent,
|
SelectContent,
|
||||||
SelectItem,
|
SelectItem,
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
} from '@evobgp/ui/components/select'
|
} from '@evobgp/ui/components/select'
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@evobgp/ui/components/tabs'
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@evobgp/ui/components/tabs'
|
||||||
import {
|
import {
|
||||||
@@ -48,6 +49,16 @@ export const Route = createFileRoute('/_auth/tenant-settings')({
|
|||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const RUNTIME_LOGS_ENABLED_ITEMS = [
|
||||||
|
{ value: 'true', label: 'Вкл' },
|
||||||
|
{ value: 'false', label: 'Выкл' },
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const RUNTIME_LOGS_MODE_ITEMS = [
|
||||||
|
{ value: 'truncate', label: 'truncate — обнулить' },
|
||||||
|
{ value: 'delete', label: 'delete — удалить файл' },
|
||||||
|
] as const
|
||||||
|
|
||||||
const BIRD_LABELS: Record<BirdSettingKey, string> = {
|
const BIRD_LABELS: Record<BirdSettingKey, string> = {
|
||||||
bird_router_id: 'Router ID',
|
bird_router_id: 'Router ID',
|
||||||
bird_local_ipv4: 'Локальный IPv4',
|
bird_local_ipv4: 'Локальный IPv4',
|
||||||
@@ -241,6 +252,7 @@ function TenantSettingsComponent() {
|
|||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
<Label>Авто-очистка включена</Label>
|
<Label>Авто-очистка включена</Label>
|
||||||
<Select
|
<Select
|
||||||
|
items={[...RUNTIME_LOGS_ENABLED_ITEMS]}
|
||||||
value={runtimeLogsForm.runtime_logs_auto_enabled ?? 'false'}
|
value={runtimeLogsForm.runtime_logs_auto_enabled ?? 'false'}
|
||||||
onValueChange={(v) =>
|
onValueChange={(v) =>
|
||||||
v &&
|
v &&
|
||||||
@@ -251,7 +263,7 @@ function TenantSettingsComponent() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
{runtimeLogsForm.runtime_logs_auto_enabled === 'true' ? 'Вкл' : 'Выкл'}
|
<SelectValue placeholder="Выберите" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="true">Вкл</SelectItem>
|
<SelectItem value="true">Вкл</SelectItem>
|
||||||
@@ -298,6 +310,7 @@ function TenantSettingsComponent() {
|
|||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
<Label>Режим очистки</Label>
|
<Label>Режим очистки</Label>
|
||||||
<Select
|
<Select
|
||||||
|
items={[...RUNTIME_LOGS_MODE_ITEMS]}
|
||||||
value={runtimeLogsForm.runtime_logs_auto_mode ?? ''}
|
value={runtimeLogsForm.runtime_logs_auto_mode ?? ''}
|
||||||
onValueChange={(v) =>
|
onValueChange={(v) =>
|
||||||
v &&
|
v &&
|
||||||
@@ -308,11 +321,11 @@ function TenantSettingsComponent() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
{runtimeLogsForm.runtime_logs_auto_mode || 'Выберите'}
|
<SelectValue placeholder="Выберите" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="delete">Delete</SelectItem>
|
<SelectItem value="truncate">truncate — обнулить</SelectItem>
|
||||||
<SelectItem value="truncate">Truncate</SelectItem>
|
<SelectItem value="delete">delete — удалить файл</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<p className="font-mono text-xs text-muted-foreground">
|
<p className="font-mono text-xs text-muted-foreground">
|
||||||
|
|||||||
@@ -111,11 +111,15 @@ function SelectLabel({
|
|||||||
function SelectItem({
|
function SelectItem({
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
|
label,
|
||||||
...props
|
...props
|
||||||
}: SelectPrimitive.Item.Props) {
|
}: SelectPrimitive.Item.Props) {
|
||||||
|
const resolvedLabel = label ?? (typeof children === "string" ? children : undefined)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectPrimitive.Item
|
<SelectPrimitive.Item
|
||||||
data-slot="select-item"
|
data-slot="select-item"
|
||||||
|
label={resolvedLabel}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
||||||
className
|
className
|
||||||
|
|||||||
Reference in New Issue
Block a user