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
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:
@@ -1,33 +1,56 @@
|
||||
import { ColumnDef } from '@tanstack/react-table'
|
||||
import { RefreshCw } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Boxes, RefreshCw, SearchIcon } from 'lucide-react'
|
||||
|
||||
import { CategoryBadge, ModeBadge } from '@/components/category-badge'
|
||||
import { DataGridMutedCell, DataGridPrimaryCell } from '@/components/data-grid-cell'
|
||||
import { DataGridSection } from '@/components/data-grid-shell'
|
||||
import { DataGridMonoCell, DataGridMutedCell, DataGridNameCell } from '@/components/data-grid-cell'
|
||||
import { LoadingButton } from '@/components/loading-button'
|
||||
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,
|
||||
createTextFilterQuery,
|
||||
type DataGridColumnDef,
|
||||
} from '@/components/reui-kit'
|
||||
import { moduleTypeRu } from '@/lib/ui-labels'
|
||||
import type { ModuleRow } from '@/types/api'
|
||||
|
||||
const filterFields: FilterField[] = [
|
||||
{
|
||||
id: 'search',
|
||||
label: 'Поиск',
|
||||
icon: <SearchIcon className="size-3.5" aria-hidden />,
|
||||
type: 'text',
|
||||
placeholder: 'Поиск модулей…',
|
||||
},
|
||||
]
|
||||
|
||||
export function ScheduleModulesGrid({
|
||||
items,
|
||||
refreshing,
|
||||
onRefresh,
|
||||
isLoading = false,
|
||||
isError = false,
|
||||
error = null,
|
||||
onRetry,
|
||||
}: {
|
||||
items: ModuleRow[]
|
||||
refreshing: Record<string, boolean>
|
||||
onRefresh: (id: string) => void
|
||||
isLoading?: boolean
|
||||
isError?: boolean
|
||||
error?: Error | null
|
||||
onRetry?: () => void
|
||||
}) {
|
||||
const columns = useMemo<ColumnDef<ModuleRow>[]>(
|
||||
const [filterQuery, setFilterQuery] = useState<FilterQuery>(() =>
|
||||
createTextFilterQuery('search'),
|
||||
)
|
||||
|
||||
const columns = useMemo<DataGridColumnDef<ModuleRow>[]>(
|
||||
() => [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Модуль" />,
|
||||
cell: ({ row }) => <DataGridPrimaryCell title={row.original.name} accent="primary" />,
|
||||
cell: ({ row }) => <DataGridNameCell icon={Boxes} title={row.original.name} />,
|
||||
meta: { headerTitle: 'Модуль' },
|
||||
},
|
||||
{
|
||||
@@ -41,10 +64,10 @@ export function ScheduleModulesGrid({
|
||||
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">
|
||||
<DataGridMonoCell className="text-xs text-muted-foreground">
|
||||
{row.original.cron_expr ??
|
||||
(row.original.refresh_interval_sec ? `${row.original.refresh_interval_sec} с` : '—')}
|
||||
</span>
|
||||
</DataGridMonoCell>
|
||||
),
|
||||
meta: { headerTitle: 'Расписание' },
|
||||
},
|
||||
@@ -93,22 +116,27 @@ export function ScheduleModulesGrid({
|
||||
[onRefresh, refreshing],
|
||||
)
|
||||
|
||||
const { table, globalFilter, setGlobalFilter, filteredCount } = useClientDataGrid({
|
||||
data: items,
|
||||
columns,
|
||||
getSearchText: (row) => `${row.name} ${row.type} ${row.enabled ? 'вкл' : 'выкл'}`,
|
||||
getRowId: (row) => row.id,
|
||||
})
|
||||
|
||||
return (
|
||||
<DataGridSection
|
||||
table={table}
|
||||
recordCount={filteredCount}
|
||||
<ResourcePage
|
||||
title="Модули"
|
||||
description="Расписание обновления и ручной запуск"
|
||||
filterFields={filterFields}
|
||||
filterQuery={filterQuery}
|
||||
onFilterQueryChange={setFilterQuery}
|
||||
onClearFilters={() => setFilterQuery(createTextFilterQuery('search'))}
|
||||
getFilterFieldValue={(item, field) => {
|
||||
if (field !== 'search') return undefined
|
||||
return `${item.name} ${item.type} ${item.enabled ? 'вкл' : 'выкл'}`
|
||||
}}
|
||||
columns={columns}
|
||||
data={items}
|
||||
getRowId={(row) => row.id}
|
||||
isLoading={isLoading}
|
||||
emptyMessage="Нет модулей"
|
||||
searchValue={globalFilter}
|
||||
onSearchChange={setGlobalFilter}
|
||||
searchPlaceholder="Поиск модулей…"
|
||||
isError={isError}
|
||||
error={error}
|
||||
onRetry={onRetry}
|
||||
pinLastColumn
|
||||
emptyState={{ title: 'Нет модулей' }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user