Pattern: RF task queue
Who uses it: a warehouse floor worker after picking a
task from the RF task menu
— "what's next" for that task type. What "done" looks like:
the worker reads top-to-bottom, taps the task at the top, and starts
working it — no cross-referencing between columns. The task is a plain
link and the line box makes it a 128×42px target at spacious
density, so it takes a gloved thumb without a button's padding pushing
the Status column off a 320px screen (measured, roadmap 135.3b). Not for editing a
line's data on this screen — see Editable, refused
below. Composed from .bo-data-table at
data-density="spacious", two narrow columns — the SAME
component and profile membership Goods
receipt's own receiving log already proves at 360px (roadmap 59.4);
this page is a second, task-queue-shaped use of that same proof, not a
new claim about the component.
The screen — try it
Shown the way the scanner gets it: the rf-essentials
profile (Chrome/WebView 108) only, at 360×640, in an isolated
document. No profile change was needed for this page:
data-table was already a member. One screen, not two — this
page rendered the same component a second time at desktop width until
roadmap 135.2.
Markup
<div class="bo-data-table-container" tabindex="0" data-density="spacious">
<table class="bo-data-table">
<thead><tr><th scope="col">Task</th><th scope="col">Status</th></tr></thead>
<tbody>
<tr><td>PO-88213 · Dock 4</td><td><span class="bo-badge bo-badge--accent">Next</span></td></tr>
<!-- one row per queued task -->
</tbody>
</table>
</div> Anatomy
- Queue table —
.bo-data-tableat spacious density, two columns: identifying label, status. - Next-up row — the top row carries a distinct
.bo-badge--accentstatus, the row a worker taps first. - Row tap target (not in this demo — a real screen wraps each row in a link/button so the whole row is tappable, not just the text).
Data contract
| Request | Returns / on failure |
|---|---|
| GET /rf/tasks/:type | the ordered queue, next-up first; 204 for an empty queue |
| POST /rf/tasks/:id/claim | marks the task in-progress and returns the detail screen route; 409 if another worker already claimed it — re-render the queue, don't just retry |
States
| State | What ships |
|---|---|
| Loading | a skeleton row set at the same spacious row height, so the tap targets don't jump once data lands |
| Empty — nothing queued | "All caught up" text plus a link back to the task menu, not a bare blank table |
| Empty — filtered out | N/A on this screen — the queue has no filter control; filtering happens by picking a different task type from the menu |
| Claim conflict (409) | the row is removed from this worker's queue with a brief alert; no destructive retry |
| Session lost | the reconnect state: the queue re-renders as the server has it, and a claim attempted while the link was down is simply retried — claiming is idempotent server-side (the 409 row above). Offline caching is infrastructure, not a screen promise |
| No JS | fully functional — this page has no JS dependency; the demo has no button or script wired to it at all, and it imports no @busy-office/ui/js behavior |
Editable, refused
An editable variant of this list — letting a worker change quantity or status inline in the grid — was grilled and refused (roadmap 109.7): RF data correction is a one-field-at-a-time scan flow (barcode, then quantity, then confirm — see Goods receipt), not grid editing with gloves on a 360px screen. A generic editable grid composes for desktop entry; it does not compose for RF, and forcing it to would be the RF track absorbing the app catalogue's shape instead of its own (109.6's founding rule).
Components used
complexity 1 of 4