Skip to content

Commit f87948c

Browse files
KianNHsdnts
authored andcommitted
[Docs Site] Sync filters to URL params in catalog components (cloudflare#23190)
1 parent 1890c55 commit f87948c

File tree

6 files changed

+102
-15
lines changed

6 files changed

+102
-15
lines changed

src/components/FieldCatalog.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ import { useEffect, useState, type ChangeEvent } from "react";
22
import FieldBadges from "./fields/FieldBadges";
33
import Markdown from "react-markdown";
44
import type { CollectionEntry } from "astro:content";
5+
import { setSearchParams } from "~/util/url";
56

67
type Fields = CollectionEntry<"fields">["data"]["entries"];
78

89
type Filters = {
910
search: string;
1011
categories: string[];
11-
keywords: string[];
1212
};
1313

1414
const FieldCatalog = ({ fields }: { fields: Fields }) => {
1515
const [filters, setFilters] = useState<Filters>({
1616
search: "",
1717
categories: [],
18-
keywords: [],
1918
});
2019

2120
const mapped = fields.sort((f1, f2) => {
@@ -58,7 +57,6 @@ const FieldCatalog = ({ fields }: { fields: Fields }) => {
5857
});
5958

6059
useEffect(() => {
61-
// On component load, check for deep-links to categories in the query param
6260
const params = new URLSearchParams(window.location.search);
6361
const categories = params.getAll("field-category");
6462
const searchTerm = params.get("search-term") ?? "";
@@ -72,6 +70,22 @@ const FieldCatalog = ({ fields }: { fields: Fields }) => {
7270
});
7371
}, []);
7472

73+
useEffect(() => {
74+
const params = new URLSearchParams();
75+
76+
if (filters.search) {
77+
params.set("search-term", filters.search);
78+
}
79+
80+
if (filters.categories.length > 0) {
81+
filters.categories.forEach((category) =>
82+
params.append("field-category", category),
83+
);
84+
}
85+
86+
setSearchParams(params);
87+
}, [filters]);
88+
7589
return (
7690
<div className="md:flex">
7791
<div className="mr-8 w-full md:w-1/4">

src/components/LearningPathCatalog.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { useState, type ChangeEvent } from "react";
1+
import { useEffect, useState, type ChangeEvent } from "react";
22
import Markdown from "react-markdown";
33
import type { CollectionEntry } from "astro:content";
44
import type { IconifyIconBuildResult } from "@iconify/utils";
5+
import { setSearchParams } from "~/util/url";
56

67
type LearningPaths = CollectionEntry<"learning-paths">["data"][];
78
type Icons = Record<string, IconifyIconBuildResult>;
@@ -23,6 +24,34 @@ const LearningPathCatalog = ({
2324
groups: [],
2425
});
2526

27+
useEffect(() => {
28+
const params = new URLSearchParams(window.location.search);
29+
const products = params.getAll("products");
30+
const groups = params.getAll("groups");
31+
32+
if (!products && !groups) return;
33+
34+
setFilters({
35+
...filters,
36+
products,
37+
groups,
38+
});
39+
}, []);
40+
41+
useEffect(() => {
42+
const params = new URLSearchParams();
43+
44+
if (filters.products.length > 0) {
45+
filters.products.forEach((product) => params.append("products", product));
46+
}
47+
48+
if (filters.groups.length > 0) {
49+
filters.groups.forEach((group) => params.append("groups", group));
50+
}
51+
52+
setSearchParams(params);
53+
}, [filters]);
54+
2655
const sorted = paths.sort((lp1, lp2) => {
2756
return lp1.priority < lp2.priority ? -1 : 1;
2857
});

src/components/ModelCatalog.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ModelInfo from "./models/ModelInfo";
33
import ModelBadges from "./models/ModelBadges";
44
import { authorData } from "./models/data";
55
import type { WorkersAIModelsSchema } from "~/schemas";
6+
import { setSearchParams } from "~/util/url";
67

78
type Filters = {
89
search: string;
@@ -67,6 +68,30 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => {
6768
});
6869
}, []);
6970

71+
useEffect(() => {
72+
const params = new URLSearchParams();
73+
74+
if (filters.search) {
75+
params.set("search", filters.search);
76+
}
77+
78+
if (filters.authors.length > 0) {
79+
filters.authors.forEach((author) => params.append("authors", author));
80+
}
81+
82+
if (filters.tasks.length > 0) {
83+
filters.tasks.forEach((task) => params.append("tasks", task));
84+
}
85+
86+
if (filters.capabilities.length > 0) {
87+
filters.capabilities.forEach((capability) =>
88+
params.append("capabilities", capability),
89+
);
90+
}
91+
92+
setSearchParams(params);
93+
}, [filters]);
94+
7095
const mapped = sortedModels.map((model) => ({
7196
model: {
7297
...model,

src/components/ProductCatalog.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useState, type ChangeEvent } from "react";
22
import type { CollectionEntry } from "astro:content";
33
import type { IconifyIconBuildResult } from "@iconify/utils";
4+
import { setSearchParams } from "~/util/url";
45

56
export type ProductData = CollectionEntry<"products"> & {
67
icon?: IconifyIconBuildResult;
@@ -42,7 +43,6 @@ const ProductCatalog = ({ products }: { products: ProductData[] }) => {
4243
});
4344

4445
useEffect(() => {
45-
// On component load, check for deep-links to groups in the query param
4646
const params = new URLSearchParams(window.location.search);
4747
const groups = params.get("product-group")?.split(",");
4848

@@ -54,6 +54,20 @@ const ProductCatalog = ({ products }: { products: ProductData[] }) => {
5454
});
5555
}, []);
5656

57+
useEffect(() => {
58+
const params = new URLSearchParams();
59+
60+
if (filters.search) {
61+
params.set("search", filters.search);
62+
}
63+
64+
if (filters.groups.length > 0) {
65+
filters.groups.forEach((group) => params.append("product-group", group));
66+
}
67+
68+
setSearchParams(params);
69+
}, [filters]);
70+
5771
return (
5872
<div className="md:flex">
5973
<div className="mr-8 w-full md:w-1/4">

src/components/search/InstantSearch.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
FloatingPortal,
2222
} from "@floating-ui/react";
2323
import { PiCaretDownBold } from "react-icons/pi";
24+
import { setSearchParams } from "~/util/url";
2425

2526
function SearchBox(props: UseSearchBoxProps) {
2627
const { query, refine } = useSearchBox(props);
@@ -43,11 +44,7 @@ function SearchBox(props: UseSearchBoxProps) {
4344
params.delete("q");
4445
}
4546

46-
history.pushState(
47-
null,
48-
"",
49-
`${window.location.pathname}?${params.toString()}`,
50-
);
47+
setSearchParams(params);
5148
}, [query]);
5249

5350
return (
@@ -143,11 +140,7 @@ function FilterDropdown({
143140
params.set(attribute, refined.join(","));
144141
}
145142

146-
history.pushState(
147-
null,
148-
"",
149-
`${window.location.pathname}?${params.toString()}`,
150-
);
143+
setSearchParams(params);
151144
}, [items]);
152145

153146
const { refs, floatingStyles, context } = useFloating({

src/util/url.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function setSearchParams(params: URLSearchParams) {
2+
if (params.size === 0) {
3+
history.pushState(null, "", window.location.pathname);
4+
return;
5+
}
6+
7+
history.pushState(
8+
null,
9+
"",
10+
`${window.location.pathname}?${params.toString()}`,
11+
);
12+
}

0 commit comments

Comments
 (0)