Skip to content

feat(frontend): open the portal UI by default - #2358

Merged
hello1101n merged 1 commit into
constructorfabric:mainfrom
hello1101n:feat/frontend-portal-default-on
Aug 10, 2026
Merged

feat(frontend): open the portal UI by default#2358
hello1101n merged 1 commit into
constructorfabric:mainfrom
hello1101n:feat/frontend-portal-default-on

Conversation

@hello1101n

@hello1101n hello1101n commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What

The portal UI is now what a reader gets on open. insight.portal flips from opt-in to opt-out: an absent key means the portal renders, and only an explicit "false" returns the legacy shell.

  • readEnabled()readKey(ENABLED_KEY) !== "false", mirroring the showPlanned reader
  • usePortalEnabled server snapshot → true, so the first paint matches the client
  • comments in portal-store.ts / portal-layout.tsx describe the flag as opt-out

Turning it off

Unchanged and still reachable from inside the portal: SidebarSettings renders in AppSidebarFooter, which the portal's lens rail and context pane both mount. The toggle writes "false"; /portal then redirects to / and the legacy dashboard renders.

showPlanned is untouched — still ON by default, still toggled from the same panel.

Tests

  • new case: enabled defaults ON when the key is absent
  • blocked-storage case now expects the portal, since a throwing localStorage reads as "no key"
  • pnpm test (929 unit tests), tsc -b, eslint on the touched files — all clean

Summary by CodeRabbit

  • New Features

    • The portal is now enabled by default.
    • Portal access remains enabled unless explicitly set to "false".
    • Users are redirected when the portal is unavailable.
  • Documentation

    • Updated portal guidance and settings labels to reflect the new default behavior.
  • Tests

    • Added coverage confirming the portal remains enabled when settings are unavailable or unset.

@hello1101n
hello1101n requested a review from a team as a code owner August 10, 2026 03:20
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1493b3d6-040e-4211-9889-9860f0c7760e

📥 Commits

Reviewing files that changed from the base of the PR and between 69ba7ec6845ecaacc5a76e788c671895b267b5ea and 2ed319b.

📒 Files selected for processing (1)
  • src/frontend/src/lib/portal/portal-store.test.ts

📝 Walkthrough

Walkthrough

The portal now renders by default. Only an explicit "false" storage value disables it. Server-side snapshots, route documentation, settings labels, and tests match this behavior.

Changes

Portal enablement defaults

Layer / File(s) Summary
Default-on enablement semantics
src/frontend/src/lib/portal/portal-store.ts, src/frontend/src/components/portal/portal-layout.tsx, src/frontend/src/components/sidebar-settings.tsx, src/frontend/src/routes/index.tsx, src/frontend/src/routes/portal.tsx
Portal enablement now defaults to true, and only "false" disables it. Server snapshots and portal-related documentation use the new default-on terminology.
Default behavior validation
src/frontend/src/lib/portal/portal-store.test.ts
Tests verify that absent, explicitly disabled, or inaccessible local storage produces the expected portal state.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: ktursunov

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enabling the portal UI by default.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/frontend/src/lib/portal/portal-store.test.ts (1)

35-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extend coverage to the hook and opt-out branch.

This test verifies readPortalEnabled() for an absent key. It does not verify usePortalEnabled() after initialization, the server snapshot changed at src/frontend/src/lib/portal/portal-store.ts Line 115, or the explicit "false" branch. Because beforeEach sets the module state to false before clearing storage, a hook assertion here would not test default initialization. Add isolated tests for these paths, or verify that existing tests provide them and that the changed lines reach at least 80% coverage.

As per coding guidelines, new and changed lines in src/frontend/**/*.{ts,tsx} must achieve at least 80% test coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/src/lib/portal/portal-store.test.ts` around lines 35 - 39,
Extend portal-store test coverage beyond readPortalEnabled’s absent-key case:
add isolated tests for usePortalEnabled after initialization with the default
enabled state, the server snapshot behavior in the portal-store implementation,
and the explicit "false" opt-out branch. Ensure setup does not leave module
state false when testing default initialization, and verify changed frontend
lines reach at least 80% coverage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/frontend/src/lib/portal/portal-store.test.ts`:
- Around line 35-39: Extend portal-store test coverage beyond
readPortalEnabled’s absent-key case: add isolated tests for usePortalEnabled
after initialization with the default enabled state, the server snapshot
behavior in the portal-store implementation, and the explicit "false" opt-out
branch. Ensure setup does not leave module state false when testing default
initialization, and verify changed frontend lines reach at least 80% coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b292b8fa-ee68-40f1-9664-ea1bca745204

📥 Commits

Reviewing files that changed from the base of the PR and between 0fb67d3 and 1f6da06f2e252b9b8b5ec1731842a625a91be933.

📒 Files selected for processing (3)
  • src/frontend/src/components/portal/portal-layout.tsx
  • src/frontend/src/lib/portal/portal-store.test.ts
  • src/frontend/src/lib/portal/portal-store.ts

@hello1101n
hello1101n force-pushed the feat/frontend-portal-default-on branch 2 times, most recently from f359d02 to 69ba7ec Compare August 10, 2026 04:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/frontend/src/routes/index.tsx`:
- Around line 21-22: Update the comment near IndexRoute to remove the incorrect
claim that enabling the portal while mounted requires a reload. Explain that
usePortalEnabled reacts to changes and redirects immediately, while beforeLoad
serves as the initial-navigation fallback.

In `@src/frontend/src/routes/portal.tsx`:
- Around line 30-33: Update the comment above PortalRoute to accurately describe
both mount paths: when usePortalEnabled() is false, redirect the user to the
available app, and when it is true—including direct /portal navigation—render
PortalLayout. Remove the inaccurate claim that this component only mounts with
the portal disabled.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 547f545f-2f28-42f6-b8e8-a246011e23da

📥 Commits

Reviewing files that changed from the base of the PR and between 1f6da06f2e252b9b8b5ec1731842a625a91be933 and 69ba7ec6845ecaacc5a76e788c671895b267b5ea.

📒 Files selected for processing (4)
  • src/frontend/src/components/sidebar-settings.tsx
  • src/frontend/src/lib/portal/portal-store.ts
  • src/frontend/src/routes/index.tsx
  • src/frontend/src/routes/portal.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/frontend/src/lib/portal/portal-store.ts

Comment on lines +21 to 22
// `beforeLoad` only runs on navigation, so a reader who turns the portal on
// while standing here would sit on the dashboard until a reload.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 8 'setPortalEnabled|usePortalEnabled|subscribe' \
  src/frontend/src/lib/portal/portal-store.ts \
  src/frontend/src/routes/index.tsx

Repository: constructorfabric/insight

Length of output: 6380


Correct the reload claim in the route comment.

IndexRoute subscribes through usePortalEnabled() via useSyncExternalStore(subscribe, ...), and setPortalEnabled() calls emit() before reading the store. If a reader enables the portal while this route is mounted, the hook re-renders and the route returns <Navigate to="/portal" replace /> without requiring a reload. Update the comment to describe beforeLoad as the initial-navigation fallback.

Proposed comment
-  // `beforeLoad` only runs on navigation, so a reader who turns the portal on
-  // while standing here would sit on the dashboard until a reload.
+  // `beforeLoad` handles the initial navigation. The subscribed store hook
+  // below redirects if the reader enables the portal while this route is open.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// `beforeLoad` only runs on navigation, so a reader who turns the portal on
// while standing here would sit on the dashboard until a reload.
// `beforeLoad` handles the initial navigation. The subscribed store hook
// below redirects if the reader enables the portal while this route is open.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/src/routes/index.tsx` around lines 21 - 22, Update the comment
near IndexRoute to remove the incorrect claim that enabling the portal while
mounted requires a reload. Explain that usePortalEnabled reacts to changes and
redirects immediately, while beforeLoad serves as the initial-navigation
fallback.

Comment on lines +30 to +33
// The root shell swaps in PortalLayout for this route while the portal is
// on, so this component only mounts with it OFF — a pasted /portal URL, or a
// viewer who turned the preview off while standing here. Either way the
// portal must not render: send them to the app they do have.
// viewer who opted out while standing here. Either way the portal must not
// render: send them to the app they do have.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the mount-state description.

The comment says PortalRoute only mounts while the portal is off. Line 35 returns <PortalLayout /> when usePortalEnabled() is true, including for direct /portal navigation. Describe the disabled redirect and enabled render paths separately.

Proposed comment
-  // The root shell swaps in PortalLayout for this route while the portal is
-  // on, so this component only mounts with it OFF — a pasted /portal URL, or a
-  // viewer who opted out while standing here. Either way the portal must not
-  // render: send them to the app they do have.
+  // When the portal is disabled, a direct /portal URL or an opt-out while
+  // already here redirects to /. When enabled, render PortalLayout.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// The root shell swaps in PortalLayout for this route while the portal is
// on, so this component only mounts with it OFF — a pasted /portal URL, or a
// viewer who turned the preview off while standing here. Either way the
// portal must not render: send them to the app they do have.
// viewer who opted out while standing here. Either way the portal must not
// render: send them to the app they do have.
// When the portal is disabled, a direct /portal URL or an opt-out while
// already here redirects to /. When enabled, render PortalLayout.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/src/routes/portal.tsx` around lines 30 - 33, Update the comment
above PortalRoute to accurately describe both mount paths: when
usePortalEnabled() is false, redirect the user to the available app, and when it
is true—including direct /portal navigation—render PortalLayout. Remove the
inaccurate claim that this component only mounts with the portal disabled.

@hello1101n
hello1101n enabled auto-merge August 10, 2026 04:45
@hello1101n
hello1101n force-pushed the feat/frontend-portal-default-on branch 2 times, most recently from 2b0165d to 62c8622 Compare August 10, 2026 04:49
The `insight.portal` preference now reads as opt-out: an absent key means the
portal renders, and only an explicit "false" returns the legacy shell. The
sidebar toggle, reachable from the portal's own footer, still switches back
per reader.

Both preferences share that rule now, so one `readBoolPref` states it once,
and the toggle label and the two route guards drop the "preview" wording the
flag no longer carries.

Signed-off-by: hello1101n <hello1101n@users.noreply.github.com>
@hello1101n
hello1101n force-pushed the feat/frontend-portal-default-on branch from 62c8622 to 2ed319b Compare August 10, 2026 05:53
@hello1101n
hello1101n added this pull request to the merge queue Aug 10, 2026
Merged via the queue into constructorfabric:main with commit 38f9511 Aug 10, 2026
57 of 58 checks passed
@hello1101n
hello1101n deleted the feat/frontend-portal-default-on branch August 10, 2026 06:40
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.

3 participants