1
2import {
3 ColumnDef,
4 ColumnFiltersState,
5 SortingState,
6 VisibilityState,
7 flexRender,
8 getCoreRowModel,
9 getFilteredRowModel,
10 getPaginationRowModel,
11 getSortedRowModel,
12 useReactTable,
13} from "@tanstack/react-table"
14import {
15 Button,
16 Input,
17 DataTablePagination,
18 DataTableViewOptions,
19 Popover,
20 PopoverTrigger,
21 PopoverContent,
22 Table,
23 TableHeader,
24 TableRow,
25 TableHead,
26 TableCell,
27 TableBody,
28 ToggleGroup,
29 ToggleGroupItem,
30 ScrollArea
31} from "@marzneshin/components"
32import { useTranslation } from "react-i18next"
33import { useState } from "react"
34import { InboundType } from "@marzneshin/features/inbounds"
35import { Server } from "lucide-react"
36import { InboundOption } from "./inbound"
37import { LoaderIcon } from "lucide-react"
38
39interface InboundHostsDataTableProps<TData, TValue> {
40 columns: ColumnDef<TData, TValue>[]
41 data: TData[]
42 inbounds: InboundType[]
43 filteredColumn: string
44 selectedInbound: string | undefined
45 setSelectedInbound: (s: string) => void
46 onCreate?: () => void
47 onOpen?: (object: TData) => void
48 isLoading: boolean
49}
50
51export function InboundHostsDataTable<TData, TValue>({
52 columns,
53 data,
54 onCreate,
55 onOpen,
56 filteredColumn,
57 inbounds,
58 selectedInbound,
59 setSelectedInbound,
60 isLoading,
61}: InboundHostsDataTableProps<TData, TValue>) {
62 const [sorting, setSorting] = useState<SortingState>([])
63 const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
64 const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
65 const table = useReactTable({
66 data,
67 columns,
68 onSortingChange: setSorting,
69 onColumnFiltersChange: setColumnFilters,
70 getCoreRowModel: getCoreRowModel(),
71 getPaginationRowModel: getPaginationRowModel(),
72 getSortedRowModel: getSortedRowModel(),
73 getFilteredRowModel: getFilteredRowModel(),
74 onColumnVisibilityChange: setColumnVisibility,
75 state: {
76 sorting,
77 columnFilters,
78 columnVisibility,
79 },
80 })
81 const { t } = useTranslation();
82 return (
83 <div>
84 <div className="flex justify-between items-center py-4">
85 <Input
86 placeholder={t('table.filter-placeholder', { name: filteredColumn })}
87 value={(table.getColumn(filteredColumn)?.getFilterValue() as string) ?? ""}
88 onChange={(event) =>
89 table.getColumn(filteredColumn)?.setFilterValue(event.target.value)
90 }
91 className="max-w-sm"
92 />
93 <div className="flex items-center">
94 <Popover >
95 <PopoverTrigger asChild>
96 <Button
97 variant="outline"
98 className="mr-2 ml-auto lg:flex"
99 >
100 <Server className="mr-2 w-4 h-4" />
101 {t('inbounds')}
102 </Button>
103 </PopoverTrigger>
104 <PopoverContent className="w-80 max-h-100">
105 <ToggleGroup type="single" onValueChange={setSelectedInbound} defaultValue={selectedInbound} className="flex flex-col justify-center w-full h-full" >
106 <ScrollArea className="w-full h-full">
107 {inbounds.map((inbound) => {
108 return <ToggleGroupItem className="px-0 w-full h-full" value={String(inbound.id)} id={String(inbound.id)}>
109 <InboundOption inbound={inbound} />
110 </ToggleGroupItem>
111 })}
112 </ScrollArea>
113 </ToggleGroup>
114 </PopoverContent>
115 </Popover>
116 <DataTableViewOptions table={table} />
117 {onCreate && (<Button onClick={onCreate}>{t('create')}</Button>)}
118 </div>
119 </div>
120 <div className="rounded-md border">
121 <div>
122 <Table>
123 <TableHeader>
124 {table.getHeaderGroups().map((headerGroup) => (
125 <TableRow key={headerGroup.id}>
126 {headerGroup.headers.map((header) => {
127 return (
128 <TableHead key={header.id}>
129 {header.isPlaceholder
130 ? null
131 : flexRender(
132 header.column.columnDef.header,
133 header.getContext()
134 )}
135 </TableHead>
136 )
137 })}
138 </TableRow>
139 ))}
140 </TableHeader>
141 <TableBody>
142 {isLoading && <LoaderIcon className="w-5 h-5 animate-spin text-primary" />} {!isLoading && table.getRowModel().rows?.length ? (
143 table.getRowModel().rows.map((row) => (
144 <TableRow
145 key={row.id}
146 data-state={row.getIsSelected() && "selected"}
147 onClick={() => onOpen !== undefined && onOpen(row.original)}
148 >
149 {row.getVisibleCells().map((cell) => (
150 <TableCell key={cell.id}>
151 {flexRender(cell.column.columnDef.cell, cell.getContext())}
152 </TableCell>
153 ))}
154 </TableRow>
155 ))
156 ) : (
157 <TableRow>
158 <TableCell colSpan={columns.length} className="h-24 text-center">
159 {t('table.no-result')}
160 </TableCell>
161 </TableRow>
162 )}
163 </TableBody>
164 </Table>
165
166 </div>
167 <DataTablePagination table={table} />
168 </div>
169 </div >
170 )
171}