Skip to content

RR-T48 Location Fix, Hold to Confirm, Close Call Fix - #155

Merged
ucswift merged 2 commits into
masterfrom
develop
Oct 7, 2026
Merged

ucswift merged 2 commits into
masterfrom
develop

Conversation

@ucswift

@ucswift ucswift commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Pull Request Summary

This PR improves call closure, personnel status progression, and push notification handling.

Call closure updates

  • Adds an optional sendNotification flag to the close-call API request.
  • The close-call sheet now notifies everyone associated with the call by default, including dispatched personnel, groups, roles, units, and incident command.
  • Adds a switch allowing users to disable the notification before closing the call.
  • Resets the notification preference when the sheet is cancelled.
  • Displays a server-provided refusal reason when a call cannot be closed, such as when an incident command is still active.
  • Preserves the existing generic error fallback for network, timeout, rate-limit, server, empty, HTML, or otherwise unusable error responses.
  • Adds coverage for request payloads, notification behavior, refusal handling, and response propagation.

Personnel status flow improvements

  • Status pickers now use each status’s NextIds configuration to show only valid next statuses by default.
  • Adds a “Show all statuses” option when the list is restricted, with a way to return to the next-status view.
  • Keeps the current status visible and clearly marked with a red outline and current-status label.
  • Resolves the current status using the server status ID first, with text-based fallback for older payloads.
  • Falls back to showing all statuses if the current status is unknown or its configured next statuses are unavailable.
  • Applies the same flow behavior in both the Home status buttons and the personnel status bottom sheet.
  • Adds the NextIds status model field and shared status-flow helpers.

Hold-to-confirm status setting

  • Supports the department StatusHoldToConfirm configuration.
  • In hold mode, status options require a two-second press and hold instead of a tap.
  • Adds visual progress feedback, countdown, animation, completion confirmation, and a fingerprint indicator.
  • A quick tap displays guidance explaining that the user must press and hold.
  • Supports accessibility activation as an alternative to the timed hold.
  • Automatically submits statuses when no additional input is required.
  • Uses the active or default call when a call destination can be filled automatically.
  • Moves to the destination or required-note step when additional information is needed.
  • Prevents duplicate submissions while a status update is already in progress.

Push notification parsing

  • Adds support for NC:{callId} notifications indicating that a call has been closed.
  • Supports legacy colon-less C{callId} call codes and M{messageId} message codes.
  • Prevents multi-letter codes such as CT123 from being incorrectly interpreted as call notifications.
  • Preserves existing single-letter call-code behavior.

Validation

  • Adds unit and component tests covering call closure, server error extraction, status flow selection, hold-to-confirm behavior, status submission, current-status presentation, and push notification parsing.

@Resgrid-Bot

This comment has been minimized.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review paused — included plan limit reached

Keep your review moving with free on-demand reviews.

  • Run this review for free

On-demand reviews are free for the next 3 days.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Promotion and pricing details

On-demand reviews are free for the next 3 days. After that, they cost $0.25 per reviewed file.

Review limit details

Or wait 4 minutes for your next included review.

Check out review usage here.

Limit details: You’ve used all 3 included reviews currently available. Your 42 included PR review attempts over the past 7 days set your current allowance at 3 reviews per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 68450f68-8764-48e7-91fe-47e454203131
📥 Commits

Reviewing files that changed from the base of the PR and between af76734 and 73d95c6.

📒 Files selected for processing (2)
  • src/components/home/status-buttons.tsx
  • src/components/status/personnel-status-bottom-sheet.tsx

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 2e2f6245-01b4-4a34-96d0-c28f866bfff2
📥 Commits

Reviewing files that changed from the base of the PR and between 3d65c66 and af76734.

📒 Files selected for processing (33)
  • __mocks__/lucide-react-native.ts
  • src/api/calls/__tests__/closeCall.test.ts
  • src/api/calls/calls.ts
  • src/components/calls/__tests__/close-call-bottom-sheet.test.tsx
  • src/components/calls/close-call-bottom-sheet.tsx
  • src/components/home/__tests__/status-buttons.test.tsx
  • src/components/home/status-buttons.tsx
  • src/components/status/__tests__/hold-to-confirm-button.test.tsx
  • src/components/status/hold-to-confirm-button.tsx
  • src/components/status/personnel-status-bottom-sheet.tsx
  • src/lib/__tests__/call-close.test.ts
  • src/lib/__tests__/status-flow.test.ts
  • src/lib/call-close.ts
  • src/lib/status-flow.ts
  • src/models/v4/configs/getConfigResultData.ts
  • src/models/v4/statuses/statusesResultData.ts
  • src/stores/calls/__tests__/detail-store.test.ts
  • src/stores/calls/detail-store.ts
  • src/stores/push-notification/__tests__/call-closed-parsing.test.ts
  • src/stores/push-notification/__tests__/store.test.ts
  • src/stores/push-notification/store.ts
  • src/stores/status/__tests__/personnel-status-store.test.ts
  • src/stores/status/personnel-status-store.ts
  • src/translations/ar.json
  • src/translations/de.json
  • src/translations/el.json
  • src/translations/en.json
  • src/translations/es.json
  • src/translations/fr.json
  • src/translations/it.json
  • src/translations/pl.json
  • src/translations/sv.json
  • src/translations/uk.json

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour. Your free on-demand review promotion remains active until October 9, 2026 at 6:00 PM UTC.


📝 Walkthrough

Walkthrough

The pull request adds call-close notification controls and server error-message handling. It adds configurable status filtering and hold-to-confirm interactions for personnel status changes. It also expands push-notification event-code parsing.

Changes

Call closure

Layer / File(s) Summary
Close-call notification request
src/api/calls/calls.ts, src/api/calls/__tests__/closeCall.test.ts
CloseCallRequest accepts an optional notification choice. closeCall includes SendNotification when the choice is set and omits it when unset.
Close sheet and failure messages
src/components/calls/close-call-bottom-sheet.tsx, src/components/calls/__tests__/close-call-bottom-sheet.test.tsx, src/lib/call-close.ts, src/lib/__tests__/call-close.test.ts, src/stores/calls/detail-store.ts, src/stores/calls/__tests__/detail-store.test.ts, src/translations/*.json
The close sheet defaults the notification toggle to on and resets it when closed. The sheet and call store display a parsed server reason when available. Translation strings and tests cover the added controls and error handling.

Personnel status flow

Layer / File(s) Summary
Status-flow rules and data
src/lib/status-flow.ts, src/lib/__tests__/status-flow.test.ts, src/models/v4/configs/getConfigResultData.ts, src/models/v4/statuses/statusesResultData.ts
Status data adds NextIds and configuration adds StatusHoldToConfirm. Shared helpers resolve the current status, filter offered statuses, and determine whether a status can be submitted without more input.
Hold-to-confirm button
src/components/status/hold-to-confirm-button.tsx, src/components/status/__tests__/hold-to-confirm-button.test.tsx, __mocks__/lucide-react-native.ts
The new button supports timed holds, early-release taps, accessibility activation, disabled input, countdown display, and a completion state. Tests cover the interaction and timing behavior.
Held status submission
src/stores/status/personnel-status-store.ts, src/stores/status/__tests__/personnel-status-store.test.ts
The store adds confirmHeldStatus. It submits when the status needs no more input, uses a default call where applicable, and otherwise advances to a required input step.
Home status controls
src/components/home/status-buttons.tsx, src/components/home/__tests__/status-buttons.test.tsx
Home controls show offered statuses, identify the current status, and allow users to expand the list. In hold mode, confirming a held status opens the sheet and calls the store action.
Personnel status sheet
src/components/status/personnel-status-bottom-sheet.tsx, src/translations/*.json
The sheet filters and marks status choices, supports hold-to-confirm selection and final-step submission, and displays hold guidance and submission errors. Translations add the related status labels and instructions.

Push notification parsing

Layer / File(s) Summary
Notification event-code parsing
src/stores/push-notification/store.ts, src/stores/push-notification/__tests__/*
The parser recognizes the nc prefix as a call and accepts colon-less event codes with one letter followed by a numeric ID. Tests cover recognized and unknown forms.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant HoldToConfirmButton
  participant StatusButtons
  participant PersonnelStatusStore
  User->>HoldToConfirmButton: Hold a status button
  HoldToConfirmButton->>StatusButtons: Confirm held status
  StatusButtons->>PersonnelStatusStore: Call confirmHeldStatus with selected status
Loading

Merge Risk: ⚪ Minimal · up to af767

The identified timer and held-status concerns do not block the intended interactions. The PR is mergeable after normal checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
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.
Title check ✅ Passed The title names two major changes: hold-to-confirm status controls and close-call updates. It is concise and related to the pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Comment thread src/components/home/status-buttons.tsx Outdated
<HoldToConfirmButton
key={status.Id}
testID={`status-hold-button-${status.Id}`}
onConfirm={() => handleStatusHold(status)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

Per-render function allocation occurs when .bind() or inline arrow functions are used in JSX props, impacting performance; this affects src/components/home/status-buttons.tsx:94-94, 115-115, 125-125, and 129-129, plus src/components/status/personnel-status-bottom-sheet.tsx:582-583, 607-607, 655-656, 742-742, and 746-746. Move these function definitions outside the render method.

Kody rule violation: Avoid using .bind() or arrow functions in JSX props

Prompt for LLM

File src/components/home/status-buttons.tsx:

Line 93:

Per-render function allocation occurs when `.bind()` or inline arrow functions are used in JSX props, impacting performance; this affects `src/components/home/status-buttons.tsx:94-94`, `115-115`, `125-125`, and `129-129`, plus `src/components/status/personnel-status-bottom-sheet.tsx:582-583`, `607-607`, `655-656`, `742-742`, and `746-746`. Move these function definitions outside the render method.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

Comment thread src/components/home/status-buttons.tsx Outdated
const handleStatusHold = (statusData: StatusesResultData) => {
// The sheet opens on the status and saves it at once, or stays on the step that still needs the member.
setIsOpen(true, statusData);
void confirmHeldStatus?.(statusData);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

Unhandled promise rejections can occur when confirmHeldStatus rejects without a catch handler, including at src/components/home/status-buttons.tsx, src/components/status/personnel-status-bottom-sheet.tsx:308-308, 655-655, src/stores/status/personnel-status-store.ts:573-573, src/stores/status/__tests__/personnel-status-store.test.ts:1826-1827, 1846-1846, 1854-1854, 1860-1860, 1868-1868, and 1877-1878, src/api/calls/__tests__/closeCall.test.ts:20-20, 23-23, and 28-28, and src/components/calls/__tests__/close-call-bottom-sheet.test.tsx:380-380 and 403-403. Attach a catch handler to the promise returned by confirmHeldStatus and pass the error and statusData.Id to handleConfirmError.

Kody rule violation: Handle async operations with proper error handling

void confirmHeldStatus?.(statusData).catch((error) => handleConfirmError(error, statusData.Id));
Prompt for LLM

File src/components/home/status-buttons.tsx:

Line 57:

Unhandled promise rejections can occur when `confirmHeldStatus` rejects without a catch handler, including at `src/components/home/status-buttons.tsx`, `src/components/status/personnel-status-bottom-sheet.tsx:308-308`, `655-655`, `src/stores/status/personnel-status-store.ts:573-573`, `src/stores/status/__tests__/personnel-status-store.test.ts:1826-1827`, `1846-1846`, `1854-1854`, `1860-1860`, `1868-1868`, and `1877-1878`, `src/api/calls/__tests__/closeCall.test.ts:20-20`, `23-23`, and `28-28`, and `src/components/calls/__tests__/close-call-bottom-sheet.test.tsx:380-380` and `403-403`. Attach a catch handler to the promise returned by `confirmHeldStatus` and pass the error and `statusData.Id` to `handleConfirmError`.

Suggested Code:

void confirmHeldStatus?.(statusData).catch((error) => handleConfirmError(error, statusData.Id));

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

statusDetail: status.Detail,
});
} catch (error) {
console.warn('Failed to track status hold analytics:', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

Message-only console warnings from status hold analytics tracking omit the operation name, status identifier, and error object. Emit a structured warning through logger.warn with op: 'trackStatusHold', statusId: status.Id, and err: error.

Kody rule violation: Include error context in structured logs

logger.warn('status hold analytics tracking failed', { op: 'trackStatusHold', statusId: status.Id, err: error });
Prompt for LLM

File src/components/status/personnel-status-bottom-sheet.tsx:

Line 304:

Message-only console warnings from status hold analytics tracking omit the operation name, status identifier, and error object. Emit a structured warning through `logger.warn` with `op: 'trackStatusHold'`, `statusId: status.Id`, and `err: error`.

Suggested Code:

      logger.warn('status hold analytics tracking failed', { op: 'trackStatusHold', statusId: status.Id, err: error });

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

Comment thread src/lib/status-flow.ts
}

const current = all.find((status) => toId(status.Id) === currentStatusId);
const nextIds = new Set((current?.NextIds ?? []).map((id) => toId(id)).filter((id) => id !== '' && id !== '0'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug high

Invalid status filtering causes getOfferedStatuses to discard next-status ID "0", so a transition such as NextIds: [0] produces an empty offered set and incorrectly falls back to showing every status instead of only status 0. Remove the id !== '0' filter, retain the empty-ID guard, and handle the separate unknown-status/"0 means Unknown" ambiguity in current-status resolution.

const nextIds = new Set((current?.NextIds ?? []).map((id) => toId(id)).filter((id) => id !== ''));
Prompt for LLM

File src/lib/status-flow.ts:

Line 88:

Invalid status filtering causes getOfferedStatuses to discard next-status ID "0", so a transition such as NextIds: [0] produces an empty offered set and incorrectly falls back to showing every status instead of only status 0. Remove the `id !== '0'` filter, retain the empty-ID guard, and handle the separate unknown-status/"0 means Unknown" ambiguity in current-status resolution.

Suggested Code:

const nextIds = new Set((current?.NextIds ?? []).map((id) => toId(id)).filter((id) => id !== ''));

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

@Resgrid-Bot

Resgrid-Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug ✅
Performance ❌
Security ✅
Business Logic ❌

Access your configuration settings here.

​

(statusData: StatusesResultData) => {
// The sheet opens on the status and saves it at once, or stays on the step that still needs the member.
setIsOpen(true, statusData);
void confirmHeldStatus?.(statusData);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

Unhandled promise rejections occur when confirmHeldStatus returns a rejected promise that void does not handle, including at src/components/status/personnel-status-bottom-sheet.tsx:401 and :540. Attach .catch() to capture or log each status confirmation failure with operation context.

Kody rule violation: Handle async operations with proper error handling

confirmHeldStatus?.(statusData).catch((error) => {
  // handle or log the failure with operation context
});
Prompt for LLM

File src/components/home/status-buttons.tsx:

Line 124:

Unhandled promise rejections occur when `confirmHeldStatus` returns a rejected promise that `void` does not handle, including at `src/components/status/personnel-status-bottom-sheet.tsx:401` and `:540`. Attach `.catch()` to capture or log each status confirmation failure with operation context.

Suggested Code:

confirmHeldStatus?.(statusData).catch((error) => {
  // handle or log the failure with operation context
});

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

statusDetail: status.Detail,
});
} catch (error) {
console.warn('Failed to track status option analytics:', error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

Insufficient error context occurs when src/components/status/personnel-status-bottom-sheet.tsx:397 logs only a message and raw error, making failures difficult to correlate with the selected status. Include operation: 'trackStatusOptionSelected' and statusId: status.Id as structured fields in the error log.

Kody rule violation: Include error context in structured logs

console.warn('Status option analytics failed', { operation: 'trackStatusOptionSelected', statusId: status.Id, error });
Prompt for LLM

File src/components/status/personnel-status-bottom-sheet.tsx:

Line 368:

Insufficient error context occurs when `src/components/status/personnel-status-bottom-sheet.tsx:397` logs only a message and raw `error`, making failures difficult to correlate with the selected status. Include `operation: 'trackStatusOptionSelected'` and `statusId: status.Id` as structured fields in the error log.

Suggested Code:

console.warn('Status option analytics failed', { operation: 'trackStatusOptionSelected', statusId: status.Id, error });

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

@ucswift

ucswift commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Approve

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is approved.

@ucswift
ucswift merged commit 5f7742e into master Oct 7, 2026
13 of 14 checks 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