diff --git a/apps/web/src/components/data-grid-cells.tsx b/apps/web/src/components/data-grid-cells.tsx index 1c7aa16..1be6b6a 100644 --- a/apps/web/src/components/data-grid-cells.tsx +++ b/apps/web/src/components/data-grid-cells.tsx @@ -48,7 +48,7 @@ export function DataGridNameCell({ }) { return (
- +
diff --git a/apps/web/src/components/list-filters-bar.tsx b/apps/web/src/components/list-filters-bar.tsx index e25f177..844b0f7 100644 --- a/apps/web/src/components/list-filters-bar.tsx +++ b/apps/web/src/components/list-filters-bar.tsx @@ -32,7 +32,7 @@ export function ListFiltersSearch({ spellCheck = false, }: ListFiltersSearchProps) { return ( -
+
+
+ {controls} + {toggles} {search ? : null} - {controls || toggles ? ( -
- {controls} - {toggles} - {onReset ? : null} -
- ) : null} - {hasMeta ? ( -
- {chips?.length ? : null} - {shown != null && total != null ? ( - - ) : resultsSuffix ? ( -
{resultsSuffix}
- ) : null} + {onReset ? : null} + {filtered ? : null} + {chips?.length ? ( +
+
) : null}
diff --git a/apps/web/src/components/reui-kit/data-grid-kit-defaults.test.ts b/apps/web/src/components/reui-kit/data-grid-kit-defaults.test.ts index 4a63e69..9a077ec 100644 --- a/apps/web/src/components/reui-kit/data-grid-kit-defaults.test.ts +++ b/apps/web/src/components/reui-kit/data-grid-kit-defaults.test.ts @@ -5,9 +5,10 @@ import { BLOCKING_MATRIX_GRID } from '../censorcheck/blocking-grid' import { GEO_MATRIX_GRID } from '../ipregion/geo-grid' describe('kitDataGridTableLayout', () => { - it('CRUD defaults: без bg-muted header и width fixed', () => { + it('CRUD defaults: подложка шапки, без зебры, width fixed', () => { const layout = kitDataGridTableLayout() - expect(layout.headerBackground).toBe(false) + expect(layout.headerBackground).toBe(true) + expect(layout.stripped).toBe(false) expect(layout.width).toBe('fixed') expect(layout.headerSticky).toBe(true) expect(layout.columnsPinnable).toBe(false) @@ -20,7 +21,8 @@ describe('kitDataGridTableLayout', () => { }) expect(layout.width).toBe('auto') expect(layout.columnsPinnable).toBe(true) - expect(layout.headerBackground).toBe(false) + expect(layout.headerBackground).toBe(true) + expect(layout.stripped).toBe(false) }) }) diff --git a/apps/web/src/components/reui-kit/frame-data-grid.tsx b/apps/web/src/components/reui-kit/frame-data-grid.tsx index 82986ec..9945d5d 100644 --- a/apps/web/src/components/reui-kit/frame-data-grid.tsx +++ b/apps/web/src/components/reui-kit/frame-data-grid.tsx @@ -105,10 +105,11 @@ export function kitDataGridTableLayout(opts: { } = {}) { return { dense: opts.dense ?? true, - stripped: true, + // MikrotikManager v2 / макет `gh` + `rowv`: подложка у шапки, строки без зебры, разделитель. + stripped: false, rowBorder: true, headerSticky: true, - headerBackground: false, + headerBackground: true, headerBorder: true, width: opts.width ?? ('fixed' as const), columnsVisibility: opts.columnsVisibility ?? false, @@ -146,6 +147,8 @@ export interface FrameDataGridProps { title?: ReactNode description?: ReactNode actions?: ReactNode + /** Поиск / фильтры страницы — в шапке рамки рядом с заголовком (раскладка MikrotikManager v2). */ + toolbar?: ReactNode columns: DataGridColumnDef[] data: TData[] /** Ключ строки — функция, возвращающая уникальный id. */ @@ -199,25 +202,29 @@ export interface FrameDataGridProps { columnPinControls?: boolean } -function DataGridSectionHeader({ +/** Шапка рамки: заголовок слева, справа тулбар (фильтры, поиск) и действия — переносятся строкой ниже на узком экране. */ +export function DataGridSectionHeader({ title, description, actions, + toolbar, }: { title?: ReactNode description?: ReactNode actions?: ReactNode + toolbar?: ReactNode }) { - if (!title && !description && !actions) return null + if (!title && !description && !actions && !toolbar) return null return ( - -
+ +
{title ? {title} : null} {description ? ( {description} ) : null}
+ {toolbar ?
{toolbar}
: null} {actions ? (
{actions}
) : null} @@ -315,6 +322,7 @@ export function FrameDataGrid({ title, description, actions, + toolbar, columns, data, rowId, @@ -480,13 +488,13 @@ export function FrameDataGrid({ columnVisibilityAction ) - const hasHeader = Boolean(title || description || actions || showColumnVisibilityTrigger) + const hasHeader = Boolean(title || description || actions || toolbar || showColumnVisibilityTrigger) if (data.length === 0) { return ( {hasHeader ? ( - + ) : null} @@ -516,7 +524,7 @@ export function FrameDataGrid({ return ( {hasHeader ? ( - + ) : null} {gridBody} diff --git a/apps/web/src/components/reui-kit/resource-page.tsx b/apps/web/src/components/reui-kit/resource-page.tsx index c8ea051..7bb86bc 100644 --- a/apps/web/src/components/reui-kit/resource-page.tsx +++ b/apps/web/src/components/reui-kit/resource-page.tsx @@ -210,13 +210,11 @@ function ResourcePageSimple({ return (
- {toolbarExtra ? ( -
{toolbarExtra}
- ) : null} ({ })} > - {!hideHeader ? ( - -
+ {/* Раскладка MikrotikManager v2: заголовок, затем фильтры/поиск/сброс и действия в одной шапке. */} + + {!hideHeader ? ( +
{title} {description ? ( - - {description} - + {description} ) : null}
- {headerActions ? ( -
- {headerActions} -
- ) : null} -
- ) : null} + ) : ( +
+ )} + {showFilters ? ( + +