@@ -50,11 +50,17 @@ const hasFeaturedPlugins = featured.length > 0;
5050 <select aria-label =" Sort by" id =" sort" >
5151 <option value =" name-asc" selected >Name (A-Z)</option >
5252 <option value =" name-desc" >Name (Z-A)</option >
53+ <option value =" first-release-desc" >Release Date</option >
54+ <option value =" latest-release-desc" >Last Updated</option >
5355 </select >
5456 </LabelValue >
5557 </div >
5658 <div id =" store" class =" plugin-grid" >
57- { plugins .map (v => <Plugin plugin = { v } />)}
59+ { plugins .map (v => <Plugin
60+ plugin = { v }
61+ data-first-release-date = { v .firstReleaseDate }
62+ data-latest-release-date = { v .latestReleaseDate }
63+ />)}
5864 </div >
5965 <SectionSubheader >
6066 <div id =" not-found" style =" display: none;" >No plugins found</div >
@@ -115,7 +121,12 @@ const store = document.querySelector("#store") as HTMLElement;
115121
116122const plugins = document.querySelectorAll("#store > .plugin") as NodeListOf<HTMLElement>;
117123const defaultSortValue = "name-asc";
118- const allowedSortValues = ["name-asc", "name-desc"];
124+ const allowedSortValues = [
125+ "name-asc",
126+ "name-desc",
127+ "latest-release-desc",
128+ "first-release-desc",
129+ ];
119130
120131searchInput.addEventListener("input", onFilterChange);
121132tagsSelect.addEventListener("change", onFilterChange);
@@ -213,6 +224,12 @@ function filterPlugins(): void {
213224 }
214225}
215226
227+ function getDateTimestamp(plugin: HTMLElement, attributeName: string): number {
228+ const dateValue = plugin.getAttribute(attributeName) ?? "";
229+ const timestamp = Date.parse(dateValue);
230+ return Number.isNaN(timestamp) ? 0 : timestamp;
231+ }
232+
216233function applySort(): void {
217234 const sortValue = sortSelect.value;
218235
@@ -221,14 +238,32 @@ function applySort(): void {
221238 }
222239
223240 const sortedPlugins = Array.from(plugins).sort((a, b) => {
224- const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
225- const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
226-
227- if (sortValue === "name-desc") {
228- return titleB.localeCompare(titleA);
241+ switch (sortValue) {
242+ case "latest-release-desc": {
243+ const latestA = getDateTimestamp(a, "data-latest-release-date");
244+ const latestB = getDateTimestamp(b, "data-latest-release-date");
245+ return latestB - latestA;
246+ }
247+
248+ case "first-release-desc": {
249+ const firstA = getDateTimestamp(a, "data-first-release-date");
250+ const firstB = getDateTimestamp(b, "data-first-release-date");
251+ return firstB - firstA;
252+ }
253+
254+ case "name-desc": {
255+ const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
256+ const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
257+ return titleB.localeCompare(titleA);
258+ }
259+
260+ case "name-asc":
261+ default: {
262+ const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
263+ const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
264+ return titleA.localeCompare(titleB);
265+ }
229266 }
230-
231- return titleA.localeCompare(titleB);
232267 });
233268
234269 // Re-appending existing plugin nodes moves them into sorted order (no duplicates)
0 commit comments