Dashral Pro is on the wayGet 30% off at launch

Dashral

Approval workflowPro

A purchase request going round its approvers one at a time: a chip carries it from person to person, a ring fills round each avatar as they review and turns green as they approve; Finance sometimes sends it back in amber to be updated, Legal is only asked above $10k, and the purchase order goes out at the end. Pauses, and stacks on phones.

When to use

  • A request going round its approvers one at a time, approved or sent back, with its order number.
  • Procurement, expense and approval products; a live view of requests in review.

When not to use

  • Requests one person approves: a button and a status are enough.
  • Working through the queue itself: a table of requests with their stage.

Usage

Approval workflow with your own data: every prop has the sample as its default, so pass only what you have.

example.tsx
import { useEffect, useRef } from "react"
import { ApprovalWorkflow, type WorkflowHandle } from "@/components/dashral/blocks/approval-workflow"

const workflow = useRef<WorkflowHandle>(null)
useEffect(() => requests.on("submitted", (r) => workflow.current?.send(r)), [])

<ApprovalWorkflow ref={workflow} mode="live" approvers={approvers} onDone={(request) => api.requests.close(request)} />

API reference

ApprovalWorkflow

The section: a heading, the workflow in a dotted panel with a Live badge and Pause, and a row of figures. Every part comes from props, with a sample workflow by default.

PropTypeDefault
eyebrowReact.ReactNode"Approvals"
titleReact.ReactNodesample
descriptionReact.ReactNodesample
approversPerson[]

Who approves, in order; the last is only asked above threshold.

sample
thresholdnumber10_000
requestsRequest[]

The sample requests the demo plays, and the first purchase order number.

sample
firstOrdernumber2041
stats{ value: string; label: string }[]

The figures under the diagram; none hides the row.

sample
modeWorkflowProps["mode"]

With your own requests instead of the sample ones (see Workflow's mode="live").

—
onDoneWorkflowProps["onDone"]—
refReact.Ref<WorkflowHandle>—

Workflow

A request going round for approval, one at a time: a chip carries it from the requester to each approver in turn; each reviews it (a ring fills round their avatar) and approves, green; Finance sometimes asks for changes, amber, and it goes back to the requester to be updated before coming round again; the last approver is only asked above a threshold, faded otherwise; then the purchase order goes out. In a row when there's room, stacked on a narrow container. One requestAnimationFrame loop writes everything directly. The sample requests in a loop by default; with mode="live", the ones you send (see WorkflowHandle). It stops off screen, in a hidden tab, when paused and (live) once the last request is approved; with reduced motion it shows a request approved.

PropTypeDefault
requestsRequest[]

The sample requests, played in a loop ("demo").

sample
approversPerson[]

Required. Who approves, in order. The last is only asked above threshold.

—
thresholdnumber

Required.

—
firstOrdernumber

Required. The first purchase order number; it goes up with every approved request.

—
speednumber

How fast it runs: 1 is the usual pace, 2 twice as fast, 0 holds it still.

1
pausedboolean

Brings it to rest where it is (easing down, not stopping in one frame).

false
onDone(request: Request, order: number) => void

Live: called as each request's purchase order goes out, with its number.

—
mode"demo" | "live"

"demo" plays the sample requests in a loop; "live" plays a request only when you send it (see WorkflowHandle).

"demo"
refReact.Ref<WorkflowHandle>—
classNamestring—

type Person

PropTypeDefault
namestring—
rolestring—
srcstring—

type Request

A request going round for approval: what it's for, how much, and whether Finance sends it back once.

PropTypeDefault
titlestring—
amountnumber—
requesterPerson—
changesboolean—

type WorkflowHandle

Plays your own requests (mode="live").

PropTypeDefault
send(request: Request) => void

Plays one request round its approvers (the last only above threshold; with changes, Finance sends it back once), then out as a purchase order. Requests sent while one plays wait their turn; the last stays approved until the next. Off screen, in a hidden tab or with reduced motion it shows approved at once.

—