whisper-money/resources/js/components/shared
Víctor Falcón 1553325c4f
refactor(settings): move the last two settings tables onto the shared table and hook (#775)
## Why

#770 extracted `SettingsTable` for the categories and labels pages and
noted that `accounts.tsx` and `automation-rules.tsx` repeat the same
markup. This is that follow-up.

Two clusters remained across the four settings pages:

1. **The table markup** — 30 lines of header groups, body, and empty
row, still copied in `accounts` and `automation-rules`.
2. **The table setup** — all four declared the same four pieces of state
and the same `useReactTable` call with the same six options, differing
only in `data` and (for labels) the initial sort.

## What changed

**`useSettingsTable(data, columns, initialSorting?)`** — a new hook
owning the sorting / filtering / column-visibility state and the
tanstack setup. All four pages use it, so the setup exists once:

```tsx
const table = useSettingsTable(accounts, columns);
const table = useSettingsTable(labels, columns, [{ id: 'name', desc: false }]);
```

**`SettingsTable`** now renders `accounts` and `automation-rules` too,
each passing its own row component through `renderRow`.

## Behaviour

One visual change: `SettingsTable`'s container goes from
`overflow-hidden` to `overflow-x-auto` — which is what `accounts.tsx`
already used, being the widest of the four tables. Keeping
`overflow-hidden` would have clipped it on narrow screens; the other
three pages only notice when their table outgrows the container, and
scrolling is the better answer there than cutting content off.

Everything else is a move: same columns, same rows, same empty messages,
same client-side sorting and filtering.

## Metrics

Measured against `main` (which already has #766–#770):

| | before | after |
|---|---|---|
| duplicated lines (total) | 4.83% | 4.71% |
| duplicated lines (tsx) | 5.03% | 4.82% |
| clones | 302 | 297 |

Since the start of this series, total duplication has gone 5.34% →
4.71%.

## Testing

ESLint and `tsc --noEmit` clean. These pages are covered by the browser
suite (`AccountsPageTest`, `AutomationRuleBuilderTest`,
`CategoriesTest`), which needs a production asset build I don't run
locally — so CI's `browser-tests-matrix` is the verification, as in
#770.
2026-08-11 13:54:18 +00:00
..
category-breakdown-list.tsx fix(analysis): truncate long breakdown names so amounts stay in widget (#518) 2026-06-10 21:58:36 +02:00
category-combobox.tsx feat(ai): auto-categorize transactions with AI (behind flag) (#535) 2026-06-15 16:35:20 +02:00
label-combobox-state.test.ts fix: prevent account label combobox crash (#230) 2026-03-16 13:03:11 +01:00
label-combobox-state.ts fix: prevent account label combobox crash (#230) 2026-03-16 13:03:11 +01:00
label-combobox.tsx refactor(js): extract shared getCsrfToken util (#475) 2026-06-03 17:26:09 +02:00
row-edit-delete-actions.tsx refactor(settings): dedupe the categories and labels pages (#770) 2026-08-11 14:37:23 +02:00
settings-table.tsx refactor(settings): move the last two settings tables onto the shared table and hook (#775) 2026-08-11 13:54:18 +00:00