Group contract workspace rail into Read / Negotiate / History modes#177
Merged
Conversation
The right rail had six flat sub-tabs (Metadata, Clauses, Review,
Lifecycle, Signers, History) that mixed "what is this contract"
(read), "what's happening to it" (negotiate), and "what happened
to it" (versions/history) into one row. Six undifferentiated
options + no signal about which one to use → mode confusion.
This adds a top-level mode row above the sub-tabs:
- Read → Metadata, Clauses
- Negotiate → Review, Lifecycle, Signers
- History → History
The mode is derived from the active sub-tab, so any existing caller
that does ``setActiveTab("review")`` / ``setActiveTab("signers")``
/ ``setActiveTab("history")`` (lifecycle action buttons, the
overflow menu's Send-to-DocuSeal shortcut, the gate remediation
checklist, etc.) automatically switches into the right mode without
extra coordination. Clicking a mode tab lands on that mode's first
sub-tab (Read → Metadata, Negotiate → Review, History → History).
Default mode is Read so the workspace opens on the lightest view —
just metadata and clauses, no in-flight workflow noise.
New ``WorkspaceModeTabs`` component (with role=tablist + role=tab)
sits above the existing ``RightPanelTabs``, which now receives a
filtered sub-tab list driven by the active mode. The two rows are
visually distinct so it's clear which is the primary selector.
Tests:
- New ``WorkspaceModeTabs.test.tsx`` (4 specs): labels, aria-selected
state, onChange dispatch, tablist semantics.
- Existing workspace test "renders a two-pane layout … all six tabs"
rewritten to "… with mode tabs and contextual sub-tabs": asserts
the three mode tabs are present, Read mode shows only Metadata
+ Clauses (Signers is *not* in the DOM), switching to Negotiate
reveals Review/Lifecycle/Signers and hides Metadata/Clauses, and
History mode shows the History sub-tab + panel.
- Two blocked-gate tests that previously did
``fireEvent.click(getByRole("tab", { name: /signers/i }))`` now
switch to Negotiate first via the mode tab.
1161 frontend tests passing, build clean. Main bundle +1 KB for
the mode-tabs component; lazy Nango chunk untouched.
Deploying whereas with
|
| Latest commit: |
83b2efa
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://62ef0dd6.whereas.pages.dev |
| Branch Preview URL: | https://refactor-workspace-mode-tabs.whereas.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The contract workspace's right rail had six flat sub-tabs (Metadata, Clauses, Review, Lifecycle, Signers, History) that mixed three different user intents into one undifferentiated row — what is this contract, what's happening to it, what happened to it. The audit called this out as "mode confusion."
This adds a top-level mode row above the existing sub-tabs:
Default mode is Read, so the workspace opens on the lightest view — metadata + clauses, no in-flight workflow noise.
How it works
Mode is derived from
activeTabvia aTAB_TO_MODEmap, so existing call sites that already dosetActiveTab("review"),setActiveTab("signers"),setActiveTab("history")(lifecycle action buttons, overflow menu Send-to-DocuSeal shortcut, gate-remediation checklist, etc.) automatically switch into the right mode without extra coordination.Clicking a mode tab lands on that mode's first sub-tab (Read → Metadata, Negotiate → Review, History → History). Clicking a mode tab while already in that mode is a no-op.
What landed
New
components/WorkspaceModeTabs.tsx— primary mode tab bar (role=tablist), visually heavier than the sub-tab row so it's clear which row is the primary selector.components/__tests__/WorkspaceModeTabs.test.tsx— 4 specs.Modified
pages/ContractWorkspacePage.tsx:WorkspaceModetype +MODE_SUB_TABSandTAB_TO_MODEmaps next to the existingSidebarTabtype.<WorkspaceModeTabs>above<RightPanelTabs>, with the sub-tab list filtered to the active mode.handleModeChangepicks the first sub-tab of the target mode.Test updates
ContractWorkspacePage.test.tsx:fireEvent.click(getByRole("tab", { name: /signers/i }))now switch to Negotiate first via the mode tab.Test plan
npx vitest run— 1161 passing (+4 from the new mode-tabs spec).npx tsc -bclean.npm run buildsucceeds; lazy Nango chunk untouched at 11.71 KB; main bundle +1 KB for the mode-tabs component.ruff check .clean (no backend changes).setActiveTabdirectly) and confirm the mode tab updates alongside the sub-tab.Follow-ups (not in this PR)
?mode=negotiate&tab=signers) so a deep link can land directly in a specific mode-tab combo. Today the URL controls only the contract id.Generated by Claude Code