Skip to content

Hide the remaining write actions a project role can't perform - #50

Merged
TeoVader merged 3 commits into
mainfrom
t3/role-based-ui-gating
Nov 11, 2026
Merged

TeoVader merged 3 commits into
mainfrom
t3/role-based-ui-gating

Conversation

@TeoVader

Copy link
Copy Markdown
Owner

What changes

Before: a viewer or commenter on a shared project still saw actions Frame.io then refused: the folder's "+ Upload" button (upload, new folder, import) and the empty folder's "Upload"; every project in the "Share to Final(ish)" destination list; Add, the role menus and Remove on the Members screens (project, folder and workspace); the comment composer, "Comment at…", mark done and "Reply in Frame.io" for a viewer; the status menu in the viewer header ("No status" ▾), the rating stars and editable fields in Info, version reordering and "Upload new version" in Versions; Rename and Delete in a workspace's ⋯ menu.

After: each of these follows the user's role, as file menus (#42) and the project menus (#49) already do:

  • Folder: no Upload button and no empty-state "Upload" for viewer and commenter; the empty folder says files added there will show up. The project's share-links strip is hidden for roles that can't share.
  • Share to Final(ish): a project where the role can't upload is dimmed with "Your role here can't upload" once known, and can't be picked. The role is read when you tap a project (spinner on that row), never for the whole list. Last time's destination is dropped if the role there no longer allows uploads.
  • Members (project, folder, workspace): everyone sees the list and the roles. Add, the role menu with Remove, and the roles hint show only to roles that can manage members.
  • Viewer: a viewer reads comments; a note replaces the composer, and the done circle and "Reply in Frame.io" are gone. A commenter keeps commenting. Status, rating and fields are read-only for viewer and commenter (an empty status is hidden); version order and "Upload new version" need upload rights.
  • Workspace ⋯: Rename and Delete only for workspace admins, workspace full_access and account owners/admins; Members stays for everyone.

How

  • FileAccess gets an invite flag (add/remove members, change roles). manage now also covers metadata edits. Asset.readOnlyMetadata() turns every field read-only (head version too), so the Info panel needs no other change.
  • FrameioRepository.workspaceAccess(account, workspace): account owners/admins, else the user's role in GET /v4/accounts/{a}/workspaces/{w}/users (the documented workspace users list), through FileAccess.ofRole. Cached per session like fileAccess; cachedWorkspaceAccess for the first frame.
  • Lazy reads, no extra calls per card: the folder reads the role once (session cache first), the Members screen once on open, the workspace menu when it opens, the share-in picker on tap. Unknown role, or a read that fails: everything shows, the server decides.
  • Upload controls wait for the role (FolderViewModel.access is null while it loads) so a viewer doesn't see the button appear and vanish. File menus keep showing everything while it loads, as in Hide file actions the user's project role can't perform #42.
  • MembersRoute carries the folder's projectId, so folder members follow the project role.

Role mapping, from Frame.io's Managing user permissions guide and the help center:

Action Shown for Source
Upload, new folder, import, new version, version order edit_only, editor, full_access, admins guide: "upload, manage" from edit_only up
Status, rating, fields same as upload not documented; treated as "manage" (inference)
Comment, mark done, reply commenter and up guide: commenter = "view and comment", viewer = "view only"
Share-links strip editor and up guide: "share"
Project / folder members: add, change role, remove full_access, workspace_admin, account owner/admin guide: only full_access has "invite users"; help: Workspace Admin "manage all users… and their permissions"
Workspace members, Rename / Delete workspace workspace_admin, workspace full_access, account owner/admin help: Workspace Admin; guide: full_access "manage settings, and invite users"
Member list, roles (read-only) everyone
any action, unknown role shown

Not changed: the "New project" button. The help center gives project creation to Workspace Admins; whether workspace full_access can is not documented, and the button also creates workspaces, so the server decides. Collections are read-only in the app already (nothing to gate). A full_access workspace member still sees workspace_admin in the role menu, though the help center says only admins can grant it; Frame.io refuses that one.

Tests: FileAccessTest (invite, manage, comment mapping; read-only metadata incl. head version). Screenshots: members_viewer, comments_viewer, share_in_projects_viewer; baselines from the CI test-report artifact (Linux).

Checks

  • ./gradlew :app:verifyRoborazziDebug :app:lintDebug passes (lint at 0): unit tests and lint on the workstation, screenshots verified on CI with baselines recorded there
  • New or changed UI has a Roborazzi screenshot
  • Tried on a phone (if it touches playback, uploads or permissions): not done; nothing is installed on the phone without the maintainer's OK. Needs a check with a viewer and a commenter member on a test project.

🤖 Generated with Claude Code

TeoVader and others added 3 commits November 11, 2026 22:28
Viewers and commenters no longer see Upload, new folder or import in a
folder; the share-to-app picker won't take them to a project they can't
upload to. Members, folder members and workspace members show Add and
the role menus only to roles that can manage members. In the viewer, a
viewer gets a note instead of the comment composer, and status, rating,
fields, version order and new version follow the role. The workspace
"..." menu shows Rename and Delete only to workspace admins and full
access.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecorded on CI)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TeoVader
TeoVader merged commit 1c91136 into main Nov 11, 2026
2 checks passed
@TeoVader
TeoVader deleted the t3/role-based-ui-gating branch November 11, 2026 22:45
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