Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2c15dc4
reafc: move to unified filter component
AdityaHegde Jul 22, 2026
102e28b
Simplify proxy logic
AdityaHegde Jul 23, 2026
8307b26
Add measure filters
AdityaHegde Jul 23, 2026
bc00a72
Use the new manager across the explore
AdityaHegde Jul 24, 2026
7918110
Move alerts/reports to the new filter class
AdityaHegde Jul 24, 2026
1429a5c
Add pinned/required
AdityaHegde Jul 29, 2026
9d458cf
Support multiple metrics views
AdityaHegde Jul 30, 2026
8b4057e
Migrate canvas pass 1
AdityaHegde Jul 31, 2026
c4ef015
Migrate bookmarks and public url form
AdityaHegde Aug 3, 2026
f4b1110
Migrate local component filter editor
AdityaHegde Aug 3, 2026
f638ed4
Advanced filters and pivot-click-to-filter
AdityaHegde Aug 4, 2026
f12d1dd
Improve expression walking and add tests
AdityaHegde Aug 5, 2026
8d34ca4
Fix url sync in canvas
AdityaHegde Aug 5, 2026
d2675e8
Merge branch 'main' into refac/unified-filter-component
AdityaHegde Aug 5, 2026
c035165
Remove canvas specific expression filter code
AdityaHegde Aug 6, 2026
1c51894
Update leaderboard/dimension display
AdityaHegde Aug 6, 2026
0e9eb72
Remove cases of whereFilter usage
AdityaHegde Aug 10, 2026
5ade9ff
Merge branch 'main' into refac/unified-filter-component
AdityaHegde Aug 11, 2026
dc29699
Remove usages of dimensionThresholdFilters
AdityaHegde Aug 11, 2026
cc9c8e9
fix incorrect filters being applied
AdityaHegde Aug 11, 2026
dc879dd
Fix pinned/required filters
AdityaHegde Aug 12, 2026
60e9cc0
fix unit tests
AdityaHegde Aug 12, 2026
a8d142c
fix rill dev e2e tests
AdityaHegde Aug 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 42 additions & 89 deletions web-admin/src/features/alerts/metadata/AlertFilters.svelte
Original file line number Diff line number Diff line change
@@ -1,109 +1,62 @@
<script lang="ts">
import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import MetadataLabel from "@rilldata/web-admin/features/scheduled-reports/metadata/MetadataLabel.svelte";
import TimeRangeReadOnly from "@rilldata/web-common/features/dashboards/filters/TimeRangeReadOnly.svelte";
import DimensionFilterReadOnlyChip from "@rilldata/web-common/features/dashboards/filters/dimension-filters/DimensionFilterReadOnlyChip.svelte";
import MeasureFilterReadOnlyChip from "@rilldata/web-common/features/dashboards/filters/measure-filters/MeasureFilterReadOnlyChip.svelte";
import { splitWhereFilter } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-utils";
import { useMetricsView } from "@rilldata/web-common/features/dashboards/selectors";
import { getDimensionFilters } from "@rilldata/web-common/features/dashboards/state-managers/selectors/dimension-filters";
import { getMeasureFilters } from "@rilldata/web-common/features/dashboards/state-managers/selectors/measure-filters";
import type { DimensionThresholdFilter } from "@rilldata/web-common/features/dashboards/stores/explore-state";
import { getMapFromArray } from "@rilldata/web-common/lib/arrayUtils";
import type {
V1Expression,
V1TimeRange,
} from "@rilldata/web-common/runtime-client";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
import { flip } from "svelte/animate";
import { fly } from "svelte/transition";
import { ExpressionFilterManager } from "@rilldata/web-common/features/dashboards/filters/ExpressionFilterManager.svelte.ts";
import { YAMLConfigProvider } from "@rilldata/web-common/features/dashboards/providers/YAMLConfigProvider.svelte.ts";
import { MetricsViewsProvider } from "@rilldata/web-common/features/metrics-views/providers/MetricsViewsProvider.svelte.ts";
import ReadonlyExpressionFilters from "@rilldata/web-common/features/dashboards/filters/ReadonlyExpressionFilters.svelte";

export let metricsViewName: string;
export let filters: V1Expression | undefined;
export let dimensionsWithInlistFilter: string[];
export let timeRange: V1TimeRange | undefined;
export let comparisonTimeRange: V1TimeRange | undefined;

// time range could be an empty object sometimes
$: hasTimeRange = timeRange && Object.keys(timeRange).length > 0;
$: filtersLength =
(filters?.cond?.exprs?.length ?? 0) + (hasTimeRange ? 1 : 0);
let {
metricsViewName,
filters,
dimensionsWithInlistFilter,
timeRange,
comparisonTimeRange,
}: {
metricsViewName: string;
filters: V1Expression | undefined;
dimensionsWithInlistFilter: string[];
timeRange: V1TimeRange | undefined;
comparisonTimeRange: V1TimeRange | undefined;
} = $props();

let whereFilter: V1Expression;
let havingFilter: DimensionThresholdFilter[];
$: {
const { dimensionFilters, dimensionThresholdFilters } =
splitWhereFilter(filters);
whereFilter = dimensionFilters;
havingFilter = dimensionThresholdFilters;
}
const runtimeClient = useRuntimeClient();

$: metricsView = useMetricsView(runtimeClient, metricsViewName);
$: dimensionIdMap = getMapFromArray(
$metricsView.data?.metricsView?.state?.validSpec?.dimensions ?? [],
(dimension) => dimension.name,
const metricsViewProvider = new MetricsViewsProvider(runtimeClient, []);
$effect(() => metricsViewProvider.setMetricsViewNames([metricsViewName]));
const expressionFilterManager = new ExpressionFilterManager(
metricsViewProvider,
new YAMLConfigProvider(),
);
$: measureIdMap = getMapFromArray(
$metricsView.data?.metricsView?.state?.validSpec?.measures ?? [],
(measure) => measure.name,
$effect(() =>
expressionFilterManager.setExprForMetricsView(
metricsViewName,
filters,
dimensionsWithInlistFilter,
),
);

$: currentDimensionFilters = getDimensionFilters(
dimensionIdMap,
whereFilter,
dimensionsWithInlistFilter,
metricsViewName,
// time range could be an empty object sometimes
let hasTimeRange = $derived(timeRange && Object.keys(timeRange).length > 0);
let filtersLength = $derived(
(filters?.cond?.exprs?.length ?? 0) + (hasTimeRange ? 1 : 0),
);
$: currentMeasureFilters = getMeasureFilters(measureIdMap, havingFilter);
</script>

<div class="flex flex-col gap-y-3" aria-label={m.alert_metadata_filters_aria()}>
<MetadataLabel
>{m.alert_filters_label({ count: String(filtersLength) })}</MetadataLabel
>
<div class="flex flex-wrap gap-2">
{#if filtersLength}
{#if hasTimeRange}
<TimeRangeReadOnly {timeRange} {comparisonTimeRange} />
{/if}
{#each currentDimensionFilters as { name, label, mode, selectedValues, inputText, isInclude } (name)}
{@const dimension = dimensionIdMap.get(name)}
<div animate:flip={{ duration: 200 }}>
{#if dimension?.column}
<DimensionFilterReadOnlyChip
{name}
metricsViewNames={[metricsViewName]}
{mode}
label={label || name}
values={selectedValues}
{inputText}
{isInclude}
timeStart={timeRange?.start}
timeEnd={timeRange?.end}
/>
{/if}
</div>
{/each}
{#if currentMeasureFilters.length > 0}
{#each currentMeasureFilters as { name, label, dimensionName, filter } (name)}
<div animate:flip={{ duration: 200 }}>
<MeasureFilterReadOnlyChip
label={label || name}
{dimensionName}
{filter}
/>
</div>
{/each}
{/if}
{:else}
<div
in:fly|local={{ duration: 200, x: 8 }}
class="text-fg-muted grid items-center"
style:min-height="26px"
>
{m.alert_no_filters_heading()}
</div>
{/if}
</div>
<MetadataLabel>
{m.alert_filters_label({ count: String(filtersLength) })}
</MetadataLabel>
<ReadonlyExpressionFilters
{expressionFilterManager}
displayTimeRange={timeRange}
displayComparisonTimeRange={comparisonTimeRange}
queryTimeStart={timeRange?.start}
queryTimeEnd={timeRange?.end}
/>
</div>
2 changes: 0 additions & 2 deletions web-admin/src/features/bookmarks/Bookmarks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
export let organization: string;
export let project: string;
export let resource: { name: string; kind: ResourceKind };
export let metricsViewNames: string[];
export let bookmarkData: {
bookmarks: V1Bookmark[];
categorizedBookmarks: Bookmarks;
Expand Down Expand Up @@ -260,7 +259,6 @@
{resource}
{defaultUrlParams}
{showFiltersOnly}
{metricsViewNames}
onClose={() => {
showDialog = false;
bookmark = null;
Expand Down
Loading
Loading