humam kerdiah 4bfd8c84a9 feat: add template checkpoint edit dialog and vendor management components
- Implemented TemplateCheckpointEditDialog for creating and editing inspection checkpoints.
- Added VendorActions component for managing vendor actions including edit, activate/deactivate, and delete.
- Created VendorContext for managing vendor state across components.
- Developed VendorGeneralInfo component to display detailed vendor information.
- Introduced AedSymbol and Money components for consistent currency representation.
- Added PromptDialog for user input prompts throughout the application.
- Implemented RelationLink component for unified related-data display in CRUD tables.
- Created InspectionTemplatesClient for API interactions related to inspection templates.
2026-05-18 12:08:42 +04:00

102 lines
3.5 KiB
TypeScript

"use client"
import type { ColumnDef, Row } from "@tanstack/react-table"
import type { ComponentType } from "react"
import { MoreHorizontal, Pencil, Trash2 } from "lucide-react"
import { Button } from "@/shared/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/shared/components/ui/dropdown-menu"
export type ActionsColumnExtraItem<TData> = {
label: string
icon?: ComponentType<{ className?: string }>
onClick: (row: TData) => void | Promise<unknown>
variant?: "default" | "destructive"
/** Hide the item entirely when false. Useful for permission gates. */
hidden?: boolean
}
export type ActionsColumnOptions<TData> = {
onEdit?: (row: TData) => void
onDelete?: (row: TData) => Promise<unknown>
/** Extra menu items rendered between Edit and Delete. */
extraItems?: (row: TData) => ActionsColumnExtraItem<TData>[]
}
export function createActionsColumn<TData extends { id: string | number }>(
options: ActionsColumnOptions<TData>,
): ColumnDef<TData, unknown> {
return {
id: "actions",
header: () => <span className="sr-only">Actions</span>,
cell: ({ row }) => <ActionsCell row={row} options={options} />,
enableSorting: false,
enableHiding: false,
}
}
function ActionsCell<TData extends { id: string | number }>({
row,
options,
}: {
row: Row<TData>
options: ActionsColumnOptions<TData>
}) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon-sm">
<MoreHorizontal className="size-4" />
<span className="sr-only">Open menu</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{options.onEdit && (
<DropdownMenuItem onClick={(e) => {
e.stopPropagation()
options.onEdit!(row.original)
}}>
<Pencil className="size-3.5 text-muted-foreground" />
Edit
</DropdownMenuItem>
)}
{options.extraItems?.(row.original)
.filter((item) => !item.hidden)
.map((item) => {
const Icon = item.icon
return (
<DropdownMenuItem
key={item.label}
variant={item.variant}
onClick={(e) => {
e.stopPropagation()
void item.onClick(row.original)
}}
>
{Icon ? <Icon className="size-3.5 text-muted-foreground" /> : null}
{item.label}
</DropdownMenuItem>
)
})}
{options.onDelete && (
<DropdownMenuItem
variant="destructive"
onClick={(e) => {
e.stopPropagation()
options.onDelete!(row.original)
}}
>
<Trash2 className="size-3.5" />
Delete
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
)
}