feat: refactor components to utilize DataGridCard for improved UI consistency
CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 57s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m27s
CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 57s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m27s
Updated various components including AccessApiKeysCard, FirewallClientsGrid, FirewallRulesGrid, ModuleEntriesSection, and DirectoriesComponent to replace traditional card and table structures with the new DataGridCard component. This change enhances the user interface by providing a more consistent layout and improved loading states. Additionally, integrated QueryState for better handling of loading and error scenarios across these components, streamlining the overall user experience.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import { ColumnDef, useReactTable } from '@tanstack/react-table'
|
||||
import { RefreshCw } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { Badge } from '@evobgp/ui/components/badge'
|
||||
|
||||
import { DataGridShell } from '@/components/data-grid-shell'
|
||||
import { LoadingButton } from '@/components/loading-button'
|
||||
import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header'
|
||||
import { createClientDataGridOptions } from '@/lib/data-grid-defaults'
|
||||
import type { ModuleRow } from '@/types/api'
|
||||
|
||||
export function ScheduleModulesGrid({
|
||||
items,
|
||||
refreshing,
|
||||
onRefresh,
|
||||
isLoading = false,
|
||||
}: {
|
||||
items: ModuleRow[]
|
||||
refreshing: Record<string, boolean>
|
||||
onRefresh: (id: string) => void
|
||||
isLoading?: boolean
|
||||
}) {
|
||||
const columns = useMemo<ColumnDef<ModuleRow>[]>(
|
||||
() => [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Модуль" />,
|
||||
cell: ({ row }) => <span className="font-medium">{row.original.name}</span>,
|
||||
meta: { headerTitle: 'Модуль' },
|
||||
},
|
||||
{
|
||||
accessorKey: 'type',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Тип" />,
|
||||
cell: ({ row }) => <Badge variant="outline">{row.original.type}</Badge>,
|
||||
meta: { headerTitle: 'Тип' },
|
||||
},
|
||||
{
|
||||
id: 'schedule',
|
||||
accessorFn: (row) => row.cron_expr ?? String(row.refresh_interval_sec ?? ''),
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Расписание" />,
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-xs text-muted-foreground">
|
||||
{row.original.cron_expr ??
|
||||
(row.original.refresh_interval_sec ? `${row.original.refresh_interval_sec}s` : '—')}
|
||||
</span>
|
||||
),
|
||||
meta: { headerTitle: 'Расписание' },
|
||||
},
|
||||
{
|
||||
id: 'last_refreshed_at',
|
||||
accessorFn: (row) => row.last_refreshed_at ?? '',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Обновлено" />,
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap text-xs text-muted-foreground">
|
||||
{row.original.last_refreshed_at
|
||||
? new Date(row.original.last_refreshed_at).toLocaleString('ru-RU')
|
||||
: '—'}
|
||||
</span>
|
||||
),
|
||||
meta: { headerTitle: 'Обновлено' },
|
||||
},
|
||||
{
|
||||
id: 'enabled',
|
||||
accessorFn: (row) => (row.enabled ? 'on' : 'off'),
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Статус" />,
|
||||
cell: ({ row }) =>
|
||||
row.original.enabled ? (
|
||||
<Badge variant="default">Вкл</Badge>
|
||||
) : (
|
||||
<Badge variant="secondary">Выкл</Badge>
|
||||
),
|
||||
meta: { headerTitle: 'Статус' },
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
enableSorting: false,
|
||||
header: () => null,
|
||||
cell: ({ row }) => (
|
||||
<div className="text-right">
|
||||
<LoadingButton
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
type="button"
|
||||
loading={!!refreshing[row.original.id]}
|
||||
onClick={() => onRefresh(row.original.id)}
|
||||
>
|
||||
<RefreshCw />
|
||||
Обновить
|
||||
</LoadingButton>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
],
|
||||
[onRefresh, refreshing],
|
||||
)
|
||||
|
||||
const table = useReactTable({
|
||||
data: items,
|
||||
columns,
|
||||
...createClientDataGridOptions<ModuleRow>(),
|
||||
getRowId: (row) => row.id,
|
||||
})
|
||||
|
||||
return (
|
||||
<DataGridShell
|
||||
table={table}
|
||||
recordCount={items.length}
|
||||
isLoading={isLoading}
|
||||
emptyMessage="Нет модулей"
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user