Skip to content

feat(site): hide workspace UI from users without workspace access - #28042

Draft
jscottmiller wants to merge 1 commit into
mainfrom
scott/plat-460-improve-ui-for-gateway-accounts
Draft

feat(site): hide workspace UI from users without workspace access#28042
jscottmiller wants to merge 1 commit into
mainfrom
scott/plat-460-improve-ui-for-gateway-accounts

Conversation

@jscottmiller

Copy link
Copy Markdown
Contributor

Implements PLAT-460, points 1, 3, 4 and 5. The dismissible intro modal (point 2) is out of scope pending copy.

There is no server-side account type for these users. The signal is RBAC: an org member without organization-workspace-access has no workspace permissions at all. This PR adds a site-wide viewWorkspaces check (workspace read, any org, owner me) to site/permissions.json and drives the UI from it. Read is used rather than create so that members with organization-workspace-creation-ban keep the workspace UI.

Behavior when viewWorkspaces is false:

  • The dashboard index route resolves to /settings/account instead of /workspaces, and the navbar logo follows the same target.
  • Workspaces, Templates, Tasks and Agents nav items render dimmed and non-interactive with a tooltip, in both the desktop navbar and the mobile menu. The tooltip copy is a placeholder in a single constant, marked TODO(PLAT-460).
  • The workspace proxy latency menu is hidden.
  • Schedule and SSH Keys are removed from the user settings sidebar, and those routes redirect to the account page.
  • Workspace Events and Task Events notification groups are hidden.
  • The account name field drops the data.coder_workspace_owner.me.full_name hint.

The admin settings dropdown needs no change: canViewAdminSettings already hides it for a plain org member.

Also adds the missing organization-workspace-access entry to the role description map used by the role selector.

Coverage is Storybook only, per the frontend guidelines: WithoutWorkspaceAccess stories for NavbarView, MobileMenu, NotificationsPage and AccountForm, plus a new UserSettingsPage/Sidebar story file.

Not changed here: /workspaces, /templates, /tasks and /agents remain reachable by direct URL, since those pages already degrade to empty states. The pre-existing desktop and mobile nav divergence (mobile Agents is not gated by createChat, and mobile has no Tasks item) is also left alone.

Implementation plan

PLAT-460: Improve UI for users without workspace access

Scope: frontend only (site/) plus one shared site/permissions.json entry. Point 2 of the ticket (dismissible intro modal) is out of scope.

Naming rule: do not use the term "gateway account" in code, comments, or UI strings. The behaviour is driven purely by the signed-in user's permission set, so identifiers read as viewWorkspaces / canViewWorkspaces and comments describe the permission, not an account type.

Current state

  • There is no server-side account type. The only signal is RBAC: organization-workspace-access (codersdk/rbacroles.go:18, coderd/rbac/roles.go:716-729) grants the whole workspace action set; a member without it has no workspace permissions at all (coderd/rbac/roles.go:1138-1151).
  • Frontend site-wide checks live in site/permissions.json, are evaluated server-side into page metadata (site/site.go:548-590), fetched via AuthProvider and read through useAuthenticated().
  • Today only permissions.createWorkspace is used, and only to hide "New workspace" / "Create Workspace" CTAs.
  • Nav has no workspace gating at all.

Step 0: the signal

Use workspace read, not create: members with organization-workspace-creation-ban still need the workspace UI.

  1. site/permissions.json: add viewWorkspaces.
  2. Consume permissions.viewWorkspaces via useAuthenticated(); pass it down as canViewWorkspaces props. No new context.
  3. Update site/src/testHelpers/entities.ts permission fixtures.

Step 1: landing route (ticket 1)

  • Replace the static index Navigate with a component that redirects to /settings/account when viewWorkspaces is false.
  • /workspaces stays reachable; it already renders an empty state.
  • Hide the data.coder_workspace_owner.me.full_name helper text on the account page.

Step 2: navbar (tickets 3 and 4)

  • Hide ProxyMenu in desktop and mobile.
  • Admin settings dropdown: no change, canViewAdminSettings already hides it for a plain member.
  • Workspaces, Templates, Tasks and Agents render dimmed, non-clickable, with a tooltip, reusing the disabled patterns already in the codebase and keeping the wrapper focusable so the tooltip is keyboard reachable.
  • Tooltip copy: placeholder in one constant with a TODO(PLAT-460) marker.
  • Skip the idle-task count query when viewWorkspaces is false.

Step 3: settings subnav (ticket 5)

  • Keep: Account, Appearance, External Authentication, Security, Tokens, Secrets, Notifications.
  • Hide Schedule and SSH Keys; leave OAuth2 Applications as-is.
  • Guard the two hidden routes so they are not reachable by URL.

Step 4: notifications (ticket 5.3)

  • Extend canSeeNotificationGroup so "Workspace Events" and "Task Events" require viewWorkspaces. Finer-grained per-template filtering would need new backend metadata.

Step 5: tests

  • Storybook stories only, with play functions asserting the dimmed nav items are non-interactive and expose the tooltip.

Explicitly not in this plan

  • Ticket 2 (dismissible intro modal, copy TBD).
  • Backend changes: no new API field, no role changes.
  • Groups behaviour (open question in the ticket).

This pull request was created by Coder Agents on behalf of @jscottmiller.

Adds a site-wide `viewWorkspaces` permission check (workspace read, any
org, owner me) and uses it to adapt the UI for users whose org member
roles do not grant workspace access.

- The dashboard index route lands these users on their account settings.
- Workspaces, Templates, Tasks and Agents nav items render dimmed and
  non-interactive with a tooltip; the workspace proxy latency menu is
  hidden.
- Schedule and SSH Keys are removed from the user settings sidebar and
  their routes redirect to the account page.
- Workspace and Task notification groups are hidden.
- The account name field drops the template property hint.

Also adds a description for the organization-workspace-access role in
the role selector.
@linear-code

linear-code Bot commented Aug 11, 2026

Copy link
Copy Markdown

PLAT-460

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.

1 participant