Skip to content

Commit 627219a

Browse files
authored
refactor: extract data-table components and reorganize structure (#208)
Extract redundant data table components to @/components/data-table/ and reorganize data-table component usage.
1 parent 66df6a3 commit 627219a

19 files changed

Lines changed: 140 additions & 542 deletions

src/components/bulk-actions-toolbar.tsx renamed to src/components/data-table/bulk-actions.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
TooltipTrigger,
1212
} from '@/components/ui/tooltip'
1313

14-
type BulkActionsToolbarProps<TData> = {
14+
type DataTableBulkActionsProps<TData> = {
1515
table: Table<TData>
1616
entityName: string
1717
children: React.ReactNode
@@ -27,11 +27,11 @@ type BulkActionsToolbarProps<TData> = {
2727
* @param {React.ReactNode} props.children The action buttons to be rendered inside the toolbar.
2828
* @returns {React.ReactNode | null} The rendered component or null if no rows are selected.
2929
*/
30-
export function BulkActionsToolbar<TData>({
30+
export function DataTableBulkActions<TData>({
3131
table,
3232
entityName,
3333
children,
34-
}: BulkActionsToolbarProps<TData>): React.ReactNode | null {
34+
}: DataTableBulkActionsProps<TData>): React.ReactNode | null {
3535
const selectedRows = table.getFilteredSelectedRowModel().rows
3636
const selectedCount = selectedRows.length
3737
const toolbarRef = useRef<HTMLDivElement>(null)
File renamed without changes.
File renamed without changes.

src/components/data-table/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export { DataTablePagination } from './pagination'
2+
export { DataTableColumnHeader } from './column-header'
3+
export { DataTableFacetedFilter } from './faceted-filter'
4+
export { DataTableViewOptions } from './view-options'
5+
export { DataTableToolbar } from './toolbar'
6+
export { DataTableBulkActions } from './bulk-actions'
File renamed without changes.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Cross2Icon } from '@radix-ui/react-icons'
2+
import { type Table } from '@tanstack/react-table'
3+
import { Button } from '@/components/ui/button'
4+
import { Input } from '@/components/ui/input'
5+
import { DataTableFacetedFilter } from './faceted-filter'
6+
import { DataTableViewOptions } from './view-options'
7+
8+
type DataTableToolbarProps<TData> = {
9+
table: Table<TData>
10+
searchPlaceholder?: string
11+
searchKey?: string
12+
filters?: {
13+
columnId: string
14+
title: string
15+
options: {
16+
label: string
17+
value: string
18+
icon?: React.ComponentType<{ className?: string }>
19+
}[]
20+
}[]
21+
}
22+
23+
export function DataTableToolbar<TData>({
24+
table,
25+
searchPlaceholder = 'Filter...',
26+
searchKey,
27+
filters = [],
28+
}: DataTableToolbarProps<TData>) {
29+
const isFiltered =
30+
table.getState().columnFilters.length > 0 || table.getState().globalFilter
31+
32+
return (
33+
<div className='flex items-center justify-between'>
34+
<div className='flex flex-1 flex-col-reverse items-start gap-y-2 sm:flex-row sm:items-center sm:space-x-2'>
35+
{searchKey ? (
36+
<Input
37+
placeholder={searchPlaceholder}
38+
value={
39+
(table.getColumn(searchKey)?.getFilterValue() as string) ?? ''
40+
}
41+
onChange={(event) =>
42+
table.getColumn(searchKey)?.setFilterValue(event.target.value)
43+
}
44+
className='h-8 w-[150px] lg:w-[250px]'
45+
/>
46+
) : (
47+
<Input
48+
placeholder={searchPlaceholder}
49+
value={table.getState().globalFilter ?? ''}
50+
onChange={(event) => table.setGlobalFilter(event.target.value)}
51+
className='h-8 w-[150px] lg:w-[250px]'
52+
/>
53+
)}
54+
<div className='flex gap-x-2'>
55+
{filters.map((filter) => {
56+
const column = table.getColumn(filter.columnId)
57+
if (!column) return null
58+
return (
59+
<DataTableFacetedFilter
60+
key={filter.columnId}
61+
column={column}
62+
title={filter.title}
63+
options={filter.options}
64+
/>
65+
)
66+
})}
67+
</div>
68+
{isFiltered && (
69+
<Button
70+
variant='ghost'
71+
onClick={() => {
72+
table.resetColumnFilters()
73+
table.setGlobalFilter('')
74+
}}
75+
className='h-8 px-2 lg:px-3'
76+
>
77+
Reset
78+
<Cross2Icon className='ms-2 h-4 w-4' />
79+
</Button>
80+
)}
81+
</div>
82+
<DataTableViewOptions table={table} />
83+
</div>
84+
)
85+
}
File renamed without changes.

src/features/tasks/components/data-table-bulk-actions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
TooltipContent,
1616
TooltipTrigger,
1717
} from '@/components/ui/tooltip'
18-
import { BulkActionsToolbar } from '@/components/bulk-actions-toolbar'
18+
import { DataTableBulkActions as BulkActionsToolbar } from '@/components/data-table'
1919
import { priorities, statuses } from '../data/data'
2020
import { type Task } from '../data/schema'
2121
import { TasksMultiDeleteDialog } from './tasks-multi-delete-dialog'

src/features/tasks/components/data-table-toolbar.tsx

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/features/tasks/components/tasks-columns.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { type ColumnDef } from '@tanstack/react-table'
22
import { Badge } from '@/components/ui/badge'
33
import { Checkbox } from '@/components/ui/checkbox'
4+
import { DataTableColumnHeader } from '@/components/data-table'
45
import { labels, priorities, statuses } from '../data/data'
56
import { type Task } from '../data/schema'
6-
import { DataTableColumnHeader } from './data-table-column-header'
77
import { DataTableRowActions } from './data-table-row-actions'
88

99
export const tasksColumns: ColumnDef<Task>[] = [

0 commit comments

Comments
 (0)