From b09675f2b2911424e372dbaa31582f8f5caa37c9 Mon Sep 17 00:00:00 2001 From: slothful-vassal <89943360+slothful-vassal@users.noreply.github.com> Date: Sat, 4 Oct 2025 17:22:46 +0200 Subject: [PATCH] Select number of search items per page (#577) * select items per pages * fix 'all' * fix page switch * fix filter update when 'all' * startDrawing: set map to current user position * remove startDrawing change from other branch * handle 413 * remove 'all', cange increment, use local storage * remove obsolete import, fix 413 --- web/src/lib/components/base/pagination.svelte | 7 +- .../trail/map_with_elevation_maplibre.svelte | 3 +- .../lib/components/trail/trail_list.svelte | 125 ++++++++++++++++-- .../lib/components/trail/trail_table.svelte | 5 +- web/src/lib/stores/profile_store.ts | 2 +- web/src/lib/stores/trail_store.ts | 5 +- .../profile/[handle]/trails/+page.svelte | 7 +- web/src/routes/trails/+page.svelte | 62 +++++++-- 8 files changed, 186 insertions(+), 30 deletions(-) diff --git a/web/src/lib/components/base/pagination.svelte b/web/src/lib/components/base/pagination.svelte index e57e180f..154cca70 100644 --- a/web/src/lib/components/base/pagination.svelte +++ b/web/src/lib/components/base/pagination.svelte @@ -4,16 +4,17 @@ interface Props { page: number; totalPages: number; - onpagination?: (page: number) => void; + perPage: number; + onpagination?: (page: number, perPage: number) => void; } - let { page, totalPages, onpagination }: Props = $props(); + let { page, totalPages, perPage, onpagination }: Props = $props(); const maxPagesToRender = 6; function update(clickedPage: number) { if (page !== clickedPage) { - onpagination?.(clickedPage); + onpagination?.(clickedPage, perPage); } } diff --git a/web/src/lib/components/trail/map_with_elevation_maplibre.svelte b/web/src/lib/components/trail/map_with_elevation_maplibre.svelte index 9af23802..ce5a4003 100644 --- a/web/src/lib/components/trail/map_with_elevation_maplibre.svelte +++ b/web/src/lib/components/trail/map_with_elevation_maplibre.svelte @@ -809,8 +809,7 @@ animate: fitBounds == "animate", }, trackUserLocation: true, - }), - ); + })); if (showStyleSwitcher) { map.addControl(switcherControl); diff --git a/web/src/lib/components/trail/trail_list.svelte b/web/src/lib/components/trail/trail_list.svelte index 3d1a3590..5c77930a 100644 --- a/web/src/lib/components/trail/trail_list.svelte +++ b/web/src/lib/components/trail/trail_list.svelte @@ -15,14 +15,14 @@ interface Props { filter?: TrailFilter | null; trails: Trail[]; - pagination?: { page: number; totalPages: number }; + pagination?: { page: number; totalPages: number, items: number }; loading?: boolean; fullWidthCards?: boolean; onupdate?: ( filter: TrailFilter | null, selection: Set | undefined, ) => void; - onpagination?: (page: number) => void; + onpagination?: (page: number, items: number) => void; } let { @@ -31,6 +31,7 @@ pagination = { page: 1, totalPages: 1, + items: 25, }, loading = false, fullWidthCards = false, @@ -43,6 +44,20 @@ { text: $_("list", { values: { n: 1 } }), value: "list" }, { text: $_("table"), value: "table" }, ]; + + const perPageOptions: SelectItem[] = [ + { text: "10", value: 10 }, + { text: "25", value: 25 }, + { text: "50", value: 50 }, + { text: "100", value: 100 }, + ]; + + const perPageOptionsCards: SelectItem[] = [ + { text: "12", value: 12 }, + { text: "24", value: 24 }, + { text: "48", value: 48 }, + { text: "96", value: 96 }, + ]; let selectedDisplayOption = $state(displayOptions[0].value); @@ -65,6 +80,7 @@ const storedDisplayOption = localStorage.getItem("displayOption"); const storedSort = localStorage.getItem("sort"); const storedSortOrder = localStorage.getItem("sort_order"); + const paginationItems = localStorage.getItem("paginationItems"); if (storedDisplayOption) { selectedDisplayOption = storedDisplayOption; @@ -78,11 +94,84 @@ (storedSortOrder as typeof filter.sortOrder | null) ?? filter.sortOrder; } + if (paginationItems) { + pagination.items = +paginationItems; + + let itemsChanged = false; + if (selectedDisplayOption == "cards") { + if (pagination.items > 50) { + pagination.items = 96; + itemsChanged = true; + } else if (pagination.items > 25) { + pagination.items = 48; + itemsChanged = true; + } else if (pagination.items > 12) { + pagination.items = 24; + itemsChanged = true; + } else { + pagination.items = 12; + itemsChanged = true; + } + } else { + if (pagination.items > 50) { + pagination.items = 100; + itemsChanged = true; + } else if (pagination.items > 25) { + pagination.items = 50; + itemsChanged = true; + } else if (pagination.items > 12) { + pagination.items = 25; + itemsChanged = true; + } else { + pagination.items = 10; + itemsChanged = true; + } + } + + if (itemsChanged) { + localStorage.setItem("paginationItems", pagination.items.toString()); + } + } onupdate?.(filter, selection); }); function setDisplayOption() { localStorage.setItem("displayOption", selectedDisplayOption); + + let itemsChanged = false; + if (selectedDisplayOption == "cards") { + if (pagination.items > 50) { + pagination.items = 96; + itemsChanged = true; + } else if (pagination.items > 25) { + pagination.items = 48; + itemsChanged = true; + } else if (pagination.items > 12) { + pagination.items = 24; + itemsChanged = true; + } else { + pagination.items = 12; + itemsChanged = true; + } + } else { + if (pagination.items > 50) { + pagination.items = 100; + itemsChanged = true; + } else if (pagination.items > 25) { + pagination.items = 50; + itemsChanged = true; + } else if (pagination.items > 12) { + pagination.items = 25; + itemsChanged = true; + } else { + pagination.items = 10; + itemsChanged = true; + } + } + + if (itemsChanged) { + localStorage.setItem("paginationItems", pagination.items.toString()); + } } function setSort() { @@ -206,6 +295,11 @@ function handleMouseLeave(trail: Trail) { handleHoverUpdate(trail); } + + function setItemsPerPage() { + localStorage.setItem("paginationItems", pagination.items.toString()); + onpagination?.(1, pagination.items); + }
@@ -214,6 +308,7 @@
@@ -267,9 +362,10 @@ trails={null} selection={new Set()} tableHeader={sortOptions} + items={pagination.items} > {:else} - {#each { length: 12 } as _, index} + {#each { length: pagination.items } as _, index} {#if selectedDisplayOption === "cards"}
@@ -293,6 +389,7 @@ (option) => option.value !== "elevation_loss", )} {filter} + items={pagination.items} onsort={handleSortUpdate} onTrailSelect={(t) => handleSelectionUpdate(t)} > @@ -330,11 +427,23 @@ {/if} {/if}
- +
+
+ +
+
+ +
+