Skip to content

[Customer Portal][FE][Web] Implement Project Hub Empty State and Refactor Test Suite - #129

Merged
Rashmika998 merged 5 commits into
wso2-open-operations:customer-portal-milestone-1from
dileepapeiris:feat/add-empty-state
Feb 12, 2026
Merged

Rashmika998 merged 5 commits into
wso2-open-operations:customer-portal-milestone-1from
dileepapeiris:feat/add-empty-state

Conversation

@dileepapeiris

@dileepapeiris dileepapeiris commented Feb 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

This pull request introduces an improved empty state experience for the Project Hub page by adding a new EmptyIcon component, updating the UI to use this icon when there are no projects, and enhancing the test coverage to reflect these changes. Additionally, the test setup has been refactored for better reliability and maintainability.

Screenshot 2026-02-12 at 02 26 31 Screenshot 2026-02-12 at 02 26 41

User Interface Improvements:

  • Added a new EmptyIcon SVG React component to visually represent the empty state in the Project Hub (EmptyIcon.tsx).
  • Updated the Project Hub page to display the EmptyIcon and improved messaging when there are no projects, providing a more user-friendly empty state (ProjectHub.tsx). [1] [2] [3]

Testing and Test Infrastructure:

  • Refactored and enhanced the Project Hub tests to use in-file test data, mock the new EmptyIcon component, and ensure accurate rendering with the new empty state UI (ProjectHub.test.tsx). [1] [2] [3]
  • Improved mocking and test setup for dependencies such as project cards, loader context, and logger hooks to increase test reliability and isolation (ProjectHub.test.tsx). [1] [2] [3] [4]

Summary by CodeRabbit

  • New Features

    • Enhanced Project Hub empty-state with a new illustrative icon, updated header ("No Projects Yet") and clearer explanatory copy when no projects exist.
    • Improved empty-state layout centers the illustration and guidance for first-time or unassigned users.
  • Tests

    • Updated UI tests to cover the new empty-state visuals, messaging, and routing-aware render scenarios.

Add a dedicated empty-state UI to ProjectHub: import EmptyIcon and replace the plain "No projects available." message with a centered Box containing EmptyIcon. Update the header and subtitle to conditionally display more helpful copy when there are no projects, while keeping the original text for non-empty states. Improves UX for users with no projects.
Replace imported mockProjects with an inline testProjects array and update numerous test mocks and assertions. Adjust mocked component import paths (project-card and skeleton), add mocks for IconButton, Tooltip, TriangleAlert, and EmptyIcon, and introduce a mock useLoader. Wrap rendered ProjectHub in MemoryRouter in tests. Update useGetProjects and useLogger mock module paths and adapt expectations (skeleton counts, project card counts, specific text checks, and tooltip/empty-state assertions). Also add logger assertions and clear mocks in beforeEach.
Introduce EmptyIcon React component (TypeScript) under customer-portal webapp common empty-state. The component renders a detailed SVG illustration (multiple paths and gradients), accepts SVGProps<SVGSVGElement> and spreads props onto the <svg>, and is exported as the default. File includes WSO2 Apache-2.0 license header and provides a reusable empty-state icon for the app.
@dileepapeiris dileepapeiris self-assigned this Feb 11, 2026
@dileepapeiris dileepapeiris added the Type/Improvement Marks enhancements or improvements to existing features label Feb 11, 2026
@coderabbitai

coderabbitai Bot commented Feb 11, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a new typed React SVG component EmptyIcon and integrates it into ProjectHub to render a custom empty-state when no projects exist; tests are updated to cover the new UI, routing context, and loader mocks.

Changes

Cohort / File(s) Summary
New EmptyIcon Component
apps/customer-portal/webapp/src/components/common/empty-state/EmptyIcon.tsx
Adds a default-exported typed React component rendering a static SVG illustration (multiple paths, gradients, fills) for empty-state use.
ProjectHub Integration
apps/customer-portal/webapp/src/pages/ProjectHub.tsx
Imports and uses EmptyIcon; makes header/subtitle conditional on projects.length, replacing plain "No projects available." with a centered empty-state UI and updated copy.
Tests: ProjectHub
apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx
Updates tests to use MemoryRouter, adds testProjects dataset, expands mocks (EmptyIcon, Oxygen UI pieces, LoaderContext, icon mocks), and adjusts assertions to validate new empty-state rendering and loader interactions.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • v15a1
  • Rashmika998
  • cloby99

Poem

🐰 A little rabbit draws an icon bright,
For projects missing on the screen tonight.
Paths and gradients hop in line,
Empty states now look quite fine,
Hooray — the portal shines delight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete, missing several required sections from the template including Purpose, Goals, Approach, User stories, Release notes, Documentation, Training, Certification, Marketing, Automation tests details, Security checks, Samples, Related PRs, Migrations, Test environment, and Learning. Add missing sections from the template: Purpose/Goals/Approach with issue links, User stories, Release notes, Documentation/Training/Certification/Marketing links, detailed Automation tests info, Security checks confirmation, Test environment details, and Learning section.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title accurately describes the main changes: implementing an empty state UI for the Project Hub and refactoring the test suite to support these changes.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 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/UX Refers to user experience-related tasks or issues App/Customer Portal Area/Frontend Platform/Web labels Feb 11, 2026
@dileepapeiris dileepapeiris changed the title Feat/add empty state [Customer Portal][FE][Web] Implement Project Hub Empty State and Refactor Test Suite Feb 11, 2026

@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: 1

🤖 Fix all issues with AI agents
In `@apps/customer-portal/webapp/src/pages/ProjectHub.tsx`:
- Around line 222-234: The header/subtitle currently check only projects.length
and thus show "No Projects Yet" during loading/error; update the render logic in
the ProjectHub component to base the empty-state condition on a
loaded-and-successful fetch (e.g., data exists and !isLoading and !isError)
instead of just projects.length === 0; modify the two Typography blocks that
reference projects.length (and any local variable derived from data like
projects) to use a predicate such as ( !isLoading && !isError && projects.length
=== 0 ) for the empty text and the inverse for the non-empty text, and ensure
loading skeletons and error UI remain shown when isLoading or isError are true.
🧹 Nitpick comments (4)
apps/customer-portal/webapp/src/components/common/empty-state/EmptyIcon.tsx (2)

25-32: Consider adding accessibility attributes to the SVG.

The SVG lacks role="img" and an aria-label (or aria-hidden="true" if purely decorative). Since this is an illustrative empty-state icon, marking it as decorative would be appropriate.

Suggested improvement
 const EmptyIcon = (props: SVGProps<SVGSVGElement>): JSX.Element => (
   <svg
     width="268"
     height="229"
     viewBox="0 0 268 229"
     fill="none"
     xmlns="http://www.w3.org/2000/svg"
+    aria-hidden="true"
     {...props}
   >

133-211: Hardcoded gradient IDs could collide if multiple instances are rendered.

The gradient IDs (e.g., paint0_linear_1857_52) are global to the DOM. If two EmptyIcon components are ever rendered on the same page, the second instance's <path> elements would reference the first instance's gradients, potentially causing visual issues. This is low risk for an empty-state illustration but worth noting for reusability.

A common pattern is to generate a unique prefix (e.g., via useId()) and prepend it to gradient IDs.

apps/customer-portal/webapp/src/pages/ProjectHub.tsx (1)

124-124: The !projects guard is redundant.

projects is derived from useMemo with a fallback of [] (line 47), so it can never be falsy. projects.length === 0 alone suffices.

-    if (!projects || projects.length === 0) {
+    if (projects.length === 0) {
apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx (1)

189-208: Error-state assertion relies on unmocked ErrorIndicator internals.

The test asserts screen.getByTestId("tooltip") to verify the error state, but ErrorIndicator isn't explicitly mocked. This means the assertion depends on ErrorIndicator's internal use of the mocked Tooltip component. If ErrorIndicator is refactored, this test breaks without the error state actually changing.

Consider adding an explicit mock for ErrorIndicator:

vi.mock("@components/common/error-indicator/ErrorIndicator", () => ({
  default: ({ entityName }: any) => (
    <div data-testid="error-indicator">{entityName}</div>
  ),
}));

Then assert on screen.getByTestId("error-indicator") instead.

Comment thread apps/customer-portal/webapp/src/pages/ProjectHub.tsx

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

This PR improves the Project Hub empty state by introducing a dedicated EmptyIcon component, updating the Project Hub UI messaging when no projects are available, and adjusting the Project Hub tests/mocks to reflect the new UI and dependencies.

Changes:

  • Added a new EmptyIcon SVG React component for empty-state visuals.
  • Updated ProjectHub to render the new empty-state icon and conditional header/subtitle messaging.
  • Refactored ProjectHub tests to use in-file project fixtures, add router wrapping, and expand mocks for ErrorIndicator dependencies.

Reviewed changes

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

File Description
apps/customer-portal/webapp/src/pages/ProjectHub.tsx Adds EmptyIcon and conditional empty-state messaging in the Project Hub UI.
apps/customer-portal/webapp/src/components/common/empty-state/EmptyIcon.tsx Introduces the SVG-based empty-state icon component.
apps/customer-portal/webapp/src/pages/tests/ProjectHub.test.tsx Updates tests/mocks to validate the new empty state and updated error indicator behavior.
Comments suppressed due to low confidence (1)

apps/customer-portal/webapp/src/pages/tests/ProjectHub.test.tsx:206

  • This assertion only checks that some Tooltip rendered. Since the Tooltip mock preserves the title prop, it would be more robust to assert the actual error tooltip content (e.g., that the tooltip title equals "Failed to fetch projects data") so the test fails if ErrorIndicator stops rendering or is wired to the wrong entityName.
    expect(screen.getByTestId("tooltip")).toBeInTheDocument();
    await waitFor(() => {
      expect(mockLogger.error).toHaveBeenCalledWith(
        expect.stringContaining("Failed to load projects"),
      );

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

Comment thread apps/customer-portal/webapp/src/pages/__tests__/ProjectHub.test.tsx
Comment thread apps/customer-portal/webapp/src/pages/ProjectHub.tsx
Comment thread apps/customer-portal/webapp/src/pages/ProjectHub.tsx Outdated
Simplify the empty-list guard in ProjectHub.tsx by removing the unnecessary `!projects` falsy check and only checking `projects.length === 0`. This reflects that `projects` is guaranteed to be defined (non-nullable) in this component and keeps the condition concise.
Add accessibility attributes to the decorative EmptyIcon SVG (aria-hidden and focusable=false) and change ProjectHub header/subtitle logic so the "No Projects Yet" message only appears when not loading, not auth-loading, and no error. This prevents the empty-state text from showing while data or auth state is still loading. Updated tests to assert the empty message is not present during loading and to expect the "Select Your Project" heading instead.
@Rashmika998
Rashmika998 merged commit 7d6b6f1 into wso2-open-operations:customer-portal-milestone-1 Feb 12, 2026
1 check passed
@dileepapeiris dileepapeiris moved this from Done to Staging Deployed in Customer Portal Development Feb 12, 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/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