Skip to content

[Customer Portal][FE][Web] Refactor Updates Module: Transition to Recommended Update Levels API and Cleanup Legacy Stats - #164

Merged
Rashmika998 merged 23 commits into
wso2-open-operations:customer-portal-milestone-1from
dileepapeiris:feat/add-upadate-stat-cards-row
Feb 16, 2026
Merged

Rashmika998 merged 23 commits into
wso2-open-operations:customer-portal-milestone-1from
dileepapeiris:feat/add-upadate-stat-cards-row

Conversation

@dileepapeiris

@dileepapeiris dileepapeiris commented Feb 16, 2026 •

Copy link
Copy Markdown
Contributor

Description

This pull request refactors the updates statistics functionality in the customer portal webapp by replacing the previous "updates stats" logic with a new "recommended update levels" approach. The changes include renaming files, updating hooks and tests, and removing obsolete components related to the old stats system.

image image

API and Hook Refactor:

  • Replaced the useGetUpdatesStats hook with useGetRecommendedUpdateLevels, updating its implementation to fetch recommended update levels instead of general update stats. The query key, mock data, API endpoint, and response types were all updated accordingly (apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts, apps/customer-portal/webapp/src/api/__tests__/useGetRecommendedUpdateLevels.test.tsx). [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

  • Updated mock function references and test expectations to match the new recommended update levels data structure and logging messages. [1] [2] [3] [4] [5]

Removal of Deprecated Functionality:

  • Removed the obsolete useGetProductUpdatesStats hook and its implementation, as well as the associated UpdatesStatsGrid component and its tests, since these are no longer relevant under the new recommended update levels approach (apps/customer-portal/webapp/src/api/useGetProductUpdatesStats.ts, apps/customer-portal/webapp/src/components/updates/UpdatesStatsGrid.tsx, apps/customer-portal/webapp/src/components/updates/__tests__/UpdatesStatsGrid.test.tsx). [1] [2] [3]

UI Improvements:

  • Added a data-testid="error-indicator" attribute to the ErrorIndicator component's icon button for improved testability (apps/customer-portal/webapp/src/components/common/error-indicator/ErrorIndicator.tsx).

Test Refactor:

  • Updated and renamed test files to reflect the new recommended update levels logic, ensuring all test cases match the new API responses and query keys (apps/customer-portal/webapp/src/api/__tests__/useGetRecommendedUpdateLevels.test.tsx). [1] [2] [3] [4] [5] [6] [7]

These changes streamline the codebase, focus on the new recommended update levels functionality, and remove legacy update stats logic to reduce confusion and maintenance overhead.

Summary by CodeRabbit

Release Notes

  • New Features
    • Redesigned updates display with improved card-based layout for recommended update level information.
    • Enhanced error handling and loading state indicators for update data visibility.

Introduce a new Vitest test suite for the useGetRecommendedUpdateLevels hook. The tests mock logger, Asgardeo auth, mock config provider and API delay, and exercise cases for initial loading, mock-data flow, query options (staleTime), real API success and error (by stubbing fetch and window.config), and the empty projectId no-fetch behavior. Ensures proper logging calls and token retrieval are asserted.
Delete apps/customer-portal/webapp/src/api/__tests__/useGetUpdatesStats.test.tsx. The removed file contained unit tests for the useGetUpdatesStats hook, including mocks for Asgardeo, fetch, and mock config, and covered mock vs API responses, error handling, query options, and empty projectId behavior. This change cleans up or relocates the obsolete/removed tests.
Delete apps/customer-portal/webapp/src/api/useGetProductUpdatesStats.ts which implemented a React Query hook for fetching product updates statistics (handled mock mode and authenticated API calls). Remove this unused/obsolete hook and ensure any references or imports are updated accordingly.
Introduce a new React Query hook to fetch recommended update levels for a project. The hook (apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts) supports mock mode with configurable delay, uses the authenticated API client from AuthApiContext, and logs progress via useLogger. It validates CUSTOMER_PORTAL_BACKEND_BASE_URL, handles HTTP errors, and enables the query only when a projectId is present and authentication (or mock) conditions are met. Query results are cached with a 5-minute staleTime.
Delete the custom hook at apps/customer-portal/webapp/src/api/useGetUpdatesStats.ts. The hook previously fetched updates statistics using react-query, handled auth (useAsgardeo/useAuthApiClient), mock responses, and logging. Remove any imports/usages of this hook elsewhere in the codebase.
Add a data-testid attribute (error-indicator) to the IconButton in the ErrorIndicator component to make it easier to target the element in unit and integration tests.
Delete the unit test file for the UpdatesStatsGrid component (apps/customer-portal/webapp/src/components/updates/__tests__/UpdatesStatsGrid.test.tsx). This removes tests that covered headings, stat labels/values, null placeholders, and loading state skeletons. Replace or update tests if this deletion was not intended.
Introduce unit tests for the StatCard component (apps/.../StatCard.test.tsx). Tests cover rendering of label and value, loading state (skeleton hides value), error state (renders error-indicator), and rendering of extraContent. Uses Vitest and React Testing Library and includes license header.
Introduce a new StatCard component at apps/customer-portal/webapp/src/components/updates/stat-card-row/StatCard.tsx. The component renders a statistic card with an icon, colored background, value (with loading Skeleton and ErrorIndicator states), label, tooltip, and optional extra content. It uses the app theme and StatCardColor for styling and exports the typed StatCardProps interface.
Replace useGetProductUpdatesStats with useGetRecommendedUpdateLevels and update the UpdatesStatsGrid import path. Update the error banner and logger messages to reference "recommended update levels" instead of "updates statistics" to align the page with the new hook/API.
Add a new RecommendedUpdateLevelItem interface to models/responses.ts to represent a single product's recommended update level and related metadata (productName, productBaseVersion, channel, starting/ending/recommended levels, installed/available update counts, and timestamp). This provides a typed shape for frontend usage of recommended update data.
Import RecommendedUpdateLevelItem and add mockRecommendedUpdateLevels to support the /updates/recommended-update-levels endpoint. Adjust mockUpdatesStats counts/breakdowns (totalInstalled and pending/security numbers) and make minor formatting changes to project/product/deployment objects and a vulnerability resolution string for consistency.
Update ApiQueryKeys in apps/customer-portal/webapp/src/constants/apiConstants.ts: replace the UPDATES_STATS key value "updates-stats" with "recommended-update-levels" to reflect the new naming/semantics. Verify and update any usages that reference the old key.
Delete the UpdatesStatsGrid.tsx component which rendered the "Overall Update Status" grid of StatCard items (used UPDATES_STATS, StatCard, Grid, Typography). Removes apps/customer-portal/webapp/src/components/updates/UpdatesStatsGrid.tsx. Likely part of a refactor or component consolidation; no other context available in this changeset.
Introduce UpdatesStatsGrid.tsx: a new component that aggregates RecommendedUpdateLevelItem data and renders a grid of StatCard entries for Overall Update Status. Computes totals and breakdowns (installed/pending, regular/security), handles loading and error states with skeletons, and shows an action badge when security updates are pending. Exports UpdatesStatsGrid and its props interface; relies on UPDATES_STATS, StatCard, and oxygen-ui primitives.
Add a new test suite for UpdatesStatsGrid (apps/customer-portal/.../UpdatesStatsGrid.test.tsx). The tests mock the StatCard to avoid deep rendering and verify aggregated values from mockRecommendedUpdateLevels, plus loading (skeleton) and error placeholder behaviors. Uses Vitest and React Testing Library.
Introduce getMockRecommendedUpdateLevels() which returns mockRecommendedUpdateLevels (RecommendedUpdateLevelItem[]). Update imports to include mockRecommendedUpdateLevels and RecommendedUpdateLevelItem, add JSDoc for the new helper, and reformat getMockProductUpdateLevels for consistency.
@dileepapeiris dileepapeiris self-assigned this Feb 16, 2026
@coderabbitai

coderabbitai Bot commented Feb 16, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@dileepapeiris has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Refactors the updates statistics data flow by renaming the hook from useGetProductUpdatesStats to useGetRecommendedUpdateLevels, changing the API response type from UpdatesStats to RecommendedUpdateLevelItem[], and restructuring the UI component grid. Introduces utility functions for data aggregation and stat value retrieval.

Changes

Cohort / File(s) Summary
Hook Refactoring
apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts
Renamed hook from useGetProductUpdatesStats to useGetRecommendedUpdateLevels, changed return type from UpdatesStats to RecommendedUpdateLevelItem[], updated API endpoint from /updates/stats to /updates/recommended-update-levels, and updated mock data sources and logging messages.
Hook Tests
apps/customer-portal/webapp/src/api/__tests__/useGetRecommendedUpdateLevels.test.tsx
Added comprehensive test suite covering initial loading state, mocked and real data retrieval paths, API error handling, query options, and log message validation with React Query wrapper.
Type Definitions & Models
apps/customer-portal/webapp/src/models/responses.ts, apps/customer-portal/webapp/src/models/mockData.ts, apps/customer-portal/webapp/src/models/mockFunctions.ts
Added new RecommendedUpdateLevelItem interface, created mockRecommendedUpdateLevels data with 20+ product entries, added getMockRecommendedUpdateLevels() function, and updated mockUpdatesStats aggregated values.
API Constants
apps/customer-portal/webapp/src/constants/apiConstants.ts
Renamed query key from UPDATES_STATS to RECOMMENDED_UPDATE_LEVELS with updated string value.
Component Restructuring
apps/customer-portal/webapp/src/components/updates/UpdatesStatsGrid.tsx, apps/customer-portal/webapp/src/components/updates/__tests__/UpdatesStatsGrid.test.tsx
Deleted original UpdatesStatsGrid component and its tests from /updates/ directory.
New StatCard Component
apps/customer-portal/webapp/src/components/updates/stat-card-row/StatCard.tsx, apps/customer-portal/webapp/src/components/updates/stat-card-row/__tests__/StatCard.test.tsx
Added new reusable StatCard component with icon, value, label, tooltip, and loading/error state support; includes test coverage for rendering, skeleton states, errors, and extra content.
Refactored Grid Component
apps/customer-portal/webapp/src/components/updates/stat-card-row/UpdatesStatsGrid.tsx, apps/customer-portal/webapp/src/components/updates/stat-card-row/__tests__/UpdatesStatsGrid.test.tsx
Relocated and refactored UpdatesStatsGrid to use aggregateUpdateStats() utility, render individual StatCard components, and display breakdowns for installed/pending updates with optional "Action Required" badge; includes test coverage for aggregation, loading, and error states.
Utility Functions
apps/customer-portal/webapp/src/utils/updates.ts, apps/customer-portal/webapp/src/utils/__tests__/updates.test.ts
Added three new utilities: aggregateUpdateStats() to compute totals from per-product data, getStatValue() to safely retrieve stat values, and getStatTooltipText() to generate tooltips with optional breakdowns; includes comprehensive test suite covering aggregation logic, null handling, and breakdown formatting.
Page Integration
apps/customer-portal/webapp/src/pages/UpdatesPage.tsx
Updated hook import and call from useGetProductUpdatesStats(projectId) to useGetRecommendedUpdateLevels(), updated UpdatesStatsGrid import path to new location, and updated error messages and logging references.
Minor Accessibility
apps/customer-portal/webapp/src/components/common/error-indicator/ErrorIndicator.tsx
Added data-testid="error-indicator" attribute to IconButton for testing purposes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • v15a1
  • cloby99
  • Rashmika998

🐰 A hop and a skip through components so fine,
Stats get aggregated, one data design!
StatCards now render with breakdowns in view,
Recommended levels replace what was due! ✨📊

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description provides context and implementation details, but omits several required template sections (Purpose, Goals, Documentation, Security checks, etc.) that are specified in the repository template. Complete the PR description using the template format, including Purpose, Goals, Approach, Release note, Documentation, and Security checks sections.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main refactoring: transitioning from updates stats to recommended update levels API and removing legacy code.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into customer-portal-milestone-1

✏️ 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

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.

@dileepapeiris dileepapeiris added Type/New Feature Represents a request or task for a new feature Type/Improvement Marks enhancements or improvements to existing features Type/Task General task that does not fit into other categories Type/UX Refers to user experience-related tasks or issues App/Customer Portal Area/Frontend Platform/Web labels Feb 16, 2026
@dileepapeiris dileepapeiris moved this from Todo to Done in Customer Portal Development Feb 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 Customer Portal Updates module to stop using legacy “updates stats” APIs and instead fetch “recommended update levels”, while updating the UI layer to aggregate and present equivalent summary stats from the new response shape.

Changes:

  • Replaced the legacy updates stats hook usage with useGetRecommendedUpdateLevels, including new query key, endpoint, response typing, and updated hook tests.
  • Reworked the Updates “Overall Update Status” UI to compute aggregate stats from recommended update level items (new StatCard + new UpdatesStatsGrid location), and removed the old grid implementation/tests.
  • Extended mocks/types to support the new API response shape and improved ErrorIndicator test targeting.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/customer-portal/webapp/src/pages/UpdatesPage.tsx Switches the Updates page to the new hook and grid location; updates error messaging/logging.
apps/customer-portal/webapp/src/models/responses.ts Adds RecommendedUpdateLevelItem response type for the new API.
apps/customer-portal/webapp/src/models/mockFunctions.ts Adds mock accessor for recommended update levels; legacy mock stats accessor remains.
apps/customer-portal/webapp/src/models/mockData.ts Adds mockRecommendedUpdateLevels; keeps legacy mockUpdatesStats fixture.
apps/customer-portal/webapp/src/constants/apiConstants.ts Replaces UPDATES_STATS query key with RECOMMENDED_UPDATE_LEVELS.
apps/customer-portal/webapp/src/components/updates/stat-card-row/tests/UpdatesStatsGrid.test.tsx New tests for the updated grid that aggregates from recommended update level items.
apps/customer-portal/webapp/src/components/updates/stat-card-row/tests/StatCard.test.tsx New unit tests for the new StatCard component (loading/error/extra content).
apps/customer-portal/webapp/src/components/updates/stat-card-row/UpdatesStatsGrid.tsx New grid that aggregates stats from recommended update levels and renders stat cards.
apps/customer-portal/webapp/src/components/updates/stat-card-row/StatCard.tsx New stat card component for the Updates page.
apps/customer-portal/webapp/src/components/updates/tests/UpdatesStatsGrid.test.tsx Removes legacy grid tests.
apps/customer-portal/webapp/src/components/updates/UpdatesStatsGrid.tsx Removes legacy grid implementation.
apps/customer-portal/webapp/src/components/common/error-indicator/ErrorIndicator.tsx Adds data-testid="error-indicator" to the icon button to support tests.
apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts Implements the new recommended update levels hook (mock + API fetch).
apps/customer-portal/webapp/src/api/useGetProductUpdatesStats.ts Removes the legacy product updates stats hook.
apps/customer-portal/webapp/src/api/tests/useGetRecommendedUpdateLevels.test.tsx Updates hook tests for the new hook name/response shape/query key.
Comments suppressed due to low confidence (3)

apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts:84

  • The hook throws an error message that still says "updates stats" when the request fails. This is inconsistent with the new hook purpose (recommended update levels) and causes the updated test expectation to fail; update the thrown error message to reference recommended update levels (and ideally match the hook name).
    apps/customer-portal/webapp/src/api/tests/useGetRecommendedUpdateLevels.test.tsx:61
  • There is still a legacy test file (src/api/__tests__/useGetProductUpdatesStats.test.tsx) importing @api/useGetProductUpdatesStats, but the hook implementation file is removed in this PR. That will break the test suite/module resolution; remove or update the legacy test to target the new useGetRecommendedUpdateLevels hook.
    apps/customer-portal/webapp/src/models/mockFunctions.ts:346
  • getMockUpdatesStats now appears to be unused (no hooks reference it after the refactor). Consider removing this function (and the corresponding mockUpdatesStats import) to complete the legacy stats cleanup and avoid carrying dead mock data.
/**
 * Returns mock updates statistics.
 *
 * @returns {UpdatesStats} Mock updates statistics.
 */
export const getMockUpdatesStats = (): UpdatesStats => mockUpdatesStats;


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

Comment thread apps/customer-portal/webapp/src/models/mockData.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/customer-portal/webapp/src/pages/UpdatesPage.tsx (1)

45-49: ⚠️ Potential issue | 🟡 Minor

Potential infinite loader when projectId is missing.

If projectId is undefined (e.g., route mismatch), the hook receives "" so enabled becomes false. React Query won't fire the query, leaving data as undefined and isError as false — making isUpdatesLoading permanently true and the loader never hides.

Consider guarding early or adjusting the derived loading state:

Option: short-circuit when projectId is absent
+ if (!projectId) {
+   return <Typography color="error">Project not found.</Typography>;
+ }
+
  const { data, isLoading, isError } = useGetRecommendedUpdateLevels(
-   projectId || "",
+   projectId,
  );
apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts (1)

80-83: ⚠️ Potential issue | 🔴 Critical

Stale error message: still references "updates stats" instead of "recommended update levels".

This is the root cause of the test assertion mismatch flagged in useGetRecommendedUpdateLevels.test.tsx (line 212). The error text was not updated during the rename.

Proposed fix
         if (!response.ok) {
           throw new Error(
-            `Error fetching updates stats: ${response.statusText}`,
+            `Error fetching recommended update levels: ${response.statusText}`,
           );
         }
🤖 Fix all issues with AI agents
In
`@apps/customer-portal/webapp/src/api/__tests__/useGetRecommendedUpdateLevels.test.tsx`:
- Around line 210-213: The test failure is caused by a mismatch between the
hook's thrown error text and the test expectation; update the error message
thrown in the hook useGetRecommendedUpdateLevels (the throw at the response
handling around the current `throw new Error(\`Error fetching updates stats:
${response.statusText}\`)` site) to match the test expectation by changing it to
`Error fetching recommended update levels: ${response.statusText}`, or
alternatively update the test assertion to expect the existing message `Error
fetching updates stats: Internal Server Error`; pick one approach and make the
message in either useGetRecommendedUpdateLevels or the test consistent.

In `@apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts`:
- Around line 32-34: The function useGetRecommendedUpdateLevels currently
accepts a projectId and uses it in the query key but does not include it in the
fetch request URL; either drop the projectId parameter from
useGetRecommendedUpdateLevels (and remove it from the query key) if the backend
endpoint is project-agnostic, or make the request project-scoped by adding
projectId to the request URL (same style as useGetProjectSupportStats) and keep
it in the query key; locate the logic inside useGetRecommendedUpdateLevels
(query key creation and the fetch call) and update the signature and query key
or the fetch URL accordingly so the parameter usage is consistent.

In
`@apps/customer-portal/webapp/src/components/updates/stat-card-row/StatCard.tsx`:
- Around line 32-41: The StatCardProps type declares value as required but the
component uses value ?? "N/A", so make value optional to allow the fallback;
change the prop signature in StatCardProps to value?: string | number, ensure
any usages inside the StatCard component (and callers) handle undefined
appropriately (the existing value ?? "N/A" expression is fine), and update any
tests or call sites that relied on value being required to pass a value or omit
it intentionally.
🧹 Nitpick comments (4)
apps/customer-portal/webapp/src/components/updates/stat-card-row/StatCard.tsx (1)

84-88: Redundant as StatCardColor casts.

iconColor is already typed as StatCardColor, so the casts on lines 85, 88, and 103 are unnecessary noise.

Proposed fix (example for lines 84-88)
-            bgcolor: alpha(
-              theme.palette[iconColor as StatCardColor].light,
-              0.1,
-            ),
-            color: theme.palette[iconColor as StatCardColor].light,
+            bgcolor: alpha(
+              theme.palette[iconColor].light,
+              0.1,
+            ),
+            color: theme.palette[iconColor].light,
apps/customer-portal/webapp/src/components/updates/stat-card-row/__tests__/UpdatesStatsGrid.test.tsx (1)

59-72: Loading and error tests are identical and don't distinguish the two states.

Both "shows skeletons when loading" and "renders placeholders when there is an error" assert getAllByText("--")).toHaveLength(4). Since the mocked StatCard renders {value} directly (ignoring isLoading/isError), these tests only verify that the grid passes "--" as the value when data is undefined — they don't confirm that isLoading or isError is propagated to StatCard.

Consider extending the mock to capture and assert on the isLoading/isError props:

Sketch
 vi.mock("@components/updates/stat-card-row/StatCard", () => ({
-  StatCard: ({ label, value }: { label: string; value: string | number }) => (
+  StatCard: ({ label, value, isLoading, isError }: { label: string; value: string | number; isLoading?: boolean; isError?: boolean }) => (
     <div data-testid={`stat-card-${label}`}>
       <span data-testid="card-label">{label}</span>
       <span data-testid="card-value">{value}</span>
+      {isLoading && <span data-testid="loading" />}
+      {isError && <span data-testid="error" />}
     </div>
   ),
 }));
apps/customer-portal/webapp/src/components/updates/stat-card-row/UpdatesStatsGrid.tsx (2)

208-208: Move isEffectiveLoading above its first usage.

isEffectiveLoading is declared on line 208 but referenced inside renderCountWithSkeleton (line 119) and renderExtraContent (lines 141, 157, 174). While this works at runtime because the closures are only invoked in the JSX return block (after line 208), declaring the variable after its referencing closures is confusing and fragile — a future refactor could easily invoke one of these helpers earlier and hit a TDZ error.

Proposed fix

Move the declaration to right after aggregatedData:

+  const isEffectiveLoading = isLoading || (!data && !isError);
+
   const getValue = (id: keyof UpdatesStats): string | number => {

And remove the duplicate at line 208:

-  const isEffectiveLoading = isLoading || (!data && !isError);
-
   return (

132-206: Duplicated rendering logic for "installed" and "pending" breakdown sections.

The blocks on lines 139–153 and 155–169 are nearly identical, differing only in the stat.id check and the data source (totalUpdatesInstalledBreakdown vs totalUpdatesPendingBreakdown). Consider extracting a shared helper to reduce duplication.

Comment thread apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts Outdated
Introduce updates utilities and unit tests: add utils/updates.ts with aggregateUpdateStats, getStatValue, getStatTooltipText and NULL_PLACEHOLDER to compute and format update summary statistics; add Vitest tests (utils/__tests__/updates.test.ts) covering aggregation, value retrieval and tooltip text. Also tweak UpdatesPage to call useGetRecommendedUpdateLevels() without passing projectId, and adjust a mock comment in mockData.ts. These changes centralize stats logic for the Updates UI and add coverage to ensure correct behavior.
Update useGetRecommendedUpdateLevels to no longer accept a projectId parameter and remove it from the query key. Adjust logging and error messages to be project-agnostic, simplify the enabled condition to rely on mock or auth state, and reformat the hook signature/generics. Add a test import for NULL_PLACEHOLDER and a new test verifying the placeholder renders when value is missing, and clean up an unused comment in an existing test.
Move aggregation and helper logic for update stats into shared utilities and simplify components. StatCard: make value optional and use NULL_PLACEHOLDER from @utils/updates. UpdatesStatsGrid: remove inline aggregation and tooltip/value helpers, use aggregateUpdateStats, getStatValue and getStatTooltipText from @utils/updates and update imports accordingly. This centralizes update-related logic and reduces duplicated code in the grid component.
Rewrite useGetRecommendedUpdateLevels unit tests to centralize and improve mocking. Switch imports to absolute paths, add mocks for logger, @asgardeo/react, MockConfigProvider, and AuthApiContext (mocking useAuthApiClient) instead of stubbing global fetch. Adjust QueryClient defaults (staleTime/gcTime), clear/reset mocks and query client in afterEach, and replace projectId-based hooks with parameterless calls. Update assertions to use Array.isArray, add explicit waitFor timeouts, simplify window.config handling, and rename/extend test timeouts; removed the empty-projectId test.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts`:
- Line 29: The JSDoc for useGetRecommendedUpdateLevels contains a stale `@param`
{string} projectId that no longer matches the function signature; update the
JSDoc for the exported hook useGetRecommendedUpdateLevels (or remove the `@param`
line) so the comments reflect its current zero-parameter signature and any
remaining params or return types are accurate.

In
`@apps/customer-portal/webapp/src/components/updates/stat-card-row/UpdatesStatsGrid.tsx`:
- Around line 50-65: The functions renderCountWithSkeleton and
renderExtraContent reference isEffectiveLoading before it's declared, creating a
use-before-declaration smell; move the isEffectiveLoading declaration so it
occurs prior to these function definitions (or alternatively refactor the
functions to accept isEffectiveLoading as an argument) so the variable is
defined when the closures are created; update references to the same symbol
(isEffectiveLoading) inside renderCountWithSkeleton and renderExtraContent to
use the relocated variable (or the new parameter) to eliminate the fragile
ordering.

In `@apps/customer-portal/webapp/src/utils/__tests__/updates.test.ts`:
- Around line 40-43: The Biome lint error comes from mixing optional chaining
with non-null assertions on the test variable `stats`; replace uses like
`stats?.totalUpdatesInstalledBreakdown!.regular` and
`stats?.totalUpdatesPendingBreakdown!.security` with direct property access
since `stats` is already defined in the test (e.g.,
`stats.totalUpdatesInstalledBreakdown.regular` and
`stats.totalUpdatesPendingBreakdown.security`), removing both the `?.` and `!`
operators for all assertions in this test file (`updates.test.ts`).

Comment thread apps/customer-portal/webapp/src/api/useGetRecommendedUpdateLevels.ts Outdated
Comment thread apps/customer-portal/webapp/src/utils/__tests__/updates.test.ts Outdated
Move the computed isEffectiveLoading flag earlier in UpdatesStatsGrid to avoid a duplicate declaration and make it available to render helpers. Update unit test to guard against undefined aggregate results (early return) before asserting fields to prevent runtime errors. Remove an outdated @PARAM line from the JSDoc in useGetRecommendedUpdateLevels for minor documentation cleanup.
@Rashmika998
Rashmika998 merged commit f196902 into wso2-open-operations:customer-portal-milestone-1 Feb 16, 2026
1 check passed
@dileepapeiris dileepapeiris moved this from Done to Staging Deployed in Customer Portal Development Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/Customer Portal Area/Frontend Platform/Web Type/Improvement Marks enhancements or improvements to existing features Type/New Feature Represents a request or task for a new feature Type/Task General task that does not fit into other categories Type/UX Refers to user experience-related tasks or issues

Projects

Status: Staging Deployed

Development

Successfully merging this pull request may close these issues.

3 participants