Batches E and F: flows, gates and system cards
6. Batch E — Flows (FlowLayout)
Section titled “6. Batch E — Flows (FlowLayout)”E1. Bulk import — tab bulk
Section titled “E1. Bulk import — tab bulk”- Route
/admin/bulk-import·panels/BulkImport.tsx,BulkImportHelpers.ts. - Job: add or update many items from a spreadsheet, safely (preview first).
- Reference: org3 (focused form), mgr2 (progress).
- Layout:
FlowLayout(page), steps:- Upload — a big drop zone (org3 logo drop style): “Drop a CSV or Excel file here, or choose a file” + “or paste a table” (expands the textarea). Advanced JSON is behind “Use JSON instead” (disclosure).
- Match columns — the mapping grid (today’s modal becomes the step body): each field ← column
select (“Don’t import”). Pre-filled by
suggestMapping. - Review — summary stat cards Create / Update / Warnings / Errors / Rows
[loaded from preview], then the row table with status pills; error rows first. The footer primary is disabled while errors exist (“Fix {n} errors to continue”). - Import — progress bar with “{processed} of {total} rows”, then a result summary and “View inventory →”.
footer: Back · primary “Preview” (step 2) / “Import {n} rows” (step 3). The file-job path (“Apply file job”) is chosen automatically for large files, so the user never picks between “Apply rows” and “Apply file job”.
- States: unreadable file: “We couldn’t read that file. Save it as CSV or .xlsx and try again.” · no rows: “That file has no rows.” · job failed: “The import stopped. Nothing after row {n} was saved.” (only if the API reports it; otherwise the job error text).
E2. QR tools (print batch builder) — tab qr
Section titled “E2. QR tools (print batch builder) — tab qr”- Route
/admin/qr-tools·panels/QrTools.tsx,QrImage.tsx. Moduleqr_print_batches. - Job: build a sheet of QR labels for items, units and boxes, then download them to print.
- Reference: mgr4 (date cards → batch cards), mgr3 (columns + dashed add).
- Layout:
ListLayout(batches) →DetailLayout(a batch) as the working surface. It is not a strict wizard, because users add labels in any order.- Index:
title“QR labels”,subtitle“Print labels for items, units and boxes.” · primary “New batch” · batch cards (title, “{n} labels”, created date). Today’s “Select a print batch” dropdown goes away. - Batch detail:
back“← All batches”,titlebatch title,meta“{n} labels”.actions: primary “Download all (ZIP)” (disabled at 0).bodyleft: “Add labels” card with a segmented control Item · Units · Reprint a unit (replaces three stacked forms), then fields + “Add to batch”.bodyright/below: label grid (QR image + label text), dashed “+ Add labels” tile when empty.
- Index:
- States: no batches: “No label batches yet. Start one to print QR labels.” · empty batch: “This batch is empty. Add an item, units or a box.” · item with no units: “This item has no individual units yet.”
E3. Create makerspace — inside Users (core page), superadmin
Section titled “E3. Create makerspace — inside Users (core page), superadmin”- Route
/admin/users(opened from the core Users page) ·usersModals/CreateMakerspaceModal.tsx,CreationWizardSteps.tsx. - Reference: org3 (form + live preview).
- Layout:
FlowLayout, page presentation via?create=makerspace(no route change). Today it is a modal with “Step 1 of 5” text.stepper: Identity · Profile & hours · Modules · First staff · Review.aside: live preview card (org3) showing space avatar tile, name,/m/{slug}, public code, and “Your catalogue will appear here”.- Identity: Name, Public code (4 chars, helper “Shown on labels and receipts”), Slug (prefix
…/m/), Location. - Profile & hours: Timezone, Country, Currency, hours editor. Helper “Leave as is to use the pack or deployment defaults.”
- Modules: Space pack picker, or “Choose modules myself” (switch) → module check-cards.
- First staff: Email (optional), Role.
- Review: key-value summary with “Edit” links per step.
footer: Cancel (text) · Back · Next / “Create makerspace”.
- States: validation inline per field (not one sentence for all of step 1).
E4. Tenant migration — tab migration (superadmin)
Section titled “E4. Tenant migration — tab migration (superadmin)”- Route
/admin/tenant-migration·TenantMigrationPanel.tsx,TenantMigrationDisclosure.tsx,TenantMigrationExports.tsx,TenantMigrationPairings.tsx,TenantMigrationImports.tsx,TenantMigrationIdentityDecisions.tsx. - Job: move one space from a managed deployment to a self-hosted one, irreversibly, in a safe order.
- Reference: mgr2’s door-station card (strong, staged controls) + org5 danger zone.
- Layout:
FlowLayout(page) with a visible, persistent stepper, because the order is the safety model. Steps (with the side each one runs on):- Review disclosure (source) — closure summary, identity list, acknowledgement checkbox, “Approve disclosure” / revoke.
- Pin deployments (both) — the pairing JSON fields, “Use this deployment’s identity”, “Pin pairing”.
- Encrypt export (source) — recipient key, “Create encrypted export”, job rows with “Download one-use archive”.
- Import & resolve (target) — archive + digest, “Start import”, per-person identity decisions.
- Verify & materialise (target) — verification stat cards (imported / resolved / dropped), “Materialise”.
- Cut over (both) — a danger zone card holding “Quiesce source”, “Archive source”, “Activate target”, “Abort target”, “Recover source”. Each one confirms by typing the space name.
aside: a status card per step (Not started / Done ✓ / Blocked: “needs step 2”).- Top callout (danger tint, replaces the red box): “This is one-way. Cut-over archives the source space; it isn’t deleted, and archives sit outside the purge guarantee.”
- States: pairings loading as skeleton; each step’s error stays inside its step.
E5. Password recovery — /reset-password
Section titled “E5. Password recovery — /reset-password”- Route
features/staff/ResetPasswordPage.tsx→auth/PasswordRecoveryFlow.tsx(code flow),auth/LegacyPasswordResetForm.tsx(uid/token link),auth/NewPasswordFields.tsx. - Reference: auth2 (set new password), auth3 (confirm card).
- Layout:
CenteredCardLayoutper step (a 3-step flow rendered as a sequence of centred cards, not asFlowLayout):- Request: icon tile (key) · “Reset your password” · “We’ll email you a code.” · Email · primary “Send code” · “Back to sign in”.
- Confirm: icon tile (mail) · “Check your email” · “We sent a code to {email}.” · Code · New password with strength meter + rule checks (auth2: “✓ At least 12 characters”) · Confirm · primary “Save new password” · secondary “Use a different email”.
- Success: icon tile (check) · “Password updated” · “You’ve been signed out on other devices.” · primary “Go to sign in”.
- Unavailable: icon tile (warn) · “Password reset isn’t available” · body from the server · “Back to sign in”.
- Legacy link: same as step 2 without the code field.
- Copy: never confirm whether an email exists (“If that address has an account, a code is on its way.”) — keep whatever the current flow guarantees.
7. Batch F — Gates and system cards (CenteredCardLayout)
Section titled “7. Batch F — Gates and system cards (CenteredCardLayout)”All of these use the same card: logo top-left, icon tile, title, body, one primary, one secondary.
| # | Screen | Component · trigger | Icon · title · body | Primary / secondary |
|---|---|---|---|---|
| F1 | Change-password gate | staff/ChangePasswordGate.tsx · must_change_password |
lock · “Set a new password” · “{username} is using a temporary password. Choose your own to continue.” · fields Current / New (meter + rules) / Confirm | Save new password / “Sign out” (text) |
| F2 | MFA challenge / enrol | auth/MfaFlow.tsx · login returns a challenge |
shield · Enrol: “Set up two-step sign-in” + QR (white tile) + “Can’t scan? Enter this key” (mono, Copy) · Verify: “Enter your 6-digit code” + “Use a recovery code instead” link · Codes: grid + Copy all / Download | Verify / “Back to sign in”; codes: I’ve saved my codes · footnote “This sign-in expires in {n} minutes.” |
| F3 | Access denied (single-tenant) | staff/StaffAccessDenied.tsx |
lock · “You don’t have access to {space}” · “This console is only for {space}’s team. Sign in with an account that’s a member here.” | Sign out / theme toggle moves to footer |
| F4 | Recovery quarantine (superadmin) | staff/RecoveryQuarantinePanel.tsx |
danger tile · eyebrow “Recovery quarantine” · “Staff access is paused” · reason · residual risk in a bordered danger box · confirm checkbox | Lift quarantine (danger pill, disabled until ticked) |
| F5 | Org invitation redeem | organizations/OrganizationInvitationRedeemPage.tsx · /organization-invitations/redeem/:token |
auth4: overlapping avatar tiles (org + you) · “You’ve been invited to join” · org name (if known) · scope pill · “This link works once.” · Not signed in: Username or email + Password + Sign in and continue · Redeemed: success state “You’re in” + Open organizations | footnote “Signed in as {user} · Switch account”. Owner decision: today redemption fires automatically once signed in. The UX spec asks for an explicit Accept invite click. Recommended (frontend-only: call the mutation on click), but it is a behaviour change. |
| F6 | 404 | AppRoutes.NotFoundPage |
compass · eyebrow “404” · “We couldn’t find that page” · “The link may be old, or the page moved.” | Go to home (/ or tenant home) / “Staff sign-in” (only on /admin*-like paths) |
| F7 | Session / route loading | StaffApp.StaffLoading, AppRoutes.RouteFallback |
logo + spinner · “Restoring your session…” / “Opening {space}…” | none. Keep these messages in a role=status region |
| F8 | No makerspace assigned | StaffTabContent Panel title="No makerspace" |
empty tile · “No space assigned yet” · “Ask a space manager to add you to their team.” | Sign out |
| F9 | Panel crashed | StaffPanelErrorBoundary |
in-page (not full-screen) danger-tinted empty card inside the current layout’s body · “This page couldn’t load” · “Something went wrong on our side. Reloading usually fixes it.” | Reload / “Report details” (copies the error id if one exists) |
| F10 | Tenant home unavailable | AppRoutes.FamilyHome error / no public programme |
public variant inside PublicLayout: “We couldn’t load this space” + Try again · “{Space} hasn’t published anything yet. Check back soon.” |
— |
Part of UX spec: long-tail screens (Space Works UX across all of SpaceWorks), published from docs/ux-screens-longtail.md. Edit it there.