"use client"; import { getRelativeTime } from "../lib/getRelativeTime"; import { InsertModal, UpdateModal } from "./InsertModal"; import { callServerPromise } from "./callServerPromise"; import { LoadingIcon } from "@/components/LoadingIcon"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { type MachineType } from "@/db/schema"; import type { AccessType } from "@/lib/AccessType"; import { addCustomMachineSchema, addMachineSchema, } from "@/server/addMachineSchema"; import { addCustomMachine, addMachine, buildMachine, deleteMachine, disableMachine, enableMachine, updateCustomMachine, updateMachine, } from "@/server/curdMachine"; import { editWorkflowOnMachine } from "@/server/editWorkflowOnMachine"; import { getCurrentPlanWithAuth } from "@/server/getCurrentPlan"; import type { ColumnDef, ColumnFiltersState, SortingState, VisibilityState, } from "@tanstack/react-table"; import { flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table"; import { ArrowUpDown, Lock, MoreHorizontal, Plus } from "lucide-react"; import * as React from "react"; import { useState } from "react"; import { toast } from "sonner"; import type { z } from "zod"; export type Machine = MachineType; export const columns: ColumnDef[] = [ { accessorKey: "id", id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="Select all" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="Select row" /> ), enableSorting: false, enableHiding: false, }, { accessorKey: "name", header: ({ column }) => { return ( ); }, cell: ({ row }) => { return ( //
{row.getValue("name")} {row.original.disabled && ( Disabled )} {row.original.status == "building" && ( {row.original.status} )} {!row.original.disabled && row.original.status && row.original.status != "building" && ( {row.original.status} )}
// ); }, }, { accessorKey: "endpoint", header: () =>
Endpoint
, cell: ({ row }) => { return (
{row.original.endpoint}
); }, }, { accessorKey: "type", header: () =>
Type
, cell: ({ row }) => { return ( {row.original.type} ); }, }, { accessorKey: "date", sortingFn: "datetime", enableSorting: true, header: ({ column }) => { return ( ); }, cell: ({ row }) => (
{getRelativeTime(row.original.updated_at)}
), }, { id: "actions", enableHiding: false, cell: ({ row }) => { const machine = row.original; const [open, setOpen] = useState(false); const sub = useCurrentPlan(); return ( Actions { callServerPromise(deleteMachine(machine.id), { loadingText: "Deleting machine", }); }} > Delete Machine {machine.disabled ? ( { callServerPromise(enableMachine(machine.id), { loadingText: "Enabling machine", }); }} > Enable Machine ) : ( { callServerPromise(disableMachine(machine.id), { loadingText: "Disabling machine", }); }} > Disable Machine )} {machine.type === "comfy-deploy-serverless" && ( <> { const url = await callServerPromise( editWorkflowOnMachine(machine.id), { loadingText: "Getting machine url...", }, ); if (url && typeof url !== "object") { window.open(url, "_blank"); } else if (url && typeof url === "object" && url.error) { console.error(url.error); } }} > Open ComfyUI { callServerPromise( buildMachine({ id: machine.id, }), { loadingText: "Starting machine build process", }, ); }} > Rebuild )} setOpen(true)}> Edit {machine.type === "comfy-deploy-serverless" ? ( ) : ( )} ); }, }, ]; import { useCurrentPlan } from "./useCurrentPlan"; export function MachineList({ data, userMetadata, }: { data: Machine[]; userMetadata: z.infer; }) { const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [], ); const [columnVisibility, setColumnVisibility] = React.useState({}); const [rowSelection, setRowSelection] = React.useState({}); const sub = useCurrentPlan(); const table = useReactTable({ data, columns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), onColumnVisibilityChange: setColumnVisibility, onRowSelectionChange: setRowSelection, state: { sorting, columnFilters, columnVisibility, rowSelection, }, }); let machineMaxCount = 2; // Temp fixes for machine count if (userMetadata.betaFeaturesAccess) machineMaxCount = 5; if (sub?.plan == "pro") { machineMaxCount = 10; } else if (sub?.plan == "enterprise") { machineMaxCount = 99; } const locked = data.some((machine) => machine.type === "modal-serverless") && data.length >= machineMaxCount; return (
table.getColumn("name")?.setFilterValue(event.target.value) } className="max-w-sm" />
New Machine {locked ? : } } title={"New Machine"} description="Add custom ComfyUI machines to your account." serverAction={addCustomMachine} formSchema={addCustomMachineSchema} fieldConfig={{ type: { fieldType: "fallback", inputProps: { disabled: true, showLabel: false, type: "hidden", }, }, snapshot: { fieldType: "snapshot", inputProps: { showLabel: false, }, }, models: { fieldType: "models", inputProps: { showLabel: false, }, }, gpu: { fieldType: "gpuPicker", inputProps: { sub: sub, }, }, }} />
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )} ); })} ))} {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} )) ) : ( No results. )}
{table.getFilteredSelectedRowModel().rows.length} of{" "} {table.getFilteredRowModel().rows.length} row(s) selected.
); }