From f00e5e47b2609a8cf25a484d62456952e6afa038 Mon Sep 17 00:00:00 2001 From: Davide Scaini Date: Wed, 13 May 2026 11:17:22 +0200 Subject: [PATCH] SegmentDetail: sort efforts by time by default, sortable column headers --- site/src/components/SegmentDetail.svelte | 55 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/site/src/components/SegmentDetail.svelte b/site/src/components/SegmentDetail.svelte index d8afe1e..b76f6b6 100644 --- a/site/src/components/SegmentDetail.svelte +++ b/site/src/components/SegmentDetail.svelte @@ -27,6 +27,8 @@ np_power_w: number | null; } + type SortKey = 'started_at' | 'elapsed_s' | 'avg_speed_kmh' | 'avg_hr_bpm' | 'avg_power_w' | 'np_power_w'; + let segment: Segment | null = null; let efforts: Effort[] = []; let loading = true; @@ -36,9 +38,24 @@ let mapReady = false; let retriggering = false; let retriggerMsg: string | null = null; + let sortKey: SortKey = 'elapsed_s'; + let sortDir: 1 | -1 = 1; $: prElapsed = efforts.length ? Math.min(...efforts.map(e => e.elapsed_s)) : null; + $: sortedEfforts = [...efforts].sort((a, b) => { + const av = a[sortKey], bv = b[sortKey]; + if (av == null && bv == null) return 0; + if (av == null) return 1; + if (bv == null) return -1; + return av < bv ? -sortDir : av > bv ? sortDir : 0; + }); + + function setSort(key: SortKey) { + if (sortKey === key) sortDir = sortDir === 1 ? -1 : 1; + else { sortKey = key; sortDir = 1; } + } + function delta(elapsed: number): number { return prElapsed != null ? elapsed - prElapsed : 0; } @@ -209,17 +226,41 @@ - - + + - - - - + + + + - {#each efforts as e (e.activity_id + e.started_at)} + {#each sortedEfforts as e (e.activity_id + e.started_at)} {@const d = delta(e.elapsed_s)} {@const isPR = d === 0}
DateTime + + + + Δ PR