Skip to content

Centralize TierLimitReachErrorModal with shared redux state#10268

Open
sheronjay wants to merge 23 commits into
wso2:masterfrom
sheronjay:tier-limit-modal
Open

Centralize TierLimitReachErrorModal with shared redux state#10268
sheronjay wants to merge 23 commits into
wso2:masterfrom
sheronjay:tier-limit-modal

Conversation

@sheronjay
Copy link
Copy Markdown
Contributor

@sheronjay sheronjay commented May 10, 2026

Purpose

Centralize TierLimitReachErrorModal so it is rendered once and controlled through redux instead of being managed independently in each page/component.
This removes duplicated local modal state, close handlers, and repeated modal JSX across the affected create flows. Resource specific modal content is still preserved by storing the modal visibility and display content in Redux and dispatching it from each feature’s tier limit error path.

A dedicated Redux slice was used for this instead of extending the existing global reduce.

Related Issues

wso2/product-is#27714

Related PRs

  • N/A

Checklist

  • e2e cypress tests locally verified. (for internal contributers)
  • Manual test round performed and verified.
  • UX/UI review done on the final implementation.
  • Documentation provided. (Add links if there are any)
  • Relevant backend changes deployed and verified
  • Unit tests provided. (Add links if there are any)
  • Integration tests provided. (Add links if there are any)

Security checks

Developer Checklist (Mandatory)

  • Complete the Developer Checklist in the related product-is issue to track any behavioral change or migration impact.

Copilot AI review requested due to automatic review settings May 10, 2026 16:10
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

Review Change Stack

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 7ca16f0f-7a85-4427-ab19-65dedf6ce2ba

📥 Commits

Reviewing files that changed from the base of the PR and between 9f2f27a and ad91745.

📒 Files selected for processing (1)
  • .changeset/tier-limit-modal-updates.md
✅ Files skipped from review due to trivial changes (1)
  • .changeset/tier-limit-modal-updates.md

📝 Walkthrough

Walkthrough

This PR centralizes tier-limit-reached modal handling: adds Redux types/actions/reducer, wires the reducer into the root store, renders the modal from app root, and refactors many wizards to dispatch showTierLimitReachedModal() and close instead of using local modal state.

Changes

Unified Tier-Limit Modal System

Layer / File(s) Summary
Redux Types and State Contract
features/admin.core.v1/models/reducer-state.ts, features/admin.core.v1/store/actions/types/tier-limit-modal.ts
New TierLimitModalReducerStateInterface with actionLabel, header, description, message, and open. New action type enum and action interfaces for show/hide and a union action type.
Redux Infrastructure (actions)
features/admin.core.v1/store/actions/tier-limit-modal.ts
Added action creators showTierLimitReachedModal() and hideTierLimitReachedModal() that produce typed show/hide actions.
Redux Infrastructure (reducer)
features/admin.core.v1/store/reducers/tier-limit-modal.ts
Added tierLimitModalReducer with initial empty fields and open: false; SHOW_TIER_LIMIT_REACHED_MODAL sets payload fields and open: true, HIDE_TIER_LIMIT_REACHED_MODAL resets to initial state.
Root Store Integration
features/admin.core.v1/store/combine-reducers.ts
Registers tierLimitModalReducer under the tierLimitModal slice in the root combineReducers.
Modal Component Props Update
features/admin.core.v1/components/modals/tier-limit-reach-error-modal.tsx
TierLimitReachErrorModal props updated to open (from openModal) and makes actionLabel/header optional; default props adjusted.
Global Modal Display
apps/console/src/app.tsx
App root selects state.tierLimitModal, renders TierLimitReachErrorModal using Redux state (actionLabel, header, description, message, open), and dispatches hideTierLimitReachedModal() on close.
Feature Component Refactoring
features/*/components/*, features/*/pages/* (multiple wizards and modals)
Multiple components remove local openLimitReachedModal state and TierLimitReachErrorModal imports. On 403 tier-limit errors they now dispatch showTierLimitReachedModal({...}) with localized modal fields and then close the wizard/modal; conditional JSX branches that rendered the local modal were removed.
  • Suggested reviewers:
    • pavinduLakshan
    • DonOmalVindula
    • NipuniBhagya
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Centralize TierLimitReachErrorModal with shared redux state' clearly summarizes the main change: consolidating a modal component into a Redux-managed state.
Description check ✅ Passed The description covers the purpose, related issues, and security checks. However, most checklist items remain unchecked (e2e tests, UX review, unit tests, integration tests), and the Developer Checklist is incomplete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Changeset Required ✅ Passed Valid changeset file exists (.changeset/tier-limit-modal-updates.md) with proper YAML format, listing 10 affected packages including @wso2is/console with patch version bumps.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • 🛠️ create changeset

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
Copy Markdown
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

Centralizes the TierLimitReachErrorModal so it’s rendered once at the Console app root and controlled via a dedicated Redux slice, replacing per-flow local modal state and duplicated JSX across multiple “create” wizards/pages.

Changes:

  • Added a new Redux slice (tierLimitModal) with actions + reducer to control tier-limit modal visibility and content.
  • Updated multiple create flows (roles, groups, apps, connections, orgs, API resources, onboarding) to dispatch showTierLimitReachedModal(...) on tier-limit errors and then navigate/close the relevant wizard/page.
  • Rendered the centralized TierLimitReachErrorModal once in apps/console/src/app.tsx, wired to Redux state and a close action.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
features/admin.roles.v2/pages/create-role-wizard.tsx Dispatch centralized tier-limit modal and redirect instead of local modal state/rendering.
features/admin.roles.v2/components/wizard-updated/application-role-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.organizations.v1/components/add-organization-modal.tsx Replace local tier-limit modal handling with centralized modal dispatch (incl. org-level variant).
features/admin.onboarding.v1/components/onboarding-wizard.tsx Dispatch centralized tier-limit modal and redirect instead of rendering local modal.
features/admin.groups.v1/components/wizard/create-group-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.core.v1/store/reducers/tier-limit-modal.ts Introduce reducer for centralized tier-limit modal state.
features/admin.core.v1/store/combine-reducers.ts Register tierLimitModal reducer in root reducer.
features/admin.core.v1/store/actions/types/tier-limit-modal.ts Define action types and TS interfaces for tier-limit modal actions.
features/admin.core.v1/store/actions/tier-limit-modal.ts Add showTierLimitReachedModal/hideTierLimitReachedModal action creators.
features/admin.core.v1/models/reducer-state.ts Add TierLimitModalReducerStateInterface to shared reducer-state models.
features/admin.connections.v1/components/wizards/trusted-token-issuer-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.connections.v1/components/wizards/organization-enterprise/organization-enterprise-connection-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.connections.v1/components/wizards/expert-mode/expert-mode-authentication-provider-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.connections.v1/components/create/add-connection-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.applications.v1/components/wizard/minimal-application-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.applications.v1/components/try-it/try-it-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
features/admin.application-templates.v1/components/application-create-wizard.tsx Dispatch centralized tier-limit modal and close wizard instead of returning local modal.
features/admin.api-resources.v2/components/wizard/add-api-resource.tsx Dispatch centralized tier-limit modal and close wizard instead of local modal state/rendering.
apps/console/src/app.tsx Render centralized TierLimitReachErrorModal once and wire it to Redux state + hide action.

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

Comment thread features/admin.core.v1/store/reducers/tier-limit-modal.ts Outdated
Copy link
Copy Markdown
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: 6

🧹 Nitpick comments (1)
features/admin.core.v1/store/reducers/tier-limit-modal.ts (1)

47-50: ⚡ Quick win

Return state directly instead of spreading.

The default case creates a new object reference by spreading state, which causes unnecessary re-renders when unrelated actions are dispatched. Return the existing state reference to maintain Redux best practices.

⚡ Proposed fix
         default:
-            return {
-                ...state
-            };
+            return state;
🤖 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 `@features/admin.core.v1/store/reducers/tier-limit-modal.ts` around lines 47 -
50, In the reducer handling actions for the tier limit modal, the switch default
currently returns a new object via "return { ...state }" which creates a new
reference and triggers unnecessary re-renders; change the default branch to
return the existing state reference ("return state") so the reducer preserves
identity for unrelated actions (update the switch default in the
tier-limit-modal reducer accordingly).
🤖 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 `@apps/console/src/app.tsx`:
- Around line 199-200: The variable tierLimitReachedModal is missing an explicit
type annotation; update its declaration to explicitly type it as
TierLimitModalReducerStateInterface | undefined (since the selector uses
optional chaining) by annotating the const (referencing tierLimitReachedModal,
TierLimitModalReducerStateInterface, useSelector and AppState) so the result of
useSelector((state: AppState) => state?.tierLimitModal) is explicitly typed
rather than inferred.
- Around line 673-680: The TierLimitReachErrorModal usage is missing the
required data-componentid attribute; update the JSX for TierLimitReachErrorModal
to include a data-componentid prop (e.g.,
data-componentid={tierLimitReachedModal?.componentId ??
"tier-limit-reach-error-modal"}) so it implements
IdentifiableComponentInterface; ensure the attribute is passed alongside
actionLabel, handleModalClose, header, description, message and openModal props.
- Around line 223-225: The handler handleTierLimitReachedModalClose should have
an explicit function type and be stabilized with React.useCallback: import
useCallback, change the declaration to a const with a full signature (e.g. const
handleTierLimitReachedModalClose: () => void) and assign it using useCallback(()
=> { dispatch(hideTierLimitReachedModal()); }, [dispatch]); ensuring
hideTierLimitReachedModal and dispatch are in the dependency array as
appropriate.

In
`@features/admin.connections.v1/components/wizards/expert-mode/expert-mode-authentication-provider-create-wizard.tsx`:
- Around line 171-173: In ExpertModeAuthenticationProviderCreateWizard, guard
access to error.response before reading status: change the condition that
currently uses error.response.status to use optional chaining or an explicit
existence check (e.g., error?.response?.status or error?.response &&
error.response.status) so the clause becomes something like checking
error?.response?.status === 403 && error?.response?.data?.code ===
identityAppsError.getErrorCode(); update any similar checks in the same
conditional to consistently use optional chaining on error.response and
error.response.data to avoid TypeError on network failures.

In
`@features/admin.connections.v1/components/wizards/organization-enterprise/organization-enterprise-connection-create-wizard.tsx`:
- Around line 168-170: The check that reads if (error.response.status === 403 &&
error?.response?.data?.code === identityAppsError.getErrorCode()) can throw when
error.response is undefined; update the condition to use optional chaining for
status (and for data.code for safety) so it becomes if (error?.response?.status
=== 403 && error?.response?.data?.code === identityAppsError.getErrorCode()) in
the organization-enterprise-connection-create-wizard (the if that references
error.response.status and identityAppsError.getErrorCode()) to ensure
network/timeouts won't cause an exception and the tier-limit handling still
runs.

In `@features/admin.onboarding.v1/components/onboarding-wizard.tsx`:
- Around line 466-473: The modal is using hardcoded English strings in the
dispatch(showTierLimitReachedModal(...)) call; replace these literals with
translations resolved via react-i18next: import and call useTranslation() in the
component, then replace actionLabel, description, header and message with
t('yourNamespace:path.to.actionLabel'), t('yourNamespace:path.to.description'),
etc. Ensure keys follow the "<namespace>:<path.to.key>" format and pass the
translated values into showTierLimitReachedModal so the modal uses t(...)
results instead of raw strings.

---

Nitpick comments:
In `@features/admin.core.v1/store/reducers/tier-limit-modal.ts`:
- Around line 47-50: In the reducer handling actions for the tier limit modal,
the switch default currently returns a new object via "return { ...state }"
which creates a new reference and triggers unnecessary re-renders; change the
default branch to return the existing state reference ("return state") so the
reducer preserves identity for unrelated actions (update the switch default in
the tier-limit-modal reducer accordingly).
🪄 Autofix (Beta)

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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: a7a02650-749e-454a-8cdc-1a72e16363cc

📥 Commits

Reviewing files that changed from the base of the PR and between 8760670 and 14b7a15.

📒 Files selected for processing (19)
  • apps/console/src/app.tsx
  • features/admin.api-resources.v2/components/wizard/add-api-resource.tsx
  • features/admin.application-templates.v1/components/application-create-wizard.tsx
  • features/admin.applications.v1/components/try-it/try-it-create-wizard.tsx
  • features/admin.applications.v1/components/wizard/minimal-application-create-wizard.tsx
  • features/admin.connections.v1/components/create/add-connection-wizard.tsx
  • features/admin.connections.v1/components/wizards/expert-mode/expert-mode-authentication-provider-create-wizard.tsx
  • features/admin.connections.v1/components/wizards/organization-enterprise/organization-enterprise-connection-create-wizard.tsx
  • features/admin.connections.v1/components/wizards/trusted-token-issuer-create-wizard.tsx
  • features/admin.core.v1/models/reducer-state.ts
  • features/admin.core.v1/store/actions/tier-limit-modal.ts
  • features/admin.core.v1/store/actions/types/tier-limit-modal.ts
  • features/admin.core.v1/store/combine-reducers.ts
  • features/admin.core.v1/store/reducers/tier-limit-modal.ts
  • features/admin.groups.v1/components/wizard/create-group-wizard.tsx
  • features/admin.onboarding.v1/components/onboarding-wizard.tsx
  • features/admin.organizations.v1/components/add-organization-modal.tsx
  • features/admin.roles.v2/components/wizard-updated/application-role-wizard.tsx
  • features/admin.roles.v2/pages/create-role-wizard.tsx

Comment thread apps/console/src/app.tsx Outdated
Comment thread apps/console/src/app.tsx
Comment thread apps/console/src/app.tsx
Comment thread features/admin.onboarding.v1/components/onboarding-wizard.tsx
@codecov
Copy link
Copy Markdown

codecov Bot commented May 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 55.70%. Comparing base (77e6e92) to head (ad91745).
⚠️ Report is 53 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #10268   +/-   ##
=======================================
  Coverage   55.70%   55.70%           
=======================================
  Files          42       42           
  Lines        1016     1016           
  Branches      246      231   -15     
=======================================
  Hits          566      566           
- Misses        416      450   +34     
+ Partials       34        0   -34     
Flag Coverage Δ
@wso2is/core 55.70% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 10 files with indirect coverage changes

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

@pavinduLakshan
Copy link
Copy Markdown
Member

Hi @sheronjay, apologies for the delay in reviewing. I’ve been a bit busy over the past few weeks for WSO2Con. I’ll review over the weekend and let you know if there are any improvements needed.

@sheronjay
Copy link
Copy Markdown
Contributor Author

@pavinduLakshan no worries, take your time. I’m in the middle of exams too. If you’d like me to squash or clean up any extra commits just let me know. ;)

Comment thread apps/console/src/app.tsx Outdated
Comment thread apps/console/src/app.tsx Outdated
Comment thread features/admin.application-templates.v1/components/application-create-wizard.tsx Outdated
Comment thread features/admin.core.v1/models/reducer-state.ts
@sheronjay
Copy link
Copy Markdown
Contributor Author

@pavinduLakshan I've addressed the review comments. there are a couple of places where the i18n strings exceed 120 characters so I left them as it is. also actionLabel and header don't seem to be rendered anywhere in the modal. Are they used elsewhere, or can we get rid of them?

Copy link
Copy Markdown
Member

@pavinduLakshan pavinduLakshan left a comment

Choose a reason for hiding this comment

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

Let's add the changset by running pnpm changeset from the project root

@pavinduLakshan
Copy link
Copy Markdown
Member

I've addressed the review comments. there are a couple of places where the i18n strings exceed 120 characters so I left them as it is.

Thanks, I will take a look.

also actionLabel and header don't seem to be rendered anywhere in the modal. Are they used elsewhere, or can we get rid of them?

will check and get back.

@coderabbitai coderabbitai Bot requested a review from pavinduLakshan May 25, 2026 16:54
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