[CSM Portal Microapp] Add a Linked Items tab to case details - #1394
Conversation
The case detail page had no way to see or manage a case's related records —
child cases, linked service requests, and linked change requests were all
fetched by the backend but never surfaced, and there was no way to link a
case to another one or file a service request pre-linked to it. Adds a
"Linked Items" tab mirroring the webapp's `related` tab: Child cases and
Linked service requests both page through a new parentId-scoped case search
(POST /cases/search { filters: { parentId } }, the same relationship both
widgets share), and Linked change requests fans out a per-row GET via the
change-request ids the case-detail response already carries. Adapted from
the webapp's desktop tables to mobile cards, dropping its per-widget refresh
buttons — this page already refetches the whole case on every mutation.
Also adds LinkCaseDialog (search-and-pick a case to link as parent or
related, confirm-before-committing like the webapp) and threads a
CreateServiceRequestFromCaseNavState through to NewServiceRequestPage so
"Create service request" locks the Project field and links the new request
back to the originating case in one step, instead of a separate
create-then-link round trip.
📝 WalkthroughWalkthroughAdds linked-case search and confirmation, a Linked Items tab, child and related-record retrieval, case-link mutations, and case-originated service-request creation. ChangesCase linked-items workflow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CaseDetailPage
participant LinkCaseDialog
participant cases.quickSearch
participant LinkedItemsTab
participant NewServiceRequestPage
CaseDetailPage->>LinkCaseDialog: Open case-link dialog
LinkCaseDialog->>cases.quickSearch: Search for cases
cases.quickSearch-->>LinkCaseDialog: Return matching cases
LinkCaseDialog->>CaseDetailPage: Confirm case ID and link type
CaseDetailPage->>LinkedItemsTab: Refresh linked items
LinkedItemsTab->>NewServiceRequestPage: Open linked service-request form
NewServiceRequestPage->>NewServiceRequestPage: Submit relatedCaseId
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/csm-portal/microapp/src/components/case-detail/LinkedItemsTab.tsx`:
- Around line 240-245: Update the enrichment flow around searchChildren and
enrichedById to use the related-case relationship for service requests: fetch
linked service-request details by ref.id or add a query filtering by
relatedCaseId, then merge those records into the map used by the cards so state,
severity, and assignee are populated.
- Around line 187-205: Update the count prop on the Child cases
LinkedItemsSection so it remains undefined while isError is true, as it already
does during loading; only use rows.length when the query succeeds. Preserve the
existing error content and empty-state behavior for non-error results.
In `@apps/csm-portal/microapp/src/pages/NewServiceRequestPage.tsx`:
- Around line 77-85: Handle errors from lockedProjectQuery in the project
initialization flow around lockedProjectId and the ProjectSelect disabled logic:
show a clear project-load failure state with retry or back navigation, or enable
ProjectSelect so the user can choose another project when loading fails. Ensure
the form is not left unusable when fromCaseState exists but lockedProjectQuery
cannot resolve the project.
In `@apps/csm-portal/microapp/src/services/cases.ts`:
- Around line 293-313: The searchChildCases function only retrieves the first
CHILD_CASES_LIMIT records, so update it to accept pagination parameters and
return the resulting pagination metadata alongside mapped cases. Update the
Linked Items child-case consumer to use load-more or an infinite-query flow,
requesting subsequent offsets until all cases are available while preserving the
existing filters and row mapping.
🪄 Autofix
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 Plus
Run ID: a0f6b98a-dc23-4265-b742-a66bed6346aa
📒 Files selected for processing (7)
apps/csm-portal/microapp/src/components/case-detail/LinkCaseDialog.tsxapps/csm-portal/microapp/src/components/case-detail/LinkedItemsTab.tsxapps/csm-portal/microapp/src/pages/CaseDetailPage.tsxapps/csm-portal/microapp/src/pages/NewServiceRequestPage.tsxapps/csm-portal/microapp/src/services/cases.tsapps/csm-portal/microapp/src/types/case.dto.tsapps/csm-portal/microapp/src/types/case.model.ts
… lock Two CodeRabbit findings on PR wso2-open-operations#1394, both still valid: Child cases' count fell back to rows.length (0) on a search error, which tripped LinkedItemsSection's isEmpty check and rendered the generic "No child cases linked to this case." message instead of the actual error text sitting right there in children. count now stays undefined on error too, same as it already did while loading. NewServiceRequestPage locked the Project field whenever arriving with fromCaseState, with no way out if the project lookup itself failed — project stayed null and the field stayed disabled forever. It now only stays locked while that lookup hasn't errored, with an inline message telling the engineer to pick a project manually if it has. Left two other findings as-is: linked-service-request enrichment scoped to the parentId children search, and the 20-item cap on child cases with no pagination, both faithfully mirror the webapp's own useSearchChildCases / LinkedServiceRequestsWidget rather than being regressions introduced here.
Summary
relatedtab — the backend already returns child cases, linked service requests, and linked change requests on the case-detail response, but none of it was surfaced anywhere in the microapp.parentId-scoped case search (POST /cases/search { filters: { parentId } }) — the same underlying relationship both lists share, so the two queries dedupe against one cache entry. Rows are tappable, navigating straight to that case/change request.GET /change-requests/{id}(viauseQueries) using the ids the case-detail response already carries, so state/target-environment resolve independently per row without blocking the others.CreateServiceRequestFromCaseNavStatethrough toNewServiceRequestPage, so "Create service request" from a case locks the Project field, pre-seeds deployment/deployed product, and links the new request back to the originating case in the same create call — no separate create-then-link round trip.Test plan
tsc --noEmitandeslintpass clean across every touched/new file.relatedtab,useSearchChildCases,useQuickCaseSearch, andLinkCaseDialog.Summary by CodeRabbit