feat(web): upgrade lists to ReUI Table v9 and EventCalendar
quality / commitlint (push) Skipped
quality / changes (push) Successful in 9s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 39s
quality / web (push) Successful in 1m29s
quality / go (push) Successful in 1m3s
quality / bird2 (push) Successful in 15s
CD / quality (push) Successful in 3m43s
CD / publish (push) Failing after 8m29s

Единый kitDataGridTableLayout и ResourcePage/FrameDataGrid на всех списках.
Календарь задач переведён на EventCalendar, lookup — на cascader, у операций появился вид доски.
Удалены settings-7 и самописные DataGridSection/toolbar.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-23 01:38:56 +07:00
co-authored by Cursor
parent 927e27640a
commit d56405af7b
157 changed files with 39067 additions and 6110 deletions
@@ -1,36 +1,51 @@
import { ColumnDef } from '@tanstack/react-table'
import { useMemo } from 'react'
import { useMemo, useState, type ReactNode } from 'react'
import { Globe } from 'lucide-react'
import { CategoryBadge } from '@/components/category-badge'
import { DataGridPrimaryCell } from '@/components/data-grid-cell'
import { DataGridSection } from '@/components/data-grid-shell'
import { DataGridMonoCell, DataGridNameCell } from '@/components/data-grid-cell'
import { DirectoriesRowActions } from '@/components/directories/directories-row-actions'
import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header'
import { useClientDataGrid } from '@/hooks/use-client-data-grid'
import type { FilterField, FilterQuery } from '@/components/reui/filters/filters-types'
import {
ResourcePage,
createSearchFilterField,
createTextFilterQuery,
type DataGridColumnDef,
} from '@/components/reui-kit'
import type { DohProfile } from '@/types/api'
const filterFields: FilterField[] = [
createSearchFilterField('search', 'Поиск', 'Поиск DoH профилей…'),
]
export function DirectoriesDohGrid({
items,
isLoading = false,
canWrite = false,
onEdit,
actions,
}: {
items: DohProfile[]
isLoading?: boolean
canWrite?: boolean
onEdit?: (row: DohProfile) => void
actions?: ReactNode
}) {
const columns = useMemo<ColumnDef<DohProfile>[]>(() => {
const cols: ColumnDef<DohProfile>[] = [
const [filterQuery, setFilterQuery] = useState<FilterQuery>(() =>
createTextFilterQuery('search'),
)
const columns = useMemo<DataGridColumnDef<DohProfile>[]>(() => {
const cols: DataGridColumnDef<DohProfile>[] = [
{
id: 'name',
accessorFn: (row) => row.name ?? row.url,
header: ({ column }) => <DataGridColumnHeader column={column} title="Название" />,
cell: ({ row }) => (
<DataGridPrimaryCell
<DataGridNameCell
icon={Globe}
title={row.original.name ?? row.original.url}
subtitle={row.original.name ? row.original.url : undefined}
accent="primary"
/>
),
meta: { headerTitle: 'Название' },
@@ -38,7 +53,7 @@ export function DirectoriesDohGrid({
{
accessorKey: 'url',
header: ({ column }) => <DataGridColumnHeader column={column} title="URL" />,
cell: ({ row }) => <DataGridPrimaryCell title={row.original.url} accent="mono" />,
cell: ({ row }) => <DataGridMonoCell>{row.original.url}</DataGridMonoCell>,
meta: { headerTitle: 'URL' },
},
{
@@ -56,9 +71,7 @@ export function DirectoriesDohGrid({
enableSorting: false,
enableHiding: false,
header: () => <span className="sr-only">Действия</span>,
cell: ({ row }) => (
<DirectoriesRowActions onEdit={() => onEdit(row.original)} />
),
cell: ({ row }) => <DirectoriesRowActions onEdit={() => onEdit(row.original)} />,
meta: { headerTitle: 'Действия' },
})
}
@@ -66,22 +79,22 @@ export function DirectoriesDohGrid({
return cols
}, [canWrite, onEdit])
const { table, globalFilter, setGlobalFilter, filteredCount } = useClientDataGrid({
data: items,
columns,
getSearchText: (row) => `${row.name ?? ''} ${row.url}`,
getRowId: (row) => row.id,
})
return (
<DataGridSection
table={table}
recordCount={filteredCount}
<ResourcePage
title="DoH профили"
description="Резолверы DNS-over-HTTPS для доменных модулей"
filterFields={filterFields}
filterQuery={filterQuery}
onFilterQueryChange={setFilterQuery}
onClearFilters={() => setFilterQuery(createTextFilterQuery('search'))}
getFilterFieldValue={(row) => `${row.name ?? ''} ${row.url}`}
columns={columns}
data={items}
getRowId={(row) => row.id}
isLoading={isLoading}
emptyMessage="Нет DoH профилей"
searchValue={globalFilter}
onSearchChange={setGlobalFilter}
searchPlaceholder="Поиск DoH профилей…"
primaryAction={actions}
pinLastColumn={Boolean(canWrite && onEdit)}
emptyState={{ title: 'Нет DoH профилей', action: actions }}
/>
)
}