Skip to content

[CSM Portal] collect Post Resolution Activity when closing or proposing a solution - #1094

Merged
Rashmika998 merged 3 commits into
wso2-open-operations:mainfrom
rksk:csm-case-resolution-dialog
Jul 8, 2026
Merged

[CSM Portal] collect Post Resolution Activity when closing or proposing a solution#1094
Rashmika998 merged 3 commits into
wso2-open-operations:mainfrom
rksk:csm-case-resolution-dialog

Conversation

@rksk

@rksk rksk commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Purpose

Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.

resolutionCode, cause, and closeNotes were added to the PATCH /cases/{id} contract at the API layer only — the entity-service and this repo's own openapi.yaml accept them, and the BFF handler passes them through as-is. But no UI was ever built to collect these from the user: closing a case or proposing a solution just fired a plain state-transition PATCH with none of the Post Resolution Activity (PRA) fields the product requirement (case resolution management) calls for.

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Collect resolution code, root cause, and optional close notes from the CS engineer before a case is closed or a solution is proposed, and send them in the same PATCH /cases/{id} call as the state transition.

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

  • New ResolutionDialog component: a resolution-code select and a cause select (both required, populated from the full backend enums), plus a free-text close-notes field (optional). Opens for both the "Close" and "Propose solution" actions.
  • CsmCaseDetailPage's action handler now intercepts close/propose_solution before the generic state-PATCH branch and opens this dialog instead of PATCHing immediately; submitting sends { state, resolutionCode, cause, closeNotes } in one call.
  • The dialog's own confirmation copy (customer-notification text) replaces CaseActionBar's old plain yes/no confirm for these two targets, so that now-unused confirm mechanism (ActionConfirm type, pendingConfirm state, its Dialog) is removed from CaseActionBar rather than left dead.
  • New caseResolution.ts util holds the two enum value lists plus a humanizeResolutionEnum helper (mirrors the existing humanizeState convention) so dropdown labels stay readable without a hand-maintained label map.
  • Extended BeCaseUpdatePayload's state variant with the three optional fields; no other request shapes change.

No API contract change — this only starts sending fields the backend has accepted since PR #1077.

User stories

Summary of user stories addressed by this change

As a CS engineer, when I close a case or propose a solution, I record the resolution code, root cause, and any closing notes as part of that action, instead of the case closing with no resolution record at all.

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Added: closing a case or proposing a solution now collects the Post Resolution Activity (resolution code, cause, close notes) before submitting.

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter "N/A" plus brief explanation of why there's no doc impact

N/A — internal case-detail UI behavior, not separately documented.

Automation tests

  • Unit tests

    Code coverage information

New ResolutionDialog.test.tsx covers: submit disabled until both required fields are chosen, correct payload shape on submit, and cancel behavior. Updated CaseActionBar.test.tsx for the removed confirm-dialog behavior on Close (confirmation now happens via the resolution dialog upstream, not inside CaseActionBar). pnpm build, pnpm test, and pnpm lint all pass (two pre-existing, unrelated test failures on origin/main persist unchanged).

  • Integration tests

    Details about the test cases and coverage

N/A — no integration test suite for this component.

Security checks

Samples

N/A

Related PRs

None

Migrations (if applicable)

N/A — no schema or data migration involved.

Test environment

Local: pnpm build + pnpm test + pnpm lint, on macOS.

Learning

N/A

Summary by CodeRabbit

  • New Features
    • Added a new case resolution dialog for closing cases or proposing solutions.
    • Users can now select a resolution code and root cause, and add optional closing notes.
    • Case actions now open the dialog flow and save the selected details with the case update.
    • Improved case action behavior so close/propose actions respond immediately and use the shared resolution flow.

…ng a solution

PRs wso2-open-operations#1074/wso2-open-operations#1077 added resolutionCode, cause, and closeNotes to
PATCH /cases/{id} at the API contract level (entity-service + BFF
openapi.yaml passthrough), but no UI was ever built to collect them —
Close and Propose Solution just fired a plain state PATCH.

Adds a ResolutionDialog (resolution code + cause selects, required;
free-text close notes, optional) that opens for both transitions
instead of the old plain yes/no confirm — it doubles as the
confirmation step, so CaseActionBar's now-unused confirm mechanism is
removed. Submitting PATCHes state + resolutionCode + cause +
closeNotes in one call, per the existing contract.
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR replaces the in-component confirmation dialog in CaseActionBar with a new ResolutionDialog component that collects resolution code, cause, and close notes before closing a case or proposing a solution. Backend types are extended, and CsmCaseDetailPage is updated to orchestrate the new dialog flow.

Changes

Case resolution dialog workflow

Layer / File(s) Summary
Backend closure metadata types
apps/csm-portal/webapp/src/api/backend/types.ts
Adds BeCaseResolutionCode and BeCaseCause unions and extends BeCaseUpdatePayload's state variant with optional resolutionCode, cause, and closeNotes fields.
Resolution enum display utilities
apps/csm-portal/webapp/src/features/csm-cases/utils/caseResolution.ts
Adds RESOLUTION_CODES, CASE_CAUSES arrays and humanizeResolutionEnum helper for formatting enum values.
ResolutionDialog component
apps/csm-portal/webapp/src/features/csm-cases/components/ResolutionDialog.tsx, ResolutionDialog.test.tsx
Implements a new dialog collecting resolutionCode, cause, and closeNotes with submit gating and callbacks; adds tests for enable/disable state, submit payload, and cancel behavior.
Remove CaseActionBar confirm gate
apps/csm-portal/webapp/src/features/csm-cases/components/CaseActionBar.tsx, CaseActionBar.test.tsx
Removes ActionConfirm type, confirm field, pendingConfirm state, and Dialog UI so lifecycle transitions dispatch onAction immediately; updates tests accordingly.
CsmCaseDetailPage resolution dialog wiring
apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx
Opens ResolutionDialog for close/propose_solution actions, PATCHes state with collected resolution fields via onResolutionSubmit, and renders the dialog conditionally.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CaseActionBar
    participant CsmCaseDetailPage
    participant ResolutionDialog
    participant BackendAPI

    User->>CaseActionBar: Click "Close" or "Propose Solution"
    CaseActionBar->>CsmCaseDetailPage: onAction(action, targetState)
    CsmCaseDetailPage->>CsmCaseDetailPage: setResolutionDialog(action, targetState)
    CsmCaseDetailPage->>ResolutionDialog: render with kind/isSubmitting
    User->>ResolutionDialog: select resolutionCode, cause, enter closeNotes
    User->>ResolutionDialog: click confirm
    ResolutionDialog->>CsmCaseDetailPage: onSubmit({resolutionCode, cause, closeNotes})
    CsmCaseDetailPage->>BackendAPI: PATCH case {state, resolutionCode, cause, closeNotes}
    BackendAPI-->>CsmCaseDetailPage: success/error
    CsmCaseDetailPage->>CsmCaseDetailPage: close dialog, show feedback/error
Loading

Possibly related PRs

Suggested labels: Type/New Feature

Suggested reviewers: cloby99

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: collecting post-resolution activity when closing or proposing a solution.
Description check ✅ Passed The description follows the template closely and provides substantive details for purpose, goals, approach, testing, and release notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

rksk added 2 commits July 8, 2026 19:34
…ialog

# Conflicts:
#	apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx
…ialog

# Conflicts:
#	apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx
@rksk

rksk commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@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.

🧹 Nitpick comments (1)
apps/csm-portal/webapp/src/api/backend/types.ts (1)

415-425: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider splitting the state branch to enforce the resolution-field constraint at the type level.

The comment on line 421 documents that resolutionCode, cause, and closeNotes are only accepted by the backend alongside state: "closed" or "solution_proposed", but the type allows them with any BeCaseState. This means TypeScript won't catch a payload like { state: "open", resolutionCode: "SOLVED_BY_CUSTOMER" } that the backend would reject. Splitting the branch — consistent with the ?: never pattern already used for severity, workState, etc. — would enforce the contract at compile time.

♻️ Proposed type refinement
 export type BeCaseUpdatePayload =
   | {
-      state: BeCaseState;
+      state: "closed" | "solution_proposed";
       severity?: never;
       workState?: never;
       assigneeEmail?: never;
       watchList?: never;
       /** Post Resolution Activity — only meaningful (and only accepted by the backend) alongside `state: "closed"` or `"solution_proposed"`. */
       resolutionCode?: BeCaseResolutionCode;
       cause?: BeCaseCause;
       closeNotes?: string;
     }
+  | {
+      state: Exclude<BeCaseState, "closed" | "solution_proposed">;
+      severity?: never;
+      workState?: never;
+      assigneeEmail?: never;
+      watchList?: never;
+      resolutionCode?: never;
+      cause?: never;
+      closeNotes?: never;
+    }
   | { state?: never; severity: BeCaseSeverity; workState?: never; assigneeEmail?: never; watchList?: never }
🤖 Prompt for 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.

In `@apps/csm-portal/webapp/src/api/backend/types.ts` around lines 415 - 425, The
`BeCase` payload union in `types.ts` currently allows `resolutionCode`, `cause`,
and `closeNotes` for any `BeCaseState`, even though they should only be valid
with `state: "closed"` or `"solution_proposed"`. Update the `state` branch in
the relevant type definition to split those cases at the type level, following
the existing `?: never` pattern used for `severity`, `workState`, and
`assigneeEmail`. Make sure the `resolutionCode`/`cause`/`closeNotes` fields are
only present in the allowed states so TypeScript rejects invalid combinations
like an open case with resolution fields.
🤖 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.

Nitpick comments:
In `@apps/csm-portal/webapp/src/api/backend/types.ts`:
- Around line 415-425: The `BeCase` payload union in `types.ts` currently allows
`resolutionCode`, `cause`, and `closeNotes` for any `BeCaseState`, even though
they should only be valid with `state: "closed"` or `"solution_proposed"`.
Update the `state` branch in the relevant type definition to split those cases
at the type level, following the existing `?: never` pattern used for
`severity`, `workState`, and `assigneeEmail`. Make sure the
`resolutionCode`/`cause`/`closeNotes` fields are only present in the allowed
states so TypeScript rejects invalid combinations like an open case with
resolution fields.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aa7a6dfd-260c-4ea0-a534-10632334036e

📥 Commits

Reviewing files that changed from the base of the PR and between a0f6918 and 9408403.

📒 Files selected for processing (7)
  • apps/csm-portal/webapp/src/api/backend/types.ts
  • apps/csm-portal/webapp/src/features/csm-cases/components/CaseActionBar.test.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/CaseActionBar.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/ResolutionDialog.test.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/ResolutionDialog.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/utils/caseResolution.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants