From 53fe31585a8d9fef8c8bee613f87b43dca0c5165 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Tue, 17 Jun 2025 13:23:48 -0500 Subject: [PATCH] Select workspace folder in Project view --- src/webview/WebviewProvider/index.ts | 18 ++++++++++--- src/webview/WebviewProvider/lib/index.ts | 2 +- ...{queryWorkspace.ts => previewWorkspace.ts} | 8 +++--- .../src/Context/WorkspaceProvider/index.tsx | 26 ++++++++++++++++++ webview-ui/src/Layout/Project/index.tsx | 27 +++++++++++++++---- 5 files changed, 68 insertions(+), 13 deletions(-) rename src/webview/WebviewProvider/lib/workspace/{queryWorkspace.ts => previewWorkspace.ts} (90%) diff --git a/src/webview/WebviewProvider/index.ts b/src/webview/WebviewProvider/index.ts index 793268c3..05f9ee7e 100644 --- a/src/webview/WebviewProvider/index.ts +++ b/src/webview/WebviewProvider/index.ts @@ -11,14 +11,14 @@ import { fetchPlatformData, fetchRuns, getRepoInfo, - queryWorkspace, + getWorkspaces, + getWorkspacePreview, getContainer, addPipeline } from "./lib"; import { AuthProvider, getAccessToken } from "../../auth"; import { jwtExpired } from "../../auth/AuthProvider/utils/jwt"; import { sleep } from "./lib/utils"; -import { Pipeline } from "./lib/platform/types"; import fetchHubPipelines from "./lib/platform/fetchHubPipelines"; class WebviewProvider implements vscode.WebviewViewProvider { @@ -87,6 +87,9 @@ class WebviewProvider implements vscode.WebviewViewProvider { case "addPipeline": this.addPipeline(message); break; + case "previewWorkspace": + this.previewWorkspace(message); + break; } }); @@ -190,11 +193,18 @@ class WebviewProvider implements vscode.WebviewViewProvider { await fetchPlatformData(accessToken, view.webview, _context, refresh); } if (viewID === "project") { - const nodes = await queryWorkspace(); - view.webview.postMessage({ nodes }); + const folders = getWorkspaces(); + view.webview.postMessage({ folders }); } } + private async previewWorkspace(name: string) { + const nodes = await getWorkspacePreview(name); + this._currentView?.webview.postMessage({ + nodes + }); + } + private async emitTestCreated(filePath: string, successful: boolean) { this._currentView?.webview.postMessage({ testCreated: { diff --git a/src/webview/WebviewProvider/lib/index.ts b/src/webview/WebviewProvider/lib/index.ts index 9fc24062..0a99ddc7 100644 --- a/src/webview/WebviewProvider/lib/index.ts +++ b/src/webview/WebviewProvider/lib/index.ts @@ -2,4 +2,4 @@ export { default as fetchPlatformData } from "./platform/fetchPlatformData"; export { default as getAuthState } from "./platform/getAuthState"; export * from "./platform/utils"; -export { queryWorkspace } from "./workspace/queryWorkspace"; +export { getWorkspaces, getWorkspacePreview } from "./workspace/previewWorkspace"; diff --git a/src/webview/WebviewProvider/lib/workspace/queryWorkspace.ts b/src/webview/WebviewProvider/lib/workspace/previewWorkspace.ts similarity index 90% rename from src/webview/WebviewProvider/lib/workspace/queryWorkspace.ts rename to src/webview/WebviewProvider/lib/workspace/previewWorkspace.ts index 35a24e83..0b2d36d4 100644 --- a/src/webview/WebviewProvider/lib/workspace/queryWorkspace.ts +++ b/src/webview/WebviewProvider/lib/workspace/previewWorkspace.ts @@ -45,12 +45,14 @@ async function previewWorkspace(name: string): Promise { } } -export async function queryWorkspace(): Promise { +export function getWorkspaces(): string[] { const folders = vscode.workspace.workspaceFolders; - if (!folders || folders.length == 0) + if (!folders) return []; + return folders.map(folder => folder.name); +} - const name = folders[0].name; +export async function getWorkspacePreview(name: string): Promise { const res: any = await previewWorkspace(name); if (!res || !res.result) { if (res?.error) diff --git a/webview-ui/src/Context/WorkspaceProvider/index.tsx b/webview-ui/src/Context/WorkspaceProvider/index.tsx index 5a2ca7d8..127ede29 100644 --- a/webview-ui/src/Context/WorkspaceProvider/index.tsx +++ b/webview-ui/src/Context/WorkspaceProvider/index.tsx @@ -3,6 +3,10 @@ import { createContext, useContext, useEffect, useState } from "react"; import { TestCreation, TreeNode } from "./types"; const WorkspaceContext = createContext({ + folders: [], + selectedFolder: 0, + setSelectedFolder: () => {}, + previewWorkspace: () => {}, nodes: [], findChildren: () => [], openFile: () => {}, @@ -23,6 +27,10 @@ const WorkspaceContext = createContext({ }); interface WorkspaceContextType { + folders: string[]; + selectedFolder: number; + setSelectedFolder: (index: number) => void; + previewWorkspace: (name: string) => void; nodes: TreeNode[]; findChildren: (node: TreeNode) => TreeNode[]; openFile: (filePath: string, line: number) => void; @@ -52,6 +60,8 @@ type Props = { const WorkspaceProvider = ({ children, vscode, viewID, isCursor }: Props) => { const state = vscode.getState(); + const [folders, setFolders] = useState([]); + const [selectedFolder, setSelectedFolder] = useState(0); const [nodes, setNodes] = useState([]); const [testCreation, setCreatingTest] = useState< WorkspaceContextType["testCreation"] @@ -68,6 +78,14 @@ const WorkspaceProvider = ({ children, vscode, viewID, isCursor }: Props) => { useEffect(() => { const handleMessage = (event: MessageEvent) => { const message = event.data; + if (message.folders) { + const folders = message.folders as string[]; + setFolders(folders); + if (folders.length > 0) { + setSelectedFolder(0); + previewWorkspace(folders[0]); + } + } if (message.nodes) setNodes(message.nodes); if (message.testCreated) { const data = message.testCreated; @@ -94,6 +112,10 @@ const WorkspaceProvider = ({ children, vscode, viewID, isCursor }: Props) => { return selectedItems.includes(name); } + function previewWorkspace(name: string) { + vscode.postMessage({ command: "previewWorkspace", name: name }); + } + function findChildren(node: TreeNode): TreeNode[] { if (!node.children) return []; return node.children.flatMap((call) => @@ -137,6 +159,10 @@ const WorkspaceProvider = ({ children, vscode, viewID, isCursor }: Props) => { return ( { - const { nodes } = useWorkspaceContext(); + const { folders, selectedFolder, setSelectedFolder, previewWorkspace, nodes } = useWorkspaceContext(); const [viewMode, setViewMode] = useState("list"); const [search, setSearch] = useState(""); - const entryNodes = nodes.filter((n) => n.name === ""); + function selectFolder(name: string) { + setSelectedFolder(folders.indexOf(name)); + previewWorkspace(name); + } + + function entryNodes() { + return nodes.filter((n) => n.name === ""); + } function testCoverage() { - const totalCount = nodes.length - entryNodes.length; + const totalCount = nodes.length - entryNodes().length; if( totalCount == 0 ) return <>; const testCount = nodes.filter((n) => n.test !== undefined).length; @@ -37,11 +44,12 @@ const Project = () => { }; function treeView() { - if (entryNodes.length == 0) + const nodes = entryNodes(); + if (nodes.length == 0) return
No entry workflows found
; return (
- {entryNodes.map((node) => ( + {nodes.map((node) => ( ))}
@@ -60,6 +68,15 @@ const Project = () => { return ( <> +
+