Skip to content

feat(customer-portal): Service Requests list, detail view, and create flow - #290

Merged
Rashmika998 merged 32 commits into
wso2-open-operations:customer-portal-milestone-1from
Suwagath:feature/service-requests-list-page
Mar 3, 2026
Merged

Rashmika998 merged 32 commits into
wso2-open-operations:customer-portal-milestone-1from
Suwagath:feature/service-requests-list-page

Conversation

@Suwagath

@Suwagath Suwagath commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

Introduces the Service Requests feature in the Customer Portal so users can view, create, and manage service requests. Resolves the need for a dedicated service request workflow separate from general cases.

Goals

  • Provide a Service Requests list page with filters (All, Pending, In Progress, Completed) and counts
  • Add a Service Request detail view with Request Details, Activity Timeline, Assignment, and Communication
  • Enable creation of service requests via catalog selection (deployment → product → catalog item → variables)
  • Support "View my requests" and "View all requests" for filtering by ownership
  • Show stat cards (Pending, In Progress, Completed, Rejected) at the top of the Service Requests page

Approach

  • List page: Integrates with case search API, shows environment, product, and team on cards, with search and status filter tabs
  • Detail view: Renders Request Details (parsed from description), Activity Timeline (created, comments, status changes), Assignment (Assigned To, Category), Manage status actions, and Communication (comments with Add Comment)
  • Create flow: Multi-step form: Select Deployment → Select Product → Select Catalog Item → Fill variables (including File Copy Path as text input, Attachments as file upload). Context fields (Project, Deployment, Product) auto-populated; WSO2 Product hidden from UI
  • Navigation: Get Help dropdown routes "Service Request" to /support/service-requests/create
  • UI: Follows Oxygen UI rules (no border radius, hover effects, or border color; Lucide icons via @wso2/oxygen-ui-icons-react)

User stories

  • As a customer, I can view all my service requests in a list with status filters
  • As a customer, I can open a service request to see details, timeline, assignment, and comments
  • As a customer, I can create a service request by selecting deployment, product, and catalog item and filling required variables
  • As a customer, I can add comments to a service request
  • As a customer, I can change service request status (e.g., Close, Reopen) when allowed

Release note

Added Service Requests feature to the Customer Portal: list view with filters and stat cards, detail view with activity timeline and comments, and create flow with catalog-based variable forms.

Automation tests

  • Unit tests: Existing unit tests for affected components; new service request components covered by integration with existing APIs
  • Integration tests: Manual verification of list, detail, and create flows against backend APIs

Security checks

Learning

  • Used existing case search and case creation APIs for service requests
  • Catalog search and catalog item variables APIs for the create flow
  • Oxygen UI components and Lucide icons for consistent styling

Summary by CodeRabbit

  • New Features
    • Dedicated Service Requests module: list, search, filter, paginate, create, and view details.
    • Multi-step creation flow with catalog selection, dynamic variable-driven forms, attachments, and validation.
    • Detailed service request view with timeline, comments, status actions, and assignment info.
    • Catalog search and catalog-item variable fetching for dynamic forms.
    • Service request statistics, status-based filters, updated Support navigation, and enhanced request cards with multiple footer actions.

Suwagath added 24 commits March 3, 2026 01:52
- ServiceRequestsList: Card-based list displaying SR details with status chips, request type, metadata, and relative timestamps
- ServiceRequestsSearchBar: Search input with status filter tabs (All, Pending, In Progress, Completed)
- ServiceRequestsListSkeleton: Loading skeleton for the list
- Filters cases by Service Request type
- Search functionality with frontend filtering
- Status filter tabs (All, Pending, In Progress, Completed)
- Sort by newest/oldest
- Pagination support
- Add /support/service-requests route in App.tsx
- Update ServiceRequestCard to navigate to the new page
- Fix New Service Request button to use skipChat mode
- Add catalog types and CreateServiceRequestPayload to models
- Add useSearchCatalogs and useGetCatalogItemVariables API hooks
- Add CatalogSelector with category icons and VariableFormFields
- Add CreateServiceRequestPage with deployment/product/catalog/variables flow
- Update navigation: ServiceRequestCard, GetHelpDropdown, ServiceRequestsPage
- Add route /support/service-requests/create
- Extend usePostCase to accept CreateServiceRequestPayload
…terisks, SR detail styling

- Use Rich Text Editor for Description fields in VariableFormFields
- Add file input for attachment variables with onAttachmentAdd
- Add red asterisk for required fields, remove placeholders
- Extend CreateCaseResponse with backend fields (number, createdBy, etc.)
- SR detail: activity timeline with vertical flow, assigned/category cards
- Communication: chat icons blue (user) vs orange (team) per case chat style
- Add serviceRequestValidation utils: isAttachmentField, getFirstEmptyRequiredField
- VariableFormFields: use file picker for attachment vars (by type or questionText)
- Make attachment variables optional in validation
- CreateServiceRequestPage: filter variables to only send non-empty values
…roved styling

- Updated timeline entries to include actor information for created, commented, and closed statuses.
- Adjusted layout and styling for better visual consistency, including icon sizes and background colors.
- Refined the sorting logic for timeline entries based on date.
…istics

- Introduced ServiceRequestsStatCards component to display statistics for service requests including pending, in progress, completed, and rejected counts.
- Updated supportConstants to include configuration and valid keys for service request statistics.
- Integrated ServiceRequestsStatCards into ServiceRequestsPage, utilizing memoized stats calculation based on service request statuses.
… and search parameters

- Updated RequestCard component to support optional footer buttons for enhanced user interaction.
- Modified ServiceRequestCard to utilize the new footer buttons for navigating service requests.
- Enhanced ServiceRequestsPage to handle search parameters, allowing users to filter requests by creator.
- Adjusted UI text based on the presence of search parameters for improved clarity.
…tistics display

- Added dark mode detection to ServiceRequestsSearchBar using a custom hook.
- Introduced stats prop to display counts for pending, in progress, completed, and rejected service requests.
- Updated button labels in the status tabs to include corresponding counts for improved user feedback.
- Integrated stats into the ServiceRequestsPage to provide a comprehensive overview of service request statuses.
…tent components

- Streamlined the footer button layout in RequestCard by removing unnecessary borders and adjusting spacing.
- Replaced custom Box components with Divider for cleaner separation in ServiceRequestDetailContent.
- Removed redundant border styles and improved overall component styling for better visual consistency.
… new field handling

- Updated ServiceRequestDetailContent to improve comment button styling and layout.
- Introduced a new File Copy Path field in VariableFormFields for better user input handling.
- Enhanced validation utilities to support the new File Copy Path field.
- Updated CaseDetails model to include catalog and catalogItem references for improved data handling.
…nt and VariableFormFields

- Updated ServiceRequestDetailContent to exclude sections labeled as "WSO2 Product" from display.
- Enhanced VariableFormFields to hide context fields matching the "WSO2 Product" pattern from the UI.
- Improved overall user experience by ensuring only relevant fields are shown in both components.
…gation

- Introduced a Cancel button in the CreateServiceRequestPage to allow users to easily navigate back.
- Enhanced button styling with a gap for better visual separation from the submit button.
- Removed unnecessary border radius and border color styles for improved visual consistency.
- Streamlined AccordionDetails styling by consolidating properties for cleaner code.
…stPage components

- Removed commented-out code in ServiceRequestDetailContent for improved readability.
- Eliminated debug console log in CreateServiceRequestPage to streamline the code and reduce clutter.
- Replaced useGetCasesFilters with useGetProjectFilters for improved data handling.
- Enhanced filter metadata retrieval to align with project-specific requirements.
@coderabbitai

coderabbitai Bot commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a service-requests feature: new pages, nested routes, API hooks, models, validation utilities, and multiple UI components to search, create (multi-step with attachments), list, and view catalog-driven service requests.

Changes

Cohort / File(s) Summary
Routing & Pages
apps/customer-portal/webapp/src/App.tsx, apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx, apps/customer-portal/webapp/src/pages/ServiceRequestDetailsPage.tsx, apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
Added nested /:projectId/service-requests routes and pages: list, details, and a multi-step create flow with navigation, loader, and error handling.
API Hooks & Query Keys
apps/customer-portal/webapp/src/api/useGetCatalogItemVariables.ts, apps/customer-portal/webapp/src/api/useSearchCatalogs.ts, apps/customer-portal/webapp/src/api/usePostCase.ts, apps/customer-portal/webapp/src/constants/apiConstants.ts
New hooks to fetch catalog search and catalog item variables; extended usePostCase to accept CreateServiceRequestPayload; added CATALOGS_SEARCH and CATALOG_ITEM_VARIABLES query keys.
Service Request Components
apps/customer-portal/webapp/src/components/support/service-requests/* (CatalogSelector, ServiceRequestDetailContent, ServiceRequestsList, ServiceRequestsListSkeleton, ServiceRequestsSearchBar, ServiceRequestsStatCards, VariableFormFields)
Added components for catalog selection, variable-driven forms (with attachments), stats, search bar, list + skeleton, and detailed request view (timeline, comments, actions).
Existing Component Updates
apps/customer-portal/webapp/src/components/common/header/GetHelpDropdown.tsx, apps/customer-portal/webapp/src/components/support/request-cards/RequestCard.tsx, apps/customer-portal/webapp/src/components/support/request-cards/ServiceRequestCard.tsx
Changed service-request navigation target; made RequestCard secondary action optional and introduced footerButtons; updated ServiceRequestCard to use footerButtons and new routes.
Models, Types & Validation
apps/customer-portal/webapp/src/models/requests.ts, apps/customer-portal/webapp/src/models/responses.ts, apps/customer-portal/webapp/src/constants/supportConstants.ts, apps/customer-portal/webapp/src/utils/serviceRequestValidation.ts
Added CreateServiceRequestPayload, catalog/catalog-item models and responses, service-request stat types/config, and validation utilities for attachments, context/hidden fields, and required-field checks.
Tests / Fixtures
apps/customer-portal/webapp/src/api/__tests__/useGetCaseAttachments.test.tsx
Formatting-only update to mock attachment fixtures (reflowed objects); no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Browser as Browser/UI
    participant DeploymentsAPI as "Deployments API"
    participant CatalogsAPI as "Catalogs API"
    participant VariablesAPI as "Variables API"
    participant CaseAPI as "Case API"

    User->>Browser: Open "Create Service Request"
    Browser->>DeploymentsAPI: GET /projects/:projectId/deployments
    DeploymentsAPI-->>Browser: deployments list

    User->>Browser: Select deployed product
    Browser->>CatalogsAPI: POST /deployments/products/:deployedProductId/catalogs/search
    CatalogsAPI-->>Browser: catalogs + items

    User->>Browser: Select catalog item
    Browser->>VariablesAPI: GET /catalogs/:catalogId/items/:itemId (variables)
    VariablesAPI-->>Browser: catalog item variables

    User->>Browser: Fill variables & attach files
    Browser->>Browser: encode attachments (base64)

    User->>Browser: Submit
    Browser->>CaseAPI: POST /cases (type: service_request)
    CaseAPI-->>Browser: created case (id/number)

    Browser->>Browser: Navigate to /:projectId/service-requests/:serviceRequestId
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • #114: Backend POST /cases and updated Case response fields — frontend changes consume those API and model updates.
  • #140: Modifications to usePostCase and routing/providers that this PR extends for service-request payloads and routes.
  • #271: Backend addition of createdByMe case filter — ServiceRequestsPage reads createdByMe and relies on that filter.

Suggested labels

Type/New Feature, Type/Task, Type/UX, App/Customer Portal, Area/Frontend, Platform/Web

Suggested reviewers

  • Rashmika998
  • v15a1

Poem

🐰 I hopped through catalogs near and far,
Picked items, fields, and a shiny star.
Files encoded, variables snug and tight,
A service request sprung into light.
Happy hops — the portal now takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: introducing Service Requests list, detail view, and create flow functionality to the customer portal.
Description check ✅ Passed The pull request description covers all major required sections: Purpose, Goals, Approach, User stories, Release note, Security checks, and Learning. Documentation and Testing sections are present with appropriate context.

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

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

🧹 Nitpick comments (1)
apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsStatCards.tsx (1)

25-30: Consider removing unused ServiceRequestStats interface.

This interface is defined but not used within this component. The ServiceRequestsStatCardsProps.stats property uses Partial<Record<ServiceRequestStatKey, number>> instead. If this interface isn't exported for use elsewhere, consider removing it to reduce dead code.

♻️ Proposed fix
-export interface ServiceRequestStats {
-  pending: number;
-  inProgress: number;
-  completed: number;
-  rejected: number;
-}
-

If the interface is needed elsewhere, ensure it's being imported and used accordingly.

🤖 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/service-requests/ServiceRequestsStatCards.tsx`
around lines 25 - 30, The ServiceRequestStats interface is unused in this file
(ServiceRequestStats) while ServiceRequestsStatCardsProps.stats uses
Partial<Record<ServiceRequestStatKey, number>>; either remove the dead interface
ServiceRequestStats from the file or replace the props type to use
ServiceRequestStats (or export/import it where needed). Locate the
ServiceRequestStats declaration and either delete it to eliminate dead code or
update ServiceRequestsStatCardsProps.stats to reference ServiceRequestStats (and
export/import it if used across modules).
🤖 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/api/usePostCase.ts`:
- Around line 49-55: The logger.debug call in usePostCase currently spreads the
entire body (body) into logs which can leak sensitive data; replace that spread
with a sanitized summary: construct an object that includes only safe fields
(e.g., caseId, type, truncated description via the existing description slice
logic, and a boolean or masked indicator for attachments rather than attachment
contents), and log that object instead of "...body"; update the logger.debug
invocation in usePostCase to use this sanitizedPayload and consider adding a
small helper (e.g., sanitizeCasePayload) to centralize masking of
attachment-related fields and any other sensitive keys.

In
`@apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestDetailContent.tsx`:
- Around line 274-285: The handleAddComment flow swallows errors on
postComment.mutate so failures are silent; add an onError handler to
postComment.mutate (in the handleAddComment function) that surfaces the error to
the user (e.g., set a local error state or call the app's notification/banner
utility) and optionally logs the error, while preserving the existing onSuccess
that calls setCommentText(""); reference postComment.mutate and handleAddComment
to locate the change.
- Around line 462-489: The current render logic filters requestDetailSections
(in ServiceRequestDetailContent) to remove sections matching /^wso2\s*product$/i
into the local variable filtered, but when requestDetailSections exists and
filtered becomes empty the component returns nothing; change the conditional to
check filtered.length as well and render the existing fallback content when
filtered.length === 0 (i.e., if filtered is empty, render the same fallback
branch used when requestDetailSections.length === 0), so adjust the anonymous
render block around requestDetailSections/filter/filtered to fall back to the
fallback JSX when filtered has no items.

In
`@apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsSearchBar.tsx`:
- Around line 125-134: The count calculation in ServiceRequestsSearchBar.tsx
incorrectly uses tab.value (e.g., "in_progress") to index ServiceRequestStats
(which has camelCase keys like inProgress), causing the "In Progress" tab to
show 0; update the logic that computes count (the const named count that
references tab.value and stats) to map the snake_case tab values to the
camelCase stats keys (either by adding a small mapping object or a conditional
for "in_progress" => stats.inProgress) so stats?.inProgress is used for that tab
while leaving other tabs to use stats?.[tab.value as keyof ServiceRequestStats]
?? 0.

In `@apps/customer-portal/webapp/src/constants/supportConstants.ts`:
- Around line 881-887: Remove the locally redeclared ChangeRequestFilterValues
interface in this file and rely on the existing interface imported from
`@models/responses` (the imported symbol ChangeRequestFilterValues). Delete the
duplicate export block, ensure the import statement for
ChangeRequestFilterValues remains (or add it if missing), and update any local
references to use the imported type so there's no shadowing or duplicate
declaration.

In `@apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx`:
- Around line 273-276: The submit handler currently blocks requests when
variablePayload.length === 0 by calling showError; instead allow submission for
request types that legitimately require zero user variables: remove or alter the
conditional in the submit function inside CreateServiceRequestPage so it only
validates variables when the request type indicates variables are required (use
the request type / schema check already used to render "No additional fields
required"); update the logic around variablePayload and showError so that absent
variables are only an error when the request type expects user-provided
variables (also apply the same change to the duplicate validation block around
the other check at the second location covering lines 326-333).
- Around line 152-173: The handlers handleDeploymentChange, handleProductChange,
and handleSelectCatalogItem currently reset variableValues but leave uploaded
attachments intact; update each handler to also clear the attachments state
(e.g., call setAttachments([]) or the appropriate attachment-reset function)
whenever deployment, product, or catalog selection changes so stale files are
not submitted with a different request type.

In `@apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx`:
- Around line 111-137: srStats bucketization diverges from the tab-filtering
logic so counts and displayed results can mismatch; extract a single canonical
status-bucketing helper (e.g., getStatusBucket(statusLabel) that normalizes
sr.status.label to one of: "pending", "inProgress", "completed", "rejected") and
replace the ad-hoc logic inside the srStats useMemo and the tab filter predicate
with calls to that helper so both counting and filtering use the same mapping;
ensure the helper covers the same label checks currently used
(open/awaiting/waiting/pending → pending; progress → inProgress;
rejected/cancelled → rejected; closed/resolved/completed → completed) and update
both srStats and the tab selection/filtering code to rely on it.
- Around line 78-90: The loading logic can get stuck because it only checks data
and isLoading; update the useGetProjectCases destructure to also pull isError
(or error) and use that in isCasesAreaLoading and any other loading checks
(e.g., in the block that defines isCasesAreaLoading and the analogous area at
lines ~249-283) so that when isError is true the UI stops showing infinite
loading/skeletons; adjust isCasesAreaLoading to: const isCasesAreaLoading =
isCasesQueryLoading || (!!projectId && !hasCasesResponse && !isError) and add a
simple error/render fallback where appropriate to surface the error.

In `@apps/customer-portal/webapp/src/utils/serviceRequestValidation.ts`:
- Around line 138-146: The validator currently iterates every item returned by
getUserEditableVariables and can flag required errors for backend-duplicate
variables; to match the UI deduplication, deduplicate userEditable by their
visible question text before checking required values: map each variable v to a
normalized label (use v.questionText with leading asterisk/spaces removed and
trimmed), keep the first variable for each unique label, then iterate that
deduplicated array and apply the existing logic (skip
isAttachmentField/isFileCopyPathField checks, read value from
variableValues[v.id], and return the normalized label when empty). Ensure you
reference getUserEditableVariables, isAttachmentField, isFileCopyPathField,
variableValues and questionText when updating the function.

---

Nitpick comments:
In
`@apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsStatCards.tsx`:
- Around line 25-30: The ServiceRequestStats interface is unused in this file
(ServiceRequestStats) while ServiceRequestsStatCardsProps.stats uses
Partial<Record<ServiceRequestStatKey, number>>; either remove the dead interface
ServiceRequestStats from the file or replace the props type to use
ServiceRequestStats (or export/import it where needed). Locate the
ServiceRequestStats declaration and either delete it to eliminate dead code or
update ServiceRequestsStatCardsProps.stats to reference ServiceRequestStats (and
export/import it if used across modules).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d7d8ec and ad32f29.

📒 Files selected for processing (23)
  • apps/customer-portal/webapp/src/App.tsx
  • apps/customer-portal/webapp/src/api/__tests__/useGetCaseAttachments.test.tsx
  • apps/customer-portal/webapp/src/api/useGetCatalogItemVariables.ts
  • apps/customer-portal/webapp/src/api/usePostCase.ts
  • apps/customer-portal/webapp/src/api/useSearchCatalogs.ts
  • apps/customer-portal/webapp/src/components/common/header/GetHelpDropdown.tsx
  • apps/customer-portal/webapp/src/components/support/request-cards/RequestCard.tsx
  • apps/customer-portal/webapp/src/components/support/request-cards/ServiceRequestCard.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/CatalogSelector.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestDetailContent.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsList.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsListSkeleton.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsSearchBar.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsStatCards.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/VariableFormFields.tsx
  • apps/customer-portal/webapp/src/constants/apiConstants.ts
  • apps/customer-portal/webapp/src/constants/supportConstants.ts
  • apps/customer-portal/webapp/src/models/requests.ts
  • apps/customer-portal/webapp/src/models/responses.ts
  • apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx
  • apps/customer-portal/webapp/src/pages/ServiceRequestDetailsPage.tsx
  • apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
  • apps/customer-portal/webapp/src/utils/serviceRequestValidation.ts

Comment thread apps/customer-portal/webapp/src/api/usePostCase.ts Outdated
Comment thread apps/customer-portal/webapp/src/constants/supportConstants.ts Outdated
Comment thread apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx
Comment thread apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx Outdated
Comment thread apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
Comment thread apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
Comment thread apps/customer-portal/webapp/src/utils/serviceRequestValidation.ts

@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/api/usePostCase.ts (1)

49-61: Sanitized logging addresses prior feedback; minor redundancy in type guards.

The structured logging summary properly avoids leaking sensitive data. However, the "deploymentId" in body and "deployedProductId" in body checks on lines 52-54 are redundant since both CreateCaseRequest and CreateServiceRequestPayload define these as required fields—you can access them directly like projectId.

♻️ Optional simplification
       logger.debug("[usePostCase] Request payload summary:", {
         requestType: "type" in body ? body.type : "case",
         projectId: body.projectId,
-        deploymentId: "deploymentId" in body ? body.deploymentId : undefined,
-        deployedProductId:
-          "deployedProductId" in body ? body.deployedProductId : undefined,
+        deploymentId: body.deploymentId,
+        deployedProductId: body.deployedProductId,
         descriptionPreview:
           "description" in body && body.description
             ? `${body.description.slice(0, 80)}...`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/customer-portal/webapp/src/api/usePostCase.ts` around lines 49 - 61, The
structured logging uses redundant type-guards for "deploymentId" and
"deployedProductId"; inside usePostCase's logger.debug payload you can directly
reference body.deploymentId and body.deployedProductId (remove the
`"deploymentId" in body` and `"deployedProductId" in body` checks) because
CreateCaseRequest and CreateServiceRequestPayload declare them as
required—update the logger.debug call in usePostCase to log body.deploymentId
and body.deployedProductId directly while keeping other fields unchanged.
🤖 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/support/service-requests/ServiceRequestDetailContent.tsx`:
- Around line 163-166: The comments fetch currently treats errors as empty
results; update the component that calls useGetCaseComments (the const { data:
commentsData } = useGetCaseComments(...) usage and the other instance around
lines 526-529) to read the hook's error/status flags (e.g., error, isError,
isLoading) in addition to data, and render a distinct error UI when the query
fails (use isLoading to keep loading state, render "No comments yet" only when
data is empty and there is no error). Ensure you reference the same hook return
values (error/isError/isLoading) where commentsData is used so a failed fetch
shows an explicit error state instead of "No comments yet."
- Around line 467-513: The fallback rendering can re-expose "WSO2 Product";
update ServiceRequestDetailContent to apply the same filter used for parsed
sections to the fallback text: reuse the requestDetailSections.filter((s) =>
!/^wso2\s*product$/i.test(s.label.trim())) logic (the filtered variable) and
when filtered.length === 0 or when falling back to stripHtml(data?.description),
remove any "WSO2 Product" lines from the fallback output (e.g., strip or filter
lines matching /^wso2\s*product$/i before rendering); reference
requestDetailSections, filtered, stripHtml, data?.description and the
/^wso2\s*product$/i regex so the fallback no longer shows that context.

---

Nitpick comments:
In `@apps/customer-portal/webapp/src/api/usePostCase.ts`:
- Around line 49-61: The structured logging uses redundant type-guards for
"deploymentId" and "deployedProductId"; inside usePostCase's logger.debug
payload you can directly reference body.deploymentId and body.deployedProductId
(remove the `"deploymentId" in body` and `"deployedProductId" in body` checks)
because CreateCaseRequest and CreateServiceRequestPayload declare them as
required—update the logger.debug call in usePostCase to log body.deploymentId
and body.deployedProductId directly while keeping other fields unchanged.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad32f29 and 3c2805f.

📒 Files selected for processing (6)
  • apps/customer-portal/webapp/src/api/usePostCase.ts
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestDetailContent.tsx
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsSearchBar.tsx
  • apps/customer-portal/webapp/src/constants/supportConstants.ts
  • apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx
  • apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestsSearchBar.tsx
  • apps/customer-portal/webapp/src/pages/CreateServiceRequestPage.tsx
  • apps/customer-portal/webapp/src/pages/ServiceRequestsPage.tsx

@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

🤖 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/support/service-requests/ServiceRequestDetailContent.tsx`:
- Around line 114-125: The flush() routine currently drops buffered text that
appears before the first <strong> label; update flush() so that if rawLabel is
empty but valueText has content, it is preserved: if sections already has at
least one entry, prepend/merge valueText into sections[0].value (e.g., join with
a newline or space) so the unlabeled intro is kept, otherwise push a new section
with label: rawLabel (empty) and value: valueText; keep the existing resets for
currentLabel and currentValueParts. Ensure you modify the flush function (and
replicate the same logic in the other similar blocks referenced) so unlabeled
intro text is not discarded.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c2805f and 5c96929.

📒 Files selected for processing (2)
  • apps/customer-portal/webapp/src/api/usePostCase.ts
  • apps/customer-portal/webapp/src/components/support/service-requests/ServiceRequestDetailContent.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/customer-portal/webapp/src/api/usePostCase.ts

@Rashmika998
Rashmika998 merged commit b72392c into wso2-open-operations:customer-portal-milestone-1 Mar 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants