Skip to content

Commit b5532ec

Browse files
authored
[Docs Site] Add filters to Learning Paths overview (#18296)
* [Docs Site] Add filters to Learning Paths overview * remove logs
1 parent 9fcbcc2 commit b5532ec

File tree

1 file changed

+192
-12
lines changed

1 file changed

+192
-12
lines changed

src/pages/learning-paths.astro

Lines changed: 192 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
3-
import { getCollection } from "astro:content";
3+
import { getCollection, type CollectionEntry } from "astro:content";
44
import { marked } from "marked";
55
import { CardGrid, LinkTitleCard, Description } from "~/components";
66
@@ -12,21 +12,201 @@ const frontmatter = {
1212
} as const;
1313
1414
const learningPaths = await getCollection("learning-paths");
15+
16+
function lpGroups(paths: Array<CollectionEntry<"learning-paths">>) {
17+
const groups = paths.flatMap((p) => p.data.product_group ?? []);
18+
const additional = paths.flatMap((p) => p.data.additional_groups ?? []);
19+
20+
const unique = [...new Set(groups.concat(additional))];
21+
22+
return unique.sort();
23+
}
24+
25+
function lpProducts(paths: Array<CollectionEntry<"learning-paths">>) {
26+
const products = paths.flatMap((p) => p.data.products ?? []);
27+
28+
const unique = [...new Set(products)];
29+
30+
return unique.sort();
31+
}
32+
33+
const groups = lpGroups(learningPaths);
34+
const products = lpProducts(learningPaths);
1535
---
1636

1737
<StarlightPage frontmatter={frontmatter}>
1838
<Description>
1939
{frontmatter.description}
2040
</Description>
21-
<CardGrid>
22-
{
23-
learningPaths.map((lp) => (
24-
<LinkTitleCard
25-
title={lp.data.title}
26-
href={lp.data.path}
27-
set:html={marked.parse(lp.data.description)}
28-
/>
29-
))
30-
}
31-
</CardGrid>
41+
<div class="flex">
42+
<div class="w-1/4 pr-4 hidden lg:block">
43+
<div class="border-b-2 border-accent-600 dark:border-accent-200">
44+
<h2>Filters</h2>
45+
</div>
46+
<div id="areas-filter">
47+
<p>
48+
<strong>Product areas</strong>
49+
</p>
50+
{
51+
groups.map((group) => (
52+
<>
53+
<input type="checkbox" id={group} />
54+
<label for={group}>{group}</label>
55+
<br />
56+
</>
57+
))
58+
}
59+
</div>
60+
<div id="products-filter">
61+
<p>
62+
<strong>Products</strong>
63+
</p>
64+
{
65+
products.map((product) => (
66+
<>
67+
<input type="checkbox" id={product} />
68+
<label for={product}>{product}</label>
69+
<br />
70+
</>
71+
))
72+
}
73+
</div>
74+
</div>
75+
<div id="lp-grid" class="w-full">
76+
<CardGrid>
77+
{
78+
learningPaths
79+
.sort((a, b) => a.data.priority - b.data.priority)
80+
.map((lp) => (
81+
<div
82+
class="[&>article]:h-full [&>article]:w-full"
83+
data-groups={JSON.stringify(
84+
[lp.data.product_group].concat(
85+
lp.data.additional_groups ?? [],
86+
),
87+
)}
88+
data-products={JSON.stringify(lp.data.products)}
89+
>
90+
<LinkTitleCard
91+
title={lp.data.title}
92+
href={lp.data.path}
93+
set:html={marked.parse(lp.data.description)}
94+
/>
95+
</div>
96+
))
97+
}
98+
</CardGrid>
99+
</div>
100+
</div>
32101
</StarlightPage>
102+
103+
<script>
104+
function getAreaFilters(): NodeListOf<HTMLInputElement> | undefined {
105+
const groupFiltersContainer =
106+
document.querySelector<HTMLDivElement>("#areas-filter");
107+
108+
if (!groupFiltersContainer) return undefined;
109+
110+
const groupFilters =
111+
groupFiltersContainer.querySelectorAll<HTMLInputElement>("input");
112+
113+
if (!groupFilters) return undefined;
114+
115+
return groupFilters;
116+
}
117+
118+
function getProductFilters(): NodeListOf<HTMLInputElement> | undefined {
119+
const groupFiltersContainer =
120+
document.querySelector<HTMLDivElement>("#products-filter");
121+
122+
if (!groupFiltersContainer) return undefined;
123+
124+
const groupFilters =
125+
groupFiltersContainer.querySelectorAll<HTMLInputElement>("input");
126+
127+
if (!groupFilters) return undefined;
128+
129+
return groupFilters;
130+
}
131+
132+
function getLearningPaths(): NodeListOf<HTMLDivElement> | undefined {
133+
const learningPathsContainer =
134+
document.querySelector<HTMLDivElement>("#lp-grid");
135+
136+
if (!learningPathsContainer) return undefined;
137+
138+
const learningPaths =
139+
learningPathsContainer.querySelectorAll<HTMLDivElement>("[data-groups]");
140+
141+
if (!learningPaths) return undefined;
142+
143+
return learningPaths;
144+
}
145+
146+
function filterProducts() {
147+
const areaFilters = getAreaFilters();
148+
const productFilters = getProductFilters();
149+
150+
if (!areaFilters || !productFilters) return;
151+
152+
const checkedAreas: Array<string> = [];
153+
const checkedProducts: Array<string> = [];
154+
155+
for (const filter of areaFilters) {
156+
if (filter.checked) {
157+
checkedAreas.push(filter.id);
158+
}
159+
}
160+
161+
for (const filter of productFilters) {
162+
if (filter.checked) {
163+
checkedProducts.push(filter.id);
164+
}
165+
}
166+
167+
const learningPaths = getLearningPaths();
168+
169+
if (!learningPaths) return;
170+
171+
if (checkedAreas.length === 0 && checkedProducts.length === 0) {
172+
learningPaths.forEach((card) => {
173+
card.style.display = "";
174+
});
175+
return;
176+
}
177+
178+
for (const learningPath of learningPaths) {
179+
if (!learningPath.dataset.groups || !learningPath.dataset.products)
180+
continue;
181+
182+
const groups: Array<string> = JSON.parse(learningPath.dataset.groups);
183+
const products: Array<string> = JSON.parse(learningPath.dataset.products);
184+
185+
let show = true;
186+
187+
show = checkedAreas.some((v) => {
188+
return groups.includes(v);
189+
});
190+
191+
if (!show) {
192+
show = checkedProducts.some((v) => {
193+
return products.includes(v);
194+
});
195+
}
196+
197+
if (show) {
198+
learningPath.style.display = "";
199+
} else {
200+
learningPath.style.display = "none";
201+
}
202+
}
203+
}
204+
205+
getAreaFilters()?.forEach((input) => {
206+
input.addEventListener("change", filterProducts);
207+
});
208+
209+
getProductFilters()?.forEach((input) => {
210+
input.addEventListener("change", filterProducts);
211+
});
212+
</script>

0 commit comments

Comments
 (0)