Skip to content

Commit 43dfdb4

Browse files
committed
feat: add search to pivot filter pills (#7377)
* feat: add search to pivot filter pills * fix: lint * fix: tests * fix: lint * nit: reorder measures first
1 parent 976a70f commit 43dfdb4

File tree

2 files changed

+119
-41
lines changed

2 files changed

+119
-41
lines changed
Lines changed: 114 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
<script lang="ts" context="module">
2-
import Button from "@rilldata/web-common/components/button/Button.svelte";
32
import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu/";
43
import Add from "@rilldata/web-common/components/icons/Add.svelte";
54
import { getStateManagers } from "../state-managers/state-managers";
65
import { metricsExplorerStore } from "../stores/dashboard-stores";
6+
7+
import { useTimeControlStore } from "@rilldata/web-common/features/dashboards/time-controls/time-control-store";
8+
import {
9+
getAllowedTimeGrains,
10+
isGrainBigger,
11+
} from "@rilldata/web-common/lib/time/grains";
12+
import { V1TimeGrain } from "@rilldata/web-common/runtime-client";
13+
14+
import type { SearchableFilterSelectableGroup } from "@rilldata/web-common/components/searchable-filter-menu/SearchableFilterSelectableItem";
15+
import SearchableMenuContent from "@rilldata/web-common/components/searchable-filter-menu/SearchableMenuContent.svelte";
16+
17+
import { PivotChipType } from "./types";
718
import type { PivotChipData } from "./types";
819
</script>
920

@@ -16,51 +27,116 @@
1627
},
1728
exploreName,
1829
} = getStateManagers();
30+
const timeControlsStore = useTimeControlStore(getStateManagers());
1931
2032
let open = false;
2133
22-
function handleSelectValue(data: PivotChipData) {
23-
metricsExplorerStore.addPivotField($exploreName, data, zone === "rows");
34+
$: allTimeGrains = getAllowedTimeGrains(
35+
new Date($timeControlsStore.timeStart!),
36+
new Date($timeControlsStore.timeEnd!),
37+
).map((tgo) => {
38+
return {
39+
id: tgo.grain,
40+
title: tgo.label,
41+
type: PivotChipType.Time,
42+
};
43+
});
44+
45+
$: timeGrainOptions = allTimeGrains.filter(
46+
(tgo) =>
47+
$timeControlsStore.minTimeGrain === undefined ||
48+
$timeControlsStore.minTimeGrain === V1TimeGrain.TIME_GRAIN_UNSPECIFIED ||
49+
!isGrainBigger($timeControlsStore.minTimeGrain, tgo.id),
50+
);
51+
52+
$: selectableGroups = [
53+
...(zone === "columns"
54+
? [
55+
<SearchableFilterSelectableGroup>{
56+
name: "MEASURES",
57+
items: $measures?.map((m) => ({
58+
name: m.id,
59+
label: m.title,
60+
})),
61+
},
62+
]
63+
: []),
64+
<SearchableFilterSelectableGroup>{
65+
name: "DIMENSIONS",
66+
items: $dimensions?.map((d) => ({
67+
name: d.id,
68+
label: d.title,
69+
})),
70+
},
71+
<SearchableFilterSelectableGroup>{
72+
name: "TIME",
73+
items: timeGrainOptions.map((tgo) => ({
74+
name: tgo.id,
75+
label: tgo.title,
76+
type: PivotChipType.Time,
77+
})),
78+
},
79+
];
80+
81+
$: allDimensionsMeasures = [
82+
...$dimensions,
83+
...$measures,
84+
...timeGrainOptions,
85+
];
86+
87+
function handleSelectValue(name) {
88+
const selectedItem = allDimensionsMeasures.find(
89+
(item) => item.id === name,
90+
) as PivotChipData;
91+
92+
metricsExplorerStore.addPivotField(
93+
$exploreName,
94+
selectedItem,
95+
zone === "rows",
96+
);
2497
}
2598
</script>
2699

27-
<DropdownMenu.Root bind:open>
100+
<DropdownMenu.Root bind:open typeahead={false}>
28101
<DropdownMenu.Trigger asChild let:builder>
29-
<Button builders={[builder]} type="add" selected={open} label="add-field">
102+
<button
103+
class:active={open}
104+
use:builder.action
105+
{...builder}
106+
aria-label="Add filter button"
107+
>
30108
<Add size="17px" />
31-
</Button>
109+
</button>
32110
</DropdownMenu.Trigger>
33111

34-
<DropdownMenu.Content
35-
class="min-h-10 max-h-80 w-64 overflow-y-auto"
36-
align="start"
37-
>
38-
{#if zone === "columns"}
39-
<DropdownMenu.Label>Measures</DropdownMenu.Label>
40-
<DropdownMenu.Group>
41-
{#each $measures as measure}
42-
<DropdownMenu.Item
43-
on:click={() => {
44-
handleSelectValue(measure);
45-
}}
46-
>
47-
{measure.title}
48-
</DropdownMenu.Item>
49-
{/each}
50-
</DropdownMenu.Group>
51-
<DropdownMenu.Separator />
52-
{/if}
53-
<DropdownMenu.Label>Dimensions</DropdownMenu.Label>
54-
<DropdownMenu.Group>
55-
{#each $dimensions as dimension}
56-
<DropdownMenu.Item
57-
on:click={() => {
58-
handleSelectValue(dimension);
59-
}}
60-
>
61-
{dimension.title}
62-
</DropdownMenu.Item>
63-
{/each}
64-
</DropdownMenu.Group>
65-
</DropdownMenu.Content>
112+
<SearchableMenuContent
113+
allowMultiSelect={false}
114+
onSelect={(name) => {
115+
handleSelectValue(name);
116+
}}
117+
{selectableGroups}
118+
selectedItems={[]}
119+
/>
66120
</DropdownMenu.Root>
121+
122+
<style lang="postcss">
123+
button {
124+
@apply w-[34px] h-[26px] rounded-2xl;
125+
@apply flex items-center justify-center;
126+
127+
@apply bg-white;
128+
}
129+
130+
button.addBorder {
131+
@apply border border-dashed border-slate-300;
132+
}
133+
134+
button:hover {
135+
@apply bg-slate-100;
136+
}
137+
138+
button:active,
139+
.active {
140+
@apply bg-slate-200;
141+
}
142+
</style>

web-local/tests/explores/pivot.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,8 @@ test.describe("pivot run through", () => {
594594
// add second measure using menu and add column dimension
595595
await domain.dragTo(columnZone);
596596
const addColumnField = page
597-
.getByRole("button", { name: "add-field" })
598-
.nth(1);
597+
.getByRole("button", { name: "Add filter button" })
598+
.nth(2);
599599
await addColumnField.click();
600600
await clickMenuButton(page, "Sum of Bid Price");
601601
await expect(page.locator(".status.running")).toHaveCount(0);
@@ -619,7 +619,9 @@ test.describe("pivot run through", () => {
619619
const timeMonth = page.getByLabel("month pivot chip", { exact: true });
620620
await timeMonth.dragTo(rowZone);
621621

622-
const addRowField = page.getByRole("button", { name: "add-field" }).nth(0);
622+
const addRowField = page
623+
.getByRole("button", { name: "Add filter button" })
624+
.nth(1);
623625
await addRowField.click();
624626
await clickMenuButton(page, "Publisher");
625627

0 commit comments

Comments
 (0)