feat: show every amount in one currency, chosen in the header, $ toggles it

A selector in the header and the palette's Currency group pick the
currency, the primary one by default; the choice persists between pages
and $ switches it on and off. Rates come from Firefly's exchange rates,
then from the owner's own transactions with a foreign amount, walking
through other currencies when there is no direct pair. Amount converts
with a ≈ and keeps the original in its title; Money sums several
currencies into one converted amount.
This commit is contained in:
hh committed 2026-10-16 18:15:53 +00:00
1 parent 3c1d8a4867
commit 2231c08eee
6 files changed
+315 -44

No files matched your search

+1 -35
View File
@@ -14,30 +14,11 @@
import PiggyBanksBox from "#lib/components/dashboard/PiggyBanksBox.svelte";
import SubscriptionsBox from "#lib/components/dashboard/SubscriptionsBox.svelte";
import PageHeader from "#lib/components/shell/PageHeader.svelte";
import Checkbox from "#lib/components/ui/checkbox/checkbox.svelte";
import { provideColumn } from "#lib/dashboard/column.svelte.js";
import { inPrimary, ratesQuery } from "#lib/dashboard/primary.svelte.js";
import { useKeys } from "#lib/keys.svelte.js";
import { period } from "#lib/period.svelte.js";
import { session } from "#lib/session.svelte.js";
provideColumn();
const rates = createQuery(() => ratesQuery());
const primary = $derived(session.primary?.code ?? "");
const ownRates = $derived(
inPrimary.on && Object.values(rates.data ?? {}).some((r) => r.own)
);
useKeys(() => [
{
group: "Dashboard",
keys: "$",
label: `Show totals in ${primary}`,
run: () => inPrimary.toggle(),
},
]);
const assets = createQuery(() =>
accountsQuery("asset", period.start, period.end)
);
@@ -49,22 +30,7 @@
});
</script>
<PageHeader subtitle="What's playing?" title="Dashboard">
{#snippet actions()}
<div class="flex items-center gap-1.5 text-[12px] text-cladd-fg-soft">
<Checkbox
checked={inPrimary.on}
id="in-primary"
onCheckedChange={() => inPrimary.toggle()}
/>
<label for="in-primary">Show in {primary}</label>
<span class="hidden sm:inline"><span class="kbd">$</span></span>
{#if ownRates}
<span>≈ from your own exchanges</span>
{/if}
</div>
{/snippet}
</PageHeader>
<PageHeader subtitle="What's playing?" title="Dashboard" />
<InfoBoxes />