feat(web): миграция таблиц на @reui/data-grid (TanStack Table + virtualization + pinning)
- Установлен @reui/data-grid через shadcn CLI: зависимости @tanstack/react-table, @tanstack/react-virtual, @dnd-kit/* добавлены в apps/web - Поправлены type-only импорты во всех файлах data-grid (verbatimModuleSyntax), убран unused параметр table в DataGridTableVirtualBody - Создана shared-обёртка apps/web/src/components/data-grid-card.tsx (замена DataTableCard) с типизированными ColumnDef<TData>, сортировкой, пагинацией (>25 строк), column pinning, optional virtualization (DataGridScrollArea + DataGridTableVirtual), footer-контентом и хелпером columnDefFromDataTable - Мигрированы все 7 страниц: vps, dashboard, payments, balance, accounts, tariffs, providers — DataTableCard/TableCard+Table → DataGridCard - Virtualization включена для VPS и payments при >200 строк (height 560) - Column pinning последней колонки (actions) — vps, payments, balance, accounts, providers - Footer rows с итогами: balance (приходы/списания/итого), payments (по валютам) - build + tsc --noEmit без ошибок Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Select as SelectPrimitive } from "@base-ui/react/select"
|
||||
|
||||
@@ -59,9 +61,9 @@ function SelectContent({
|
||||
children,
|
||||
side = "bottom",
|
||||
sideOffset = 4,
|
||||
align = "start",
|
||||
align = "center",
|
||||
alignOffset = 0,
|
||||
alignItemWithTrigger = false,
|
||||
alignItemWithTrigger = true,
|
||||
...props
|
||||
}: SelectPrimitive.Popup.Props &
|
||||
Pick<
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { cn } from "@cfdm/ui/lib/utils"
|
||||
import { Loader2Icon } from "lucide-react"
|
||||
|
||||
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
|
||||
return (
|
||||
<Loader2Icon data-slot="spinner" role="status" aria-label="Loading" className={cn("size-4 animate-spin", className)} {...props} />
|
||||
)
|
||||
}
|
||||
|
||||
export { Spinner }
|
||||
@@ -39,6 +39,15 @@
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
--destructive-foreground: var(--color-red-800);
|
||||
--success: var(--color-emerald-500);
|
||||
--success-foreground: var(--color-emerald-900);
|
||||
--info: var(--color-violet-500);
|
||||
--info-foreground: var(--color-violet-900);
|
||||
--warning: var(--color-yellow-500);
|
||||
--warning-foreground: var(--color-yellow-900);
|
||||
--invert: var(--color-zinc-900);
|
||||
--invert-foreground: var(--color-zinc-50);
|
||||
}
|
||||
|
||||
.dark {
|
||||
@@ -73,6 +82,15 @@
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
--destructive-foreground: var(--color-red-600);
|
||||
--success: var(--color-emerald-500);
|
||||
--success-foreground: var(--color-emerald-600);
|
||||
--info: var(--color-violet-500);
|
||||
--info-foreground: var(--color-violet-600);
|
||||
--warning: var(--color-yellow-500);
|
||||
--warning-foreground: var(--color-yellow-600);
|
||||
--invert: var(--color-zinc-700);
|
||||
--invert-foreground: var(--color-zinc-50);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
@@ -111,6 +129,15 @@
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--color-invert-foreground: var(--invert-foreground);
|
||||
--color-invert: var(--invert);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
--color-warning: var(--warning);
|
||||
--color-info-foreground: var(--info-foreground);
|
||||
--color-info: var(--info);
|
||||
--color-success-foreground: var(--success-foreground);
|
||||
--color-success: var(--success);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
|
||||
Reference in New Issue
Block a user