Files
chartdb/src/pages/editor-page/canvas/toolbar/toolbar.tsx
Jonathan Fishner bda150d4b6 feat: add floating "Show All" button when tables are out of view (#787)
* feat: add floating "Show All" button when tables are out of view

* fix view of show all for mobile

* fix

---------

Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
2025-07-27 16:25:14 +03:00

201 lines
8.0 KiB
TypeScript

import React, { useCallback, useState } from 'react';
import { Card, CardContent } from '@/components/card/card';
import { ZoomIn, ZoomOut, Funnel, Redo, Undo, Scan } from 'lucide-react';
import { Separator } from '@/components/separator/separator';
import { ToolbarButton } from './toolbar-button';
import { useHistory } from '@/hooks/use-history';
import { useOnViewportChange, useReactFlow } from '@xyflow/react';
import {
Tooltip,
TooltipTrigger,
TooltipContent,
} from '@/components/tooltip/tooltip';
import { useTranslation } from 'react-i18next';
import { Button } from '@/components/button/button';
import { keyboardShortcutsForOS } from '@/context/keyboard-shortcuts-context/keyboard-shortcuts';
import { KeyboardShortcutAction } from '@/context/keyboard-shortcuts-context/keyboard-shortcuts';
import { useCanvas } from '@/hooks/use-canvas';
import { useChartDB } from '@/hooks/use-chartdb';
import { cn } from '@/lib/utils';
const convertToPercentage = (value: number) => `${Math.round(value * 100)}%`;
export interface ToolbarProps {
readonly?: boolean;
}
export const Toolbar: React.FC<ToolbarProps> = () => {
const { t } = useTranslation();
const { redo, undo, hasRedo, hasUndo } = useHistory();
const { getZoom, zoomIn, zoomOut, fitView } = useReactFlow();
const [zoom, setZoom] = useState<string>(convertToPercentage(getZoom()));
const { setShowFilter } = useCanvas();
const { hiddenTableIds } = useChartDB();
const toggleFilter = useCallback(() => {
setShowFilter((prev) => !prev);
}, [setShowFilter]);
useOnViewportChange({
onChange: ({ zoom }) => {
setZoom(convertToPercentage(zoom));
},
});
const zoomDuration = 200;
const zoomInHandler = () => {
zoomIn({ duration: zoomDuration });
};
const zoomOutHandler = () => {
zoomOut({ duration: zoomDuration });
};
const resetZoom = () => {
fitView({
minZoom: 1,
maxZoom: 1,
duration: zoomDuration,
});
};
const showAll = useCallback(() => {
fitView({
duration: 500,
padding: 0.1,
maxZoom: 0.8,
});
}, [fitView]);
return (
<div className="px-1">
<Card className="h-[44px] bg-secondary p-0 shadow-none">
<CardContent className="flex h-full flex-row items-center p-1">
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton
onClick={toggleFilter}
className={cn(
'transition-all duration-200',
{
'bg-pink-500 text-white hover:bg-pink-600 hover:text-white':
(hiddenTableIds ?? []).length >
0,
}
)}
>
<Funnel />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>
{t('toolbar.filter')}
<span className="ml-2 text-muted-foreground">
{
keyboardShortcutsForOS[
KeyboardShortcutAction.TOGGLE_FILTER
].keyCombinationLabel
}
</span>
</TooltipContent>
</Tooltip>
<Separator orientation="vertical" />
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton onClick={showAll}>
<Scan />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>
{t('toolbar.show_all')}
<span className="ml-2 text-muted-foreground">
{
keyboardShortcutsForOS[
KeyboardShortcutAction.SHOW_ALL
].keyCombinationLabel
}
</span>
</TooltipContent>
</Tooltip>
<Separator orientation="vertical" />
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton onClick={zoomOutHandler}>
<ZoomOut />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>{t('toolbar.zoom_out')}</TooltipContent>
</Tooltip>
<Button
variant="ghost"
onClick={resetZoom}
className="w-[60px] p-2 hover:bg-primary-foreground"
>
{zoom}
</Button>
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton onClick={zoomInHandler}>
<ZoomIn />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>{t('toolbar.zoom_in')}</TooltipContent>
</Tooltip>
<Separator orientation="vertical" />
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton
onClick={undo}
disabled={!hasUndo}
>
<Undo />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>
{t('toolbar.undo')}
<span className="ml-2 text-muted-foreground">
{
keyboardShortcutsForOS[
KeyboardShortcutAction.UNDO
].keyCombinationLabel
}
</span>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton
onClick={redo}
disabled={!hasRedo}
>
<Redo />
</ToolbarButton>
</span>
</TooltipTrigger>
<TooltipContent>
{t('toolbar.redo')}
<span className="ml-2 text-muted-foreground">
{
keyboardShortcutsForOS[
KeyboardShortcutAction.REDO
].keyCombinationLabel
}
</span>
</TooltipContent>
</Tooltip>
</CardContent>
</Card>
</div>
);
};