whisper-money/resources/js/components/transactions
Víctor Falcón 8df44c2ef4
feat(transactions): save and reuse transaction filters (#496)
## What

Adds **saved filters** on the transactions page so users can name a set
of filters and reuse them later. The whole feature is gated behind a new
\`transaction-analysis\` Pennant feature flag (off by default).

## Why

Reusing the same filter combinations (e.g. "Japan trip", "Utilities") is
currently manual every time. This ports the saved-filters work from the
\`analysis-page\` branch, scoped down to **only** the transactions page
— the analysis screen and unrelated query changes from that branch are
intentionally left out.

## Changes

**Feature flag**
- \`App\Features\TransactionAnalysis\` — class-based flag, resolves
\`false\` by default.
- Shared to the frontend as \`features.transactionAnalysis\` and added
to the \`Features\` type.

**Backend (saved filters)**
- \`SavedFilter\` model (UUID, \`filters\` json cast, user belongsTo) +
migration + factory.
- \`Api\SavedFilterController\` — user-scoped index/store/update/destroy
under \`/api/saved-filters\`, ownership enforced with \`abort_unless\`.
- \`StoreSavedFilterRequest\` / \`UpdateSavedFilterRequest\` — name
unique per user, snake_case filter rules.

**Frontend**
- \`transaction-filter-serialization.ts\` —
serialize/deserialize/fingerprint between UI filter state and the
persisted snake_case shape.
- \`SavedFilters\` dropdown — load/save/update/delete with active +
dirty indicators.
- Integrated into the filter bar via an opt-in \`enableSavedFilters\`
prop, so it renders **only** on the transactions page (budgets/accounts
reuse the same component and stay unchanged). Render is also gated by
the feature flag.

**Filter bar UX**
- Split search + filters + saved searches onto their own row, separate
from the actions row (Categorize / Add transactions / columns), which
were getting cramped.
- On mobile, the text search moves into the filters popover.

## Reviewer notes
- Backend endpoints are **not** flag-gated; only the UI is, per the
request.
- Two-layer scoping: page opt-in prop **and** feature flag — flag off
means no UI anywhere.
- Translation keys fall back to the key (English); \`es.json\` entries
not added, matching the source branch.

## Testing
- \`tests/Feature/SavedFilterTest.php\` — 9 passing (auth, per-user
listing/uniqueness, ownership on update/delete).
- Pint, Prettier, ESLint clean. No new TypeScript errors introduced.
2026-06-05 18:00:14 +02:00
..
bulk-actions-bar.tsx Fix label creation dropdown refresh (#363) 2026-05-07 10:26:43 +01:00
bulk-category-select.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
bulk-label-select.tsx Fix label creation dropdown refresh (#363) 2026-05-07 10:26:43 +01:00
categorizer-card.tsx feat(categorize): show debtor and creditor names (#454) 2026-05-30 12:27:59 +02:00
categorizer-command.tsx feat: parent/child category tree (#474) 2026-06-03 19:30:12 +02:00
category-cell.tsx Prompt automation after categorizing transactions (#378) 2026-05-14 09:17:12 +02:00
category-select.tsx feat(shared): Add CategoryCombobox component 2025-11-14 16:05:53 +01:00
edit-transaction-dialog.test.tsx feat(transactions): add counterparty fields (#440) 2026-05-27 16:20:55 +02:00
edit-transaction-dialog.tsx refactor(js): extract shared getCsrfToken util (#475) 2026-06-03 17:26:09 +02:00
encrypted-transaction-description.tsx feat: Plaintext transactions behind feature flag (#105) 2026-02-10 14:31:24 +01:00
import-step-account.test.tsx Fix transaction importer account preselect (#396) 2026-05-14 12:38:44 +02:00
import-step-account.tsx Fix transaction importer account preselect (#396) 2026-05-14 12:38:44 +02:00
import-step-mapping.tsx fix(import): honor selected date format for CSV imports (#494) 2026-06-05 15:10:48 +02:00
import-step-preview.tsx feat(import): calculate balances from transactions (#403) 2026-05-20 10:29:14 +01:00
import-step-upload.test.tsx Fix transaction importer account preselect (#396) 2026-05-14 12:38:44 +02:00
import-step-upload.tsx Fix transaction importer account preselect (#396) 2026-05-14 12:38:44 +02:00
import-transactions-button.tsx fix(i18n): translate Unknown Income/Expense and other missing ES strings (#331) 2026-04-24 17:58:26 +01:00
import-transactions-drawer.tsx fix(import): honor selected date format for CSV imports (#494) 2026-06-05 15:10:48 +02:00
saved-filters.tsx feat(transactions): save and reuse transaction filters (#496) 2026-06-05 18:00:14 +02:00
transaction-actions-menu.tsx fix(banking): correct backfill-ibans endpoint, handle expired sessions, and update labels (#223) 2026-03-12 12:23:32 +00:00
transaction-columns.tsx feat(transactions): add counterparty fields (#440) 2026-05-27 16:20:55 +02:00
transaction-filters.tsx feat(transactions): save and reuse transaction filters (#496) 2026-06-05 18:00:14 +02:00
transaction-list.tsx feat: optionally update manual account balance on transaction delete (#491) 2026-06-05 11:30:31 +02:00