FactuGES_ERP/packages/rdx-ui/src/components/datatable/data-table-toolbar.tsx

171 lines
5.8 KiB
TypeScript
Raw Normal View History

2025-10-16 17:59:13 +00:00
import { Button, Separator, Tooltip, TooltipContent, TooltipTrigger } from '@repo/shadcn-ui/components'
import { cn } from '@repo/shadcn-ui/lib/utils'
2025-10-16 11:18:55 +00:00
import { Table } from "@tanstack/react-table"
2025-10-16 17:59:13 +00:00
import { ArrowDownIcon, ArrowUpIcon, CopyPlusIcon, PlusIcon, ScanIcon, TrashIcon } from 'lucide-react'
import { useCallback, useMemo } from 'react'
import { useTranslation } from "../../locales/i18n.ts"
2025-10-16 11:18:55 +00:00
import { DataTableViewOptions } from './data-table-view-options.tsx'
2025-10-16 17:59:13 +00:00
import { DataTableMeta } from './data-table.tsx'
2025-10-16 11:18:55 +00:00
interface DataTableToolbarProps<TData> {
table: Table<TData>
2025-10-16 17:59:13 +00:00
showViewOptions?: boolean
2025-10-16 11:18:55 +00:00
}
export function DataTableToolbar<TData>({
table,
2025-10-16 17:59:13 +00:00
showViewOptions = true,
2025-10-16 11:18:55 +00:00
}: DataTableToolbarProps<TData>) {
2025-10-16 17:59:13 +00:00
const { t } = useTranslation()
const meta = table.options.meta as DataTableMeta<TData>
| undefined
const rowSelection = table.getSelectedRowModel().rows;
const selectedCount = rowSelection.length;
const hasSelection = selectedCount > 0;
const selectedRowIndexes = useMemo(() => rowSelection.map((row) => row.index), [rowSelection]);
const handleAdd = useCallback(() => meta?.tableOps?.onAdd?.(table), [meta])
const handleDuplicateSelected = useCallback(
() => meta?.bulkOps?.duplicateSelected?.(selectedRowIndexes, table),
[meta, selectedRowIndexes]
)
const handleMoveSelectedUp = useCallback(
() => meta?.bulkOps?.moveSelectedUp?.(selectedRowIndexes, table),
[meta, selectedRowIndexes]
)
const handleMoveSelectedDown = useCallback(
() => meta?.bulkOps?.moveSelectedDown?.(selectedRowIndexes, table),
[meta, selectedRowIndexes]
)
const handleRemoveSelected = useCallback(
() => meta?.bulkOps?.removeSelected?.(selectedRowIndexes, table),
[meta, selectedRowIndexes]
)
2025-10-16 11:18:55 +00:00
return (
2025-10-16 17:59:13 +00:00
<div
className={cn(
"flex items-center justify-between gap-2 py-2",
"border-b border-muted px-1 sm:px-2"
)}
>
{/* IZQUIERDA: acciones globales y sobre selección */}
<div className="flex flex-1 items-center gap-2 flex-wrap">
{meta?.tableOps?.onAdd && (
<Button
type='button'
size="sm"
onClick={handleAdd}
aria-label={t("components.datatable.actions.add")}
>
<PlusIcon className="size-4 mr-1" aria-hidden="true" />
<span>{t("components.datatable.actions.add")}</span>
</Button>
)}
{hasSelection && (
<>
<Separator orientation="vertical" className="h-5 mx-1" />
{meta?.bulkOps?.duplicateSelected && (
<Button
type='button'
size="sm"
variant="outline"
onClick={handleDuplicateSelected}
aria-label={t("components.datatable.actions.duplicate")}
>
<CopyPlusIcon className="size-4 mr-1" aria-hidden="true" />
<span>{t("components.datatable.actions.duplicate")}</span>
</Button>
)}
2025-10-16 11:18:55 +00:00
2025-10-16 17:59:13 +00:00
{meta?.bulkOps?.moveSelectedUp && (
<Tooltip>
<TooltipTrigger asChild>
<Button
type='button'
size="sm"
variant="outline"
onClick={handleMoveSelectedUp}
aria-label={t("components.datatable.actions.move_up")}
>
<ArrowUpIcon className="size-4" aria-hidden="true" />
</Button>
</TooltipTrigger>
<TooltipContent>{t("components.datatable.actions.move_up")}</TooltipContent>
</Tooltip>
)}
{meta?.bulkOps?.moveSelectedDown && (
<Tooltip>
<TooltipTrigger asChild>
<Button
type='button'
size="sm"
variant="outline"
onClick={handleMoveSelectedDown}
aria-label={t("components.datatable.actions.move_down")}
>
<ArrowDownIcon className="size-4" aria-hidden="true" />
</Button>
</TooltipTrigger>
<TooltipContent>{t("components.datatable.actions.move_down")}</TooltipContent>
</Tooltip>
)}
{meta?.bulkOps?.removeSelected && (
<>
<Separator orientation="vertical" className="h-5 mx-1 w-1 bg-red-500" />
<Button
type='button'
size="sm"
variant="destructive"
onClick={handleRemoveSelected}
aria-label={t("components.datatable.actions.remove")}
>
<TrashIcon className="size-4 mr-1" aria-hidden="true" />
<span>{t("components.datatable.actions.remove")}</span>
</Button>
</>
)}
<Separator orientation="vertical" className="h-6 mx-1 bg-muted/50" />
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
size="sm"
variant="outline"
disabled={!table.getSelectedRowModel().rows.length}
onClick={() => table.resetRowSelection()}
>
<ScanIcon className="size-4 mr-1" aria-hidden="true" />
<span>Quitar selección</span>
</Button>
</TooltipTrigger>
<TooltipContent>Quita la selección</TooltipContent>
</Tooltip>
</>
)}
2025-10-16 11:18:55 +00:00
</div>
2025-10-16 17:59:13 +00:00
{/* DERECHA: opciones de vista / filtros */}
2025-10-16 11:18:55 +00:00
<div className="flex items-center gap-2">
2025-10-16 17:59:13 +00:00
{showViewOptions && <DataTableViewOptions table={table} />}
2025-10-16 11:18:55 +00:00
</div>
</div>
)
}