Files
budget2.0/src/ui/monthPie.ts
T
Lucas Winther 7cccd7a41a
Continuous Integration / lint-and-test (push) Successful in 17s
Continuous Integration / docker-build-and-push (push) Successful in 35s
feat: add month breakdown and session backups
Allow recurring costs and confirmations to remain unassigned when created from a purchase without a post. Add browser backup retention and restore controls, with coverage and documentation updates.
2026-10-01 04:01:49 +02:00

30 lines
1.1 KiB
TypeScript

import type { MonthViewModel } from "../domain/views.ts";
export type MonthPieMode = "spending" | "allocation";
export interface MonthPieSlice {
id: string;
label: string;
amount: number;
}
/** Chart data comes from the same folded figures as the month table. */
export function monthPieData(view: MonthViewModel, mode: MonthPieMode) {
const items: MonthPieSlice[] = view.rows.map(({ post, figures }) => ({
id: post.id,
label: post.name,
amount: mode === "spending" ? figures.charges : figures.allocation,
}));
if (mode === "spending" && view.looseCharges !== 0) {
items.push({ id: "unassigned", label: "Unassigned", amount: view.looseCharges });
}
const byAmount = (a: MonthPieSlice, b: MonthPieSlice) => b.amount - a.amount || a.label.localeCompare(b.label);
const positive = items.filter((item) => item.amount > 0).sort(byAmount);
const adjustments = items.filter((item) => item.amount < 0).sort((a, b) => a.amount - b.amount);
return {
positive,
adjustments,
positiveTotal: positive.reduce((sum, item) => sum + item.amount, 0),
netTotal: mode === "spending" ? view.totalCharges : view.totalAllocation,
};
}