Skip to content

Add Conditional Rendering For Feature Preview Menu Item.#9767

Merged
pavinduLakshan merged 6 commits intowso2:masterfrom
ImalshaD:ImalshaD/conditional-rendering-on-feature-preview-modal
Mar 14, 2026
Merged

Add Conditional Rendering For Feature Preview Menu Item.#9767
pavinduLakshan merged 6 commits intowso2:masterfrom
ImalshaD:ImalshaD/conditional-rendering-on-feature-preview-modal

Conversation

@ImalshaD
Copy link
Contributor

This pull request refactors the feature preview modal logic by extracting it into a new reusable hook, usePreviewFeatures, and updates the Header and modal components to use this hook. The changes improve code modularity, readability, and maintainability by centralizing preview feature logic and reducing duplication.

Feature Preview Modal Refactoring:

  • Created a new hook, usePreviewFeatures, which encapsulates all logic related to preview features, including accessible features, toggle handlers, and modal state. This replaces the previous inline logic in the modal component.
  • Updated FeaturePreviewModal to use the new hook, removing redundant code and type definitions, and delegating all feature preview logic to usePreviewFeatures. [1] [2]

Header Component Updates:

  • Integrated usePreviewFeatures in the Header component to determine if preview features are available, and conditionally render the Feature Preview menu item and modal based on this state. [1] [2] [3] [4] [5]

Type and Interface Consolidation:

  • Moved PreviewFeaturesListInterface definition from the modal component to the new hook, reducing duplication and improving type organization. [1] [2]

Copilot AI review requested due to automatic review settings March 13, 2026 09:42
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces a new usePreviewFeatures hook and refactors header and FeaturePreviewModal to consume it; header now conditionally renders the Feature Preview UI via canUsePreviewFeatures, and the modal delegates feature listing, selection, toggles, redirection, and CDS toggle logic to the hook.

Changes

Cohort / File(s) Summary
New Hook
features/admin.core.v1/hooks/use-preview-features.ts
Adds usePreviewFeatures plus PreviewFeaturesListInterface and UsePreviewFeaturesReturnInterface. Builds preview feature list (CDS), computes accessibleFeatures and canUsePreviewFeatures, manages selection state, and exposes handlers (handleCDSToggle, handleToggleChange, handlePageRedirection).
Header component
features/admin.core.v1/components/header.tsx
Replaces prior feature-gating selectors with usePreviewFeatures usage and uses canUsePreviewFeatures to conditionally render the Feature Preview MenuItem and Modal; removes selectors for loginAndRegistration and customerDataService.
Feature Preview Modal
features/admin.core.v1/components/modals/feature-preview-modal.tsx
Removes in-component Redux/CDS reads, local effects, and mutation logic. Consumes accessibleFeatures, selected, selectedFeatureIndex, and handler functions from usePreviewFeatures, delegating side effects and simplifying UI logic.
Changelog
.changeset/six-books-clap.md
Adds changelog entry noting conditional Feature Preview rendering logic and package patch updates.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change—adding conditional rendering for the feature preview menu item based on the new usePreviewFeatures hook.
Description check ✅ Passed The PR description provides detailed context about the refactoring, though it lacks information from the required checklist sections like testing, security, and backend verification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Changeset Required ✅ Passed Pull request includes properly configured changeset file (.changeset/six-books-clap.md) documenting patch-level updates to @wso2is/admin.core.v1 and @wso2is/console with appropriate description.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors the Feature Preview modal to centralize preview-feature state/handlers into a reusable usePreviewFeatures hook, and updates Header + modal to use the hook for conditional rendering and feature interactions.

Changes:

  • Added usePreviewFeatures hook to encapsulate preview feature list building, scope-based access, selection state, and toggle handlers.
  • Refactored FeaturePreviewModal to consume usePreviewFeatures and removed duplicated inline logic/types.
  • Updated Header to conditionally show the Feature Preview menu item/modal based on hook-derived availability.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
features/admin.core.v1/hooks/use-preview-features.ts Introduces the shared hook that builds accessible preview features, manages selection, and implements CDS toggle/update behavior.
features/admin.core.v1/components/modals/feature-preview-modal.tsx Simplifies modal by delegating feature list, selection, and actions to usePreviewFeatures.
features/admin.core.v1/components/header.tsx Uses usePreviewFeatures to decide whether to render Feature Preview entry points in the header.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

@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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@features/admin.core.v1/components/header.tsx`:
- Around line 687-703: The menu item and modal use different visibility checks
causing the modal to be mountable when the menu is hidden; update
usePreviewFeatures to return a single canonical boolean (e.g.,
canUsePreviewFeatures) and replace all disparate checks (hasPreviewFeatures,
cdsFeatureConfig scope checks, and any direct uses of FeatureGateConstants
gating around the MenuItem and modal mount) with that one boolean; ensure
setShowPreviewFeaturesModal and showPreviewFeaturesModal still control
opening/closing but are only reachable when canUsePreviewFeatures is true so
both the <Show> wrapper (or its replacement) around the MenuItem and the modal
render/use the same gate.

In `@features/admin.core.v1/hooks/use-preview-features.ts`:
- Around line 153-158: The enable branch only assigns CDS_CONSOLE_APP when
system_applications is empty, so update the nextApps logic to always ensure
CDS_CONSOLE_APP is present when enable is true: compute currentApps from
cdsConfig, then if enable is true add CDS_CONSOLE_APP to currentApps if it's not
already included (e.g., push or create a new array with the value only when
absent), otherwise (when enable is false) filter out CDS_CONSOLE_APP as before;
adjust the calculation for nextApps (the variable in this diff) to reflect this
presence-check and de-dup behavior.
- Around line 85-90: The hook currently starts fetching CDS config whenever CDS
is enabled, even if the user lacks update scope; change the enable flag passed
to useCDSConfig so fetching is gated by the same access check: pass
(cdsFeatureConfig?.enabled ?? false) && hasCDSScopes to useCDSConfig (keep
calling useCDSConfig unconditionally to obey hooks rules but compute the boolean
so the request only runs when both cdsFeatureConfig is enabled and hasCDSScopes
is true).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 8e8026cb-819f-43ad-a05e-f03e9cc03bb3

📥 Commits

Reviewing files that changed from the base of the PR and between 18a2ed9 and f0da752.

📒 Files selected for processing (3)
  • features/admin.core.v1/components/header.tsx
  • features/admin.core.v1/components/modals/feature-preview-modal.tsx
  • features/admin.core.v1/hooks/use-preview-features.ts

Copy link
Contributor

@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.

Actionable comments posted: 2

♻️ Duplicate comments (2)
features/admin.core.v1/hooks/use-preview-features.ts (2)

160-164: ⚠️ Potential issue | 🟠 Major

Ensure CONSOLE is always present when CDS is enabled.

Enable flow currently preserves existing system_applications as-is when non-empty, so CONSOLE may remain missing after re-enable.

💡 Suggested update
             const currentApps: string[] = cdsConfig?.system_applications ?? [];
             const nextApps: string[] = enable
-                ? currentApps.length === 0
-                    ? [ CDS_CONSOLE_APP ]
-                    : currentApps
+                ? currentApps.includes(CDS_CONSOLE_APP)
+                    ? currentApps
+                    : [ ...currentApps, CDS_CONSOLE_APP ]
                 : currentApps.filter((app: string) => app !== CDS_CONSOLE_APP);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.core.v1/hooks/use-preview-features.ts` around lines 160 - 164,
When enabling CDS, the current logic sets nextApps to currentApps unchanged when
non-empty, which can leave CDS_CONSOLE_APP out; update the assignment for
nextApps in use-preview-features.ts so that when enable is true you always
include CDS_CONSOLE_APP (e.g., merge CDS_CONSOLE_APP into currentApps if
missing) — modify the nextApps computation (using nextApps, enable, currentApps,
CDS_CONSOLE_APP) to ensure CDS_CONSOLE_APP is present in the returned array for
system_applications.

93-97: ⚠️ Potential issue | 🟠 Major

Gate CDS config fetch by access scope to avoid unnecessary API calls.

The fetch currently runs whenever CDS is enabled in config, even for users who cannot access the feature. Use the same scope gate used for visibility.

💡 Suggested update
-    const {
+    const shouldFetchCDSConfig: boolean = Boolean(cdsFeatureConfig?.enabled) && hasCDSScopes;
+
+    const {
         data: cdsConfig,
         mutate: mutateCDSConfig
-    } = useCDSConfig(cdsFeatureConfig?.enabled ?? false);
+    } = useCDSConfig(shouldFetchCDSConfig);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.core.v1/hooks/use-preview-features.ts` around lines 93 - 97,
The CDS config fetch is only gated by cdsFeatureConfig?.enabled; update the call
to useCDSConfig to also require the same access-scope/visibility gate used
elsewhere so the API call only runs for users who can access the feature—i.e.,
change useCDSConfig(cdsFeatureConfig?.enabled ?? false) to
useCDSConfig((cdsFeatureConfig?.enabled ?? false) && <the visibility/access gate
variable or function used for CDS visibility>) so useCDSConfig and
mutateCDSConfig only run when both enabled and accessible.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@features/admin.core.v1/components/header.tsx`:
- Around line 687-693: The new menu item uses a literal string for translation
and lacks a component id; update the ListItemText to use a namespaced i18n key
(e.g., "admin:featurePreview" or similar) instead of t("Feature Preview") and
add a data-componentid attribute on the MenuItem (or the clickable element) to
follow conventions; locate the MenuItem that calls setShowPreviewFeaturesModal
and uses PreviewFeaturesIcon/ListItemText and replace the literal key with the
namespaced key and add data-componentid="header-feature-preview-menuitem" (or
repo-standard id) so localization and component identification are consistent.

In `@features/admin.core.v1/hooks/use-preview-features.ts`:
- Around line 75-76: The JSDoc `@returns` text is out of sync: it mentions
hasPreviewFeatures but the hook exposes canUsePreviewFeatures; update the
comment in use-preview-features.ts so the `@returns` description lists the actual
API names (including canUsePreviewFeatures, previewFeatures list, accessible
list, and modal state/handlers) instead of hasPreviewFeatures to accurately
reflect the hook's exported values.

---

Duplicate comments:
In `@features/admin.core.v1/hooks/use-preview-features.ts`:
- Around line 160-164: When enabling CDS, the current logic sets nextApps to
currentApps unchanged when non-empty, which can leave CDS_CONSOLE_APP out;
update the assignment for nextApps in use-preview-features.ts so that when
enable is true you always include CDS_CONSOLE_APP (e.g., merge CDS_CONSOLE_APP
into currentApps if missing) — modify the nextApps computation (using nextApps,
enable, currentApps, CDS_CONSOLE_APP) to ensure CDS_CONSOLE_APP is present in
the returned array for system_applications.
- Around line 93-97: The CDS config fetch is only gated by
cdsFeatureConfig?.enabled; update the call to useCDSConfig to also require the
same access-scope/visibility gate used elsewhere so the API call only runs for
users who can access the feature—i.e., change
useCDSConfig(cdsFeatureConfig?.enabled ?? false) to
useCDSConfig((cdsFeatureConfig?.enabled ?? false) && <the visibility/access gate
variable or function used for CDS visibility>) so useCDSConfig and
mutateCDSConfig only run when both enabled and accessible.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b92d62e1-9bd7-4646-a2dd-1035bc36ac9a

📥 Commits

Reviewing files that changed from the base of the PR and between f0da752 and ec7f9d4.

📒 Files selected for processing (2)
  • features/admin.core.v1/components/header.tsx
  • features/admin.core.v1/hooks/use-preview-features.ts

@ImalshaD ImalshaD changed the title Add Config based Fature preview rendering. Add Conditional Rendering For Feature Preview Menu Item. Mar 13, 2026
@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.01%. Comparing base (c8422c3) to head (b978bdd).
⚠️ Report is 64 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9767   +/-   ##
=======================================
  Coverage   56.01%   56.01%           
=======================================
  Files          42       42           
  Lines        1023     1023           
  Branches      247      254    +7     
=======================================
  Hits          573      573           
  Misses        416      416           
  Partials       34       34           
Flag Coverage Δ
@wso2is/core 56.01% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
features/admin.core.v1/components/modals/feature-preview-modal.tsx (1)

67-69: Memoize handleClose with useCallback.

handleClose is recreated on every render; memoizing it aligns with the callback stability rule.

💡 Proposed change
-import React, { ChangeEvent, FunctionComponent, ReactElement } from "react";
+import React, { ChangeEvent, FunctionComponent, ReactElement, useCallback } from "react";

-    const handleClose: () => void = (): void => {
-        onClose();
-    };
+    const handleClose: () => void = useCallback(
+        (): void => {
+            onClose();
+        },
+        [ onClose ]
+    );

As per coding guidelines, "Stabilize callbacks with useCallback and expensive computations with useMemo."

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

In `@features/admin.core.v1/components/modals/feature-preview-modal.tsx` around
lines 67 - 69, The handleClose function in feature-preview-modal.tsx is
recreated each render; wrap it with React.useCallback to stabilize the callback
reference (e.g., const handleClose = useCallback(() => onClose(), [onClose])) so
it doesn't change unnecessarily; update imports if needed and ensure you
reference the existing handleClose and onClose symbols when applying the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@features/admin.core.v1/components/modals/feature-preview-modal.tsx`:
- Around line 59-65: The destructuring of usePreviewFeatures() lacks explicit
types; import UsePreviewFeaturesReturnInterface from the hooks module and
annotate the destructured binding accordingly so the const is typed as
UsePreviewFeaturesReturnInterface (e.g., const { accessibleFeatures,
handlePageRedirection, handleToggleChange, selected, setSelectedFeatureIndex }:
UsePreviewFeaturesReturnInterface = usePreviewFeatures()), ensuring you update
imports to include UsePreviewFeaturesReturnInterface and keep the existing
variable names (accessibleFeatures, handlePageRedirection, handleToggleChange,
selected, setSelectedFeatureIndex).

---

Nitpick comments:
In `@features/admin.core.v1/components/modals/feature-preview-modal.tsx`:
- Around line 67-69: The handleClose function in feature-preview-modal.tsx is
recreated each render; wrap it with React.useCallback to stabilize the callback
reference (e.g., const handleClose = useCallback(() => onClose(), [onClose])) so
it doesn't change unnecessarily; update imports if needed and ensure you
reference the existing handleClose and onClose symbols when applying the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 89ea234a-f1f2-4e92-9caa-353dc5d62a43

📥 Commits

Reviewing files that changed from the base of the PR and between f587566 and b978bdd.

📒 Files selected for processing (1)
  • features/admin.core.v1/components/modals/feature-preview-modal.tsx

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