Skip to content

[Customer Portal][FE][Web] Improve Empty State UX with Refinement-Aware Messaging , Icons and refine search logic - #436

Merged
Rashmika998 merged 27 commits into
wso2-open-operations:dev-app-customer-portal-v1.0.xfrom
dileepapeiris:add-project-type-based-hiding
Mar 30, 2026
Merged

Rashmika998 merged 27 commits into
wso2-open-operations:dev-app-customer-portal-v1.0.xfrom
dileepapeiris:add-project-type-based-hiding

Conversation

@dileepapeiris

@dileepapeiris dileepapeiris commented Mar 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

Closes(https://github.com/wso2-enterprise/digiops-cs/issues/1486)

This pull request improves the empty state UX for case and conversation lists by introducing more descriptive and visually distinct empty states depending on whether filters or search terms are active. It also updates the logic for detecting active filters/search across several components, and enhances test coverage to reflect these changes.

Empty State UX Improvements:

  • Added EmptyIcon and SearchNoResultsIcon components to visually differentiate between "no data" and "no results due to filters/search" states in CasesList, AllCasesList, AllConversationsList, and AnnouncementList. The displayed message and icon now depend on whether the list is empty due to refinement (filters/search) or truly empty. [1] [2] [3] [4] [5] [6] [7]

  • Introduced a new hasListRefinement prop to the above components and their usages, which determines which empty state to show. This prop is set based on the presence of active filters or search terms. [1] [2] [3] [4] [5] [6]

Filter/Search Detection Logic:

  • Updated logic in search bar and table components to consider both filters and non-empty search terms as active refinements, ensuring the correct empty state is shown and filter-clearing logic resets search input as well. [1] [2] [3] [4] [5] [6]

Testing Enhancements:

  • Updated and extended tests for CasesList and AllCasesList to verify the correct empty state is rendered depending on hasListRefinement. Also improved test mock setups for utility functions and component props. [1] [2] [3] [4]

Other UI/UX Improvements:

  • Added a loading skeleton to AllCasesSearchBar when project context is loading, improving perceived performance and feedback. [1] [2] [3]

Code Consistency and Cleanup:

  • Minor formatting and consistency changes in test mocks and props, improving code readability and maintainability. [1] [2] [3]

Let me know if you want to see how the new empty states look or need help understanding how to use the new hasListRefinement prop!

Summary by CodeRabbit

Release Notes

  • New Features
    • Enhanced empty state messaging that distinguishes between "no data" and "no matching results" when filters or search queries are applied
    • Search inputs now treated as active filters with consistent behavior throughout the application
    • Improved filter clearing functionality that resets both filters and search terms simultaneously

Adjust unit tests for CasesList by refining mocked Oxygen UI components and updating assertions. TableRow mock now forwards onClick (and ignores unused props) so click behavior can be tested reliably; mocked imports were reformatted for consistency. Update the empty-state assertion to match the new message text and reformat objectContaining expectations for readability. These changes make tests more realistic and less flaky.
Improve empty-state UX in CasesList: add EmptyIcon and SearchNoResultsIcon imports, introduce hasListRefinement prop (default false), and render a centered empty-state layout with appropriate icon and message depending on whether the list was refined (search/filters) or truly empty. Includes styling for icon sizing and spacing.
Pass hasListRefinement to the ListingTable based on getActiveFiltersCount() > 0 so the table can know when list filters are active and adjust its UI/behavior accordingly.
Reset the search input when clearing all filters and treat a non-empty trimmed search as an active filter. handleClearFilters now calls setSearchInput("") and activeFilterCount's memo adds 1 when searchInput.trim() is non-empty, with searchInput added to the dependency array so the count updates correctly.
Introduce hasListSearchOrFilters to determine whether a list has an active search term or any non-empty filter value. The function trims the search term and checks filter values for undefined, null, or empty (after stringifying), returning true if any are present. Includes JSDoc for usage and intent (used to choose refined vs default empty-state copy).
Add a hasListRefinement prop to ServiceRequestsList to indicate when the list is being refined. The prop is true if the trimmed searchTerm is non-empty or if statusFilter is not "all". This lets the list component react to active refinements (e.g. show reset/clear UI) and prevents relying on internal heuristics.
Reset the search term when clearing filters and compute a list refinement flag using hasListSearchOrFilters(searchTerm, filters). Pass the resulting hasListRefinement prop to AllCasesList so the list can react to active search/filters. Also import the helper from @utils/support.
Import hasListSearchOrFilters, clear the search term when clearing filters, compute listHasRefinement from searchTerm and filters, and pass it as hasListRefinement to ChangeRequestsList so the child can react when search or filters are active.
Import hasListSearchOrFilters and use it to determine whether the announcements list has active search or filters. Reset searchTerm when clearing filters, compute listHasRefinement, and pass it as hasListRefinement to AnnouncementList so the list can adjust its UI/behavior when refinements are present.
Import hasListSearchOrFilters and compute listHasRefinement from searchTerm and filters, then pass it as hasListRefinement to AllConversationsList. Also reset the searchTerm when clearing filters so the list fully clears refinements and pagination is reset to page 1.
Adjust AllCasesPage to better handle project loading state and list refinements. Add hasListSearchOrFilters import and compute listHasRefinement from searchTerm and filters. Include projectDetailsReady/isProjectLoading in stats loading checks and guard deployments prop until project details are ready. Clear searchTerm when clearing filters and pass isProjectContextLoading to the Filters component. Finally, forward hasListRefinement to the cases list so the UI can reflect active search/filters.
Replace the plain text fallback with a centered empty state component for when there are no change requests. Adds an EmptyIcon import and renders a Box with the icon and a simplified "No change requests." message (with layout/styling) to improve UX.
Introduce hasListRefinement prop to ServiceRequestsList to show a different empty state when filters/search are applied. Import and render SearchNoResultsIcon for the refined-empty case and keep EmptyIcon for the initial-empty case, update copy accordingly, and center icons/text with consistent styling. Default hasListRefinement to false to preserve existing behavior.
Treat the current searchTerm as an active filter in ChangeRequestsSearchBar. Previously hasActiveFilters only checked the filters object, so a non-empty search input wasn't considered active; this change adds searchTerm.trim().length > 0 to ensure the UI reflects when a search is active.
Treat the search input as an active filter by including searchTerm.trim().length > 0 in the hasActiveFilters check. This ensures whitespace-only input is ignored while preserving the existing filters check so the UI correctly reflects when a search is active.
Include a check for a non-empty trimmed searchTerm in hasActiveFilters so that entering a search is considered an active filter. This ensures the UI reflects active searches even when other filter values are empty and ignores whitespace-only input.
Introduce isProjectContextLoading prop (default false) to show loading placeholders while project context loads. Import Skeleton from the UI library and return a Paper containing Skeletons for the search bar and button when loading. Also update hasActiveFilters to consider searchTerm.trim() so an active search counts as a filter.
Treat the search term as an active filter by checking trimmed length in hasActiveFilters, and clear the search term when handleClearFilters is invoked. This ensures the UI correctly reflects search-based filtering and resets search state when filters are cleared.
Introduce a hasListRefinement prop (default false) and import EmptyIcon and SearchNoResultsIcon. Render a distinct "no results" UI when filters/search yield no items, and keep a separate "no change requests yet" empty state for initial/empty lists. Adjusts icon layout and message text accordingly.
Introduce distinct empty-state UIs for AnnouncementList: import EmptyIcon and SearchNoResultsIcon, add an optional hasListRefinement prop (default false), and render a "no results" illustration and message when filters/search are applied; otherwise render a generic "no announcements yet" illustration. Also adjust layout/styling for both empty states.
Introduce hasListRefinement prop (default false) to AllConversationsList and import EmptyIcon and SearchNoResultsIcon. When conversations are empty, show a centered SearchNoResultsIcon and a suggestion to adjust filters/search if hasListRefinement is true; otherwise show the generic EmptyIcon and updated copy ('No conversations yet.'). Minor layout adjustments to center icons and text.
Add hasListRefinement prop and conditional empty-state rendering for AllCasesList. Import EmptyIcon and SearchNoResultsIcon, default hasListRefinement to false, and render SearchNoResultsIcon + helpful message when filters/search yield no results; otherwise render EmptyIcon with "No cases yet." message. Minor layout tweaks to center the empty-state content.
Expand support utils mocks and update tests for AllCasesList. Adds mocks for formatDateTime, getStatusColor, mapSeverityToDisplay, and getAssignedEngineerLabel, and adjusts assertions for the empty-state copy. Also adds a new test covering the refined/search empty state message when the list is empty and hasListRefinement is true. No production code changes.
@dileepapeiris dileepapeiris self-assigned this Mar 30, 2026
@coderabbitai

coderabbitai Bot commented Mar 30, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR distinguishes "no data" from "no results" across list UIs by adding a boolean hasListRefinement and a hasListSearchOrFilters utility; empty states now render different icons/messages and search inputs are counted as active filters and cleared by Clear actions.

Changes

Cohort / File(s) Summary
Dashboard Cases Table
apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx, apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx
Added hasListRefinement prop to CasesList and pass it from CasesTable; replaced plain empty text with EmptyIcon/SearchNoResultsIcon variants and updated empty-state layout.
Dashboard Tests
apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesList.test.tsx
Adjusted Oxygen UI mocks to forward onClick; updated empty-state expectation text and refined object matchers.
Support: All Cases
apps/customer-portal/webapp/src/components/support/all-cases/AllCasesList.tsx, apps/customer-portal/webapp/src/components/support/all-cases/AllCasesSearchBar.tsx, apps/customer-portal/webapp/src/components/support/all-cases/__tests__/AllCasesList.test.tsx
Added hasListRefinement and isProjectContextLoading props; search term now counts as active filter; updated empty-state icons/messages/layouts; tests expanded and new refined-empty test added.
Support: Conversations
apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsList.tsx, .../AllConversationsSearchBar.tsx
Added hasListRefinement prop; conditional empty-state icons/messages and centered flex layout; search term considered an active filter.
Support: Announcements
apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx, .../AnnouncementsSearchBar.tsx
Added hasListRefinement prop; empty states now use icons and flex layout; search term treated as active filter and Clear resets it.
Support: Change Requests
apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsList.tsx, .../ChangeRequestsSearchBar.tsx
Added hasListRefinement prop; updated empty-state icons/messages/layout and counted search term as active filter.
Support: Service Requests & Overview
apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsList.tsx, apps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingChangeRequestsList.tsx
Added hasListRefinement to ServiceRequestsList; replaced zero-results text with EmptyIcon-based layouts and conditional SearchNoResultsIcon when refined.
Security Components
apps/customer-portal/webapp/src/components/security/ProductVulnerabilitiesTable.tsx, apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx
hasActiveFilters/activeFilterCount now include trimmed search input; handleClearFilters clears search terms in addition to filters and pagination.
Pages (propagation)
apps/customer-portal/webapp/src/pages/.../AllCasesPage.tsx, AllConversationsPage.tsx, AnnouncementsPage.tsx, ChangeRequestsPage.tsx, EngagementsPage.tsx, ServiceRequestsPage.tsx
Imported hasListSearchOrFilters, computed listHasRefinement from searchTerm+filters, passed it to list components; Clear actions now also clear search term; AllCasesPage gates deployments on project context readiness.
Utility
apps/customer-portal/webapp/src/utils/support.ts
Added export function hasListSearchOrFilters(searchTerm, filters) to detect non-empty search or filter values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Rashmika998
  • v15a1

Poem

🐇 I hopped through lists both near and far,
Found empty fields and wondered what they are.
Now icons guide when searches miss the mark,
Filters and queries light up the dark.
A little rabbit cheers with a joyful spark! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: improving empty state UX with refinement-aware messaging and icons, plus refining search logic across list components.
Description check ✅ Passed The PR description provides a comprehensive overview with Purpose section (issue reference), detailed breakdowns of changes by category, and examples with links. However, it deviates from the required template structure by using custom sections instead of the prescribed template.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ 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 and usage tips.

@dileepapeiris dileepapeiris added 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 labels Mar 30, 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: 4

Caution

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

⚠️ Outside diff range comments (1)
apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesList.test.tsx (1)

148-164: ⚠️ Potential issue | 🟠 Major

Empty-state test is asserting the refined branch without enabling refinement.

At Line 160-164, the test expects refined copy, but the rendered component at Line 150-157 does not pass hasListRefinement, so default behavior should be the non-refined empty state.

✅ Suggested test fix
   it("should render empty state when no cases", () => {
     render(
       <CasesList
         isLoading={false}
         data={{ cases: [], totalRecords: 0, offset: 0, limit: 10 } as any}
         page={0}
         rowsPerPage={10}
         onPageChange={mockOnPageChange}
         onRowsPerPageChange={mockOnRowsPerPageChange}
+        hasListRefinement={true}
       />,
     );

     expect(
       screen.getByText(
         "No outstanding cases.Try adjusting your filters or search query",
       ),
     ).toBeInTheDocument();
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesList.test.tsx`
around lines 148 - 164, The test asserts the refined empty-state copy but
doesn't enable refinement on the component; either pass the hasListRefinement
prop into the rendered CasesList (e.g., hasListRefinement={true}) or change the
expected string in the expect(...) to the non-refined copy; update the test in
CasesList.test.tsx to use the chosen approach so the assertion matches the
rendered CasesList component.
🧹 Nitpick comments (2)
apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsSearchBar.tsx (1)

67-69: Use the shared refinement helper here to avoid logic drift.

Line 67-Line 69 re-implements refinement detection while hasListSearchOrFilters already centralizes this behavior. Reusing it keeps search bars and list empty-state logic consistent.

♻️ Suggested refactor
+import { hasListSearchOrFilters } from "@utils/support";
...
-  const hasActiveFilters =
-    searchTerm.trim().length > 0 ||
-    Object.values(filters).some((value) => !!value);
+  const hasActiveFilters = hasListSearchOrFilters(
+    searchTerm,
+    filters as Record<string, string | number | undefined | null>,
+  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsSearchBar.tsx`
around lines 67 - 69, Replace the ad-hoc refinement detection in
ChangeRequestsSearchBar (the hasActiveFilters computation) with the shared
helper hasListSearchOrFilters to avoid logic drift: remove the current
searchTerm.trim()/Object.values(filters) logic and call
hasListSearchOrFilters(searchTerm, filters) (import the helper if not already)
so the component uses the centralized refinement detection used by list
empty-state logic.
apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx (1)

196-199: Include all active filter keys in hasActiveFilters.

Line 196-Line 199 currently checks only statusId and deploymentId. If other filter fields (e.g., severityId, issueTypes) are set, the UI can misreport refinement state.

♻️ Suggested refactor
-  const hasActiveFilters =
-    searchTerm.trim().length > 0 ||
-    !!filters.statusId ||
-    !!filters.deploymentId;
+  const hasActiveFilters = hasListSearchOrFilters(searchTerm, {
+    statusId: filters.statusId,
+    deploymentId: filters.deploymentId,
+    severityId: filters.severityId,
+    issueTypes: filters.issueTypes,
+  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx`
around lines 196 - 199, The current hasActiveFilters calculation (variable
hasActiveFilters) only checks searchTerm, filters.statusId, and
filters.deploymentId, so other filter fields like severityId or issueTypes are
ignored; update hasActiveFilters to treat any filter property as active by
checking all keys of the filters object (e.g., Object.keys/values) and returning
true if any value is non-empty (for strings/numbers), truthy, or non-empty
array, in addition to the existing searchTerm check; locate and update the
hasActiveFilters definition in SecurityReportAnalysis.tsx to use this generic
check so all filter fields (severityId, issueTypes, etc.) correctly mark the UI
as refined.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx`:
- Around line 127-128: Fix the missing space in the empty-state copy inside the
CasesList component: locate the JSX text "No outstanding cases.Try adjusting
your filters or search query" in CasesList.tsx and add a space after the period
so it reads "No outstanding cases. Try adjusting your filters or search query"
(update the string wherever rendered in the CasesList component).

In
`@apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsList.tsx`:
- Around line 104-105: Update the user-facing empty-state copy in the
AllConversationsList component: locate the Typography string currently reading
"No conversations found, Try adjusting your filters or search query." and
replace it with properly punctuated/capitalized copy such as "No conversations
found. Try adjusting your filters or search query." so the comma is a period and
"Try" is capitalized.

In
`@apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx`:
- Line 78: In AnnouncementList.tsx update the empty-state copy string (the JSX
text "No announcements found, Try adjusting your filters or search query.") to
use sentence punctuation — replace the comma with a period so it reads "No
announcements found. Try adjusting your filters or search query." in the
AnnouncementList component's render/return.

In `@apps/customer-portal/webapp/src/pages/AllCasesPage.tsx`:
- Around line 146-149: The current isStatsLoading expression mixes "still
loading" with "project details missing" (using !projectDetailsReady) which
causes permanent loading when projectDetailsReady resolves to undefined; update
the logic that computes isStatsLoading to remove the !projectDetailsReady clause
(keep isProjectLoading || isStatsQueryLoading || (!!projectId &&
!hasStatsResponse)) and instead introduce a separate explicit check (e.g.,
isProjectMissing or projectDetailsReady === false) to drive the
empty/missing-data UI path; update any render branches that relied on
!projectDetailsReady to use that new missing-data flag so skeletons only show
while actual loading flags (isProjectLoading, isStatsQueryLoading) are true.

---

Outside diff comments:
In
`@apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesList.test.tsx`:
- Around line 148-164: The test asserts the refined empty-state copy but doesn't
enable refinement on the component; either pass the hasListRefinement prop into
the rendered CasesList (e.g., hasListRefinement={true}) or change the expected
string in the expect(...) to the non-refined copy; update the test in
CasesList.test.tsx to use the chosen approach so the assertion matches the
rendered CasesList component.

---

Nitpick comments:
In
`@apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx`:
- Around line 196-199: The current hasActiveFilters calculation (variable
hasActiveFilters) only checks searchTerm, filters.statusId, and
filters.deploymentId, so other filter fields like severityId or issueTypes are
ignored; update hasActiveFilters to treat any filter property as active by
checking all keys of the filters object (e.g., Object.keys/values) and returning
true if any value is non-empty (for strings/numbers), truthy, or non-empty
array, in addition to the existing searchTerm check; locate and update the
hasActiveFilters definition in SecurityReportAnalysis.tsx to use this generic
check so all filter fields (severityId, issueTypes, etc.) correctly mark the UI
as refined.

In
`@apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsSearchBar.tsx`:
- Around line 67-69: Replace the ad-hoc refinement detection in
ChangeRequestsSearchBar (the hasActiveFilters computation) with the shared
helper hasListSearchOrFilters to avoid logic drift: remove the current
searchTerm.trim()/Object.values(filters) logic and call
hasListSearchOrFilters(searchTerm, filters) (import the helper if not already)
so the component uses the centralized refinement detection used by list
empty-state logic.
🪄 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.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ac85ebc-d7e1-4112-b4c2-21d671b41982

📥 Commits

Reviewing files that changed from the base of the PR and between 4d2d409 and 755735a.

📒 Files selected for processing (23)
  • apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx
  • apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesTable.tsx
  • apps/customer-portal/webapp/src/components/dashboard/cases-table/__tests__/CasesList.test.tsx
  • apps/customer-portal/webapp/src/components/security/ProductVulnerabilitiesTable.tsx
  • apps/customer-portal/webapp/src/components/security/SecurityReportAnalysis.tsx
  • apps/customer-portal/webapp/src/components/support/all-cases/AllCasesList.tsx
  • apps/customer-portal/webapp/src/components/support/all-cases/AllCasesSearchBar.tsx
  • apps/customer-portal/webapp/src/components/support/all-cases/__tests__/AllCasesList.test.tsx
  • apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsList.tsx
  • apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsSearchBar.tsx
  • apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx
  • apps/customer-portal/webapp/src/components/support/announcements/AnnouncementsSearchBar.tsx
  • apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsList.tsx
  • apps/customer-portal/webapp/src/components/support/change-requests/ChangeRequestsSearchBar.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsList.tsx
  • apps/customer-portal/webapp/src/components/support/support-overview-cards/OutstandingChangeRequestsList.tsx
  • apps/customer-portal/webapp/src/pages/AllCasesPage.tsx
  • apps/customer-portal/webapp/src/pages/AllConversationsPage.tsx
  • apps/customer-portal/webapp/src/pages/AnnouncementsPage.tsx
  • apps/customer-portal/webapp/src/pages/ChangeRequestsPage.tsx
  • apps/customer-portal/webapp/src/pages/EngagementsPage.tsx
  • apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
  • apps/customer-portal/webapp/src/utils/support.ts

Comment thread apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx Outdated
Comment thread apps/customer-portal/webapp/src/pages/AllCasesPage.tsx Outdated
@dileepapeiris dileepapeiris changed the title Add project type based hiding [Customer Portal][FE][Web] Improve Empty State UX with Refinement-Aware Messaging , Icons and refine search logic Mar 30, 2026
Introduce a local isProjectContextLoading variable and use it in loading checks. Replace the inline isProjectContextLoading prop (previously isProjectLoading || !projectDetailsReady) with the new variable, and remove !projectDetailsReady from isStatsLoading. This centralizes the project-context loading flag and simplifies the loading logic (note: child components will now receive only isProjectLoading via the prop).
Add a missing period in the AnnouncementList empty-state copy: "No announcements found. Try adjusting your filters or search query." This is a minor text change for grammar/readability in apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx with no behavior changes.
Replace a comma with a period in the empty-state copy to improve punctuation and readability in AllConversationsList.tsx: "No conversations found. Try adjusting your filters or search query."
Corrects spacing and punctuation in CasesList.tsx empty-state copy: changes "No outstanding cases.Try adjusting your filters or search query" to "No outstanding cases. Try adjusting your filters or search query." to improve readability and grammar.

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

🧹 Nitpick comments (1)
apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx (1)

58-103: Consider consolidating duplicated empty-state JSX into one render path.

Line 61-80 and Line 84-103 duplicate container and icon styles. A small helper/variant object will reduce drift when updating spacing, alignment, or typography later.

♻️ Suggested refactor
+  const emptyStateSx = {
+    display: "flex",
+    flexDirection: "column" as const,
+    alignItems: "center",
+    py: 6,
+  };
+
+  const emptyIconStyle = {
+    width: 200,
+    maxWidth: "100%",
+    height: "auto",
+    marginBottom: 16,
+  };
+
   if (cases.length === 0) {
-    if (hasListRefinement) {
-      return (
-        <Box
-          sx={{
-            display: "flex",
-            flexDirection: "column",
-            alignItems: "center",
-            py: 6,
-          }}
-        >
-          <SearchNoResultsIcon
-            style={{
-              width: 200,
-              maxWidth: "100%",
-              height: "auto",
-              marginBottom: 16,
-            }}
-          />
-          <Typography variant="body1" color="text.secondary">
-            No announcements found. Try adjusting your filters or search query.
-          </Typography>
-        </Box>
-      );
-    }
+    const message = hasListRefinement
+      ? "No announcements found. Try adjusting your filters or search query."
+      : "No announcements yet.";
+
+    const icon = hasListRefinement ? (
+      <SearchNoResultsIcon style={emptyIconStyle} />
+    ) : (
+      <EmptyIcon style={emptyIconStyle} />
+    );
+
     return (
-      <Box
-        sx={{
-          display: "flex",
-          flexDirection: "column",
-          alignItems: "center",
-          py: 6,
-        }}
-      >
-        <EmptyIcon
-          style={{
-            width: 200,
-            maxWidth: "100%",
-            height: "auto",
-            marginBottom: 16,
-          }}
-        />
+      <Box sx={emptyStateSx}>
+        {icon}
         <Typography variant="body1" color="text.secondary">
-          No announcements yet.
+          {message}
         </Typography>
       </Box>
     );
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx`
around lines 58 - 103, The empty-state JSX in AnnouncementList.tsx duplicates
the same Box container and Typography styling for both conditional branches
(when cases.length === 0 and hasListRefinement vs not), so extract the shared
container props and icon styles into local constants (e.g., containerSx and
iconStyle) inside the AnnouncementList component, choose the icon component
conditionally (use SearchNoResultsIcon when hasListRefinement is true else
EmptyIcon), and render a single return block that uses those shared constants
and the conditional icon and message; update references to cases and
hasListRefinement accordingly so behavior remains identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx`:
- Around line 116-129: The empty-state message in CasesList.tsx contradicts how
hasListRefinement is computed (it relies on getActiveFiltersCount() in
CasesTable.tsx which only counts structured filters); either remove "or search
query" from the copy in CasesList.tsx so the text matches current logic, or
update getActiveFiltersCount() in CasesTable.tsx to include the active search
term (e.g., treat non-empty search string as a refinement) and ensure
hasListRefinement reflects that change; pick one approach and update the
corresponding function/text so the message and refinement logic are consistent.

---

Nitpick comments:
In
`@apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx`:
- Around line 58-103: The empty-state JSX in AnnouncementList.tsx duplicates the
same Box container and Typography styling for both conditional branches (when
cases.length === 0 and hasListRefinement vs not), so extract the shared
container props and icon styles into local constants (e.g., containerSx and
iconStyle) inside the AnnouncementList component, choose the icon component
conditionally (use SearchNoResultsIcon when hasListRefinement is true else
EmptyIcon), and render a single return block that uses those shared constants
and the conditional icon and message; update references to cases and
hasListRefinement accordingly so behavior remains identical.
🪄 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.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5dcb37fc-50f7-4ca2-8519-4f19629ca982

📥 Commits

Reviewing files that changed from the base of the PR and between 755735a and 15527dd.

📒 Files selected for processing (4)
  • apps/customer-portal/webapp/src/components/dashboard/cases-table/CasesList.tsx
  • apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsList.tsx
  • apps/customer-portal/webapp/src/components/support/announcements/AnnouncementList.tsx
  • apps/customer-portal/webapp/src/pages/AllCasesPage.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/customer-portal/webapp/src/components/support/all-conversations/AllConversationsList.tsx

Comment thread apps/customer-portal/webapp/src/pages/AllCasesPage.tsx
@Rashmika998
Rashmika998 merged commit 0713723 into wso2-open-operations:dev-app-customer-portal-v1.0.x Mar 30, 2026
1 check passed
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/Task General task that does not fit into other categories Type/UX Refers to user experience-related tasks or issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants