Skip to content

feat: shared workspaces support#957

Open
aslilac wants to merge 1 commit into
mainfrom
lilac/shared-workspaces
Open

feat: shared workspaces support#957
aslilac wants to merge 1 commit into
mainfrom
lilac/shared-workspaces

Conversation

@aslilac
Copy link
Copy Markdown
Member

@aslilac aslilac commented May 15, 2026

Adds a third tree view, Shared Workspaces, that lists workspaces the current user has access to but does not own. The view is visible to any authenticated user, sits between My Workspaces and All Workspaces, and reuses the existing context-menu actions and refresh/search affordances.

Implementation notes
  • New WorkspaceQuery.Shared = "shared:true" value; the provider filters out workspaces owned by the current user client-side, because shared:true server-side also matches workspaces the current user shared out.
  • DeploymentManager exposes getCurrentUserId() so the new provider can scope the filter to the active session; this is cleared on logout/suspend.
  • coder.refreshWorkspaces now also refreshes the new view.

Generated with Coder Agents on behalf of @aslilac.

Adds a third tree view, Shared Workspaces, that lists workspaces the
current user has access to but does not own. Visible to any
authenticated user (unlike All Workspaces, which is admin-only).

Generated with Coder Agents on behalf of @aslilac.
@EhabY EhabY self-requested a review May 18, 2026 08:52
Comment on lines +26 to +29
// Shared returns workspaces the user has access to via sharing but does not
// own. The server-side `shared:true` filter also includes workspaces the
// user owns and has shared out, so the provider filters those out
// client-side using the current user's id.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agents tend to over explain with what and not why. I'd trim this a bit more (same for all of the new comments here)

Comment on lines +63 to +64
private readonly getCurrentUserId: () => string | undefined = () =>
undefined,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather decouple this, like maybe pass filterWorkspaces?: (ws: Workspace[]) => Workspace[] and remove any knowledge of the current user from here

Comment on lines 39 to +40
#deployment: Deployment | null = null;
#currentUserId: string | undefined;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call it #authedUser: User | null so it's more explicit, we can keep the derived getCurrentUserId

Comment thread src/extension.ts
client,
output,
isAuthenticated,
undefined,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to poll for refreshes or keep it like All and only on manual refreshes?

Comment on lines +126 to +134
let workspaces = resp.workspaces;
if (this.getWorkspacesQuery === WorkspaceQuery.Shared) {
const currentUserId = this.getCurrentUserId();
if (currentUserId) {
workspaces = workspaces.filter(
(workspace) => workspace.owner_id !== currentUserId,
);
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we make this a filter then we can just make it a const and should be cleaner (separation of concerns)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants