Fix sidebar unit navigation to include reverse conversion pairs
This commit is contained in:
@@ -23,35 +23,75 @@
|
||||
|
||||
type UnitGroup = {
|
||||
label: string;
|
||||
conversions: CalculatorDef[];
|
||||
conversions: UnitConversionLink[];
|
||||
};
|
||||
|
||||
type UnitBucket = {
|
||||
label: string;
|
||||
conversions: CalculatorDef[];
|
||||
conversions: UnitConversionLink[];
|
||||
};
|
||||
|
||||
const sortConversionsForUnit = (conversions: CalculatorDef[]) =>
|
||||
type UnitConversionLink = {
|
||||
name: string;
|
||||
slug: string;
|
||||
sortKey: string;
|
||||
};
|
||||
|
||||
const sortConversionsForUnit = (conversions: UnitConversionLink[]) =>
|
||||
conversions.slice().sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const toPairKey = (unitA: string, unitB: string) =>
|
||||
[unitA.toLowerCase(), unitB.toLowerCase()].sort().join('::');
|
||||
|
||||
const toDirectionKey = (fromUnit: string, toUnit: string) =>
|
||||
`${fromUnit.toLowerCase()}::${toUnit.toLowerCase()}`;
|
||||
|
||||
function addConversion(
|
||||
buckets: Map<string, UnitBucket>,
|
||||
fromUnit: string,
|
||||
toUnit: string,
|
||||
slug: string
|
||||
) {
|
||||
const bucketKey = fromUnit.toLowerCase();
|
||||
const directionKey = toDirectionKey(fromUnit, toUnit);
|
||||
const conversion: UnitConversionLink = {
|
||||
name: `${fromUnit} to ${toUnit}`,
|
||||
slug,
|
||||
sortKey: directionKey,
|
||||
};
|
||||
|
||||
const existing = buckets.get(bucketKey);
|
||||
if (existing) {
|
||||
if (!existing.conversions.some(link => link.sortKey === directionKey)) {
|
||||
existing.conversions.push(conversion);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buckets.set(bucketKey, {
|
||||
label: fromUnit,
|
||||
conversions: [conversion],
|
||||
});
|
||||
}
|
||||
|
||||
$: categoryUnitGroups = Object.entries(categories).map(([key, meta]) => {
|
||||
const buckets = new Map<string, UnitBucket>();
|
||||
const calcs = getCalculatorsByCategory(key);
|
||||
const canonicalByPair = new Map<string, CalculatorDef>();
|
||||
|
||||
calcs.forEach(calc => {
|
||||
const unit = calc.labels.in1;
|
||||
const bucketKey = unit.toLowerCase();
|
||||
const existing = buckets.get(bucketKey);
|
||||
if (existing) {
|
||||
existing.conversions.push(calc);
|
||||
} else {
|
||||
buckets.set(bucketKey, {
|
||||
label: unit,
|
||||
conversions: [calc],
|
||||
});
|
||||
const pairKey = toPairKey(calc.labels.in1, calc.labels.in2);
|
||||
const existing = canonicalByPair.get(pairKey);
|
||||
if (!existing || calc.slug.localeCompare(existing.slug) < 0) {
|
||||
canonicalByPair.set(pairKey, calc);
|
||||
}
|
||||
});
|
||||
|
||||
canonicalByPair.forEach(calc => {
|
||||
addConversion(buckets, calc.labels.in1, calc.labels.in2, calc.slug);
|
||||
addConversion(buckets, calc.labels.in2, calc.labels.in1, calc.slug);
|
||||
});
|
||||
|
||||
const units = [...buckets.entries()]
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([, bucket]) => ({
|
||||
@@ -178,14 +218,14 @@
|
||||
</button>
|
||||
{#if expandedUnits[group.key] === unit.label}
|
||||
<ul class="unit-list">
|
||||
{#each unit.conversions as calc}
|
||||
{#each unit.conversions as conversion}
|
||||
<li>
|
||||
<a
|
||||
href="/{calc.slug}"
|
||||
class:current={currentPath === `/${calc.slug}`}
|
||||
aria-current={currentPath === `/${calc.slug}` ? 'page' : undefined}
|
||||
href="/{conversion.slug}"
|
||||
class:current={currentPath === `/${conversion.slug}`}
|
||||
aria-current={currentPath === `/${conversion.slug}` ? 'page' : undefined}
|
||||
>
|
||||
{calc.name}
|
||||
{conversion.name}
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user