feat: per-group sort order (defined/alpha) in group form and converter
This commit is contained in:
@@ -37,6 +37,8 @@ export interface Group {
|
|||||||
baseUnitId: string;
|
baseUnitId: string;
|
||||||
/** Relative scale for cross-group YOLO conversions. */
|
/** Relative scale for cross-group YOLO conversions. */
|
||||||
toUniversal: number;
|
toUniversal: number;
|
||||||
|
/** Display order for units in the converter. Defaults to 'defined'. */
|
||||||
|
sortOrder?: 'defined' | 'alpha';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Full data payload for units and groups. */
|
/** Full data payload for units and groups. */
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
fromUnitId = id;
|
fromUnitId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Group units for display — single O(n) pass ──────────────────────────────
|
// ── Derived: results per group for display — single O(n) pass ──────────────
|
||||||
let orderedResults: { groupLabel: string | null; items: ResultItem[] }[] = $derived.by(() => {
|
let orderedResults: { groupLabel: string | null; items: ResultItem[] }[] = $derived.by(() => {
|
||||||
// Build a Map of groupId → items in a single pass over results
|
// Build a Map of groupId → items in a single pass over results
|
||||||
const byGroup = new Map<string | null, ResultItem[]>();
|
const byGroup = new Map<string | null, ResultItem[]>();
|
||||||
@@ -147,7 +147,12 @@
|
|||||||
const sections: { groupLabel: string | null; items: ResultItem[] }[] = [];
|
const sections: { groupLabel: string | null; items: ResultItem[] }[] = [];
|
||||||
for (const group of groups) {
|
for (const group of groups) {
|
||||||
const items = byGroup.get(group.id);
|
const items = byGroup.get(group.id);
|
||||||
if (items?.length) sections.push({ groupLabel: group.label, items });
|
if (items?.length) {
|
||||||
|
const sorted = group.sortOrder === 'alpha'
|
||||||
|
? [...items].sort((a, b) => a.unit.label.localeCompare(b.unit.label))
|
||||||
|
: items;
|
||||||
|
sections.push({ groupLabel: group.label, items: sorted });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const orphaned = byGroup.get(null);
|
const orphaned = byGroup.get(null);
|
||||||
if (orphaned?.length) sections.push({ groupLabel: 'Ungrouped', items: orphaned });
|
if (orphaned?.length) sections.push({ groupLabel: 'Ungrouped', items: orphaned });
|
||||||
|
|||||||
@@ -803,6 +803,15 @@
|
|||||||
<small class="muted">Relative scale for cross-group (YOLO) conversions. Arbitrary.</small>
|
<small class="muted">Relative scale for cross-group (YOLO) conversions. Arbitrary.</small>
|
||||||
<input type="number" bind:value={groupForm.toUniversal} min="0.000001" step="any" />
|
<input type="number" bind:value={groupForm.toUniversal} min="0.000001" step="any" />
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
Display order
|
||||||
|
<small class="muted">How units in this group are sorted in the converter.</small>
|
||||||
|
<select bind:value={groupForm.sortOrder}>
|
||||||
|
<option value={undefined}>Defined order (default)</option>
|
||||||
|
<option value="defined">Defined order</option>
|
||||||
|
<option value="alpha">Alphabetical</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button onclick={saveGroup}>{groupFormNew ? 'Create' : 'Save'}</button>
|
<button onclick={saveGroup}>{groupFormNew ? 'Create' : 'Save'}</button>
|
||||||
{#if !groupFormNew}
|
{#if !groupFormNew}
|
||||||
|
|||||||
Reference in New Issue
Block a user