From 3d3c45e4d2a76c992f7049a372e0fa45923f4cb1 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 13 Sep 2026 14:46:17 +0700 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D1=83=20?= =?UTF-8?q?=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=20=D0=B8=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D1=82=D1=80=D0=BE=D0=B2=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(main)/servers/page.tsx | 16 +-- components/data-grids/server-filters.tsx | 14 +++ components/data-grids/servers-data-grid.tsx | 15 ++- .../shared/data-grid-sort-header.tsx | 8 +- components/data-page-toolbar.tsx | 6 +- components/reui/cascader/cascader-async.tsx | 4 +- components/reui/cascader/cascader-virtual.tsx | 7 +- components/reui/cascader/cascader.tsx | 55 ++++++----- .../reui/data-grid/data-grid-scroll-area.tsx | 6 +- .../data-grid/data-grid-table-dnd-rows.tsx | 14 +-- .../reui/data-grid/data-grid-table-dnd.tsx | 3 +- .../data-grid/data-grid-table-virtual.tsx | 18 ++-- components/reui/data-grid/data-grid-table.tsx | 20 ++-- components/reui/data-grid/data-grid.tsx | 98 ++++--------------- components/reui/filters/filters-advanced.tsx | 50 +++------- components/reui/filters/filters-chip.tsx | 17 ++-- docs/reui-migration-lint.md | 59 ++--------- docs/ux-ui-progress.md | 38 ++++++- lib/data-filters/apply-filter-query.test.ts | 39 ++++++++ lib/data-filters/apply-filter-query.ts | 42 ++++++++ lib/data-filters/filter-labels-ru.ts | 43 ++++++++ lib/data-filters/migrate-filter-query.ts | 15 +++ lib/data-filters/server-filter-fields.ts | 16 +-- tests/e2e/servers.spec.ts | 45 ++++++++- 24 files changed, 385 insertions(+), 263 deletions(-) create mode 100644 components/data-grids/server-filters.tsx create mode 100644 lib/data-filters/apply-filter-query.test.ts create mode 100644 lib/data-filters/apply-filter-query.ts create mode 100644 lib/data-filters/filter-labels-ru.ts create mode 100644 lib/data-filters/migrate-filter-query.ts diff --git a/app/(main)/servers/page.tsx b/app/(main)/servers/page.tsx index 85b155d3..45e3c89b 100644 --- a/app/(main)/servers/page.tsx +++ b/app/(main)/servers/page.tsx @@ -9,9 +9,10 @@ import { PageHeader } from "@/components/page-header" import { FormField, FormToggle, SectionTitle, SegmentedControl } from "@/components/form-kit" import { DataPageToolbar } from "@/components/data-page-toolbar" import { ServersDataGrid } from "@/components/data-grids/servers-data-grid" -import type { Filter } from "@/components/reui/filters" -import { applyReuiFilters } from "@/lib/data-filters/apply-reui-filters" -import { SERVER_FILTER_ACCESSORS, SERVER_FILTER_FIELDS } from "@/lib/data-filters/server-filter-fields" +import { createFilterQuery } from "@/components/reui/filters/filters-query" +import { ServerFilters } from "@/components/data-grids/server-filters" +import { applyFilterQuery } from "@/lib/data-filters/apply-filter-query" +import { SERVER_FILTER_ACCESSORS } from "@/lib/data-filters/server-filter-fields" import { servers as initialServers } from "@/lib/data" import type { ServerType, Server, WanUplink } from "@/lib/data" import type { ServerCreate, ServerUpdate } from "@mmapp/contracts/servers" @@ -225,7 +226,7 @@ export default function ServersPage() { const [_backendOk, setBackendOk] = useState(false) const [search, setSearch] = useState("") const [typeFilter, setTypeFilter] = useState("all") - const [advancedFilters, setAdvancedFilters] = useState([]) + const [advancedFilters, setAdvancedFilters] = useState(() => createFilterQuery()) const [open, setOpen] = useState(false) const [sheetMode, setSheetMode] = useState("add") const [editingId, setEditingId] = useState(null) @@ -556,7 +557,7 @@ export default function ServersPage() { const q = search.toLowerCase() return sv.name.toLowerCase().includes(q) || sv.host.includes(q) || sv.site.toLowerCase().includes(q) }) - return applyReuiFilters(base, advancedFilters, SERVER_FILTER_ACCESSORS) + return applyFilterQuery(base, advancedFilters, SERVER_FILTER_ACCESSORS) }, [serverList, search, typeFilter, advancedFilters]) const counts = useMemo(() => ({ @@ -654,9 +655,7 @@ export default function ServersPage() { count: tab.value === "all" ? counts.all : counts[tab.value as ServerType], })), }} - filters={advancedFilters} - onFiltersChange={setAdvancedFilters} - filterFields={SERVER_FILTER_FIELDS} + filterControl={} search={search} onSearchChange={setSearch} searchPlaceholder="Поиск по имени, хосту…" @@ -664,6 +663,7 @@ export default function ServersPage() { /> 0} isLive={isLive} pollingIds={pollingIds} busy={controlsBusy} diff --git a/components/data-grids/server-filters.tsx b/components/data-grids/server-filters.tsx new file mode 100644 index 00000000..90f7d37f --- /dev/null +++ b/components/data-grids/server-filters.tsx @@ -0,0 +1,14 @@ +"use client" + +import { Filters } from "@/components/reui/filters/filters" +import type { FilterQuery } from "@/components/reui/filters/filters-types" +import { SERVER_FILTER_FIELDS } from "@/lib/data-filters/server-filter-fields" +import { FILTER_LABELS_RU, FILTER_OPERATOR_LABELS_RU } from "@/lib/data-filters/filter-labels-ru" + +export function ServerFilters({ query, onQueryChange }: { + query: FilterQuery + onQueryChange: (query: FilterQuery) => void +}) { + return +} diff --git a/components/data-grids/servers-data-grid.tsx b/components/data-grids/servers-data-grid.tsx index f358531a..28be4882 100644 --- a/components/data-grids/servers-data-grid.tsx +++ b/components/data-grids/servers-data-grid.tsx @@ -163,6 +163,7 @@ function ServerRowActions({ } interface ServersDataGridProps { + hasUnfilteredRows?: boolean busy?: boolean servers: Server[] isLive: boolean @@ -174,6 +175,7 @@ interface ServersDataGridProps { } function ServersDataGrid({ + hasUnfilteredRows = false, busy = false, servers, isLive, @@ -196,9 +198,14 @@ function ServersDataGrid({ const expanded = row.getIsExpanded() return (
+

{s.name}

{s.host}

@@ -374,8 +381,8 @@ function ServersDataGrid({ return ( } - title="Нет серверов" - description="Добавьте первый MikroTik-сервер для мониторинга" + title={hasUnfilteredRows ? "Нет совпадений" : "Нет серверов"} + description={hasUnfilteredRows ? "Измените поиск или сбросьте фильтры" : "Добавьте первый MikroTik-сервер для мониторинга"} className="border-0 py-12" /> ) diff --git a/components/data-grids/shared/data-grid-sort-header.tsx b/components/data-grids/shared/data-grid-sort-header.tsx index 06a3254e..f7fe2c28 100644 --- a/components/data-grids/shared/data-grid-sort-header.tsx +++ b/components/data-grids/shared/data-grid-sort-header.tsx @@ -32,18 +32,18 @@ function DataGridSortHeader({ type="button" className={cn( "inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground", - "hover:text-foreground transition-colors rounded-md -ml-1 px-1 py-0.5", + "hover:text-foreground transition-colors rounded-md -ml-1 px-1 py-0.5 focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2", className, )} onClick={column.getToggleSortingHandler()} > {title} {sorted === "asc" ? ( - +