[Customer Portal][FE][Web] Add Knowledge Base Recommendations API Integration and Refactor List Layout Components - #512
Conversation
Add a new recommendations.ts utility module for the customer-portal support feature. Provides helpers to convert recommendation scores to percentages, build envProducts from case data, determine API roles from case comments, and construct RecommendationSearchRequest payloads from CaseDetails+comments or ConversationMessage arrays. Messages/comments are sorted chronologically, bot/"novera" authors are mapped to assistant, chat history is concatenated into conversationData, and functions return null when no usable content exists. Includes Apache-2.0 license header.
Add vitest unit tests for recommendation utilities at apps/customer-portal/webapp/src/features/support/utils/__tests__/recommendations.test.ts. Tests cover recommendationScoreToPercent (mapping 0–1 to percentages and treating values >1 as percent-like) and buildRecommendationRequestFromCase (handling undefined case data and building chat history + envProducts mapping). Ensures expected behavior for recommendation request generation.
Add an optional knowledgeBaseCount to CaseDetailsTabsProps and an onKnowledgeBaseCountChange callback to CaseDetailsTabPanelsProps. These props allow the case details UI to receive and propagate updates to the number of knowledge base items associated with a case.
Introduce TypeScript types for the customer-portal support recommendations API. Adds types for message roles, API messages, conversation data, request/response payloads, and individual recommendation items (used by POST /conversations/recommendations/search and mapped to OpenAPI models). File includes Apache-2.0 license header.
Replace the static "Knowledge Base Articles Suggested" placeholder with the ConversationKnowledgeRecommendations component. Adds an import and renders <ConversationKnowledgeRecommendations messages={messages} /> in place of the previous Paper block that displayed an Error500Page placeholder, wiring the real KB recommendations UI into the conversation details page.
Replace the locally defined KB_BASE_URL with the exported KB_ARTICLE_VIEW_BASE_URL from supportConstants and use it when opening KB articles. This centralizes the KB base URL for easier maintenance and avoids hardcoded URLs; also adjust window.open call formatting.
Introduce a new React component that displays knowledge base article recommendations for a conversation. It builds a recommendation request from conversation messages, calls the shared recommendations API via useConversationRecommendationsSearch, and renders loading, error, empty, and results states. Articles are clickable (open in a new tab) and show a relevance percent chip; utility functions and a KB base URL constant are used. Includes WSO2 license header.
Introduce CaseKnowledgeBaseRecommendations, a React component for the Support Knowledge Base tab. It fetches case comments, builds a recommendation payload, and queries conversation-driven article recommendations. The component handles loading skeletons, empty and error states, and renders recommended articles with a relevance percentage and a View Article action that opens the KB in a new tab. Props: caseId, projectId, data, onCountChange. Uses useGetCaseComments, useConversationRecommendationsSearch, buildRecommendationRequestFromCase, and recommendationScoreToPercent.
Add a new unit test for the ConversationKnowledgeRecommendations component. The test file (Vitest) mocks useConversationRecommendationsSearch to return sample recommendation data, renders the component inside QueryClientProvider and ThemeProvider, and asserts that the recommendation header, article title, and query text are present.
Add a knowledgeBaseCount prop to CaseDetailsTabs and update tab rendering to detect the "Knowledge Base" tab and append its count when provided, mirroring the existing behavior for Attachments and Calls.
Replace the static Knowledge Base placeholder with the CaseKnowledgeBaseRecommendations component. Adds import and a new onKnowledgeBaseCountChange prop, computes a resolvedProjectId fallback (data?.project?.id ?? projectId ?? ""), and passes caseId, projectId, data, and onCountChange to the recommendations component. Also updates the doc comment to reflect API-driven recommendations.
Add a vi.mock for useConversationRecommendationsSearch in CaseDetailsTabPanels tests to return an empty recommendations payload (data, isLoading: false, isError: false). Also update the test name and assertion for the Knowledge Base tab to check the new UI copy (/Knowledge base articles that may help/i) instead of the previous placeholder text.
Import case comments and recommendation hooks and build a KB recommendation payload from the case to fetch recommendations eagerly on page load. Adds useGetCaseComments, useConversationRecommendationsSearch, and buildRecommendationRequestFromCase; computes knowledgeBaseCount (guarded by hideKnowledgeBaseTab and comment-loading state) so the Knowledge Base tab can display its item count immediately. Passes knowledgeBaseCount into the child component. React Query dedupes the network call when the KB tab mounts later.
Introduce useConversationRecommendationsSearch hook to POST chat context to /conversations/recommendations/search and return KB recommendation results via react-query. The hook serializes the payload for the queryKey, validates payload and backend base URL, uses the authenticated fetch client and Asgardeo auth state, and enables the query only when signed in, not auth-loading, and the payload.chatHistory has entries. Includes debug logging, error handling for missing config or non-OK responses, and a 5-minute staleTime.
Introduce CONVERSATION_RECOMMENDATIONS_SEARCH to ApiQueryKeys in apps/customer-portal/webapp/src/constants/apiConstants.ts to standardize the query key used for conversation recommendations search (e.g. caching and query identification).
Swap the previous MUI Grid layout for a CSS Grid implemented via Box. Adds columnsFromSegment helper to convert 12-column segments into repeat(...) grid tracks and derives responsive xs/sm/md/lg/xl segment values with fallbacks. Replaces Grid container/items with a Box using gridTemplateColumns and gap (spacing), removes the Grid import and the size prop on items, and adds minWidth: 0 to item boxes. StatCard rendering and icon handling remain unchanged.
Replace nested Box layout with Oxygen UI Stack for improved responsive layout and spacing. Import Stack from @wso2/oxygen-ui, adjust the back Button styles (remove margin, use alignSelf, px/minWidth tweaks), and convert the header container to a responsive Stack with direction, spacing, justifyContent and alignItems tuned for actions presence. Also add minWidth: 0 to the title wrapper to help truncation and keep actions with flexShrink removed. Small header comment spacing added.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 55 minutes and 27 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (15)
📝 WalkthroughWalkthroughIntroduces knowledge base recommendation functionality to the customer portal by adding an API hook to fetch recommendations based on chat history, creating UI components to display recommendations in case details and conversations, developing utility functions to build recommendation payloads, and refactoring layout components for improved responsive design. Changes
Sequence Diagram(s)sequenceDiagram
participant CaseDetailsContent
participant useGetCaseComments
participant buildRecommendationRequestFromCase
participant useConversationRecommendationsSearch
participant RecommendationAPI as /conversations/recommendations/search
participant CaseDetailsTabs
CaseDetailsContent->>useGetCaseComments: fetch(projectId, caseId)
useGetCaseComments-->>CaseDetailsContent: comments loaded
CaseDetailsContent->>buildRecommendationRequestFromCase: build payload from case + comments
buildRecommendationRequestFromCase-->>CaseDetailsContent: RecommendationSearchRequest
CaseDetailsContent->>useConversationRecommendationsSearch: call with payload + enabled flag
useConversationRecommendationsSearch->>RecommendationAPI: POST /conversations/recommendations/search
RecommendationAPI-->>useConversationRecommendationsSearch: RecommendationSearchResponse
useConversationRecommendationsSearch-->>CaseDetailsContent: recommendations + metadata
CaseDetailsContent->>CaseDetailsTabs: pass knowledgeBaseCount prop
CaseDetailsTabs-->>CaseDetailsContent: render with count in tab label
sequenceDiagram
participant ConversationDetailsPage
participant buildRecommendationRequestFromConversationMessages
participant useConversationRecommendationsSearch
participant RecommendationAPI as /conversations/recommendations/search
participant ConversationKnowledgeRecommendations
ConversationDetailsPage->>buildRecommendationRequestFromConversationMessages: build from messages
buildRecommendationRequestFromConversationMessages-->>ConversationDetailsPage: RecommendationSearchRequest
ConversationDetailsPage->>useConversationRecommendationsSearch: fetch recommendations
useConversationRecommendationsSearch->>RecommendationAPI: POST with message history
RecommendationAPI-->>useConversationRecommendationsSearch: articles + query summary
useConversationRecommendationsSearch-->>ConversationDetailsPage: recommendations data
ConversationDetailsPage->>ConversationKnowledgeRecommendations: render with results
ConversationKnowledgeRecommendations-->>ConversationDetailsPage: clickable KB articles
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
apps/customer-portal/webapp/src/features/support/pages/ConversationDetailsPage.tsx (1)
313-313: Consider gating on load/error state of messages.
ConversationKnowledgeRecommendationsis rendered unconditionally — even whenisLoadingorisErroris true for the conversation fetch, it will build a payload from whatevermessagesis (possibly empty) and display its own skeleton/empty state. This means on error the page shows a red error box AND the KB section attempts to fetch against an empty payload. Consider only rendering it in the success branch (aftermessages.length > 0or at least!isError).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/support/pages/ConversationDetailsPage.tsx` at line 313, ConversationKnowledgeRecommendations is being rendered unconditionally and can trigger requests with an empty payload when the conversation fetch is loading or errored; update the render logic in ConversationDetailsPage to only render <ConversationKnowledgeRecommendations messages={messages} /> when the conversation fetch is successful (e.g., !isLoading && !isError) and preferably when messages.length > 0 so the KB component receives a valid payload and won’t fetch on empty/error states.apps/customer-portal/webapp/src/features/support/components/case-details/header/CaseDetailsTabPanels.tsx (1)
109-119: Count propagation is disconnected.
onKnowledgeBaseCountChangeis plumbed through toCaseKnowledgeBaseRecommendations.onCountChange, butCaseDetailsContent.tsxnever passesonKnowledgeBaseCountChangetoCaseDetailsTabPanels— the count shown in the tab label comes entirely from the parent's ownuseConversationRecommendationsSearchcall. Either remove this prop (dead plumbing) or wire it through and drop the parent-side fetch to avoid duplicated responsibility.Also,
resolvedProjectIdcan still be""here whendata?.project?.idis unavailable;CaseKnowledgeBaseRecommendationswill then calluseGetCaseComments("", caseId)— please confirm that's gracefully disabled inside the hook.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/support/components/case-details/header/CaseDetailsTabPanels.tsx` around lines 109 - 119, The prop onKnowledgeBaseCountChange passed into CaseKnowledgeBaseRecommendations from CaseDetailsTabPanels is dead — either remove the prop plumbing and the onKnowledgeBaseCountChange usage in CaseDetailsTabPanels and rely on the parent's useConversationRecommendationsSearch, or wire the callback end-to-end: have CaseDetailsContent.tsx accept and forward onKnowledgeBaseCountChange into CaseDetailsTabPanels, then drop the parent-side useConversationRecommendationsSearch fetch to avoid duplicated responsibilities; also prevent passing an empty projectId into CaseKnowledgeBaseRecommendations by ensuring resolvedProjectId is undefined/null (not "") or guard inside CaseKnowledgeBaseRecommendations/useGetCaseComments so useGetCaseComments(projectId, caseId) is a no-op when projectId is falsy (check useGetCaseComments for an early return when projectId is empty).apps/customer-portal/webapp/src/features/support/components/knowledge-base/CaseKnowledgeBaseRecommendations.tsx (2)
68-73:useMemohas a fresh dependency every render.
commentsData?.comments ?? []returns a new[]array on every render when the data is absent, socommentsis a fresh reference and theuseMemoforpayloadrecomputes each render. IfuseConversationRecommendationsSearchderives its React Query key frompayloadby reference, this may cause unstable keys.Proposed fix
- const comments = commentsData?.comments ?? []; - const payload = useMemo( - () => buildRecommendationRequestFromCase(data, comments), - [data, comments], + () => buildRecommendationRequestFromCase(data, commentsData?.comments ?? []), + [data, commentsData], );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/support/components/knowledge-base/CaseKnowledgeBaseRecommendations.tsx` around lines 68 - 73, The current comments variable gets a fresh [] each render when commentsData is absent, causing payload (built by buildRecommendationRequestFromCase) to recompute; change comments to a stable memoized value e.g. replace const comments = commentsData?.comments ?? [] with const comments = useMemo(() => commentsData?.comments ?? [], [commentsData?.comments]) so payload’s useMemo([data, comments]) sees a stable reference and avoids unstable keys for useConversationRecommendationsSearch.
92-96:onCountChangeis not reference-stable in the effect deps.If callers pass an inline arrow for
onCountChange(whichCaseDetailsTabPanels/CaseDetailsContentwould do if wired), this effect runs on every render even whenitems.lengthis unchanged — causing redundant state updates in the parent. Either memoize the callback at call sites or compare against a previously-reported count ref before invoking.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/webapp/src/features/support/components/knowledge-base/CaseKnowledgeBaseRecommendations.tsx` around lines 92 - 96, The effect in CaseKnowledgeBaseRecommendations calls onCountChange directly and includes it in deps, causing runs when callers pass unstable callbacks; modify the effect to remove onCountChange from the dependency requirement by keeping a local ref (e.g., lastReportedCountRef) that stores the last items.length reported and only call onCountChange(items.length) when recData is present and items.length !== lastReportedCountRef.current, then update the ref; keep other deps (isLoading, isError, recData, items.length) so the effect fires correctly but avoid invoking the parent callback on every render when it is not actually changed.
🤖 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/list-view/ListStatGrid.tsx`:
- Around line 46-48: columnsFromSegment currently divides 12 by segment and
returns a repeat(n, ...) string which breaks for non-divisors; instead make the
container use a fixed 12-column template (e.g. "repeat(12, minmax(0, 1fr))") and
compute integer column spans per segment for items. Modify columnsFromSegment to
return the fixed 12-column template and add a helper (e.g.
columnSpanFromSegment(segment)) that computes span = clamp(1, round(12/segment),
12). Then update callers (the grid container usage and item sx in
EngagementsStatCards and SecurityStats) to set gridTemplateColumns to the fixed
12-column string and set each item’s gridColumn to responsive spans using
cascading breakpoints (xs: `span ${spanXs}`, sm: `span ${spanSm ?? spanXs}`, md:
`span ${spanMd ?? spanSm ?? spanXs}`) so breakpoint values cascade like MUI
Grid.
In
`@apps/customer-portal/webapp/src/features/support/api/useConversationRecommendationsSearch.ts`:
- Around line 43-50: The query key currently embeds full payload via the
variable `serialized` in `useConversationRecommendationsSearch` (used in the
`queryKey` with `ApiQueryKeys.CONVERSATION_RECOMMENDATIONS_SEARCH`), which leaks
chat content to React Query metadata; change the key to a sanitized identifier
set (e.g., `conversationId`, message count, latest message timestamp or other
minimal filters) derived from `payload` instead of JSON.stringify(payload).
Update the `queryKey` construction to use those minimal fields and mirror the
same change pattern found in `useSearchConversations.ts` (remove embedding of
full request object, use only necessary filter IDs) so cache keys no longer
contain raw conversation text.
In
`@apps/customer-portal/webapp/src/features/support/components/case-details/header/__tests__/CaseDetailsTabPanels.test.tsx`:
- Around line 239-244: The test expecting "Knowledge base articles that may
help" is incorrect because with the mock returning recommendations: [] the
CaseKnowledgeBaseRecommendations component renders the empty-state message;
update the test in CaseDetailsTabPanels.test.tsx (the it block using
renderTabPanels(4)) to assert that the empty-state text "No matching knowledge
base articles were found for this case." is in the document, or alternatively
change the test fixture/mock that provides recommendations to include at least
one item and then assert the existing heading; reference renderTabPanels and
CaseKnowledgeBaseRecommendations when making the change.
In
`@apps/customer-portal/webapp/src/features/support/components/knowledge-base/ConversationKnowledgeRecommendations.tsx`:
- Around line 118-170: The Paper wrapper's click and keyboard accessibility need
fixes: update the Button's onClick handler in
ConversationKnowledgeRecommendations (where Button currently calls
openArticle(item.articleId)) to accept the event and call e.stopPropagation()
before invoking openArticle(item.articleId) to prevent the Paper's onClick from
firing twice; additionally add keyboard affordances to the Paper component (set
role="button", tabIndex={0}, and an onKeyDown handler that calls
openArticle(item.articleId) when Enter or Space is pressed) so the Paper is
keyboard-accessible. Ensure you modify the Paper and Button instances in
ConversationKnowledgeRecommendations.tsx and reuse the same openArticle
function.
In `@apps/customer-portal/webapp/src/features/support/utils/recommendations.ts`:
- Around line 105-178: The code uses new Date().toISOString() as a fallback
timestamp which changes each render; make a deterministic fallback instead:
compute a stableFallback timestamp (for example the earliest existing createdOn
found in the input or a fixed constant like "1970-01-01T00:00:00Z") and replace
occurrences of new Date().toISOString() used as fallbacks (e.g., the createdOn
assignment at the top of the case builder and the timestamp fallback in
buildRecommendationRequestFromConversationMessages where you use m.createdOn ??
new Date().toISOString()) to use stableFallback so identical inputs produce
identical request bodies and cache keys.
---
Nitpick comments:
In
`@apps/customer-portal/webapp/src/features/support/components/case-details/header/CaseDetailsTabPanels.tsx`:
- Around line 109-119: The prop onKnowledgeBaseCountChange passed into
CaseKnowledgeBaseRecommendations from CaseDetailsTabPanels is dead — either
remove the prop plumbing and the onKnowledgeBaseCountChange usage in
CaseDetailsTabPanels and rely on the parent's
useConversationRecommendationsSearch, or wire the callback end-to-end: have
CaseDetailsContent.tsx accept and forward onKnowledgeBaseCountChange into
CaseDetailsTabPanels, then drop the parent-side
useConversationRecommendationsSearch fetch to avoid duplicated responsibilities;
also prevent passing an empty projectId into CaseKnowledgeBaseRecommendations by
ensuring resolvedProjectId is undefined/null (not "") or guard inside
CaseKnowledgeBaseRecommendations/useGetCaseComments so
useGetCaseComments(projectId, caseId) is a no-op when projectId is falsy (check
useGetCaseComments for an early return when projectId is empty).
In
`@apps/customer-portal/webapp/src/features/support/components/knowledge-base/CaseKnowledgeBaseRecommendations.tsx`:
- Around line 68-73: The current comments variable gets a fresh [] each render
when commentsData is absent, causing payload (built by
buildRecommendationRequestFromCase) to recompute; change comments to a stable
memoized value e.g. replace const comments = commentsData?.comments ?? [] with
const comments = useMemo(() => commentsData?.comments ?? [],
[commentsData?.comments]) so payload’s useMemo([data, comments]) sees a stable
reference and avoids unstable keys for useConversationRecommendationsSearch.
- Around line 92-96: The effect in CaseKnowledgeBaseRecommendations calls
onCountChange directly and includes it in deps, causing runs when callers pass
unstable callbacks; modify the effect to remove onCountChange from the
dependency requirement by keeping a local ref (e.g., lastReportedCountRef) that
stores the last items.length reported and only call onCountChange(items.length)
when recData is present and items.length !== lastReportedCountRef.current, then
update the ref; keep other deps (isLoading, isError, recData, items.length) so
the effect fires correctly but avoid invoking the parent callback on every
render when it is not actually changed.
In
`@apps/customer-portal/webapp/src/features/support/pages/ConversationDetailsPage.tsx`:
- Line 313: ConversationKnowledgeRecommendations is being rendered
unconditionally and can trigger requests with an empty payload when the
conversation fetch is loading or errored; update the render logic in
ConversationDetailsPage to only render <ConversationKnowledgeRecommendations
messages={messages} /> when the conversation fetch is successful (e.g.,
!isLoading && !isError) and preferably when messages.length > 0 so the KB
component receives a valid payload and won’t fetch on empty/error states.
🪄 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: 960148d5-59ba-4c23-bc85-c6aec6d4086d
📒 Files selected for processing (18)
apps/customer-portal/webapp/src/components/list-view/ListPageHeader.tsxapps/customer-portal/webapp/src/components/list-view/ListStatGrid.tsxapps/customer-portal/webapp/src/constants/apiConstants.tsapps/customer-portal/webapp/src/features/support/api/useConversationRecommendationsSearch.tsapps/customer-portal/webapp/src/features/support/components/case-details/details-tab/CaseDetailsContent.tsxapps/customer-portal/webapp/src/features/support/components/case-details/header/CaseDetailsTabPanels.tsxapps/customer-portal/webapp/src/features/support/components/case-details/header/CaseDetailsTabs.tsxapps/customer-portal/webapp/src/features/support/components/case-details/header/__tests__/CaseDetailsTabPanels.test.tsxapps/customer-portal/webapp/src/features/support/components/knowledge-base/CaseKnowledgeBaseRecommendations.tsxapps/customer-portal/webapp/src/features/support/components/knowledge-base/ConversationKnowledgeRecommendations.tsxapps/customer-portal/webapp/src/features/support/components/knowledge-base/__tests__/ConversationKnowledgeRecommendations.test.tsxapps/customer-portal/webapp/src/features/support/components/novera-ai-assistant/novera-chat-page/RecommendationsCard.tsxapps/customer-portal/webapp/src/features/support/constants/supportConstants.tsapps/customer-portal/webapp/src/features/support/pages/ConversationDetailsPage.tsxapps/customer-portal/webapp/src/features/support/types/recommendations.tsapps/customer-portal/webapp/src/features/support/types/supportComponents.tsapps/customer-portal/webapp/src/features/support/utils/__tests__/recommendations.test.tsapps/customer-portal/webapp/src/features/support/utils/recommendations.ts
Replace runtime-generated timestamps with a fixed epoch string for missing createdOn fields in recommendations utilities. This makes outputs deterministic and avoids using the current time. Updated buildRecommendationRequestFromCase and buildRecommendationRequestFromConversationMessages to use "1970-01-01T00:00:00Z" instead of new Date().toISOString().
Make knowledge-base recommendation items keyboard-accessible by adding role="button", tabIndex, and an onKeyDown handler to open articles on Enter/Space. Prevent double-handling when clicking the external link by stopping propagation on the button's onClick. Also remove the now-unused onKnowledgeBaseCountChange prop from CaseDetailsTabPanelsProps to clean up types.
UI: Constrain the Details column in CasesList (maxWidth 320) and enable text truncation (overflow/ellipsis, white-space nowrap) with minWidth:0 on the container so long titles don't overflow. API: Replace JSON serialization in useConversationRecommendationsSearch query key with lightweight values (message count, first and last timestamps) to produce a more stable and efficient cache key for react-query.
Drop the knowledge-base result count callback from the case details tab and the CaseKnowledgeBaseRecommendations component. Memoize fetched comments to avoid recalculating arrays on each render and remove the effect that reported recommendation counts. Update the tab panel to stop passing the removed prop and adjust the test expectation to the new empty-state message. Files changed: - CaseDetailsTabPanels.tsx: remove onKnowledgeBaseCountChange prop and its propagation. - CaseKnowledgeBaseRecommendations.tsx: remove onCountChange prop and related useEffect, memoize comments, clean up imports. - CaseDetailsTabPanels.test.tsx: update assertion to match the new empty-state text.
Add a loading state for the Knowledge Base tab count to show a Skeleton while recommendations/comments are being fetched. Compute knowledgeBaseCountLoading in CaseDetailsContent and pass it to CaseDetailsTabs; render a Skeleton in the tab label when loading. Also update the props type (knowledgeBaseCountLoading?) and import ReactNode and Skeleton in CaseDetailsTabs.
Remove an extra '//' blank comment line from the top of apps/customer-portal/webapp/src/components/list-view/ListPageHeader.tsx to tidy the Apache license header.
Apply code formatting and reflow across the knowledge-base recommendation feature. Changes include removing stray license comment lines, reflowing JSX and props to multiple lines for readability, expanding destructured assignments, and making small test formatting tweaks in ConversationKnowledgeRecommendations.test.tsx. No functional behavior changes were made.
Remove an extra stray '//' blank comment line from the license header in ListStatGrid.tsx to tidy the file and ensure consistent header formatting.
ee4451b
into
wso2-open-operations:dev-app-customer-portal
Description
This pull request introduces a new API integration for Knowledge Base article recommendations in the case details view and refactors related UI components to support this feature. It also improves the layout of the
ListPageHeaderandListStatGridcomponents for better flexibility and maintainability.Knowledge Base Recommendations Integration
useConversationRecommendationsSearchto POST chat/case context and fetch Knowledge Base article recommendations from the backend.CONVERSATION_RECOMMENDATIONS_SEARCHquery key toapiConstants.UI Component Improvements
ListPageHeaderto useStackfor layout instead of nestedBoxcomponents, improving responsiveness and code clarity. [1] [2] [3]ListStatGridto use CSS grid instead of MUI'sGridfor more flexible and maintainable layouts, with a utility for responsive column counts. [1] [2] [3] [4]Testing
Summary by CodeRabbit
Release Notes
New Features
UI Improvements