124 lines
3.5 KiB
TypeScript
124 lines
3.5 KiB
TypeScript
"use client"
|
|
|
|
import { createColumnHelper } from "@tanstack/react-table"
|
|
|
|
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
|
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
|
|
|
|
import { labels, priorities, statuses } from "../data/data"
|
|
import { type Task } from "../data/schema"
|
|
import { DataTableColumnHeader } from "./data-table-column-header"
|
|
import { type TasksTableFeatures } from "./data-table-features"
|
|
import { DataTableRowActions } from "./data-table-row-actions"
|
|
|
|
// Use `accessor` for data columns and `display` for columns without one.
|
|
const columnHelper = createColumnHelper<TasksTableFeatures, Task>()
|
|
|
|
export const columns = columnHelper.columns([
|
|
columnHelper.display({
|
|
id: "select",
|
|
header: ({ table }) => (
|
|
<Checkbox
|
|
checked={
|
|
table.getIsAllPageRowsSelected() ||
|
|
(table.getIsSomePageRowsSelected() && "indeterminate")
|
|
}
|
|
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
|
aria-label="Select all"
|
|
className="translate-y-[2px]"
|
|
/>
|
|
),
|
|
cell: ({ row }) => (
|
|
<Checkbox
|
|
checked={row.getIsSelected()}
|
|
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
|
aria-label="Select row"
|
|
className="translate-y-[2px]"
|
|
/>
|
|
),
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
}),
|
|
columnHelper.accessor("id", {
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Task" />
|
|
),
|
|
cell: ({ row }) => <div className="w-[80px]">{row.getValue("id")}</div>,
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
}),
|
|
columnHelper.accessor("title", {
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Title" />
|
|
),
|
|
cell: ({ row }) => {
|
|
const label = labels.find((label) => label.value === row.original.label)
|
|
|
|
return (
|
|
<div className="flex gap-2">
|
|
{label && <Badge variant="outline">{label.label}</Badge>}
|
|
<span className="max-w-[500px] truncate font-medium">
|
|
{row.getValue("title")}
|
|
</span>
|
|
</div>
|
|
)
|
|
},
|
|
}),
|
|
columnHelper.accessor("status", {
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Status" />
|
|
),
|
|
cell: ({ row }) => {
|
|
const status = statuses.find(
|
|
(status) => status.value === row.getValue("status")
|
|
)
|
|
|
|
if (!status) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<div className="flex w-[100px] items-center gap-2">
|
|
{status.icon && (
|
|
<status.icon className="size-4 text-muted-foreground" />
|
|
)}
|
|
<span>{status.label}</span>
|
|
</div>
|
|
)
|
|
},
|
|
filterFn: (row, id, value) => {
|
|
return value.includes(row.getValue(id))
|
|
},
|
|
}),
|
|
columnHelper.accessor("priority", {
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Priority" />
|
|
),
|
|
cell: ({ row }) => {
|
|
const priority = priorities.find(
|
|
(priority) => priority.value === row.getValue("priority")
|
|
)
|
|
|
|
if (!priority) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
{priority.icon && (
|
|
<priority.icon className="size-4 text-muted-foreground" />
|
|
)}
|
|
<span>{priority.label}</span>
|
|
</div>
|
|
)
|
|
},
|
|
filterFn: (row, id, value) => {
|
|
return value.includes(row.getValue(id))
|
|
},
|
|
}),
|
|
columnHelper.display({
|
|
id: "actions",
|
|
cell: ({ row }) => <DataTableRowActions row={row} />,
|
|
}),
|
|
])
|