@@ -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 >
@@ -114,7 +120,12 @@ const store = document.querySelector("#store") as HTMLElement;
114120
115121const plugins = document.querySelectorAll("#store > .plugin") as NodeListOf<HTMLElement>;
116122const defaultSortValue = "name-asc";
117- const allowedSortValues = ["name-asc", "name-desc"];
123+ const allowedSortValues = [
124+ "name-asc",
125+ "name-desc",
126+ "latest-release-desc",
127+ "first-release-desc",
128+ ];
118129
119130searchInput.addEventListener("input", onFilterChange);
120131tagsSelect.addEventListener("change", onFilterChange);
@@ -212,6 +223,12 @@ function filterPlugins(): void {
212223 }
213224}
214225
226+ function getDateTimestamp(plugin: HTMLElement, attributeName: string): number {
227+ const dateValue = plugin.getAttribute(attributeName) ?? "";
228+ const timestamp = Date.parse(dateValue);
229+ return Number.isNaN(timestamp) ? 0 : timestamp;
230+ }
231+
215232function applySort(): void {
216233 const sortValue = sortSelect.value;
217234
@@ -220,14 +237,32 @@ function applySort(): void {
220237 }
221238
222239 const sortedPlugins = Array.from(plugins).sort((a, b) => {
223- const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
224- const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
225-
226- if (sortValue === "name-desc") {
227- return titleB.localeCompare(titleA);
240+ switch (sortValue) {
241+ case "latest-release-desc": {
242+ const latestA = getDateTimestamp(a, "data-latest-release-date");
243+ const latestB = getDateTimestamp(b, "data-latest-release-date");
244+ return latestB - latestA;
245+ }
246+
247+ case "first-release-desc": {
248+ const firstA = getDateTimestamp(a, "data-first-release-date");
249+ const firstB = getDateTimestamp(b, "data-first-release-date");
250+ return firstB - firstA;
251+ }
252+
253+ case "name-desc": {
254+ const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
255+ const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
256+ return titleB.localeCompare(titleA);
257+ }
258+
259+ case "name-asc":
260+ default: {
261+ const titleA = a.querySelector(".name")!.textContent!.trim().toLowerCase();
262+ const titleB = b.querySelector(".name")!.textContent!.trim().toLowerCase();
263+ return titleA.localeCompare(titleB);
264+ }
228265 }
229-
230- return titleA.localeCompare(titleB);
231266 });
232267
233268 // Re-appending existing plugin nodes moves them into sorted order (no duplicates)
0 commit comments