mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-23 13:32:19 +00:00
- Added a "Ports" column to display container port information with sorting functionality. - Implemented a dropdown menu item to copy the Container ID to the clipboard with a success toast notification. - Introduced a state filter dropdown to filter containers by their current state, with options for all defined states. - Added a refresh button to allow manual refreshing of the container list.
192 lines
4.8 KiB
TypeScript
192 lines
4.8 KiB
TypeScript
import type { ColumnDef } from "@tanstack/react-table";
|
|
import copy from "copy-to-clipboard";
|
|
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
|
|
import { toast } from "sonner";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { ShowContainerConfig } from "../config/show-container-config";
|
|
import { ShowDockerModalLogs } from "../logs/show-docker-modal-logs";
|
|
import { ShowContainerMounts } from "../mounts/show-container-mounts";
|
|
import { ShowContainerNetworks } from "../networks/show-container-networks";
|
|
import { RemoveContainerDialog } from "../remove/remove-container";
|
|
import { DockerTerminalModal } from "../terminal/docker-terminal-modal";
|
|
import { UploadFileModal } from "../upload/upload-file-modal";
|
|
import type { Container } from "./show-containers";
|
|
|
|
export const columns: ColumnDef<Container>[] = [
|
|
{
|
|
accessorKey: "name",
|
|
header: ({ column }) => {
|
|
return (
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
>
|
|
Name
|
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
);
|
|
},
|
|
cell: ({ row }) => {
|
|
return <div>{row.getValue("name")}</div>;
|
|
},
|
|
},
|
|
{
|
|
accessorKey: "state",
|
|
filterFn: "equals",
|
|
header: ({ column }) => {
|
|
return (
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
>
|
|
State
|
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
);
|
|
},
|
|
cell: ({ row }) => {
|
|
const value = row.getValue("state") as string;
|
|
return (
|
|
<div className="capitalize">
|
|
<Badge
|
|
variant={
|
|
value === "running"
|
|
? "default"
|
|
: value === "exited" || value === "dead"
|
|
? "destructive"
|
|
: "secondary"
|
|
}
|
|
>
|
|
{value}
|
|
</Badge>
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
accessorKey: "status",
|
|
header: ({ column }) => {
|
|
return (
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
>
|
|
Status
|
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
);
|
|
},
|
|
cell: ({ row }) => {
|
|
return <div className="capitalize">{row.getValue("status")}</div>;
|
|
},
|
|
},
|
|
{
|
|
accessorKey: "image",
|
|
header: ({ column }) => {
|
|
return (
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
>
|
|
Image
|
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
);
|
|
},
|
|
cell: ({ row }) => <div className="lowercase">{row.getValue("image")}</div>,
|
|
},
|
|
{
|
|
accessorKey: "ports",
|
|
header: ({ column }) => {
|
|
return (
|
|
<Button
|
|
variant="ghost"
|
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
>
|
|
Ports
|
|
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
</Button>
|
|
);
|
|
},
|
|
cell: ({ row }) => {
|
|
const value = row.getValue("ports") as string;
|
|
return (
|
|
<div className="max-w-[16rem] truncate lowercase" title={value}>
|
|
{value}
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
id: "actions",
|
|
enableHiding: false,
|
|
cell: ({ row }) => {
|
|
const container = row.original;
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
<span className="sr-only">Open menu</span>
|
|
<MoreHorizontal className="h-4 w-4" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
<DropdownMenuItem
|
|
onClick={() => {
|
|
copy(container.containerId);
|
|
toast.success("Container ID copied to clipboard");
|
|
}}
|
|
>
|
|
Copy Container ID
|
|
</DropdownMenuItem>
|
|
<ShowDockerModalLogs
|
|
containerId={container.containerId}
|
|
serverId={container.serverId}
|
|
>
|
|
View Logs
|
|
</ShowDockerModalLogs>
|
|
<ShowContainerConfig
|
|
containerId={container.containerId}
|
|
serverId={container.serverId || ""}
|
|
/>
|
|
<ShowContainerMounts
|
|
containerId={container.containerId}
|
|
serverId={container.serverId || ""}
|
|
/>
|
|
<ShowContainerNetworks
|
|
containerId={container.containerId}
|
|
serverId={container.serverId || ""}
|
|
/>
|
|
<DockerTerminalModal
|
|
containerId={container.containerId}
|
|
serverId={container.serverId || ""}
|
|
>
|
|
Terminal
|
|
</DockerTerminalModal>
|
|
<UploadFileModal
|
|
containerId={container.containerId}
|
|
serverId={container.serverId || undefined}
|
|
>
|
|
Upload File
|
|
</UploadFileModal>
|
|
<RemoveContainerDialog
|
|
containerId={container.containerId}
|
|
serverId={container.serverId ?? undefined}
|
|
/>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
},
|
|
},
|
|
];
|