refactor(libra): redesign transactions list status + type encoding #93

Merged
padreug merged 1 commit from feat/libra-tx-status-encoding into dev 2026-06-06 21:16:45 +00:00
Owner

Summary

Follow-up to #92. Reworks the libra standalone transactions list so each visual channel does one job and the filter UI matches the underlying axes.

Encoding

Channel Encodes
Signed/tinted amount (+green / -red) Type — matches the bank-statement convention
Income / Expense badge Type, again, as a text label. Income = green fill, Expense = orange fill (deliberately not red so it doesn't collide with Voided)
Voided badge Status — outlined grey, sits to the right of the type badge
Pending approval badge Status — yellow fill, the only colored status badge (reserved for "needs attention")
Strike-through + muted amount/title Voided overrides everything visually
(no left border, no status icons) Dropped — they were duplicating signals the badges + amount already carry

Badge order on each row: [Income | Expense] [Voided | Pending approval]? [user tags...]. Type sits first, status (mutually exclusive between Voided and Pending) sits after.

Filter UI

Replaces the previous type radio + voided switch with three category chips in one row:

⧁ [Income]  [Expenses]  [Voided]

Each chip independently toggles inclusion of one bucket of rows. Every row belongs to exactly one bucket — voided rows go to the Voided bucket regardless of their underlying type — so the model stays simple.

Defaults: Income + Expenses on, Voided off (voided is noise day-to-day; the user already saw and rejected them). The empty-selection state nudges the user to enable a category instead of showing a generic "try a different time period".

Test plan

  • Cleared expense renders with - red amount + orange Expense badge
  • Cleared income renders with + green amount + green Income badge
  • Pending entry adds a yellow "Pending approval" badge after the type badge
  • Voided entry strikes through the title + mutes the amount + adds an outlined grey Voided badge
  • Voided chip is off by default; toggling it on reveals voided rows
  • Toggling all chips off shows the empty state with a "select a category" hint
  • User-added tags (not type/status) pass through unchanged on the right
  • Verified end-to-end in regtest against Nancy's view (which has 2 voided + 4 non-voided entries)
## Summary Follow-up to #92. Reworks the libra standalone transactions list so each visual channel does one job and the filter UI matches the underlying axes. ## Encoding | Channel | Encodes | |---|---| | Signed/tinted amount (`+`green / `-`red) | Type — matches the bank-statement convention | | Income / Expense badge | Type, again, as a text label. Income = green fill, **Expense = orange fill** (deliberately not red so it doesn't collide with Voided) | | Voided badge | Status — outlined grey, sits to the right of the type badge | | Pending approval badge | Status — yellow fill, the only colored status badge (reserved for "needs attention") | | Strike-through + muted amount/title | Voided overrides everything visually | | (no left border, no status icons) | Dropped — they were duplicating signals the badges + amount already carry | Badge order on each row: `[Income | Expense] [Voided | Pending approval]? [user tags...]`. Type sits first, status (mutually exclusive between Voided and Pending) sits after. ## Filter UI Replaces the previous type radio + voided switch with **three category chips** in one row: ``` ⧁ [Income] [Expenses] [Voided] ``` Each chip independently toggles inclusion of one bucket of rows. Every row belongs to exactly one bucket — voided rows go to the Voided bucket regardless of their underlying type — so the model stays simple. Defaults: **Income + Expenses on, Voided off** (voided is noise day-to-day; the user already saw and rejected them). The empty-selection state nudges the user to enable a category instead of showing a generic "try a different time period". ## Test plan - [x] Cleared expense renders with `-` red amount + orange Expense badge - [x] Cleared income renders with `+` green amount + green Income badge - [x] Pending entry adds a yellow "Pending approval" badge after the type badge - [x] Voided entry strikes through the title + mutes the amount + adds an outlined grey Voided badge - [x] Voided chip is off by default; toggling it on reveals voided rows - [x] Toggling all chips off shows the empty state with a "select a category" hint - [x] User-added tags (not type/status) pass through unchanged on the right - [x] Verified end-to-end in regtest against Nancy's view (which has 2 voided + 4 non-voided entries)
Original styling used the left border for entry-type (green=income,
red=expense), which clashed visually with the status icons: a red
border on a pending expense suggested "rejected". Split the visual
channels so each conveys one thing:

  - Left border + status icon = workflow state (green accepted,
    yellow pending, red rejected/voided)
  - Signed/tinted amount = type (+green income, -red expense)
  - Strike-through + muted amount = voided
  - Badges = user-added tags only; income-entry / expense-entry
    suppressed (redundant with the amount), Voided kept as a
    high-signal status badge

Follows the conventional bank-statement / personal-finance encoding
(Wise, Mint, YNAB), where amount sign carries direction and chrome
carries state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The status border (green/yellow/red) and the type-tinted amount (green
income, red expense) both used the same palette, so cleared expenses
showed a green border with a red amount and pending income showed a
yellow border with a green amount — same colors carrying two different
meanings on the same row.

Concentrate the encoding so each meaning has one home:
- Status lives in the icon (small, single glyph at the title)
- Type lives in the amount (sign + red/green tint)
- Voided still wins via strike-through + muted amount + Voided badge

Per Wise / Mint / YNAB convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Voided transactions are noise in the day-to-day view (the user already
saw and rejected them), so default to hiding them. A Switch in the filter
row toggles 'Show voided'. When voided are present but hidden, the
results-count line shows '(N voided hidden)' so the toggle has a
discoverable hook.

Pending entries gain a yellow Pending badge symmetric with the red
Voided badge — both signal 'needs attention' states in the badge row,
while cleared entries stay unmarked (the default, quiet state).

Status / type encoding (icon = status, signed/colored amount = type)
is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each chip toggles inclusion of one bucket of rows. Every row belongs to
exactly one bucket — voided rows go to the Voided bucket regardless of
their underlying type — so the model is straightforward:

  [Income] [Expenses] [Voided]
     |         |          |
  income     expense    voided
  (non-voided only)    (any type)

Defaults: Income + Expenses on, Voided off. Independent multi-select.
Empty selection shows the empty state with a 'select a category' hint
instead of an open-ended 'try a different time period'.

Replaces the previous 'type radio + voided switch' pair: same axes, one
control type, no left/right visual split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per the iteration: the title-row status icons (green check / yellow
clock / red X) were doing the same job as the new status badges and
amount color, so each row had three signals fighting for the same
meaning. Drop the icons and lean on badges instead.

Badge row order (left-to-right): Voided > Income/Expense > Pending >
user tags. Type badge sits between the high-attention Voided marker
and the secondary Pending marker, so the type chip is easy to spot
on every row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug force-pushed feat/libra-tx-status-encoding from 58cf5cb762 to 46e255315d 2026-06-06 21:07:02 +00:00 Compare
padreug force-pushed feat/libra-tx-status-encoding from 46e255315d to 9343bc1907 2026-06-06 21:08:23 +00:00 Compare
padreug force-pushed feat/libra-tx-status-encoding from 9343bc1907 to 1fc382c029 2026-06-06 21:11:37 +00:00 Compare
padreug force-pushed feat/libra-tx-status-encoding from 1fc382c029 to 75dfd8a541 2026-06-06 21:13:02 +00:00 Compare
padreug changed title from refactor(libra): encode status on border, type on signed amount to refactor(libra): redesign transactions list status + type encoding 2026-06-06 21:16:34 +00:00
padreug deleted branch feat/libra-tx-status-encoding 2026-06-06 21:16:46 +00:00
Sign in to join this conversation.
No description provided.