Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
76 changes: 18 additions & 58 deletions web-admin/src/features/branches/BranchesSection.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,16 @@
import { TableToolbar } from "@rilldata/web-common/components/table-toolbar";
import type { FilterGroup } from "@rilldata/web-common/components/table-toolbar/types";
import DelayedSpinner from "@rilldata/web-common/features/entity-management/DelayedSpinner.svelte";
import {
createUrlFilterSync,
parseArrayParam,
parseStringParam,
} from "@rilldata/web-common/lib/url-filter-sync";
import {
GitBranchIcon,
PlayIcon,
StopCircleIcon,
Trash2Icon,
} from "lucide-svelte";
import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus";
import { onMount } from "svelte";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { UrlParamsState } from "@rilldata/web-common/lib/store-utils/url-params-state.svelte.ts";
import { DebouncedRuneStore } from "@rilldata/web-common/lib/store-utils/types.svelte.ts";
import { m } from "@rilldata/web-common/lib/i18n/gen/messages";

let { organization, project }: { organization: string; project: string } =
Expand Down Expand Up @@ -121,41 +117,13 @@
: null,
);

// Toolbar state — synced to URL params `q` and `status` (multi-select array)
const filterSync = createUrlFilterSync([
{ key: "q", type: "string" },
{ key: "status", type: "array" },
]);

let searchText = $state(parseStringParam(page.url.searchParams.get("q")));
let statusFilter = $state<string[]>(
parseArrayParam(page.url.searchParams.get("status")),
const searchTextStore = new DebouncedRuneStore(
UrlParamsState.createStringParam("q"),
500,
);
let mounted = $state(false);

onMount(() => {
filterSync.init(page.url);
mounted = true;
});

// URL → local state on external navigation (back/forward)
$effect(() => {
if (!mounted) return;
const url = page.url;
if (filterSync.hasExternalNavigation(url)) {
filterSync.markSynced(url);
searchText = parseStringParam(url.searchParams.get("q"));
statusFilter = parseArrayParam(url.searchParams.get("status"));
}
});
const statusFilterStore = UrlParamsState.createStringArrayParam("status");

// Local state → URL
$effect(() => {
if (!mounted) return;
filterSync.syncToUrl({ q: searchText, status: statusFilter });
});

let filterGroups = $derived([
let filterGroups = $derived<FilterGroup[]>([
{
label: m.common_status(),
key: "status",
Expand All @@ -165,16 +133,21 @@
{ label: m.branch_status_error(), value: "errored" },
{ label: m.branch_status_stopped(), value: "stopped" },
],
selected: statusFilter,
selectedStore: statusFilterStore,
defaultValue: [],
multiSelect: true,
},
] satisfies FilterGroup[]);
]);

function onClearAllFilters() {
searchTextStore.setter("");
statusFilterStore.setter([]);
}

function statusMatches(d: V1Deployment): boolean {
if (statusFilter.length === 0) return true;
if (statusFilterStore.value.length === 0) return true;
const s = d.status;
return statusFilter.some((sel) => {
return statusFilterStore.value.some((sel) => {
switch (sel) {
case "running":
return s === V1DeploymentStatus.DEPLOYMENT_STATUS_RUNNING;
Expand All @@ -197,7 +170,7 @@
}

let visibleDeployments = $derived.by(() => {
const q = searchText.trim().toLowerCase();
const q = searchTextStore.value.trim().toLowerCase();
const active = ($allDeployments.data?.deployments ?? []).filter(
(d: V1Deployment) =>
d.status !== V1DeploymentStatus.DEPLOYMENT_STATUS_DELETED &&
Expand Down Expand Up @@ -246,10 +219,6 @@
editable: boolean;
} | null>(null);

function onFilterChange(key: string, selected: string[]) {
if (key === "status") statusFilter = selected;
}

async function mutateDeployment(
deploymentId: string,
branch: string | undefined,
Expand Down Expand Up @@ -316,16 +285,7 @@
<section class="flex flex-col gap-y-5">
<h2 class="text-lg font-medium">{m.branch_branches()}</h2>

<TableToolbar
bind:searchText
{filterGroups}
{onFilterChange}
onClearAllFilters={() => {
statusFilter = [];
searchText = "";
}}
showSort={false}
/>
<TableToolbar {searchTextStore} {filterGroups} {onClearAllFilters} />

{#if $allDeployments.isLoading}
<div class="empty-container">
Expand Down
18 changes: 9 additions & 9 deletions web-admin/src/features/dashboards/listing/DashboardsTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import ResizableSidebar from "@rilldata/web-common/layout/ResizableSidebar.svelte";
import DashboardsTagSidebar from "@rilldata/web-admin/features/dashboards/listing/DashboardsTagSidebar.svelte";
import { filterResources } from "@rilldata/web-common/features/resources/resource-filter-utils.ts";
import { Throttler } from "@rilldata/web-common/lib/throttler.ts";
import { DebouncedRuneStore } from "@rilldata/web-common/lib/store-utils/types.svelte.ts";
import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { escapeHtml } from "@rilldata/web-common/lib/i18n";

Expand All @@ -32,11 +32,10 @@

const selectedTagsState = UrlParamsState.createStringArrayParam("tags");

const searchTextState = UrlParamsState.createStringParam("search");
const throttler = new Throttler(500, 500);
const throttledSearchSetter = (newValue: string) => {
throttler.throttle(() => searchTextState.setter(newValue));
};
const searchTextStore = new DebouncedRuneStore(
UrlParamsState.createStringParam("q"),
500,
);

const runtimeClient = useRuntimeClient();
let { organization, project } = $derived(page.params);
Expand All @@ -61,7 +60,7 @@
filterResources(
allDashboards,
[],
searchTextState.value,
searchTextStore.value,
[],
selectedTagsState.value,
),
Expand Down Expand Up @@ -161,9 +160,10 @@
<Search
placeholder={m.common_search()}
autofocus={false}
bind:value={searchTextState.getter, throttledSearchSetter}
bind:value={searchTextStore.getter, searchTextStore.setter}
rounded="lg"
retainValueOnMount
large
/>
</div>
{/if}
Expand All @@ -180,7 +180,7 @@
>
<DashboardsTagSidebar
resources={allDashboards}
searchText={searchTextState.value}
searchText={searchTextStore.value}
/>
</ResizableSidebar>
{/if}
Expand Down
Loading
Loading