Approval Action Bottom Sheet
Component Detail
Description
Modal bottom sheet presented when a coordinator reviews an individual claim. Provides approve and reject actions with an optional freetext comment field. Validates that rejection includes a reason and confirms irreversible state transitions before submitting.
approval-action-sheet
Summaries
The Approval Action Bottom Sheet is the decision interface that coordinators use to approve or reject individual expense claims. It ensures that every approval decision is deliberate and documented — rejection requires a written reason, and irreversible state changes require explicit confirmation before submission. This enforces accountability in the approval process, reducing disputes between employees and coordinators by creating a clear audit trail of decisions and the reasoning behind them. By building the comment requirement and confirmation step directly into the interface, the organization reduces the risk of accidental rejections and ensures compliance with internal expense policy without relying on coordinators to remember procedural steps.
This medium-complexity component has a single upstream dependency on approval-workflow-service, making it relatively straightforward to integrate once that service is stable. The primary delivery risk lies in the validation and confirmation logic: rejection without a comment must be blocked at the UI layer, and the confirmation dialog for irreversible transitions must be robust against rapid repeated taps (double-submit prevention). Testing requirements include: approve with and without comment, reject with valid comment, reject with empty comment (should be blocked), confirmation dialog cancel flow, and network error handling when the service call fails. The component is used exclusively from coordinator-review-queue-screen's single-claim detail path, so its interface contract is narrow and changes are isolated.
Allow time for UX review of the bottom sheet animation and comment field keyboard behavior on both iOS and Android.
Implemented as a modal bottom sheet (showModalBottomSheet in Flutter or equivalent) with internal form state managing the comment TextField and the selected action (approve/reject). validateComment() enforces that action === 'reject' requires a non-empty, non-whitespace comment string, returning a validation error displayed inline below the field. showConfirmationDialog() renders a platform-adaptive AlertDialog confirming the irreversible nature of the transition before delegating to onApprove() or onReject(). Both action handlers call approval-workflow-service with the claimId and trimmed comment string; the sheet dismisses on success and propagates errors to the caller via a result callback or exception.
Double-submit prevention requires disabling the action buttons during the async service call and re-enabling on error. The component is stateless with respect to claim data — it receives claimId on show() and does not fetch claim details internally, keeping it decoupled from the data layer.
Responsibilities
- Present approve and reject action buttons
- Capture optional coordinator comment
- Enforce comment requirement on rejection
- Confirm and submit coordinator decision
Interfaces
show(claimId)
dismiss()
onApprove(claimId, comment)
onReject(claimId, comment)
validateComment(action, comment)
showConfirmationDialog(action)
Relationships
Related Data Entities (2)
Data entities managed by this component