fix tx listing

This commit is contained in:
davmar
2026-09-09 11:40:05 +02:00
parent 2a741c7f2a
commit 903a2980de
8 changed files with 1638 additions and 281 deletions
+30 -17
View File
@@ -42,6 +42,9 @@ class _OverviewScreenState extends State<OverviewScreen> {
/// Empty = include every label. Non-empty = only these ids on the Labels chart.
final Set<String> _includedLabelIds = {};
/// Labels chart flow filter (defaults to expenses / labeled spend).
var _labelFlow = TxFlowFilter.expense;
/// Selected calendar year for Monthly mode (`DateTime(year)`).
late DateTime _cursor;
@@ -100,13 +103,12 @@ class _OverviewScreenState extends State<OverviewScreen> {
});
}
Future<void> _pickChartLabels(
BuildContext context,
List<TxLabel> available,
) async {
Future<void> _pickChartLabels(BuildContext context) async {
final meta = context.read<TxMetaController>();
final available = meta.allLabels;
if (available.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No labels in use for this period yet')),
const SnackBar(content: Text('No labels yet — create some first')),
);
return;
}
@@ -125,18 +127,22 @@ class _OverviewScreenState extends State<OverviewScreen> {
subtitle:
'Choose which labels appear. Long-press to nest under another.',
allowMove: true,
includeFlow: true,
initialFlow: _labelFlow,
);
if (result == null || !mounted) return;
setState(() {
_labelFlow = result.flow;
final allIds = available.map((l) => l.id).toSet();
if (result.isEmpty ||
(result.length == allIds.length && result.containsAll(allIds))) {
if (result.labelIds.isEmpty ||
(result.labelIds.length == allIds.length &&
result.labelIds.containsAll(allIds))) {
_includedLabelIds.clear();
} else {
_includedLabelIds
..clear()
..addAll(result);
..addAll(result.labelIds);
}
_metric = _MetricMode.labels;
});
@@ -203,7 +209,6 @@ class _OverviewScreenState extends State<OverviewScreen> {
// all txs 3–4 times and resolving full meta each time.
Map<DateTime, _MonthBucket> monthly = const {};
var labelSpend = const <_LabelSpend>[];
var availableLabels = const <TxLabel>[];
Map<DateTime, Map<String, double>> labelAmountByPeriod = const {};
if (_metric == _MetricMode.flow) {
@@ -215,9 +220,9 @@ class _OverviewScreenState extends State<OverviewScreen> {
periods,
_period,
includedLabelIds: _includedLabelIds,
flow: _labelFlow,
);
labelSpend = labels.spend;
availableLabels = [for (final row in labels.allSpend) row.label];
labelAmountByPeriod = labels.amountByPeriod;
}
@@ -253,11 +258,14 @@ class _OverviewScreenState extends State<OverviewScreen> {
labelSpend: labelSpend,
labelAmountByMonth: labelAmountByPeriod,
currency: currency,
includedLabelCount: _includedLabelIds.isEmpty
includedLabelCount: _includedLabelIds.isEmpty &&
_labelFlow == TxFlowFilter.expense
? null
: _includedLabelIds.length,
availableLabelCount: availableLabels.length,
onPickLabels: () => _pickChartLabels(context, availableLabels),
: (_includedLabelIds.isEmpty
? meta.allLabels.length
: _includedLabelIds.length),
availableLabelCount: meta.allLabels.length,
onPickLabels: () => _pickChartLabels(context),
onLabelTap: (label) {
Navigator.of(context).push(
MaterialPageRoute<void>(
@@ -309,7 +317,11 @@ class _OverviewScreenState extends State<OverviewScreen> {
labelSpend.fold<double>(0, (s, e) => s + e.amount),
currency,
),
label: 'Labeled spend · $_periodTitle',
label: switch (_labelFlow) {
TxFlowFilter.income => 'Labeled income · $_periodTitle',
TxFlowFilter.expense => 'Labeled spend · $_periodTitle',
TxFlowFilter.all => 'Labeled activity · $_periodTitle',
},
),
],
const SizedBox(height: 20),
@@ -518,13 +530,14 @@ class _LabelAggregates {
int get availableCount => allSpend.length;
}
/// One pass over outflows: totals, per-period series, and history amounts.
/// One pass over labeled amounts: totals, per-period series, and history.
_LabelAggregates _labelAggregates(
List<BankTransaction> txs,
TxMetaController meta,
List<DateTime> periods,
_PeriodMode mode, {
Set<String> includedLabelIds = const {},
TxFlowFilter flow = TxFlowFilter.expense,
}) {
final keys = {for (final p in periods) _periodKey(p, mode)};
final allByLabel = <String, double>{};
@@ -537,7 +550,7 @@ _LabelAggregates _labelAggregates(
final filtering = includedLabelIds.isNotEmpty;
for (final tx in txs) {
if (tx.amount >= 0) continue;
if (!txMatchesFlow(tx, flow)) continue;
final date = _txDate(tx);
if (date == null) continue;
final key = _periodKey(date, mode);