UX Patterns
Backoffice applications are work tools. Their quality is measured not by visual flair but by productivity, safety, and the reduction of cognitive effort. Users spend hours inside these systems — every unnecessary click, every lost filter, every context switch carries a real operational cost.
Mateu’s thesis is that good business UX is regular enough to be codified once, on the backend, and applied consistently without writing frontend code. This section documents the patterns Mateu supports and how to express each one.
Principles
Section titled “Principles”Seven principles drive every pattern in this catalogue. Each exists to eliminate a concrete cost.
| # | Principle | What it prevents |
|---|---|---|
| 01 | Preserve context | Users should never lose their orientation or mental state. Leaving a screen to come back is the most expensive form of context loss. |
| 02 | Minimize navigation | Fewer screens and fewer jumps equal more productivity. Composing beats navigating. |
| 03 | Keyboard-first | Power users live on the keyboard. If a frequent task requires a mouse, it is badly designed. |
| 04 | Workflow over screens | The unit of design is the task, not the screen. Design to complete work, not to display an entity. |
| 05 | Progressive complexity | Show complexity only when it adds value. Advanced features are revealed, not imposed. |
| 06 | Recoverability | Every error must be correctable. Confirm destructive actions, undo reversible ones, never lose work in progress. |
| 07 | Consistency | Patterns repeat predictably. What a user learns on one screen works on all. |
Pattern catalogue
Section titled “Pattern catalogue”Looking for full-page templates (record overview, collection detail, guided process, create and edit in a drawer…)? They have their own map: Page templates.
| Pattern | Status | Key primitive |
|---|---|---|
| Navigation & Menus | ✅ Implemented | @App(AppVariant.*), ⌘K command palette |
| Split View | ✅ Implemented | @SplitCrud |
| Tree CRUD | ✅ Implemented | gridLayout() = GridLayout.tree, @SplitCrud |
| Filters & Listing | ✅ Implemented | @List, @Filterable, @RowAction |
| Bulk actions | ✅ Implemented | @ListToolbarButton + typed List<Row> selection |
| Saved views | ✅ Implemented | Smart search bar bookmark — named condition sets, default view |
| Totals & row grouping | ✅ Implemented | @Aggregate(sum/avg/…) footer + @GroupBy subtotal rows |
| Column chooser | ✅ Implemented | Show/hide/reorder columns per user, per listing |
| Guided import | ✅ Implemented | ImportWizard<Row> — upload → map columns → validate → import |
| Concurrent edit conflicts | ✅ Implemented | @Version — conflict dialog: reload / overwrite |
| Notification inbox | ✅ Implemented | NotificationsSupplier — header bell, unread count, mark-as-read |
| Undo | ✅ Implemented | Message.undoable(...) — toast with an Undo button |
| Session expiry | ✅ Implemented | onSessionExpired — re-auth + retry, work intact |
| Audit version diff | ✅ Implemented | History grouped by save moment — old → new per field |
| Global entity search | ✅ Implemented | GlobalSearchSupplier — ⌘K searches data, grouped by category |
| Planning board | ✅ Implemented | PlanningBoard — resources × days tape chart, drag to move |
| Wizard | ✅ Implemented | @WizardCompletionAction, @WizardProgress(BAR/STEPS/RAIL) |
| CRUD editing in a drawer | ✅ Implemented | editInDrawer() — create/edit slides over the listing |
| Collection detail | ✅ Implemented | CollectionDetail<Row> — searchable list + in-place detail |
| General overview | ✅ Implemented | GeneralOverview<Row> — record context switcher + overview |
| Entity Picker | ✅ Implemented | @Lookup, @Composition |
| Workspace | Composition | @SplitLayout, @Tabs, @Accordion |
| Task-centric page | Composition | @Action, @MainAction |
| Long-running jobs | ✅ Implemented | @Action(background, sse), @Trigger |
| Autosave | ✅ Implemented | @AutoSave |
| Keyboard Shortcuts | ✅ Implemented | @Action(shortcut = ...), @Trigger(OnEnter) |
| Push Notifications | ✅ Implemented | @Trigger(OnLoad + OnSuccess), Hydratable, MicroFrontend |
| Partial Forms | ✅ Implemented | @FoldedLayout, @Section, nested subform records |
| High-density screens | ✅ Implemented | @Compact, StyleConstants.COMPACT |
| Audience projection | ✅ Implemented | @Audience + @AppContext field named audience |
| Front-office screens | Composition | TaskQueue + EntityHeader + Wizard + Ledger + … |
| Entity header | ✅ Implemented | EntityHeader (title, badges, facts, metric) |
| Meter | ✅ Implemented | Meter (value/max, warn/danger thresholds) |
| Task progress | ✅ Implemented | TaskProgress (done/total pills + CTA) |
| Status list | ✅ Implemented | StatusList + StatusItem (status chip or action) |
| Task queue | ✅ Implemented | TaskQueue + QueueGroup/QueueItem |
| Resource grid | ✅ Implemented | ResourceGrid + ResourceItem (availability picker) |
| Offer card | ✅ Implemented | OfferCard (features, price delta, CTA) |
| Add-on picker | ✅ Implemented | AddOnPicker + AddOn (running total) |
| Ledger | ✅ Implemented | Ledger + LedgerLine (folio breakdown) |
| Payment picker | ✅ Implemented | PaymentPicker + PaymentMethod |
| Process monitor | ✅ Implemented | ProcessMonitor + ProcessItem (health + fix) |
| Notice | ✅ Implemented | Notice / @Notice (inline banner, status, action) |
| Kanban | ✅ Implemented | Kanban + KanbanColumn/KanbanCard |
| Timeline | ✅ Implemented | Timeline + TimelineItem (activity feed) |
| Progress steps | ✅ Implemented | ProgressSteps (also @WizardProgress(STEPS)) |
| Stat / KPI tile | ✅ Implemented | Stat (value, trend, sparkline) |
| Calendar | ✅ Implemented | Calendar month view + CalendarEvent |
| Pricing table | ✅ Implemented | PricingTable + PricingPlan |
| Org chart | ✅ Implemented | OrgChart + OrgNode |
| Heatmap | ✅ Implemented | Heatmap (calendar heatmap) |
| Funnel | ✅ Implemented | Funnel + FunnelStage |
| Trend chart | ✅ Implemented | TrendChart (line/area, dependency-free) |
| Feature grid | ✅ Implemented | FeatureGrid + Feature tiles |
| Testimonials | ✅ Implemented | Testimonials + Testimonial |
| FAQ | ✅ Implemented | Faq + FaqItem (collapsible) |
| Callout card | ✅ Implemented | CalloutCard (title, body, CTA) |
| Comment thread | ✅ Implemented | CommentThread + Comment |
| File list | ✅ Implemented | FileList + FileItem (attachments) |
| Comparison card | ✅ Implemented | ComparisonCard (side-by-side options) |
| Checklist | ✅ Implemented | Checklist + ChecklistItem (progress) |
Anti-patterns
Section titled “Anti-patterns”Each anti-pattern has a name so it can be recognised quickly — and a pattern that prevents it.
| Anti-pattern | Description | Solved by |
|---|---|---|
| CRUD Tunnel | List → detail → back, breaking the flow on every row visit. | Split View |
| Modal Hell | Nested modals that destroy orientation. | Split View, Task-centric page |
| Spinner Prison | Freezing the entire screen while something loads. | Long-running jobs |
| Filter Amnesia | Losing filters when navigating away. | Filter state synced to URL — browser bookmarks become saved views |
| Desktop Denial | Ignoring the keyboard and penalising the expert user. | Keyboard Shortcuts — @Action(shortcut = ...) |