From ff09c7a9726a86483f4e0a1dc5be2a350407712d Mon Sep 17 00:00:00 2001
From: Brian Holmes <120223836+briangregoryholmes@users.noreply.github.com>
Date: Mon, 18 Dec 2023 01:20:42 -0500
Subject: [PATCH] support for Add Filter button (#3671)
* rework of footer to match new design and improve readability
* adding filter button functionality, plus design tweaks to relevant menus
* new icon
* chip should not be removed when deselecting the only selected value
* removing limit from filter list query
* changed searchedValues to allValues, simplified display logic
* updated tests to meet updated requirements
* prettier unused vars build fix
* remove keep-alive event
* update let directive for named slot, add timeout to dashboard.spec
* remove unused function
* change to active logic when mounting chip component
* resolve name collision
* update page wait from timeout to selector
* added specific method for adding a dimension name without a value
* only unselected dimension names are shown in the add filter dropdown
* add back limit
* toggleDimensionNameSelection is now actually a toggling function
* dispatch remove event rather than handle remove directly, plus bind to active property
* use state manager action and prop cleanup
* add back limit
---
.../chip/removable-list-chip/Footer.svelte | 21 +++-
.../RemovableListChip.svelte | 45 +++++---
.../RemovableListMenu.spec.ts | 53 ++++-----
.../RemovableListMenu.svelte | 78 ++++++-------
.../src/components/icons/ChevronRight.svelte | 19 ++++
.../src/components/search/Search.svelte | 11 +-
.../SearchableFilterDropdown.svelte | 5 +-
.../src/features/dashboards/actions/index.ts | 6 -
.../dashboards/filters/FilterButton.svelte | 84 ++++++++++++++
.../dashboards/filters/Filters.svelte | 107 ++++++++++--------
.../features/dashboards/selectors/index.ts | 2 +-
.../actions/dimension-filters.ts | 29 +++++
web-local/test/ui/dashboards.spec.ts | 2 +
13 files changed, 309 insertions(+), 153 deletions(-)
create mode 100644 web-common/src/components/icons/ChevronRight.svelte
create mode 100644 web-common/src/features/dashboards/filters/FilterButton.svelte
diff --git a/web-common/src/components/chip/removable-list-chip/Footer.svelte b/web-common/src/components/chip/removable-list-chip/Footer.svelte
index 1ba6c126b93..0eebe05a980 100644
--- a/web-common/src/components/chip/removable-list-chip/Footer.svelte
+++ b/web-common/src/components/chip/removable-list-chip/Footer.svelte
@@ -1,5 +1,18 @@
-
+
+
+
+
diff --git a/web-common/src/components/chip/removable-list-chip/RemovableListChip.svelte b/web-common/src/components/chip/removable-list-chip/RemovableListChip.svelte
index c34207ef3d0..dfbbb9499a5 100644
--- a/web-common/src/components/chip/removable-list-chip/RemovableListChip.svelte
+++ b/web-common/src/components/chip/removable-list-chip/RemovableListChip.svelte
@@ -11,9 +11,9 @@ the name and then move the cursor to the right to cancel it.
existing elements in the lib as well as changing the type (include, exclude) and enabling list search. The implementation of these parts
are details left to the consumer of the component; this component should remain pure-ish (only internal state) if possible.
-->
-
+
@@ -55,7 +68,10 @@ are details left to the consumer of the component; this component should remain
>
{
+ toggleFloatingElement();
+ dispatch("click");
+ }}
on:remove={() => dispatch("remove")}
{active}
{...colors}
@@ -91,15 +107,14 @@ are details left to the consumer of the component; this component should remain
diff --git a/web-common/src/components/chip/removable-list-chip/RemovableListMenu.spec.ts b/web-common/src/components/chip/removable-list-chip/RemovableListMenu.spec.ts
index 8f3f50f1310..35ee88a02e4 100644
--- a/web-common/src/components/chip/removable-list-chip/RemovableListMenu.spec.ts
+++ b/web-common/src/components/chip/removable-list-chip/RemovableListMenu.spec.ts
@@ -1,28 +1,31 @@
import RemovableListMenu from "./RemovableListMenu.svelte";
import { describe, it, expect, vi } from "vitest";
import { render, waitFor, fireEvent, screen } from "@testing-library/svelte";
-import { writable } from "svelte/store";
describe("RemovableListMenu", () => {
- it("renders selected values by default", async () => {
+ it("does not render selected values if not in all values", async () => {
const { unmount } = render(RemovableListMenu, {
- excludeStore: writable(false),
- selectedValues: ["foo", "bar"],
- searchedValues: null,
+ excludeMode: false,
+ selectedValues: ["x"],
+ allValues: ["foo", "bar"],
});
const foo = screen.getByText("foo");
const bar = screen.getByText("bar");
expect(foo).toBeDefined();
expect(bar).toBeDefined();
+
+ const x = screen.queryByText("x");
+ expect(x).toBeNull();
+
unmount();
});
- it("renders selected values if search text is empty", async () => {
+ it("renders all values if search text is empty", async () => {
const { unmount } = render(RemovableListMenu, {
- excludeStore: writable(false),
- selectedValues: ["foo", "bar"],
- searchedValues: ["x"],
+ excludeMode: false,
+ selectedValues: [],
+ allValues: ["foo", "bar"],
});
const foo = screen.getByText("foo");
@@ -34,9 +37,9 @@ describe("RemovableListMenu", () => {
it("renders search values if search text is populated", async () => {
const { unmount } = render(RemovableListMenu, {
- excludeStore: writable(false),
+ excludeMode: false,
selectedValues: ["foo", "bar"],
- searchedValues: ["x"],
+ allValues: ["x"],
});
const searchInput = screen.getByRole("textbox", { name: "Search list" });
@@ -51,35 +54,33 @@ describe("RemovableListMenu", () => {
});
it("should render switch based on exclude store", async () => {
- const excludeStore = writable(false);
- const { unmount } = render(RemovableListMenu, {
- excludeStore,
+ const { unmount, component } = render(RemovableListMenu, {
+ excludeMode: false,
selectedValues: ["foo", "bar"],
- searchedValues: ["x"],
+ allValues: ["x"],
});
- const switchInput = screen.getByRole("switch");
- expect(switchInput.checked).toBe(false);
+ const switchInput = screen.getByText("Exclude");
+ expect(switchInput).toBeDefined();
- excludeStore.set(true);
- await waitFor(() => {
- expect(switchInput.checked).toBe(true);
- });
+ await component.$set({ excludeMode: true });
+
+ const includeButton = screen.getByText("Include");
+ expect(includeButton).toBeDefined();
unmount();
});
it("should dispatch toggle, apply, and search events", async () => {
- const excludeStore = writable(false);
const { unmount, component } = render(RemovableListMenu, {
- excludeStore,
- selectedValues: ["foo", "bar"],
- searchedValues: ["x"],
+ excludeMode: false,
+ selectedValues: [],
+ allValues: ["foo", "bar"],
});
const toggleSpy = vi.fn();
component.$on("toggle", toggleSpy);
- const switchInput = screen.getByRole("switch");
+ const switchInput = screen.getByText("Exclude");
await fireEvent.click(switchInput);
expect(toggleSpy).toHaveBeenCalledOnce();
diff --git a/web-common/src/components/chip/removable-list-chip/RemovableListMenu.svelte b/web-common/src/components/chip/removable-list-chip/RemovableListMenu.svelte
index 006e5a2a951..245e49f389c 100644
--- a/web-common/src/components/chip/removable-list-chip/RemovableListMenu.svelte
+++ b/web-common/src/components/chip/removable-list-chip/RemovableListMenu.svelte
@@ -1,17 +1,16 @@