fix(transactions): improve mobile analysis button affordance (#520)

## Summary

Improves the transaction actions menu on mobile:

- **Tap-to-show tooltip instead of a modal** — when the Analysis button
is tapped with no filter applied, it now shows the same tooltip used on
desktop ("Apply a filter to enable this button") via a controlled Radix
tooltip, instead of opening a separate modal dialog.
- **Always show the "Analysis" label on mobile** — previously the mobile
button was icon-only, which made it hard to understand. It now shows the
icon + label like desktop.
- **Move "Add transaction" into the more-actions dropdown on mobile** —
frees up horizontal space so the Analysis label fits. On desktop the
standalone Add transaction button is unchanged.

## Notes

- Reuses the existing `Add transaction` translation key (already in
`lang/es.json`).
- Removed the now-unused `Dialog` import/markup.

## Test plan

- [ ] On mobile, tap Analysis with no filter → tooltip appears on tap,
dismisses on tap outside.
- [ ] On mobile, the Analysis button shows its label.
- [ ] On mobile, "Add transaction" appears in the more-actions (⌄)
dropdown.
- [ ] On desktop, behavior is unchanged (hover tooltip, standalone Add
transaction button).
This commit is contained in:
Víctor Falcón 2026-06-12 16:21:23 +02:00 committed by GitHub
parent 9c3c4d573e
commit 3223824edb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 69 additions and 59 deletions

View File

@ -1,13 +1,6 @@
import { categorize } from '@/actions/App/Http/Controllers/TransactionController'; import { categorize } from '@/actions/App/Http/Controllers/TransactionController';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { ButtonGroup } from '@/components/ui/button-group'; import { ButtonGroup } from '@/components/ui/button-group';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -84,7 +77,7 @@ export function TransactionActionsMenu({
const handleAnalysisClick = () => { const handleAnalysisClick = () => {
if (!canAnalyze) { if (!canAnalyze) {
if (isMobile) { if (isMobile) {
setAnalysisHintOpen(true); setAnalysisHintOpen((open) => !open);
} }
return; return;
} }
@ -130,20 +123,35 @@ export function TransactionActionsMenu({
<ButtonGroup> <ButtonGroup>
{features.transactionAnalysis && {features.transactionAnalysis &&
(isMobile ? ( (isMobile ? (
<Button <TooltipProvider>
variant="outline" <Tooltip
size="icon" open={!canAnalyze && analysisHintOpen}
className={ onOpenChange={setAnalysisHintOpen}
!canAnalyze >
? 'cursor-not-allowed opacity-50' <TooltipTrigger asChild>
: '' <Button
} variant="outline"
aria-disabled={!canAnalyze} className={
aria-label={__('Analysis')} !canAnalyze
onClick={handleAnalysisClick} ? 'cursor-not-allowed opacity-50'
> : ''
<BarChart3 className="h-5 w-5" /> }
</Button> aria-disabled={!canAnalyze}
onClick={handleAnalysisClick}
>
<BarChart3 className="h-5 w-5" />
{__('Analysis')}
</Button>
</TooltipTrigger>
{!canAnalyze && (
<TooltipContent>
{__(
'Apply a filter to enable this button',
)}
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
) : ( ) : (
<TooltipProvider> <TooltipProvider>
<Tooltip> <Tooltip>
@ -211,32 +219,36 @@ export function TransactionActionsMenu({
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
<TooltipProvider> {!isMobile && (
<Tooltip> <TooltipProvider>
<TooltipTrigger asChild> <Tooltip>
<Button <TooltipTrigger asChild>
variant="outline" <Button
className={ variant="outline"
!isKeySet className={
? 'cursor-not-allowed opacity-50' !isKeySet
: '' ? 'cursor-not-allowed opacity-50'
} : ''
onClick={handleAddTransaction} }
aria-label={__('Add transaction')} onClick={handleAddTransaction}
> aria-label={__('Add transaction')}
<Plus className="h-5 w-5" /> >
<span className="hidden sm:inline"> <Plus className="h-5 w-5" />
{__('Transaction')} <span className="hidden sm:inline">
</span> {__('Transaction')}
</Button> </span>
</TooltipTrigger> </Button>
<TooltipContent> </TooltipTrigger>
{!isKeySet <TooltipContent>
? __('Unlock encryption to add transactions') {!isKeySet
: __('Create a new transaction')} ? __(
</TooltipContent> 'Unlock encryption to add transactions',
</Tooltip> )
</TooltipProvider> : __('Create a new transaction')}
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
<DropdownMenu> <DropdownMenu>
<TooltipProvider> <TooltipProvider>
@ -258,6 +270,15 @@ export function TransactionActionsMenu({
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
<DropdownMenuContent align="end"> <DropdownMenuContent align="end">
{isMobile && (
<DropdownMenuItem
onClick={handleAddTransaction}
disabled={!isKeySet}
>
<Plus className="mr-2 h-4 w-4" />
{__('Add transaction')}
</DropdownMenuItem>
)}
<DropdownMenuItem <DropdownMenuItem
onClick={handleOpenImportDrawer} onClick={handleOpenImportDrawer}
disabled={!isKeySet} disabled={!isKeySet}
@ -293,17 +314,6 @@ export function TransactionActionsMenu({
filters={filters} filters={filters}
/> />
)} )}
<Dialog open={analysisHintOpen} onOpenChange={setAnalysisHintOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>{__('Analysis')}</DialogTitle>
<DialogDescription>
{__('Apply a filter to enable this button')}
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
</> </>
); );
} }