fix(transactions): tidy filter bar into two balanced rows (#510)

## What

Tidies the transactions filter bar so it lays out as **two balanced
rows** — a control on the left and on the right of each — instead of
wrapping awkwardly once **Transaction analysis** is enabled (the
saved-filters button was crowding the row).

- **Row 1:** `Filters` (left) · search input (grows, middle) ·
saved-filters bookmark (right)
- **Row 2:** `Analysis / Categorize / + Transaction / ▾` (left) ·
`Columns` (right)

Actions row dropped `flex-wrap` + `sm:justify-end` in favour of a clean
`justify-between`; the saved-filters/clear group is now grouped to the
right with `ml-auto`.

## Screenshots

**Desktop**


![Desktop](https://github.com/whisper-money/whisper-money/blob/assets/transaction-filters-screenshots/screenshots/transactions-desktop.png?raw=true)

**Mobile**


![Mobile](https://github.com/whisper-money/whisper-money/blob/assets/transaction-filters-screenshots/screenshots/transactions-mobile.png?raw=true)

## Notes

- Screenshots are hosted on a throwaway
`assets/transaction-filters-screenshots` branch so they render here
without landing in `main`. Safe to delete after merge.
This commit is contained in:
Víctor Falcón 2026-06-09 11:04:32 +02:00 committed by GitHub
parent c944a2c37e
commit 6486908716
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 27 deletions

View File

@ -132,16 +132,17 @@ export function TransactionActionsMenu({
(isMobile ? (
<Button
variant="outline"
size="icon"
className={
!canAnalyze
? 'cursor-not-allowed opacity-50'
: ''
}
aria-disabled={!canAnalyze}
aria-label={__('Analysis')}
onClick={handleAnalysisClick}
>
<BarChart3 className="h-5 w-5" />
{__('Analysis')}
</Button>
) : (
<TooltipProvider>
@ -224,7 +225,9 @@ export function TransactionActionsMenu({
aria-label={__('Add transaction')}
>
<Plus className="h-5 w-5" />
{__('Transaction')}
<span className="hidden sm:inline">
{__('Transaction')}
</span>
</Button>
</TooltipTrigger>
<TooltipContent>

View File

@ -239,13 +239,6 @@ export function TransactionFilters({
<div className="space-y-4">
<div className="flex flex-col gap-3">
<div className="flex w-full flex-row items-center gap-2">
<Input
placeholder={__('Search description or notes...')}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
className="hidden min-w-0 flex-1 md:block md:min-w-[350px]"
/>
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button variant="outline">
@ -704,24 +697,33 @@ export function TransactionFilters({
</PopoverContent>
</Popover>
{enableSavedFilters && features.transactionAnalysis && (
<SavedFilters
filters={filters}
onLoad={onFiltersChange}
/>
)}
<Input
placeholder={__('Search description or notes...')}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
className="hidden min-w-0 flex-1 md:block md:min-w-[350px]"
/>
{activeFilterCount > 0 && (
<Button
variant="ghost"
size="sm"
onClick={clearFilters}
className="h-9"
>
<X className="mr-1 h-4 w-4" />
{__('Clear')}
</Button>
)}
<div className="ml-auto flex items-center gap-2">
{enableSavedFilters && features.transactionAnalysis && (
<SavedFilters
filters={filters}
onLoad={onFiltersChange}
/>
)}
{activeFilterCount > 0 && (
<Button
variant="ghost"
size="sm"
onClick={clearFilters}
className="h-9"
>
<X className="mr-1 h-4 w-4" />
{__('Clear')}
</Button>
)}
</div>
</div>
{actions ? <div className="w-full">{actions}</div> : null}

View File

@ -1167,7 +1167,7 @@ export default function Transactions({
isKeySet={true}
enableSavedFilters={true}
actions={
<div className="flex w-full flex-wrap justify-between gap-2 sm:justify-end">
<div className="flex w-full items-center justify-between gap-2">
<TransactionActionsMenu
categories={categories}
accounts={accounts}