SegmentDetail: sort efforts by time by default, sortable column headers

This commit is contained in:
Davide Scaini
2026-05-13 11:17:22 +02:00
parent 0ff5473dfd
commit f00e5e47b2
+48 -7
View File
@@ -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 @@
<table class="w-full text-sm">
<thead class="border-b border-zinc-800">
<tr class="text-left text-zinc-500 text-xs">
<th class="px-4 py-2">Date</th>
<th class="px-4 py-2">Time</th>
<th class="px-4 py-2">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='started_at'} on:click={() => setSort('started_at')}>
Date{sortKey==='started_at' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
<th class="px-4 py-2">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='elapsed_s'} on:click={() => setSort('elapsed_s')}>
Time{sortKey==='elapsed_s' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
<th class="px-4 py-2">Δ PR</th>
<th class="px-4 py-2 hidden sm:table-cell">Avg speed</th>
<th class="px-4 py-2 hidden sm:table-cell">Avg HR</th>
<th class="px-4 py-2 hidden md:table-cell">Avg power</th>
<th class="px-4 py-2 hidden md:table-cell">NP</th>
<th class="px-4 py-2 hidden sm:table-cell">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_speed_kmh'} on:click={() => setSort('avg_speed_kmh')}>
Avg speed{sortKey==='avg_speed_kmh' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
<th class="px-4 py-2 hidden sm:table-cell">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_hr_bpm'} on:click={() => setSort('avg_hr_bpm')}>
Avg HR{sortKey==='avg_hr_bpm' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
<th class="px-4 py-2 hidden md:table-cell">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_power_w'} on:click={() => setSort('avg_power_w')}>
Avg power{sortKey==='avg_power_w' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
<th class="px-4 py-2 hidden md:table-cell">
<button class="hover:text-white transition-colors" class:text-white={sortKey==='np_power_w'} on:click={() => setSort('np_power_w')}>
NP{sortKey==='np_power_w' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
</button>
</th>
</tr>
</thead>
<tbody>
{#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}
<tr