fix: sync resource toggle states with context on initial load #202

Closed
opened 2026-04-05 17:02:28 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @Abhinav-kodes on 2/25/2026

Community Contribution License Agreement

By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.

Description

Fixes a hydration bug where the Enable Rules, SSO, and Email Whitelist toggles on resource settings pages would always render in the OFF state on cold load, regardless of the actual saved value in the database.

Closes fosrl/pangolin#2528

Root Cause

The SwitchInput components were using the defaultChecked prop (uncontrolled), which React only reads on the first render. Since the resource context hydrates asynchronously after mount, the first render always sees undefined or a stale value, so the toggles always appeared OFF.

Additionally, the state variables were initialized once via useState(resource.X) with no mechanism to re-sync when the context updated.

Changes

src/app/[orgId]/settings/resources/proxy/[niceId]/rules/page.tsx

  • useState(resource.applyRules ?? false) — added ?? false fallback
  • Added useEffect to sync rulesEnabled when resource.applyRules updates
  • Changed defaultChecked={rulesEnabled}checked={rulesEnabled} (controlled)

src/app/[orgId]/settings/resources/proxy/[niceId]/authentication/page.tsx

  • useState(resource.sso ?? false) — added ?? false fallback
  • Added useEffect to sync ssoEnabled when resource.sso updates
  • Changed defaultChecked={resource.sso}checked={ssoEnabled} (controlled)
  • useState(resource.emailWhitelistEnabled ?? false) — added ?? false fallback
  • Added useEffect to sync whitelistEnabled when resource.emailWhitelistEnabled updates
  • Changed defaultChecked={resource.emailWhitelistEnabled}checked={whitelistEnabled} (controlled)

Before / After

Before: Toggle always renders OFF on hard refresh, even when DB value is true.
After: Toggle correctly reflects the saved DB value immediately on load.

Testing

  • Hard refresh (Ctrl+Shift+R) on a resource with applyRules = true → Rules toggle shows ON
  • Hard refresh on a resource with emailWhitelistEnabled = true → Whitelist toggle shows ON
  • Hard refresh on a resource with sso = true → SSO toggle shows ON
  • Toggling any switch and saving still works correctly
  • No React controlled/uncontrolled warnings in console

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
*Originally created by @Abhinav-kodes on 2/25/2026* ## Community Contribution License Agreement By creating this pull request, I grant the project maintainers an unlimited, perpetual license to use, modify, and redistribute these contributions under any terms they choose, including both the AGPLv3 and the Fossorial Commercial license terms. I represent that I have the right to grant this license for all contributed content. ## Description Fixes a hydration bug where the **Enable Rules**, **SSO**, and **Email Whitelist** toggles on resource settings pages would always render in the OFF state on cold load, regardless of the actual saved value in the database. Closes fosrl/pangolin#2528 ## Root Cause The `SwitchInput` components were using the `defaultChecked` prop (uncontrolled), which React only reads on the **first render**. Since the resource context hydrates asynchronously after mount, the first render always sees `undefined` or a stale value, so the toggles always appeared OFF. Additionally, the state variables were initialized once via `useState(resource.X)` with no mechanism to re-sync when the context updated. ## Changes ### `src/app/[orgId]/settings/resources/proxy/[niceId]/rules/page.tsx` - `useState(resource.applyRules ?? false)` — added `?? false` fallback - Added `useEffect` to sync `rulesEnabled` when `resource.applyRules` updates - Changed `defaultChecked={rulesEnabled}` → `checked={rulesEnabled}` (controlled) ### `src/app/[orgId]/settings/resources/proxy/[niceId]/authentication/page.tsx` - `useState(resource.sso ?? false)` — added `?? false` fallback - Added `useEffect` to sync `ssoEnabled` when `resource.sso` updates - Changed `defaultChecked={resource.sso}` → `checked={ssoEnabled}` (controlled) - `useState(resource.emailWhitelistEnabled ?? false)` — added `?? false` fallback - Added `useEffect` to sync `whitelistEnabled` when `resource.emailWhitelistEnabled` updates - Changed `defaultChecked={resource.emailWhitelistEnabled}` → `checked={whitelistEnabled}` (controlled) ## Before / After **Before:** Toggle always renders OFF on hard refresh, even when DB value is `true`. **After:** Toggle correctly reflects the saved DB value immediately on load. ## Testing - [ ] Hard refresh (`Ctrl+Shift+R`) on a resource with `applyRules = true` → Rules toggle shows ON - [ ] Hard refresh on a resource with `emailWhitelistEnabled = true` → Whitelist toggle shows ON - [ ] Hard refresh on a resource with `sso = true` → SSO toggle shows ON - [ ] Toggling any switch and saving still works correctly - [ ] No React controlled/uncontrolled warnings in console ## Type of Change - [x] Bug fix (non-breaking change which fixes an issue)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/pangolin#202