ApprovalQueue
The approval queue: status tabs with their counts, the number of results, an
actions slot, and the flows as a list or, through children, a table. It never
fetches; the caller passes useApprovalQueue's page.
import { ApprovalQueue } from "@evolve-storefront/feature-organization/approval/queue";Renders inside OrganizationProvider.
Preview
Usage
The pending tab as cards. Approve and reject show only where viewerCanDecide
holds, so the buyer's own order has none.
const { data } = useApprovalQueue({ status: "PENDING" });
<ApprovalQueue approvals={data?.items} pagination={data?.pagination} renderItem={(approval) => ( <ApprovalQueueItem approval={approval} actions={<ApproveRejectActions approval={approval} />} /> )}/>;Props
| Prop | Type | Description |
|---|---|---|
approvals? | OrderApproval[] | One page of the queue for |
pagination? | Pagination | The page's |
activeState? | ApprovalStatus | The status tab currently shown. |
onStateChange? | ((state: ApprovalStatus) => void) | Shows the status tabs, and reports the one chosen. |
counts? | Partial<Record<ApprovalStatus, number>> | null | Per-status counts for the tab labels: |
actions? | ReactNode | Beside the tabs, such as a link to manage the approval rules. |
renderItem? | ApprovalQueueItemRenderer<OrderApproval> | Renders each flow; required for the default list, ignored with children. |
empty? | ReactNode | Custom empty state for the default composition. |
children? | ReactNode | Replaces the default list, such as with an |
Any other props go to the root element, like on a plain HTML element.
Change the layout
Pass children to ApprovalQueue to arrange its parts yourself. Every part is exported from @evolve-storefront/feature-organization/approval/queue.
const mine = data.items.filter((approval) => approval.viewerCanDecide);const others = data.items.filter((approval) => !approval.viewerCanDecide);
<ApprovalQueue pagination={data.pagination}> <h2>{t("waiting-for-you")}</h2> <ApprovalQueueItems approvals={mine} renderItem={renderItem} /> <h2>{t("waiting-on-others")}</h2> <ApprovalQueueItems approvals={others} renderItem={renderItem} /></ApprovalQueue>;ApprovalQueueItemOne flow in the queue as a card: order, who placed it and when, total, status, and who decided it, or "the seller" where no associate did.
| Prop | Type | Description |
|---|---|---|
approval | OrderApproval | |
actions? | ReactNode | Approve/reject actions, composed by the caller (usually |
Any other props go to the root element, like on a plain HTML element.
ApprovalQueueItemsThe queue as a list, rendering the empty state itself when the page is empty.
| Prop | Type | Description |
|---|---|---|
approvals | OrderApproval[] | One page of the queue. An explicit prop so |
renderItem | ApprovalQueueItemRenderer<OrderApproval> | Renders each flow. Required: the feature owns no row markup. |
empty? | ReactNode | Custom empty state. Defaults to |
Any other props go to the root element, like on a plain HTML element.
ApprovalQueueResultCount"12 results": how many orders the active tab holds.
| Prop | Type | Description |
|---|---|---|
pagination? | Pagination | The queue query's |
Any other props go to the root element, like on a plain HTML element.
Loading and empty states
Render these while the data loads or when there is nothing to show, so the page does not jump when it arrives.
| Empty | ApprovalQueueEmpty | Empty state for the approval queue (no orders in the active state). |
Examples
Decided By SellerA decided flow says who decided it.
// Nothing to pass: a decision without an approver reads "Approved by the seller".<ApprovalQueueItem approval={approval} />;As TableThe queue as a table, with a link to manage the rules beside the tabs.
<ApprovalQueue activeState={status} onStateChange={setStatus} counts={data?.counts} pagination={data?.pagination} actions={<Link href="/account/approval-rules">{t("manage-rules")}</Link>}> <ApprovalTable approvals={data?.items ?? []} pagination={data?.pagination} renderOrderLink={(approval, props) => ( <Link href={`/account/orders/${approval.order.orderNumber}`} {...props} /> )} /></ApprovalQueue>;Without OrderA flow can have no order: on some engines the approval comes before the order is placed, and on others the order was deleted.
// Nothing to pass: a flow whose order is null renders from its own status.<ApprovalQueueItem approval={approval} actions={<ApproveRejectActions approval={approval} />} />;Approve From The QueueConnected to the mock gateway: approving a flow sends its version, and the queue and every count are read again, so it leaves the pending tab.
const [status, setStatus] = useState<ApprovalStatus>("PENDING");const { data } = useApprovalQueue({ status });
<ApprovalQueue approvals={data?.items} pagination={data?.pagination} counts={data?.counts} activeState={status} onStateChange={setStatus} renderItem={renderItem}/>;
