mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 07:43:33 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react";
 | |
| import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
 | |
| import { useMemo } from "react";
 | |
| import type { DeadHost } from "src/api/backend";
 | |
| import {
 | |
| 	CertificateFormatter,
 | |
| 	DomainsFormatter,
 | |
| 	EmptyData,
 | |
| 	GravatarFormatter,
 | |
| 	TrueFalseFormatter,
 | |
| } from "src/components";
 | |
| import { TableLayout } from "src/components/Table/TableLayout";
 | |
| import { intl, T } from "src/locale";
 | |
| 
 | |
| interface Props {
 | |
| 	data: DeadHost[];
 | |
| 	isFiltered?: boolean;
 | |
| 	isFetching?: boolean;
 | |
| 	onEdit?: (id: number) => void;
 | |
| 	onDelete?: (id: number) => void;
 | |
| 	onDisableToggle?: (id: number, enabled: boolean) => void;
 | |
| 	onNew?: () => void;
 | |
| }
 | |
| export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onNew, isFiltered }: Props) {
 | |
| 	const columnHelper = createColumnHelper<DeadHost>();
 | |
| 	const columns = useMemo(
 | |
| 		() => [
 | |
| 			columnHelper.accessor((row: any) => row.owner, {
 | |
| 				id: "owner",
 | |
| 				cell: (info: any) => {
 | |
| 					const value = info.getValue();
 | |
| 					return <GravatarFormatter url={value.avatar} name={value.name} />;
 | |
| 				},
 | |
| 				meta: {
 | |
| 					className: "w-1",
 | |
| 				},
 | |
| 			}),
 | |
| 			columnHelper.accessor((row: any) => row, {
 | |
| 				id: "domainNames",
 | |
| 				header: intl.formatMessage({ id: "column.source" }),
 | |
| 				cell: (info: any) => {
 | |
| 					const value = info.getValue();
 | |
| 					return <DomainsFormatter domains={value.domainNames} createdOn={value.createdOn} />;
 | |
| 				},
 | |
| 			}),
 | |
| 			columnHelper.accessor((row: any) => row.certificate, {
 | |
| 				id: "certificate",
 | |
| 				header: intl.formatMessage({ id: "column.ssl" }),
 | |
| 				cell: (info: any) => {
 | |
| 					return <CertificateFormatter certificate={info.getValue()} />;
 | |
| 				},
 | |
| 			}),
 | |
| 			columnHelper.accessor((row: any) => row.enabled, {
 | |
| 				id: "enabled",
 | |
| 				header: intl.formatMessage({ id: "column.status" }),
 | |
| 				cell: (info: any) => {
 | |
| 					return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
 | |
| 				},
 | |
| 			}),
 | |
| 			columnHelper.display({
 | |
| 				id: "id", // todo: not needed for a display?
 | |
| 				cell: (info: any) => {
 | |
| 					return (
 | |
| 						<span className="dropdown">
 | |
| 							<button
 | |
| 								type="button"
 | |
| 								className="btn dropdown-toggle btn-action btn-sm px-1"
 | |
| 								data-bs-boundary="viewport"
 | |
| 								data-bs-toggle="dropdown"
 | |
| 							>
 | |
| 								<IconDotsVertical />
 | |
| 							</button>
 | |
| 							<div className="dropdown-menu dropdown-menu-end">
 | |
| 								<span className="dropdown-header">
 | |
| 									<T
 | |
| 										id="object.actions-title"
 | |
| 										tData={{ object: "dead-host" }}
 | |
| 										data={{ id: info.row.original.id }}
 | |
| 									/>
 | |
| 								</span>
 | |
| 								<a
 | |
| 									className="dropdown-item"
 | |
| 									href="#"
 | |
| 									onClick={(e) => {
 | |
| 										e.preventDefault();
 | |
| 										onEdit?.(info.row.original.id);
 | |
| 									}}
 | |
| 								>
 | |
| 									<IconEdit size={16} />
 | |
| 									<T id="action.edit" />
 | |
| 								</a>
 | |
| 								<a
 | |
| 									className="dropdown-item"
 | |
| 									href="#"
 | |
| 									onClick={(e) => {
 | |
| 										e.preventDefault();
 | |
| 										onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
 | |
| 									}}
 | |
| 								>
 | |
| 									<IconPower size={16} />
 | |
| 									<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
 | |
| 								</a>
 | |
| 								<div className="dropdown-divider" />
 | |
| 								<a
 | |
| 									className="dropdown-item"
 | |
| 									href="#"
 | |
| 									onClick={(e) => {
 | |
| 										e.preventDefault();
 | |
| 										onDelete?.(info.row.original.id);
 | |
| 									}}
 | |
| 								>
 | |
| 									<IconTrash size={16} />
 | |
| 									<T id="action.delete" />
 | |
| 								</a>
 | |
| 							</div>
 | |
| 						</span>
 | |
| 					);
 | |
| 				},
 | |
| 				meta: {
 | |
| 					className: "text-end w-1",
 | |
| 				},
 | |
| 			}),
 | |
| 		],
 | |
| 		[columnHelper, onDelete, onEdit, onDisableToggle],
 | |
| 	);
 | |
| 
 | |
| 	const tableInstance = useReactTable<DeadHost>({
 | |
| 		columns,
 | |
| 		data,
 | |
| 		getCoreRowModel: getCoreRowModel(),
 | |
| 		rowCount: data.length,
 | |
| 		meta: {
 | |
| 			isFetching,
 | |
| 		},
 | |
| 		enableSortingRemoval: false,
 | |
| 	});
 | |
| 
 | |
| 	return (
 | |
| 		<TableLayout
 | |
| 			tableInstance={tableInstance}
 | |
| 			emptyState={
 | |
| 				<EmptyData
 | |
| 					object="dead-host"
 | |
| 					objects="dead-hosts"
 | |
| 					tableInstance={tableInstance}
 | |
| 					onNew={onNew}
 | |
| 					isFiltered={isFiltered}
 | |
| 					color="red"
 | |
| 				/>
 | |
| 			}
 | |
| 		/>
 | |
| 	);
 | |
| }
 |