Browse Source

feat: show saved filename with open-in-explorer link on Generate3D node

After generation, the node now displays the saved .glb filename below
"3D Model Generated". Clicking it reveals the file in the OS explorer.
Falls back to "Connect to 3D Viewer" when auto-save is not configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handoff-20260429-1057
gitcapoom 5 months ago
parent
commit
7f7ad4b24b
  1. 29
      src/components/nodes/Generate3DNode.tsx

29
src/components/nodes/Generate3DNode.tsx

@ -140,7 +140,7 @@ export function Generate3DNode({ id, data, selected }: NodeProps<Generate3DNodeT
}, [nodeData.status, nodeData.error]); }, [nodeData.status, nodeData.error]);
const handleClear3D = useCallback(() => { const handleClear3D = useCallback(() => {
updateNodeData(id, { output3dUrl: null, status: "idle", error: null }); updateNodeData(id, { output3dUrl: null, savedFilename: null, savedFilePath: null, status: "idle", error: null });
}, [id, updateNodeData]); }, [id, updateNodeData]);
return ( return (
@ -356,7 +356,32 @@ export function Generate3DNode({ id, data, selected }: NodeProps<Generate3DNodeT
<path strokeLinecap="round" strokeLinejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" /> <path strokeLinecap="round" strokeLinejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" />
</svg> </svg>
<span className="text-[11px] text-orange-400 font-medium">3D Model Generated</span> <span className="text-[11px] text-orange-400 font-medium">3D Model Generated</span>
<span className="text-[10px] text-neutral-500 truncate max-w-full">Connect to 3D Viewer</span> {nodeData.savedFilename ? (
<button
onClick={async (e) => {
e.stopPropagation();
if (!nodeData.savedFilePath) return;
try {
await fetch("/api/open-file", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ filePath: nodeData.savedFilePath }),
});
} catch (err) {
console.error("Failed to open file location:", err);
}
}}
className="nodrag nopan text-[10px] text-neutral-400 hover:text-orange-300 truncate max-w-full cursor-pointer transition-colors flex items-center gap-1"
title={`Open in explorer: ${nodeData.savedFilePath}`}
>
<svg className="w-3 h-3 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
</svg>
{nodeData.savedFilename}
</button>
) : (
<span className="text-[10px] text-neutral-500 truncate max-w-full">Connect to 3D Viewer</span>
)}
{/* Loading overlay for re-generation */} {/* Loading overlay for re-generation */}
{nodeData.status === "loading" && ( {nodeData.status === "loading" && (
<div className="absolute inset-0 bg-neutral-900/70 rounded flex items-center justify-center"> <div className="absolute inset-0 bg-neutral-900/70 rounded flex items-center justify-center">

Loading…
Cancel
Save