Skip to content

fix: prevent disabled View checkbox from being selected when Write is toggled#4693

Open
Grovy-3170 wants to merge 1 commit intomainfrom
fix/view-checkbox-disabled-state-custom-role
Open

fix: prevent disabled View checkbox from being selected when Write is toggled#4693
Grovy-3170 wants to merge 1 commit intomainfrom
fix/view-checkbox-disabled-state-custom-role

Conversation

@Grovy-3170
Copy link
Copy Markdown

@Grovy-3170 Grovy-3170 commented Apr 11, 2026

Type of Change

  • Bugfix

Description

When the backend doesn't include the read scope for a permission module, the View checkbox is correctly shown as disabled. However, selecting the Write checkbox would still auto-select the disabled View checkbox.

The root cause was in handleScopeChange in CreateCustomRoleV2.res — the (Write, true) case unconditionally added Read to the scopes without checking if Read was actually available:

// Before (bug)
| (Write, true) => updateScope(newScopes, Add, Read)

// After (fix)
| (Write, true) => isReadAvailable ? updateScope(newScopes, Add, Read) : newScopes

Moved isReadAvailable / isWriteAvailable above handleScopeChange so the availability check is accessible inside the handler.

Motivation and Context

Fixes #4694

On the Create Custom Roles page, each permission module has View and Write checkboxes. If the backend omits a scope (e.g., read), the corresponding checkbox is disabled. The bug caused a disabled View checkbox to become selected when Write was toggled on, which is incorrect — disabled checkboxes should never change state.

How did you test it?

  • Ran npm run re:build — compiles successfully with no errors
  • Locally on UI

Checklist

  • I ran npm run re:build
  • I reviewed submitted code
  • I added unit tests for my changes where possible

… toggled

When the backend doesn't include the "read" scope for a permission module,
the View checkbox is correctly shown as disabled. However, selecting the
Write checkbox would still auto-select the disabled View checkbox because
`handleScopeChange` unconditionally added Read when Write was toggled on.

This fix checks `isReadAvailable` before auto-selecting Read, so disabled
View checkboxes remain unselected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Grovy-3170 Grovy-3170 requested a review from a team as a code owner April 11, 2026 06:25
@semanticdiff-com
Copy link
Copy Markdown

Review changes with  SemanticDiff

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Walkthrough

A conditional logic refinement in the custom role creation component reorders boolean computations and makes the forced Read scope toggle conditional on Read availability when Write is enabled, rather than always enforcing it.

Changes

Cohort / File(s) Summary
Role Permission Logic
src/screens/UserManagement/UserRevamp/CreateCustomRoleV2.res
Moved isReadAvailable and isWriteAvailable computations before handleScopeChange, and updated the Write toggle case to conditionally add Read only if isReadAvailable is true.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A scope so wise, now conditional and neat,
Write-toggle's logic makes the dance complete,
When Read's not there, it stays in place so fair,
No forced mutations floating in the air!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: preventing a disabled View checkbox from being selected when Write is toggled, which directly addresses the root cause fix described in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/view-checkbox-disabled-state-custom-role

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Grovy-3170 Grovy-3170 self-assigned this Apr 11, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/screens/UserManagement/UserRevamp/CreateCustomRoleV2.res (1)

48-48: Add a regression test for the “Write on + Read unavailable” path.

Given this was a behavior bug, adding a focused test would protect this branch from future regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/screens/UserManagement/UserRevamp/CreateCustomRoleV2.res` at line 48, Add
a regression test that exercises the branch in CreateCustomRoleV2 where the
tuple matches (Write, true) but isReadAvailable is false: call the logic that
uses updateScope (referencing updateScope, newScopes, Add, Read and
isReadAvailable) with a starting newScopes and isReadAvailable=false, then
assert the result is exactly newScopes (i.e., no Read was added); place the test
alongside existing CreateCustomRoleV2 tests and make it fail if updateScope is
called to add Read in this scenario.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/screens/UserManagement/UserRevamp/CreateCustomRoleV2.res`:
- Line 48: Add a regression test that exercises the branch in CreateCustomRoleV2
where the tuple matches (Write, true) but isReadAvailable is false: call the
logic that uses updateScope (referencing updateScope, newScopes, Add, Read and
isReadAvailable) with a starting newScopes and isReadAvailable=false, then
assert the result is exactly newScopes (i.e., no Read was added); place the test
alongside existing CreateCustomRoleV2 tests and make it fail if updateScope is
called to add Read in this scenario.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6b1eb015-bb40-4d6f-a63f-6ac96a7b0063

📥 Commits

Reviewing files that changed from the base of the PR and between a1b7282 and e95b63c.

📒 Files selected for processing (1)
  • src/screens/UserManagement/UserRevamp/CreateCustomRoleV2.res

Copy link
Copy Markdown
Collaborator

@muditbhutani muditbhutani left a comment

Choose a reason for hiding this comment

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

Merge Confidence: 4.5/5 - Very Confident

"Ship it - low risk, well-tested"

Assessment
  • ✓ Well-scoped 1-file, 1-hunk bug fix — minimal blast radius
  • ✓ Correctly moves isReadAvailable/isWriteAvailable before the closure that references them, fixing a variable ordering issue
  • ✓ Guard condition isReadAvailable ? ... : newScopes is the right fix — prevents adding a scope that doesn't exist for the module
  • ✓ No API, auth, or data layer changes — purely client-side form state logic
  • ⚠ The symmetric case (Read, false) => Remove Write doesn't check isWriteAvailable, but this is safe assuming Write always implies Read availability

Review: Fix: Guard Read scope auto-add behind availability check in custom role creation

Small bug fix that prevents the Write scope toggle from unconditionally adding Read scope when Read isn't available for a given permission module. Also fixes variable declaration ordering so isReadAvailable is in scope within the handleScopeChange closure. Low risk, well-scoped change.

@@ -35,22 +35,22 @@ module RenderPermissionModule = {
parentGroupsField.input.onChange(updatedGroups->Identity.arrayOfGenericTypeToFormReactEvent)
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.

Verify conditional Read scope addition when Write is selected

Risk: LOW

Fixes a bug where selecting "Write" scope unconditionally added "Read", even for permission modules that don't support Read scope. Now isReadAvailable is checked before adding Read.

Two changes in one: (1) moved isReadAvailable/isWriteAvailable declarations above handleScopeChange so they're captured by the closure, and (2) added the isReadAvailable guard on the Write→Read auto-add logic.

The (Read, false) branch still unconditionally removes Write — this is safe because any module offering Write should always offer Read (Write implies Read), so removing Read should always strip Write too. Verify this invariant holds across all permission modules.

Reviewers should confirm that no permission module exists where Write is available but Read is not, as the (Read, false) => Remove Write path doesn't check isWriteAvailable.

Diagram:

stateDiagram-v2
    [*] --> NoScope
    NoScope --> ReadOnly: "Select Read (if available)"
    NoScope --> WriteOnly: "Select Write (Read unavailable)"
    NoScope --> ReadWrite: "Select Write (Read available)"
    ReadOnly --> ReadWrite: "Select Write"
    ReadOnly --> NoScope: "Deselect Read"
    ReadWrite --> NoScope: "Deselect Read (removes Write)"
    ReadWrite --> ReadOnly: "Deselect Write"
    WriteOnly --> NoScope: "Deselect Write"
Loading

@Riddhiagrawal001
Copy link
Copy Markdown
Contributor

@control_center_review_bot review the pr

@Riddhiagrawal001
Copy link
Copy Markdown
Contributor

@Grovy-3170 Please follow the PR description format. Also checks are failing please check

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Disabled View checkbox gets selected when Write is toggled in Create Custom Role

3 participants