From e9195978c14bc645b25fc0a12e63bdc1b7cab0dd Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 6 Jun 2026 20:45:25 +0200 Subject: [PATCH 1/2] feat(libra): surface voided transactions in standalone history Voided entries keep their '!' flag and gain a 'voided' tag per the libra reject convention, so detecting them needs a tag check rather than a new flag char. Render them inline with the existing 'x'-flag voided styling (grey XCircle icon, strike-through title/amount, red-tinted Voided badge) so users like Nancy can see their rejected entries instead of having them silently disappear from the list. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../expenses/views/TransactionsPage.vue | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index 70b560c..fbec2d9 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -46,6 +46,10 @@ function isExpense(t: Transaction): boolean { return t.tags?.includes('expense-entry') ?? false } +function isVoided(t: Transaction): boolean { + return t.tags?.includes('voided') ?? false +} + const walletKey = computed(() => user.value?.wallets?.[0]?.inkey) // Fuzzy search state and configuration @@ -108,17 +112,20 @@ function formatAmount(amount: number): string { return new Intl.NumberFormat('en-US').format(amount) } -// Get status icon and color based on flag -function getStatusInfo(flag?: string) { - switch (flag) { +// Get status icon and color. Voided entries (per libra convention) keep +// flag='!' and carry a 'voided' tag — surface that as the icon regardless +// of the underlying flag. +function getStatusInfo(transaction: Transaction) { + if (isVoided(transaction)) { + return { icon: XCircle, color: 'text-muted-foreground', label: 'Voided' } + } + switch (transaction.flag) { case '*': return { icon: CheckCircle2, color: 'text-green-600', label: 'Cleared' } case '!': return { icon: Clock, color: 'text-orange-600', label: 'Pending' } case '#': return { icon: Flag, color: 'text-red-600', label: 'Flagged' } - case 'x': - return { icon: XCircle, color: 'text-muted-foreground', label: 'Voided' } default: return null } @@ -328,14 +335,19 @@ onMounted(() => {
-

+

{{ transaction.description }}

@@ -346,10 +358,21 @@ onMounted(() => {
-

+

{{ formatAmount(transaction.amount) }} sats

-

+

{{ transaction.fiat_amount.toFixed(2) }} {{ transaction.fiat_currency }}

@@ -376,10 +399,11 @@ onMounted(() => { :class="[ 'text-xs', tag === 'income-entry' && 'bg-green-100 dark:bg-green-900/20 text-green-700 dark:text-green-300', - tag === 'expense-entry' && 'bg-red-100 dark:bg-red-900/20 text-red-700 dark:text-red-300' + tag === 'expense-entry' && 'bg-red-100 dark:bg-red-900/20 text-red-700 dark:text-red-300', + tag === 'voided' && 'bg-red-100 dark:bg-red-900/20 text-red-700 dark:text-red-300' ]" > - {{ tag }} + {{ tag === 'voided' ? 'Voided' : tag }} -- 2.53.0 From 1fbf7b3d26998e8a0f514b090614e3ba85f6de99 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 6 Jun 2026 20:45:55 +0200 Subject: [PATCH 2/2] fix(libra): exclude voided txs from balance Pending section BalancePage filtered tx.flag === '!' to compute pending count/sum/list. After the libra backend stops hiding voided transactions, those will arrive with flag='!' plus a 'voided' tag and would otherwise leak into the Pending section. Add the tag-aware exclusion to keep Pending showing only genuinely pending entries. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/views/BalancePage.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/accounting-app/views/BalancePage.vue b/src/accounting-app/views/BalancePage.vue index 1335021..8b6492b 100644 --- a/src/accounting-app/views/BalancePage.vue +++ b/src/accounting-app/views/BalancePage.vue @@ -98,8 +98,11 @@ async function loadData() { totalIncomeSats.value = balanceData.total_income_sats || 0 totalIncomeFiat.value = balanceData.total_income_fiat || {} - // Filter for pending transactions (flag = '!') - pendingTransactions.value = txData.entries.filter(tx => tx.flag === '!') + // Filter for pending transactions (flag = '!'), excluding voided ones + // (libra convention: voided keeps '!' flag and carries a 'voided' tag). + pendingTransactions.value = txData.entries.filter( + tx => tx.flag === '!' && !tx.tags?.includes('voided') + ) } catch (error) { console.error('[BalancePage] Error loading data:', error) toast.error('Failed to load balance data') -- 2.53.0