fix(ui): перенести фильтры BGP и бэкапов на FilterQuery

This commit is contained in:
Denozordec committed 2026-09-14 22:09:48 +07:00
1 parent a475b5c6df
commit fca42aaa81
11 files changed
+103 -34

No files matched your search

@@ -30,6 +30,12 @@ test("negative selection and empty values stay distinct", () => {
assert.deepEqual(applyFilterQuery(rows, createFilterQuery([rule("country", "empty")]), accessors), [])
})
test("text prefix and suffix use case-insensitive matching and support negation", () => {
assert.deepEqual(applyFilterQuery(rows, createFilterQuery([rule("country", "starts_with", "r")]), accessors), [rows[0]])
assert.deepEqual(applyFilterQuery(rows, createFilterQuery([rule("country", "ends_with", "e")]), accessors), [rows[1]])
assert.deepEqual(applyFilterQuery(rows, createFilterQuery([{ ...rule("country", "starts_with", "r"), negated: true }]), accessors), rows.slice(1))
})
test("migration preserves the existing operators and implicit AND", () => {
for (const operator of ["is", "isNot", "isAnyOf", "isNotAnyOf", "contains", "doesNotContain"]) {
const filters = [{ id: "country", field: "country", operator, values: ["RU", "DE"] },
+2
View File
@@ -21,6 +21,8 @@ function matchRule<T>(row: T, rule: FilterRule, accessors: FilterAccessors<T>):
case "is_none_of": result = !values.some(v => String(actual) === String(v)); break
case "contains": result = values.some(v => text(actual).includes(text(v))); break
case "not_contains": result = !values.some(v => text(actual).includes(text(v))); break
case "starts_with": result = text(actual).startsWith(text(values[0])); break
case "ends_with": result = text(actual).endsWith(text(values[0])); break
case "empty": result = empty; break
case "not_empty": result = !empty; break
// Unsupported conditions must never silently widen the result set.
+7 -7
View File
@@ -1,26 +1,26 @@
import type { FilterFieldConfig } from "@/components/reui/filters"
import type { FilterField } from "@/components/reui/filters/filters-types"
import type { Backup } from "@/lib/data"
export const BACKUP_FILTER_FIELDS: FilterFieldConfig[] = [
export const BACKUP_FILTER_FIELDS: FilterField[] = [
{
key: "server",
id: "server",
label: "Сервер",
type: "text",
placeholder: "Имя сервера",
},
{
key: "kind",
id: "kind",
label: "Тип",
type: "multiselect",
type: "select",
options: [
{ value: "auto", label: "авто" },
{ value: "manual", label: "вручную" },
],
},
{
key: "storage",
id: "storage",
label: "Хранилище",
type: "multiselect",
type: "select",
options: [
{ value: "local", label: "Локально" },
{ value: "s3", label: "S3" },
+8 -8
View File
@@ -1,10 +1,10 @@
import type { FilterFieldConfig } from "@/components/reui/filters"
import type { FilterField } from "@/components/reui/filters/filters-types"
export const BGP_FILTER_FIELDS: FilterFieldConfig[] = [
export const BGP_FILTER_FIELDS: FilterField[] = [
{
key: "state",
id: "state",
label: "Состояние",
type: "multiselect",
type: "select",
options: [
{ value: "Established", label: "Established" },
{ value: "Active", label: "Active" },
@@ -15,18 +15,18 @@ export const BGP_FILTER_FIELDS: FilterFieldConfig[] = [
],
},
{
key: "type",
id: "type",
label: "Тип",
type: "multiselect",
type: "select",
options: [
{ value: "eBGP", label: "eBGP" },
{ value: "iBGP", label: "iBGP" },
],
},
{
key: "afi",
id: "afi",
label: "AFI",
type: "multiselect",
type: "select",
options: [
{ value: "IPv4 Unicast", label: "IPv4 Unicast" },
{ value: "IPv6 Unicast", label: "IPv6 Unicast" },