SegmentDetail: sort efforts by time by default, sortable column headers
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user