Skip to content

Commit e9813d8

Browse files
committed
implemente open workspace command
1 parent 255d6b6 commit e9813d8

File tree

5 files changed

+77
-28
lines changed

5 files changed

+77
-28
lines changed

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
"title": "Create Workspace"
8080
},
8181
{
82-
"command": "coder.removeWorkspace",
83-
"title": "Remove Workspace"
82+
"command": "coder.navigateToWorkspace",
83+
"title": "Open Workspace in Browser"
8484
},
8585
{
8686
"command": "coder.workspace.update",
@@ -105,6 +105,10 @@
105105
"command": "coder.open",
106106
"when": "coder.authenticated && view == myWorkspaces || coder.authenticated && view == allWorkspaces",
107107
"group": "inline"
108+
},
109+
{
110+
"command": "coder.navigateToWorkspace",
111+
"when": "coder.authenticated && view == myWorkspaces || coder.authenticated && view == allWorkspaces"
108112
}
109113
]
110114
}

src/api-helper.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
2+
3+
export function extractAgentsAndFolderPath(
4+
workspace: Workspace,
5+
): [agents: WorkspaceAgent[], folderPath: string | undefined] {
6+
// TODO: multiple agent support
7+
const agents = workspace.latest_build.resources.reduce((acc, resource) => {
8+
return acc.concat(resource.agents || [])
9+
}, [] as WorkspaceAgent[])
10+
11+
let folderPath = undefined
12+
if (agents.length === 1) {
13+
folderPath = agents[0].expanded_directory
14+
}
15+
return [agents, folderPath]
16+
}

src/commands.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import axios from "axios"
22
import { getAuthenticatedUser, getWorkspaces, updateWorkspaceVersion } from "coder/site/src/api/api"
33
import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
44
import * as vscode from "vscode"
5+
import { extractAgentsAndFolderPath } from "./api-helper"
56
import { Remote } from "./remote"
67
import { Storage } from "./storage"
8+
import { WorkspaceTreeItem } from "./workspacesProvider"
79

810
export class Commands {
911
public constructor(private readonly vscodeProposed: typeof vscode, private readonly storage: Storage) {}
@@ -113,7 +115,12 @@ export class Commands {
113115
await vscode.commands.executeCommand("vscode.open", uri)
114116
}
115117

116-
public async open(...args: string[]): Promise<void> {
118+
public async navigateToWorkspace(workspace: WorkspaceTreeItem): Promise<void> {
119+
const uri = this.storage.getURL() + `/@${workspace.workspaceOwner}/${workspace.workspaceName}`
120+
await vscode.commands.executeCommand("vscode.open", uri)
121+
}
122+
123+
public async open(...args: unknown[]): Promise<void> {
117124
let workspaceOwner: string
118125
let workspaceName: string
119126
let folderPath: string | undefined
@@ -170,19 +177,19 @@ export class Commands {
170177
workspaceOwner = workspace.owner_name
171178
workspaceName = workspace.name
172179

173-
// TODO: multiple agent support
174-
const agents = workspace.latest_build.resources.reduce((acc, resource) => {
175-
return acc.concat(resource.agents || [])
176-
}, [] as WorkspaceAgent[])
177-
178-
if (agents.length === 1) {
179-
folderPath = agents[0].expanded_directory
180-
}
180+
const [, folderPathExtracted] = extractAgentsAndFolderPath(workspace)
181+
folderPath = folderPathExtracted
182+
} else if (args.length === 2) {
183+
// opening a workspace from the sidebar
184+
const workspaceTreeItem = args[0] as WorkspaceTreeItem
185+
workspaceOwner = workspaceTreeItem.workspaceOwner
186+
workspaceName = workspaceTreeItem.workspaceName
187+
folderPath = workspaceTreeItem.workspaceFolderPath
181188
} else {
182-
workspaceOwner = args[0]
183-
workspaceName = args[1]
189+
workspaceOwner = args[0] as string
190+
workspaceName = args[1] as string
184191
// workspaceAgent is reserved for args[2], but multiple agents aren't supported yet.
185-
folderPath = args[3]
192+
folderPath = args[3] as string | undefined
186193
}
187194

188195
// A workspace can have multiple agents, but that's handled

src/extension.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import * as vscode from "vscode"
66
import { Commands } from "./commands"
77
import { Remote } from "./remote"
88
import { Storage } from "./storage"
9-
import { WorkspaceProvider } from "./workspacesProvider"
9+
import { WorkspaceQuery, WorkspaceProvider } from "./workspacesProvider"
1010

1111
export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
1212
const output = vscode.window.createOutputChannel("Coder")
1313
const storage = new Storage(output, ctx.globalState, ctx.secrets, ctx.globalStorageUri, ctx.logUri)
1414
await storage.init()
1515

16-
vscode.window.registerTreeDataProvider("myWorkspaces", new WorkspaceProvider("owner:me"))
17-
vscode.window.registerTreeDataProvider("allWorkspaces", new WorkspaceProvider())
16+
vscode.window.registerTreeDataProvider("myWorkspaces", new WorkspaceProvider(WorkspaceQuery.Mine))
17+
vscode.window.registerTreeDataProvider("allWorkspaces", new WorkspaceProvider(WorkspaceQuery.All))
1818

1919
getAuthenticatedUser()
2020
.then(() => {
@@ -81,6 +81,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
8181
vscode.commands.registerCommand("coder.open", commands.open.bind(commands))
8282
vscode.commands.registerCommand("coder.workspace.update", commands.updateWorkspace.bind(commands))
8383
vscode.commands.registerCommand("coder.createWorkspace", commands.createWorkspace.bind(commands))
84+
vscode.commands.registerCommand("coder.navigateToWorkspace", commands.navigateToWorkspace.bind(commands))
8485

8586
// Since the "onResolveRemoteAuthority:ssh-remote" activation event exists
8687
// in package.json we're able to perform actions before the authority is

src/workspacesProvider.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,47 @@
11
import { getWorkspaces } from "coder/site/src/api/api"
22
import * as path from "path"
33
import * as vscode from "vscode"
4+
import { extractAgentsAndFolderPath } from "./api-helper"
45

5-
export class WorkspaceProvider implements vscode.TreeDataProvider<TreeItem> {
6-
constructor(private readonly getWorkspacesQuery?: string) {}
7-
getTreeItem(element: TreeItem): vscode.TreeItem {
6+
export enum WorkspaceQuery {
7+
Mine = "owner:me",
8+
All = "",
9+
}
10+
11+
export class WorkspaceProvider implements vscode.TreeDataProvider<WorkspaceTreeItem> {
12+
constructor(private readonly getWorkspacesQuery: WorkspaceQuery) {}
13+
14+
getTreeItem(element: WorkspaceTreeItem): vscode.TreeItem {
815
return element
916
}
1017

11-
getChildren(): Thenable<TreeItem[]> {
18+
getChildren(): Thenable<WorkspaceTreeItem[]> {
1219
return getWorkspaces({ q: this.getWorkspacesQuery }).then((workspaces) => {
13-
return workspaces.workspaces.map(
14-
(workspace) => new TreeItem(workspace.name, vscode.TreeItemCollapsibleState.None),
15-
)
20+
return workspaces.workspaces.map((workspace) => {
21+
const status =
22+
workspace.latest_build.status.substring(0, 1).toUpperCase() + workspace.latest_build.status.substring(1)
23+
24+
const label =
25+
this.getWorkspacesQuery === WorkspaceQuery.All
26+
? `${workspace.owner_name} / ${workspace.name}`
27+
: workspace.name
28+
const detail = `Template: ${workspace.template_display_name || workspace.template_name} • Status: ${status}`
29+
const [, folderPath] = extractAgentsAndFolderPath(workspace)
30+
return new WorkspaceTreeItem(label, detail, workspace.owner_name, workspace.name, folderPath)
31+
})
1632
})
1733
}
1834
}
1935

20-
class TreeItem extends vscode.TreeItem {
21-
constructor(public readonly label: string, public readonly collapsibleState: vscode.TreeItemCollapsibleState) {
22-
super(label, collapsibleState)
23-
this.tooltip = `${this.label}`
36+
export class WorkspaceTreeItem extends vscode.TreeItem {
37+
constructor(
38+
public readonly label: string,
39+
public readonly tooltip: string,
40+
public readonly workspaceOwner: string,
41+
public readonly workspaceName: string,
42+
public readonly workspaceFolderPath: string | undefined,
43+
) {
44+
super(label, vscode.TreeItemCollapsibleState.None)
2445
}
2546

2647
iconPath = {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy