Window Actions
A WindowAction is what a menu item, a stat button or a link points at. It answers one
question — what happens when someone opens this? — and its type field is the answer.
- data_type: WindowAction name: Products identifier: sellable_products_action model: Product modes: Kanban, List, Form default_view: product_kanban_view search_view: product_search_view views: - - set - - product_kanban_view - product_list_view - product_form_viewtype — what opening it does
Section titled “type — what opening it does”type | What renders | Key field |
|---|---|---|
Window (default) | The action’s views of its model, inside the app shell | views, modes |
Client | A compiled screen the frontend ships, inside the app shell | client_action |
Route | Nothing — it navigates, leaving the shell | route |
Window is the overwhelming majority and needs no type: line. Client names a bespoke
screen the platform already ships (you cannot add one from a module — see
Views Overview).
Route — a surface that is not a view of the shell
Section titled “Route — a surface that is not a view of the shell”A Route action does not render anything itself. It sends the browser to route and stops.
- data_type: WindowAction name: Shop Floor identifier: mrp_shopfloor_action model: Shopfloor # still required — it decides who sees the menu type: Route route: /app/shopfloor action_ctx: title: Shop FloorWhen to reach for it
Section titled “When to reach for it”When the thing you are opening is not a view of the back office — an operator kiosk (a till, a shop-floor tablet, a warehouse handset), a standalone tool, or an external system.
The distinction is not cosmetic. A screen rendered as a Client action is drawn over a
live app shell, which is still mounted underneath: it has already fetched the back office’s
navigation, chat presence, activity feed and notification subscriptions before the kiosk
booted, and it keeps polling them for the rest of the shift on a screen nobody can see them
on. On a device whose whole point is to keep working with a bad connection, that is a real
cost. A Route leaves the shell instead of covering it.
If your screen is a view of the back office — it wants the navigation, the app switcher
and the record chrome around it — it is a Window action, not a route.
What route accepts
Section titled “What route accepts”Exactly two shapes, and the model refuses anything else at save:
| Value | Behaviour |
|---|---|
/app/shopfloor | An in-app path. Navigates without a page load. |
https://status.example.com | An absolute address. Leaves the application. |
A value that is neither — example.com, say — is rejected with a message naming it, because
it would otherwise be read as a relative path and quietly land the user on something like
/app/example.com: no error, no console message, just the wrong page. A Route with no
route at all is refused for the same reason — the menu item would do nothing whatsoever.
javascript: targets are refused outright.
External routes honour window
Section titled “External routes honour window”For an absolute http(s):// address, the action’s existing window field decides where it
opens — the same choice that field governs everywhere else:
window | Result |
|---|---|
New Window | Opens in a new browser tab |
Current Window (default) | Replaces the current page |
An in-app path always navigates in place; window does not apply to it.
model is still required — and still does something
Section titled “model is still required — and still does something”A Route action renders no records, but model is not ceremony: menu visibility is derived
from the acting user’s access to the model its action opens (see
Model Access). Point it at the model the surface actually works
with — the shop-floor action names Shopfloor — and users without access to that model do
not see the menu. Adding groups: to the action narrows it further.
A Route also does not grant anything. The destination enforces its own authentication and
access exactly as it would if the user typed the address; an unauthenticated visitor is sent
to the login page and returned to the route afterwards.
Precedence
Section titled “Precedence”route wins over client_action when both are set — which is what lets an existing client
action be converted to a route by adding type: Route and route: without stripping the old
value out of every database that already has it.
Related
Section titled “Related”- Views Overview — the
UiViewtypes aWindowaction can render - Action Results — what a method returns when a button is pressed
- Data Files — where
WindowActionrecords are authored