fix(ui): ограничить каталог бэкапов и вернуть фокус действий

This commit is contained in:
Denozordec committed 2026-10-04 05:01:29 +07:00
1 parent 5d9a6f3757
commit 611e542ea7
11 files changed
+123 -35

No files matched your search

+25 -20
View File
@@ -1,8 +1,8 @@
"use client"
import { dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid"
import { DataGridContainer, DataGridScrollArea, DataGridTable, dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid"
import { useMemo, type ReactNode } from "react"
import { useEffect, useMemo, type ReactNode } from "react"
import {
type ColumnDef,
useTable,
@@ -10,9 +10,9 @@ import {
import type { Backup } from "@/lib/data"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/reui/badge"
import { IconTile } from "@/components/reui/icon-tile"
import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell"
import {
DEFAULT_DATA_GRID_LAYOUT,
DATA_GRID_CELL_PAD,
DATA_GRID_CELL_PAD_FIRST,
DATA_GRID_CELL_PAD_LAST,
@@ -20,7 +20,6 @@ import {
import { DataGridSortHeader } from "@/components/data-grids/shared/data-grid-sort-header"
import { EmptyState } from "@/components/empty-state"
import {
CloudIcon,
DownloadIcon,
HardDriveIcon,
RefreshCwIcon,
@@ -63,20 +62,12 @@ function BackupsDataGrid({
{
id: "filename",
accessorKey: "filename",
size: 280,
size: 110,
header: ({ column }) => <DataGridSortHeader column={column} title="Файл" />,
cell: ({ row }) => {
const b = row.original
const inS3 = b.storage === "s3" || b.storage === "both"
return (
<div className="flex items-center gap-3 min-w-0">
<IconTile
variant="elevated"
className={inS3 ? "size-10.5 shrink-0 text-info" : "size-10.5 shrink-0 text-muted-foreground"}
aria-hidden="true"
>
{inS3 ? <CloudIcon /> : <HardDriveIcon />}
</IconTile>
<div className="min-w-0">
<span title={b.filename} className="font-mono text-xs font-medium block break-all">{b.filename}</span>
{b.uploadError ? (
@@ -190,12 +181,12 @@ function BackupsDataGrid({
cell: ({ row }) => {
const b = row.original
return (
<div className="flex items-center gap-1 justify-end opacity-0 transition-opacity group-hover/row:opacity-100 focus-within:opacity-100">
<div className="flex items-center gap-1 justify-end sm:opacity-0 transition-opacity group-hover/row:opacity-100 focus-within:opacity-100">
<Button
type="button"
variant="ghost"
size="icon"
className="size-7"
className="size-11 min-w-[44px] min-h-[44px] sm:size-7 sm:min-w-0 sm:min-h-0"
title="Скачать"
aria-label={`Скачать ${b.filename}`}
disabled={!canDownload}
@@ -207,7 +198,7 @@ function BackupsDataGrid({
type="button"
variant="ghost"
size="icon"
className="size-7"
className="size-11 min-w-[44px] min-h-[44px] sm:size-7 sm:min-w-0 sm:min-h-0"
title="Восстановить"
aria-label={`Восстановить ${b.filename}`}
disabled={!canWrite || !canRestore || !b.serverId}
@@ -219,7 +210,7 @@ function BackupsDataGrid({
type="button"
variant="ghost"
size="icon"
className="size-7 text-destructive hover:text-destructive"
className="size-11 min-w-[44px] min-h-[44px] sm:size-7 sm:min-w-0 sm:min-h-0 text-destructive hover:text-destructive"
title="Удалить"
aria-label={`Удалить ${b.filename}`}
disabled={!canWrite}
@@ -231,7 +222,7 @@ function BackupsDataGrid({
)
},
enableSorting: false,
size: 120,
size: 176,
meta: {
headerClassName: DATA_GRID_CELL_PAD_LAST,
cellClassName: DATA_GRID_CELL_PAD_LAST,
@@ -243,12 +234,20 @@ function BackupsDataGrid({
const table = useTable({
features: dataGridFeatures,
manualPagination: true,
manualPagination: false,
autoResetPageIndex: false,
initialState: { pagination: { pageIndex: 0, pageSize: 50 }, columnPinning: { start: ["filename"], end: [] } },
data: backups,
columns,
getRowId: (row) => row.id,
})
const { pageIndex, pageSize } = table.state.pagination
useEffect(() => {
const lastPage = Math.max(0, Math.ceil(backups.length / pageSize) - 1)
if (pageIndex > lastPage) table.setPageIndex(lastPage)
}, [backups.length, pageSize, pageIndex, table])
if (backups.length === 0) {
return (
<EmptyState
@@ -261,7 +260,13 @@ function BackupsDataGrid({
)
}
return <DataGridShell table={table} recordCount={backups.length} />
return <DataGridShell table={table} recordCount={backups.length}
pagination={backups.length > 50 || pageSize !== 50}
tableLayout={{ ...DEFAULT_DATA_GRID_LAYOUT, columnsPinnable: true }}>
<DataGridContainer border={false} className="w-full rounded-none border-0">
<DataGridScrollArea orientation="horizontal"><DataGridTable /></DataGridScrollArea>
</DataGridContainer>
</DataGridShell>
}
export { BackupsDataGrid, type BackupsDataGridProps }