import {useState} from 'react'; import {Link} from 'react-router-dom'; import {Pencil, Trash2} from 'lucide-react'; import {describeDeleteImpact} from '@/lib/deleteImpact'; import type {CloudResource} from '@/types/resource'; import type {ServiceSchema} from '@/types/schema'; import {getPath} from '@/lib/resourcePath'; import {renderColumnValue} from '@/lib/columnFormat'; import {CopyValueButton} from '@/components/CopyValueButton'; interface ResourceTableProps { schema: ServiceSchema; resources: CloudResource[]; selectedId?: string; onSelect: (resource: CloudResource) => void; onEdit?: (resource: CloudResource) => void; onDelete: (resource: CloudResource) => void; deletingId?: string; dataPath?: (resource: CloudResource) => string | undefined; isDeleteMulti?: boolean; selectedItems?: CloudResource[]; onToggleSelect?: (resource: CloudResource) => void; onToggleSelectAll?: () => void; setAllSelected?: (value: boolean) => void; isAllSelected?: boolean; } export function ResourceTable({ schema, resources, selectedId, onSelect, onEdit, onDelete, deletingId, dataPath, isDeleteMulti, selectedItems, onToggleSelect, onToggleSelectAll, setAllSelected, isAllSelected = false, }: ResourceTableProps) { const [confirmId, setConfirmId] = useState(null); const canDelete = schema.actions.includes('delete'); const canEdit = schema.actions.includes('update') && Boolean(schema.updateFields?.length) && Boolean(onEdit); const hasActions = canDelete || canEdit || Boolean(dataPath && resources.some((resource) => dataPath(resource))); if (resources.length === 0) { const emptyTitle = `No ${schema.displayName} found.`; const emptyDescription = `The connected runtime did not return any ${schema.displayName} resources.`; return (

{emptyTitle}

{emptyDescription}

); } return ( {isDeleteMulti && ( )} {schema.columns.map((column) => ( ))} {hasActions && {resources.map((resource) => { const explorePath = dataPath?.(resource); return ( {isDeleteMulti && ( )} {schema.columns.map((column) => ( ))} {hasActions && ( )} ); })}
0} onChange={() => { if (onToggleSelectAll) { onToggleSelectAll(); } else { setAllSelected?.(!isAllSelected); } }} /> {column.label} }
e.stopPropagation()}> item.id === resource.id) ?? false} onChange={() => { onToggleSelect?.(resource); }} /> onSelect(resource)}>
{explorePath && ( e.stopPropagation()} > Explore data )} {canEdit && ( )} {canDelete && ( confirmId === resource.id ? (
e.stopPropagation()} >
) : ( ) )}
); } function CopyableColumnValue({resource, column}: {resource: CloudResource; column: ServiceSchema['columns'][number]}) { const value = getPath(resource, column.path ?? column.name); const copyable = typeof value === 'string' && ( column.format === 'code' || /(^id$|id$|arn|ip|endpoint|url|uri|key)/i.test(column.name) ); if (!copyable) { return renderColumnValue(value, column); } return ( {renderColumnValue(value, column)} ); } function DeleteImpact({schema, resource}: {schema: ServiceSchema; resource: CloudResource}) { const text = describeDeleteImpact(schema.deleteImpact, [resource]); return text ? {text} : null; }