diff --git a/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.spec.tsx b/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.spec.tsx
index d16445fdb2..4651121ee3 100644
--- a/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.spec.tsx
+++ b/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.spec.tsx
@@ -28,6 +28,28 @@ describe("WorkflowFilesOverlayLayer", () => {
useSidebarLayoutStore.getState().hydrateFromStorage();
});
+ it("opens the first file when files load after the overlay mounts", () => {
+ const { rerender } = render();
+
+ expect(screen.queryByTestId("monaco-stub")).not.toBeInTheDocument();
+
+ rerender(
+ ,
+ );
+
+ expect(screen.getByRole("button", { name: "Close canvas.yaml" })).toBeInTheDocument();
+ expect(screen.getByTestId("monaco-stub")).toHaveTextContent("canvas: true");
+ });
+
it("keeps all editor tabs closed after closing the last tab", async () => {
const user = userEvent.setup();
diff --git a/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.tsx b/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.tsx
index df56228f08..611307cd87 100644
--- a/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.tsx
+++ b/web_src/src/pages/workflowv2/WorkflowFilesOverlayLayer.tsx
@@ -64,17 +64,27 @@ function CanvasYamlFilesView({ files }: { files: WorkflowFile[] }) {
const filePaths = useMemo(() => files.map((file) => file.path), [files]);
const [selectedPath, setSelectedPath] = useState(() => filePaths[0] ?? null);
const [openTabs, setOpenTabs] = useState(() => (filePaths[0] ? [filePaths[0]] : []));
+ const previousFileCountRef = useRef(filePaths.length);
const selectedFile = files.find((file) => file.path === selectedPath) ?? null;
useEffect(() => {
const filePathSet = new Set(filePaths);
+ const filesLoaded = previousFileCountRef.current === 0 && filePaths.length > 0;
+ const nextOpenTabs = openTabs.filter((path) => filePathSet.has(path));
+ const ensuredOpenTabs = filesLoaded && nextOpenTabs.length === 0 ? [filePaths[0]] : nextOpenTabs;
+ const nextSelectedPath =
+ selectedPath && filePathSet.has(selectedPath) ? selectedPath : (ensuredOpenTabs[0] ?? null);
- setOpenTabs((current) => {
- const nextTabs = current.filter((path) => filePathSet.has(path));
- return nextTabs.length === current.length ? current : nextTabs;
- });
- setSelectedPath((current) => (current && filePathSet.has(current) ? current : null));
- }, [filePaths]);
+ previousFileCountRef.current = filePaths.length;
+
+ if (ensuredOpenTabs.length !== openTabs.length || ensuredOpenTabs.some((path, index) => path !== openTabs[index])) {
+ setOpenTabs(ensuredOpenTabs);
+ }
+
+ if (nextSelectedPath !== selectedPath) {
+ setSelectedPath(nextSelectedPath);
+ }
+ }, [filePaths, openTabs, selectedPath]);
const openFile = (path: string) => {
setSelectedPath(path);