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 <cursoragent@cursor.com>
118 lines
3.7 KiB
TypeScript
118 lines
3.7 KiB
TypeScript
import { useMemo, useState } from 'react'
|
|
import { Link, useNavigate } from '@tanstack/react-router'
|
|
import { BoxesIcon, PlusIcon, SearchIcon } from 'lucide-react'
|
|
|
|
import { CategoryBadge } from '@/components/category-badge'
|
|
import { DataGridNameCell } from '@/components/data-grid-cell'
|
|
import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header'
|
|
import type { FilterField, FilterQuery } from '@/components/reui/filters/filters-types'
|
|
import {
|
|
ResourcePage,
|
|
createTextFilterQuery,
|
|
type DataGridColumnDef,
|
|
} from '@/components/reui-kit'
|
|
import { Button } from '@evobgp/ui/components/button'
|
|
import { moduleTypeRu } from '@/lib/ui-labels'
|
|
import type { ModuleRow } from '@/types/api'
|
|
|
|
const MODULE_TABS = [
|
|
{ id: 'all', label: 'Все' },
|
|
{ id: 'enabled', label: 'Вкл' },
|
|
{ id: 'disabled', label: 'Выкл' },
|
|
]
|
|
|
|
const filterFields: FilterField[] = [
|
|
{
|
|
id: 'search',
|
|
label: 'Поиск',
|
|
icon: <SearchIcon className="size-3.5" aria-hidden />,
|
|
type: 'text',
|
|
placeholder: 'Поиск модулей…',
|
|
},
|
|
]
|
|
|
|
function getFilterFieldValue(item: ModuleRow, field: string): unknown {
|
|
if (field === 'search') {
|
|
return `${item.name} ${item.type} ${moduleTypeRu(item.type)}`
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
function tabFilter(item: ModuleRow, tabId: string): boolean {
|
|
if (tabId === 'enabled') return item.enabled !== false
|
|
if (tabId === 'disabled') return item.enabled === false
|
|
return true
|
|
}
|
|
|
|
export function DashboardModulesGrid({
|
|
modules,
|
|
isLoading = false,
|
|
}: {
|
|
modules: ModuleRow[]
|
|
isLoading?: boolean
|
|
}) {
|
|
const navigate = useNavigate()
|
|
const [filterQuery, setFilterQuery] = useState<FilterQuery>(() =>
|
|
createTextFilterQuery('search'),
|
|
)
|
|
|
|
const columns = useMemo<DataGridColumnDef<ModuleRow>[]>(
|
|
() => [
|
|
{
|
|
accessorKey: 'name',
|
|
id: 'name',
|
|
header: ({ column }) => <DataGridColumnHeader column={column} title="Модуль" />,
|
|
cell: ({ row }) => <DataGridNameCell icon={BoxesIcon} title={row.original.name} />,
|
|
minSize: 180,
|
|
meta: { headerTitle: 'Модуль' },
|
|
},
|
|
{
|
|
accessorKey: 'type',
|
|
id: 'type',
|
|
header: ({ column }) => <DataGridColumnHeader column={column} title="Тип" />,
|
|
cell: ({ row }) => <CategoryBadge>{moduleTypeRu(row.original.type)}</CategoryBadge>,
|
|
meta: { headerTitle: 'Тип' },
|
|
},
|
|
{
|
|
accessorKey: 'priority',
|
|
id: 'priority',
|
|
header: ({ column }) => <DataGridColumnHeader column={column} title="Приоритет" />,
|
|
cell: ({ row }) => (
|
|
<span className="font-mono text-sm tabular-nums">{row.original.priority}</span>
|
|
),
|
|
size: 88,
|
|
meta: { headerTitle: 'Приоритет' },
|
|
},
|
|
],
|
|
[],
|
|
)
|
|
|
|
return (
|
|
<ResourcePage
|
|
title="Модули"
|
|
description="Поиск и быстрый переход к настройке"
|
|
tabs={MODULE_TABS}
|
|
tabFilter={tabFilter}
|
|
filterFields={filterFields}
|
|
filterQuery={filterQuery}
|
|
onFilterQueryChange={setFilterQuery}
|
|
onClearFilters={() => setFilterQuery(createTextFilterQuery('search'))}
|
|
getFilterFieldValue={getFilterFieldValue}
|
|
columns={columns}
|
|
data={modules}
|
|
getRowId={(row) => row.id}
|
|
isLoading={isLoading}
|
|
primaryAction={
|
|
<Button variant="outline" size="sm" render={<Link to="/modules" search={{ create: true }} />}>
|
|
<PlusIcon />
|
|
Создать
|
|
</Button>
|
|
}
|
|
onRowClick={(row) =>
|
|
void navigate({ to: '/modules/$moduleId', params: { moduleId: row.id } })
|
|
}
|
|
emptyState={{ title: 'Нет модулей по выбранным фильтрам.' }}
|
|
/>
|
|
)
|
|
}
|