Skip to content

Commit d2b8959

Browse files
committed
chore: add query parameter to page
Adds query parameter to the page. If you pass in ?query=4 into the URL, it'll show only the last 4 updated extensions. Open for suggestions on other names for it. Signed-off-by: Charlie Drage <[email protected]>
1 parent e0d26c6 commit d2b8959

File tree

2 files changed

+185
-7
lines changed

2 files changed

+185
-7
lines changed

src/lib/ui/ExtensionsList.spec.ts

+138-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import '@testing-library/jest-dom/vitest';
2020

21-
import { render, screen } from '@testing-library/svelte';
21+
import { render, screen, waitFor } from '@testing-library/svelte';
2222
import { beforeEach, expect, test, vi } from 'vitest';
2323

2424
import type { CatalogExtensionInfo, ExtensionByCategoryInfo } from '$lib/api/extensions-info';
@@ -49,3 +49,140 @@ test('check categories', async () => {
4949
const category2 = screen.getByText('category2');
5050
expect(category2).toBeInTheDocument();
5151
});
52+
53+
test('if query is passed into window.location.search then it should be used to filter extensions', async () => {
54+
// Mock query to be last 1
55+
vi.spyOn(window, 'location', 'get').mockReturnValue({
56+
search: '?query=1',
57+
} as unknown as Location);
58+
59+
const extensionsByCategories: ExtensionByCategoryInfo[] = [
60+
{
61+
category: 'category1',
62+
extensions: [
63+
{
64+
displayName: 'dummy1',
65+
versions: [
66+
{
67+
version: '1.0.0',
68+
// Todays date minus 1 day, to make sure it is NOT the most recent one (we want to show dummy2)
69+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 1)),
70+
files: [],
71+
},
72+
],
73+
} as unknown as CatalogExtensionInfo,
74+
],
75+
},
76+
{
77+
category: 'category2',
78+
extensions: [
79+
{
80+
displayName: 'dummy2',
81+
versions: [
82+
{
83+
version: '1.0.0',
84+
lastUpdated: new Date(),
85+
files: [],
86+
},
87+
],
88+
} as unknown as CatalogExtensionInfo,
89+
],
90+
},
91+
];
92+
93+
render(ExtensionsList, { extensionsByCategories });
94+
95+
// Make sure that displayname dummy2 is shown, as it is the "most" up to date one.
96+
const dummy2 = screen.getByText('dummy2');
97+
expect(dummy2).toBeInTheDocument();
98+
99+
// Dummy1 should NOT be shown
100+
const dummy1 = screen.queryByText('dummy1');
101+
expect(dummy1).not.toBeInTheDocument();
102+
103+
// Categories category1 and category2 should be NOT shown
104+
const category1 = screen.queryByText('category1');
105+
expect(category1).not.toBeInTheDocument();
106+
107+
const category2 = screen.queryByText('category2');
108+
expect(category2).not.toBeInTheDocument();
109+
});
110+
111+
test('if query is passed in with 4, it should show last 4 extensions even if there is 5 in the list', async () => {
112+
// Mock query to be last 4
113+
vi.spyOn(window, 'location', 'get').mockReturnValue({
114+
search: '?query=4',
115+
} as unknown as Location);
116+
117+
const extensionsByCategories: ExtensionByCategoryInfo[] = [
118+
{
119+
category: 'category1',
120+
extensions: [
121+
{
122+
displayName: 'dummy1',
123+
versions: [
124+
{
125+
version: '1.0.0',
126+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 1)),
127+
files: [],
128+
},
129+
],
130+
} as unknown as CatalogExtensionInfo,
131+
{
132+
displayName: 'dummy2',
133+
versions: [
134+
{
135+
version: '1.0.0',
136+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 2)),
137+
files: [],
138+
},
139+
],
140+
} as unknown as CatalogExtensionInfo,
141+
{
142+
displayName: 'dummy3',
143+
versions: [
144+
{
145+
version: '1.0.0',
146+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 3)),
147+
files: [],
148+
},
149+
],
150+
} as unknown as CatalogExtensionInfo,
151+
{
152+
displayName: 'dummy4',
153+
versions: [
154+
{
155+
version: '1.0.0',
156+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 4)),
157+
files: [],
158+
},
159+
],
160+
} as unknown as CatalogExtensionInfo,
161+
{
162+
displayName: 'dummy5',
163+
versions: [
164+
{
165+
version: '1.0.0',
166+
lastUpdated: new Date(new Date().setDate(new Date().getDate() - 5)),
167+
files: [],
168+
},
169+
],
170+
} as unknown as CatalogExtensionInfo,
171+
],
172+
},
173+
];
174+
175+
render(ExtensionsList, { extensionsByCategories });
176+
177+
// Make sure that displayname dummy4 is shown, as it is the "most" up to date one.
178+
const dummy4 = screen.getByText('dummy4');
179+
expect(dummy4).toBeInTheDocument();
180+
181+
// Dummy5 should NOT be shown, as it's the "oldest" one.
182+
const dummy5 = screen.queryByText('dummy5');
183+
expect(dummy5).not.toBeInTheDocument();
184+
185+
// Categories category1 should be NOT shown
186+
const category1 = screen.queryByText('category1');
187+
expect(category1).not.toBeInTheDocument();
188+
});

src/lib/ui/ExtensionsList.svelte

+47-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,54 @@
11
<script lang="ts">
2-
import type { ExtensionByCategoryInfo } from '$lib/api/extensions-info';
3-
2+
import type { ExtensionByCategoryInfo, CatalogExtensionInfo } from '$lib/api/extensions-info';
43
import ExtensionsByCategory from './ExtensionsByCategory.svelte';
4+
import ExtensionByCategoryCard from './ExtensionByCategoryCard.svelte';
5+
6+
export let extensionsByCategories: ExtensionByCategoryInfo[];
7+
8+
let filteredExtensions: CatalogExtensionInfo[] = [];
9+
let showCategories = true;
10+
11+
// Get the query from the URL
12+
function getQueryLimit(): number | null {
13+
const query = new URLSearchParams(window.location.search).get('query');
14+
return query ? parseInt(query, 10) : null;
15+
}
16+
17+
// Sort extensions based upon the last updated date based upon what's in .versions array
18+
function getSortedExtensions(extensions: CatalogExtensionInfo[]): CatalogExtensionInfo[] {
19+
return extensions.sort((a, b) => {
20+
const aLastUpdated = a.versions?.[a.versions.length - 1]?.lastUpdated ?? 0;
21+
const bLastUpdated = b.versions?.[b.versions.length - 1]?.lastUpdated ?? 0;
22+
return Number(bLastUpdated) - Number(aLastUpdated);
23+
});
24+
}
25+
26+
$: {
27+
const limit = getQueryLimit();
28+
showCategories = !limit;
529
6-
const { extensionsByCategories }: { extensionsByCategories: ExtensionByCategoryInfo[] } = $props();
30+
if (limit) {
31+
const allExtensions = extensionsByCategories.flatMap(({ extensions }) => extensions);
32+
filteredExtensions = getSortedExtensions(allExtensions).slice(0, limit);
33+
}
34+
console.log('filteredExtensions', filteredExtensions);
35+
}
736
</script>
837

938
<div class="flex flex-col h-full">
10-
{#each extensionsByCategories as extensionByCategoryInfo}
11-
<ExtensionsByCategory {extensionByCategoryInfo} />
12-
{/each}
39+
{#if showCategories}
40+
{#each extensionsByCategories as extensionByCategoryInfo}
41+
<ExtensionsByCategory {extensionByCategoryInfo} />
42+
{/each}
43+
{:else}
44+
<div
45+
class="mt-2 grid min-[920px]:grid-cols-2 min-[1180px]:grid-cols-3 gap-3"
46+
role="region"
47+
aria-label="Queried extensions"
48+
>
49+
{#each filteredExtensions as extension}
50+
<ExtensionByCategoryCard {extension} />
51+
{/each}
52+
</div>
53+
{/if}
1354
</div>

0 commit comments

Comments
 (0)