10 — Interaction Specification (Users Module)
- 1. Touch gestures (phone/tablet)
- 2. Desktop/web (mouse + keyboard)
- 3. Haptics (mobile)
- 4. Motion language
- 5. Micro-interactions
- 6. Import progress interaction (long-running)
- 7. Frustration controls
Module-specific interactions on top of 00-shared/08_Interaction_&_Motion.md. Tokens
m-*per 00-shared/02 §6; all durations/curves from there.
1. Touch gestures (phone/tablet)
| Gesture | Behaviour | Where |
|---|---|---|
| Tap row | Navigate to detail (phone) / select in pane (≥ 840 dp); ripple m-fast | Users list |
| Long-press row | AppMenu: View · Edit · Deactivate/Activate · Delete · GDPR erase | List rows |
| Swipe left (row) | Reveal ≤ 2 actions: Deactivate, Delete (00-shared/08 §1, keep ≤ 2) | List rows (phone) |
| Pull down | Refresh list (resets to page 1, bypasses cache) | List |
| Tap FAB | New user (scale-in m-entrance; hide on scroll-down) | List |
| Back gesture | Pop; from detail → list (state preserved) | All |
2. Desktop/web (mouse + keyboard)
| Input | Behaviour |
|---|---|
| Hover row | 2% surface darken + tooltip on status badge (m-fast) |
| Right-click row | Same context menu as long-press |
Ctrl+K | Global search (shell-level) |
N | New user (list focused, no input focused) |
I | Import CSV (list focused) |
/ | Focus search field |
Esc | Close dialog/sheet/menu; from search → clear + unfocus |
Enter | Submit focused form; in dialogs = primary action (typed confirms require typing first) |
| Arrow keys | Navigate list rows (desktop master-detail); menus |
Ctrl+Enter | Submit edit form from any text area |
3. Haptics (mobile)
| Event | Haptic |
|---|---|
| Create/update success | lightImpact |
| 409 conflict / import errors shown | mediumImpact |
| Long-press menu | selectionClick |
| Pull-to-refresh complete | lightImpact |
| Delete/erase confirm | heavyImpact |
| Import complete (all rows) | lightImpact; partial success: mediumImpact |
Haptics disabled per system setting; none on desktop (00-shared/08 §3).
4. Motion language
| Interaction | Motion |
|---|---|
| List → detail | Slide forward m-base; hero avatar flight m-slow (00-shared/08 §4) |
| Skeleton → rows | Cross-fade m-slow, no pop |
| Status badge change | Color/size transition m-fast; icon morph AnimatedSwitcher |
| Filter chips toggle | m-fast color transition |
| Import step change | Fade + slight rise m-slow; stepper indicator slide m-base |
| Import progress | Determinate LinearProgressIndicator m-instant value updates (no pulse) |
| Error table expand | AnimatedSize m-base, never layout pop |
| Dialog (delete/erase) | Scale+fade m-base; scrim m-base |
| Snackbar (undo/confirm) | m-base slide |
Reduced motion: all transitions ≤ m-instant fades; no stagger, no hero
(00-shared/09 §8).
5. Micro-interactions
| Interaction | Detail |
|---|---|
| Search typing | Debounce 300 ms; clear (×) button fades in with input |
| Result count | "42 users" live-region update after search completes |
| Status toggle | Switch flips immediately; server round-trip; rollback on error + snackbar |
| FAB | Appears m-entrance scale; hides on scroll-down, shows on scroll-up |
| Import start | Button → spinner ("Importing…"); anti-double-submit (00-shared/08 §6) |
| Import row error click | Expands inline message (already visible) — no modal for single errors |
| Avatar upload | Overlay spinner on avatar; success check morph; revert on failure |
| Infinite scroll | Bottom spinner fade-in m-instant; "end of list" footer |
6. Import progress interaction (long-running)
Since POST /users/import is synchronous (users.service.ts:233-282):
- Phase 1 — parsing (client, local): indeterminate? No — determinate fake-local parse with real row count (isolate reports progress every ~200 rows).
- Phase 2 — upload: determinate byte progress (dio
onSendProgress). - Phase 3 — server processing: indeterminate spinner labeled "Server is importing N rows — this can take a minute".
- Phase 4 — result: determinate summary (imported/failed counts,
m-entranceentrance).
Rule: never display a fake percentage for phase 3 (honest labeling, OQ-6). Cancel button only during phases 1–2 (local); phase 3 cannot be cancelled (server commits row-by-row).
7. Frustration controls
- Every interactive element responds within 100 ms (00-shared/08 §6).
- All network actions show pending state (button spinners, row overlay).
- Double-tap FAB → guarded (already navigating); double-submit guarded.
- Import phase-3 offers "You'll be notified when done"
(planned)— today the request blocks the UI; keep the screen focused and show elapsed time.