feat: improve data-table responsiveness and add bulk action support
This commit is contained in:
parent
54ccda7d80
commit
68e007e305
@ -160,14 +160,39 @@ export function DataTable<TData, TValue>({
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex flex-1 items-center gap-2">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div className="flex flex-1 flex-col sm:flex-row items-stretch sm:items-center gap-2">
|
||||
<Input
|
||||
placeholder="Cari..."
|
||||
value={globalFilter ?? ""}
|
||||
onChange={(event) => setGlobalFilter(event.target.value)}
|
||||
className="max-w-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
{selectedRows.length > 0 && bulkActions && (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="secondary" className="gap-2 animate-in fade-in slide-in-from-left-2 transition-all">
|
||||
Aksi Massal ({selectedRows.length})
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{bulkActions.map((action, i) => (
|
||||
<DropdownMenuItem
|
||||
key={i}
|
||||
onClick={() => action.onClick(selectedRows.map((r) => r.original))}
|
||||
className={action.variant === "destructive" ? "text-red-600 focus:text-red-600" : ""}
|
||||
>
|
||||
{action.icon && <action.icon className="mr-2 h-4 w-4" />}
|
||||
{action.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)}
|
||||
|
||||
{filters && filters.length > 0 && (
|
||||
<DropdownMenu>
|
||||
@ -177,7 +202,7 @@ export function DataTable<TData, TValue>({
|
||||
Filter
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="w-48">
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuLabel>Filter Berdasarkan</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{filters.map((filter) => {
|
||||
@ -216,64 +241,41 @@ export function DataTable<TData, TValue>({
|
||||
</DropdownMenu>
|
||||
)}
|
||||
|
||||
{selectedRows.length > 0 && bulkActions && (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="secondary" className="gap-2 animate-in fade-in slide-in-from-left-2 transition-all">
|
||||
Aksi Massal ({selectedRows.length})
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
{bulkActions.map((action, i) => (
|
||||
<DropdownMenuItem
|
||||
key={i}
|
||||
onClick={() => action.onClick(selectedRows.map((r) => r.original))}
|
||||
className={action.variant === "destructive" ? "text-red-600 focus:text-red-600" : ""}
|
||||
>
|
||||
{action.icon && <action.icon className="mr-2 h-4 w-4" />}
|
||||
{action.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)}
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="gap-2">
|
||||
<Settings2 className="h-4 w-4" />
|
||||
Kolom
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuLabel>Tampilan Kolom</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter((column) => column.getCanHide())
|
||||
.map((column) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
>
|
||||
{(column.columnDef.meta as any)?.title ||
|
||||
(typeof column.columnDef.header === "string"
|
||||
? column.columnDef.header
|
||||
: String(column.id).replace(/_/g, " "))}
|
||||
</DropdownMenuCheckboxItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="ml-auto gap-2">
|
||||
<Settings2 className="h-4 w-4" />
|
||||
Kolom
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuLabel>Tampilan Kolom</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter((column) => column.getCanHide())
|
||||
.map((column) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
>
|
||||
{(column.columnDef.meta as any)?.title ||
|
||||
(typeof column.columnDef.header === "string"
|
||||
? column.columnDef.header
|
||||
: String(column.id).replace(/_/g, " "))}
|
||||
</DropdownMenuCheckboxItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
<div className="overflow-hidden rounded-md border bg-background">
|
||||
<div className="overflow-x-auto rounded-md border bg-background">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
@ -333,13 +335,13 @@ export function DataTable<TData, TValue>({
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between py-4">
|
||||
<div className="flex-1 text-sm text-muted-foreground">
|
||||
<div className="flex flex-col sm:flex-row items-center justify-between gap-4 py-4">
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{table.getFilteredSelectedRowModel().rows.length} dari{" "}
|
||||
{table.getFilteredRowModel().rows.length} baris dipilih.
|
||||
</div>
|
||||
<div className="flex items-center space-x-6 lg:space-x-8">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex flex-col sm:flex-row items-center gap-4 sm:gap-6 lg:gap-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm font-medium">Baris per halaman</p>
|
||||
<Select
|
||||
value={`${table.getState().pagination.pageSize}`}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user