[No QA] Read-only mode + hide archived policies in create/move flows - #97681
[No QA] Read-only mode + hide archived policies in create/move flows#97681c3024 wants to merge 6 commits into
Conversation
Adds isArchivedPolicy() and short-circuits canMemberWrite() so archived workspaces become read-only everywhere policy-editing already gates through it. Excludes archived policies from getActivePolicies() / getActivePoliciesWithExpenseChat() so create-report flows never offer them, and adds an includeArchivedPolicy opt-in to shouldShowPolicy() (threaded through useWorkspaceList()) so most pickers hide archived workspaces by default while Search's workspace filter and the policyID autocomplete keep showing them.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fec2c8ba6b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
WorkspaceInitialPage now opts into includeArchivedPolicy so an archived workspace's settings panel is still reachable by direct URL (the Workspaces list keeps hiding it). WorkspaceOverviewPage additionally treats an archived policy as read-only, reusing the page's existing auditor read-only rendering rather than 404ing the page.
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
WorkspaceRoomsPage now hides the Create button (both layouts) when the policy is archived; the rooms list itself stays visible and read-only. WorkspaceRoomCreatePage blocks direct navigation to /rooms/new for an archived policy via AccessOrNotFoundWrapper's shouldBeBlocked, showing the standard not-found page instead.
The ADMIN access variant in AccessOrNotFoundWrapper only checked canEditWorkspaceSettings, so admin-only edit RHPs without a policyFeature (name, description, currency, client ID, share, plan type, copy/duplicate settings, owner change) stayed reachable and editable by direct URL on an archived workspace. Feature pages are unaffected since ADMIN is filtered out of the checked variants whenever policyFeature is set, gating on canMemberRead/canMemberWrite instead.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64eb352439
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Archived policies are now never editable at the source (PolicyUtils canEditWorkspaceSettings), instead of the ADMIN access variant and WorkspaceOverviewPage each checking isArchivedPolicy separately. Removes the now-redundant isArchivedPolicy calls/imports from AccessOrNotFoundWrapper and WorkspaceOverviewPage; behavior unchanged.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10b972cf38
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const policyID = route.params.policyID; | ||
| const policy = usePolicy(policyID); | ||
| const isAdmin = isPolicyAdmin(policy); | ||
| const isArchived = isArchivedPolicy(policy); |
There was a problem hiding this comment.
Block room detail edits for archived workspaces
When a workspace policy has archivedDate but its room reports are not also marked private_isArchived, this new isArchived value only hides the Create buttons; admins still use the existing row action keyed on isPolicyAdmin to open DynamicReportDetailsPage. Those room detail/settings/invite flows check the report archive state rather than policy.archivedDate, so an admin can still rename rooms, change write capability/visibility, invite/remove members, etc. Please also gate the room-details path or the room edit helpers on archived policies.
Useful? React with 👍 / 👎.
|
Bug: With exactly 2 workspaces, archiving one of them removes the workspace name prefix from both workspaces' reports - in the LHN preview line and in Search / autocomplete results. The still-active workspace is affected even though nothing was done to it. bug.movRoot cause: getReportSubtitlePrefix only shows the prefix when there are >= 2 visible policies, and it counts them with |
|
@c3024 We can still submit and approve expenses via the primary action button even though both the policy and the expense chat are archived. Is that expected? Screen.Recording.2026-08-04.at.00.34.39.mov |
Explanation of Change
Makes archived workspaces read-only and hides them from flows that create/move reports onto a workspace.
PolicyUtils.isArchivedPolicy()checkspolicy.archivedDate.canMemberWrite()short-circuits tofalsefor archived policies (read-only everywhere it already gates edits).canMemberRead()untouched.getActivePolicies()/getActivePoliciesWithExpenseChat()exclude archived policies, so create flows never offer them.shouldShowPolicy()getsincludeArchivedPolicy(defaultfalse), threaded throughuseWorkspaceList(). Search's workspace filter andpolicyIDautocomplete opt in withtrueto keep showing archived workspaces.Fixed Issues
$ #97119
Tests
archivedDate: '2024-01-01'onto one of your workspaces' Policy object.https://dev.new.expensify.com:8082/workspaces/<workspace-id>and verify that everything on the page is readonly. Switch to other options from the left panel and verify that all are readonly.Onyx.merge('reportNameValuePairs_<reportID>', {private_isArchived: '2024-01-01 00:00:00'})in console to archive the expense chat of the workspace archived too.workspace:filter and open thepolicyIDautocomplete: confirm the archived workspace still appears.Screen.Recording.2026-08-03.at.7.34.49.PM.mov
Screen.Recording.2026-08-03.at.7.22.12.PM.mov
Screen.Recording.2026-08-03.at.7.34.06.PM.mov
Offline tests
Same as Tests — the change is a pure client-side Onyx read, no network calls involved, so offline behavior is unaffected.
QA Steps
This will be tested on R4 when the UI shows the archived workspaces.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2026-08-03.at.7.34.49.PM.mov
Screen.Recording.2026-08-03.at.7.22.12.PM.mov
Screen.Recording.2026-08-03.at.7.34.06.PM.mov