Skip to content

[CSM Portal] validate call-request times client-side; enter local, store UTC - #1027

Merged
cloby99 merged 2 commits into
wso2-open-operations:v2from
rksk:csm-call-request-validation
Jul 3, 2026
Merged

[CSM Portal] validate call-request times client-side; enter local, store UTC#1027
cloby99 merged 2 commits into
wso2-open-operations:v2from
rksk:csm-call-request-validation

Conversation

@rksk

@rksk rksk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

Adds client-side validation to the call-request create dialog and fixes timezone handling for proposed call times.

Previously the time picker validated almost nothing: no lead-time or past-time check, duration only gated >= 1, an unbounded number of slots, no de-duplication, and a "(UTC)" label that contradicted the local-time datetime-local widget. Every mismatch round-tripped to the backend and surfaced as a generic 400 with no actionable message.

Changes

  • Per-severity minimum lead time. Each proposed slot must be at least the case severity's lead time in the future (S0 15m, S1 30m, S2 60m, S3 90m, S4 120m; 300m fallback), mirroring the backend rule. The picker min, per-slot error text, and the submit gate all enforce it. The case severity is threaded from the case detail page through the widget to the dialog.
  • Timezone correctness. Times are entered in the user's resolved timezone and stored/submitted as UTC, with a live per-slot UTC preview. Stored times now display back in the user's timezone. This also fixes a pre-existing display bug where an unzoned UTC value was parsed as local and reformatted as UTC, double-shifting the time for any non-UTC browser.
  • Contract-matching guards. Duration clamped to 15-240, slots capped at 3, times de-duplicated, past times blocked.
  • Shared util. New timezone-aware helpers (zonedInputToUtcIso, utcMsToZonedInputValue, plus an internal offset helper) added to utils/dateTime.ts.

Notes

  • The per-severity lead-time table is a hardcoded mirror of the backend rule (composed from the severity→priority and priority→offset maps). A code comment documents the source maps and one accepted lossiness: null-priority cases collapse to S3 upstream, so they are enforced at 90m here vs 300m at the backend (lenient direction — may still 400, never falsely blocks a valid time). Exposing this as a backend contract is a tracked follow-up.

Verification

pnpm build (tsc + vite) and pnpm lint pass. Timezone conversion validated across a DST boundary and round-trips.

Summary by CodeRabbit

  • New Features

    • Call request scheduling now respects case severity when validating lead time.
    • Preferred times and slot previews/hints are shown in the user’s local timezone.
  • Bug Fixes

    • Improved timezone-aware conversion for call request time slots, including daylight saving time handling.
    • Prevents submitting invalid, duplicate, out-of-range, or unacceptable time slots; enforces per-slot and duration limits.
    • Adds clearer slot-specific validation and range helper guidance in the request dialog.

…ore UTC

The call-request create dialog previously validated almost nothing on the time
picker: no lead-time or past-time check, duration only gated >=1, unbounded slot
count, no dedupe, and a "(UTC)" label that contradicted the local-time widget.
Every mismatch round-tripped to the backend and surfaced as a generic 400.

- Enforce per-severity minimum lead time on each proposed slot (S0 15m, S1 30m,
  S2 60m, S3 90m, S4 120m; 300m fallback), mirroring the backend rule.
- Enter times in the user's timezone and store/submit UTC; show a live UTC
  preview per slot. Fix display so stored UTC times render in the user's
  timezone (previously double-shifted for any non-UTC browser).
- Clamp duration to 15-240, cap slots at 3, de-duplicate times, block past times.
- Add timezone-aware helpers (zonedInputToUtcIso, utcMsToZonedInputValue) to
  utils/dateTime.
@rksk rksk added App/CSM Portal Area/Frontend Type/Improvement Marks enhancements or improvements to existing features labels Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b7a1e7fc-0a11-40b9-9029-869c43f8371a

📥 Commits

Reviewing files that changed from the base of the PR and between fa48ed3 and 5759203.

📒 Files selected for processing (1)
  • apps/csm-portal/webapp/src/utils/dateTime.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/csm-portal/webapp/src/utils/dateTime.ts

📝 Walkthrough

Walkthrough

Adds timezone conversion utilities, severity-driven lead-time and slot validation in the create call request dialog, wires an optional severity prop through CallRequestsWidget and CsmCaseDetailPage, and updates preferred-time display to use timezone-aware formatting.

Changes

Call request severity lead-time and timezone handling

Layer / File(s) Summary
Timezone conversion utilities
apps/csm-portal/webapp/src/utils/dateTime.ts
Adds timeZoneOffsetMs, and exported zonedInputToUtcIso/utcMsToZonedInputValue to convert between datetime-local values and UTC instants with DST correction.
Severity-driven lead-time and slot validation
apps/csm-portal/webapp/src/features/csm-cases/components/CreateCallRequestDialog.tsx
Adds duration/slot/lead-time constants, an optional severity prop, and reworks slot generation, dedupe, validation, and submit logic to enforce per-severity lead times and slot limits.
Severity prop wiring
apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx, apps/csm-portal/webapp/src/features/csm-cases/components/CallRequestsWidget.tsx
Passes case severity from the detail page through CallRequestsWidget into CreateCallRequestDialog.
Preferred time display formatting
apps/csm-portal/webapp/src/features/csm-cases/components/CallRequestRow.tsx
Replaces UTC-only Intl formatting with formatBackendTimestampForDisplay to render preferred times in the local timezone.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CreateCallRequestDialog
  participant zonedInputToUtcIso
  participant onSubmit

  User->>CreateCallRequestDialog: enter timeslot and duration
  CreateCallRequestDialog->>zonedInputToUtcIso: convert local slot to UTC ISO
  zonedInputToUtcIso-->>CreateCallRequestDialog: UTC instant
  CreateCallRequestDialog->>CreateCallRequestDialog: validate lead time by severity, dedupe, check duration
  User->>CreateCallRequestDialog: click submit
  CreateCallRequestDialog->>onSubmit: submit filtered utcTimes
Loading
sequenceDiagram
  participant CsmCaseDetailPage
  participant CallRequestsWidget
  participant CreateCallRequestDialog

  CsmCaseDetailPage->>CallRequestsWidget: severity={c.severity}
  CallRequestsWidget->>CreateCallRequestDialog: severity={severity}
Loading

Suggested labels: Type/Bug

Suggested reviewers: cloby99

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the feature but omits most required template sections like user stories, release note, docs, tests, and security checks. Add the missing template sections or mark them N/A where appropriate, including user stories, release note, documentation, tests, security, and test environment.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main client-side validation and timezone handling changes.
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

rksk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 3, 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.

Actionable comments posted: 1

🤖 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/webapp/src/utils/dateTime.ts`:
- Around line 227-237: The midnight normalization logic should stay in
timeZoneOffsetMs, but not in the formatter helpers. Update
utcMsToZonedInputValue and formatAbsoluteForUser so that when an hour value of
24 is encountered it rolls the date forward to the next day’s 00:00 instead of
forcing hour 0 on the same date; keep the existing timeZoneOffsetMs behavior
unchanged. Use the utcMsToZonedInputValue and formatAbsoluteForUser symbols to
locate the formatter-side adjustment.
🪄 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: b519cc39-b82f-4e28-b72f-6f2c087e4ddb

📥 Commits

Reviewing files that changed from the base of the PR and between 30518da and fa48ed3.

📒 Files selected for processing (5)
  • apps/csm-portal/webapp/src/features/csm-cases/components/CallRequestRow.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/CallRequestsWidget.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/CreateCallRequestDialog.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx
  • apps/csm-portal/webapp/src/utils/dateTime.ts

Comment thread apps/csm-portal/webapp/src/utils/dateTime.ts Outdated
Replace `hour12: false` + defensive `hour === 24 -> 0` handling with an explicit
`hourCycle: "h23"` in timeZoneOffsetMs, utcMsToZonedInputValue, and
formatAbsoluteForUser. h23 never emits "24", so the fragile midnight branch is
removed and the calendar date is always correct.
@rksk

rksk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@rksk

rksk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

1 similar comment
@rksk

rksk commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@cloby99
cloby99 merged commit a7b26b0 into wso2-open-operations:v2 Jul 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/CSM Portal Area/Frontend Platform/Web Type/Improvement Marks enhancements or improvements to existing features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants