Job & Dashboard Reference
Input and action widgets
Configure form, field_mapping, action, task_progress, and explorer widgets: config keys, action kinds, and public execution gates.
Input and action widgets
Widgets that make a dashboard interactive: form and field_mapping persist typed configuration onto the Job, action dispatches server-executed side effects, task_progress reads run status, and explorer embeds a curated data browser. Shared keys (id, title, width, scope, refresh_interval_seconds) are on the Widgets overview.
form
Typed fields whose values persist as one object under a config_key in the Job's configuration. Tasks read the saved object in JSONata as job_config.<config_key>.
| Key | Type | Required | Description |
|---|---|---|---|
config_key |
string | Yes | job_config key the value is stored under. |
fields |
array | Yes | Non-empty array of form fields. |
validation_expr |
string | No | JSONata run against the value before persisting; a non-empty [{ field, message }] result rejects the save. |
transform_expr |
string | No | JSONata that reshapes the value just before it is written. |
Form fields use the same shape as job template job_config form entries — key (required), label, type (text | number | boolean | select | multi_select), required, default, format (email | url), inline options or a connector-backed options_source, depends_on, and hide_if_expr. The full field and option-source tables are in the job_config schema.
- id: sync_options
type: form
config_key: sync_options
fields:
- { key: batch_size, label: Batch size, type: number, required: true, default: 100 }
- { key: notify, type: boolean, default: false }
- { key: owner_email, type: text, format: email }Prefer declaring the canonical schema in the job template's top-level job_config: block; a dashboard form is then a customer-facing editor for the same persisted keys.
field_mapping
A two-column mapping editor (left = source field, right = target field). The persisted value is an array of { source_field, target_field, transform? } under config_key.
| Key | Type | Required | Description |
|---|---|---|---|
config_key |
string | Yes | job_config key the array is stored under. |
source / target |
object | Yes | An option source per side (options_source, label_expr, value_expr, search, and related keys — see job_config schema). |
allow_transform |
boolean | No | Enables the per-row JSONata transform editor. Operator-only: hidden on the public share, but operator-set values survive customer edits. |
validation_expr |
string | No | JSONata run against the value before persisting. |
cardinality |
string | No | one_to_one (default, unique targets) or many_to_one. |
extra_columns |
array | No | Typed per-row fields: { key (required), label?, type: text | select | boolean, options?, required? }. |
status_expr |
string | No | JSONata per row → { label, tone } badge, evaluated with { row, job_config, shared }. |
row_action |
string | No | action widget ID rendered as a per-row button; the row is merged into that action's JSONata context. |
- id: meeting_map
type: field_mapping
title: Salesforce → HubSpot meeting fields
config_key: meeting_field_map_sf_to_hs
allow_transform: true
source:
options_source:
connector: salesforce
method: proxy_list
args: { resource: describe, query: { object: arguments.sf_object } }
label_expr: $.label
value_expr: $.name
search: { on_frontend: true }
target:
options_source:
connector: hubspot
method: proxy_list
args: { resource: properties, query: { objectType: meetings } }
label_expr: $.label
value_expr: $.name
search: { on_frontend: true }Missing config_key fails with <path>.config_key is required for field_mapping; missing sides fail with <path>.source and .target are required for field_mapping.
action
A declarative button that runs entirely server-side. Viewers submit form values only; the server resolves the action from the stored YAML. Every action opens a confirmation dialog before running.
| Key | Type | Required | Description |
|---|---|---|---|
label |
string | Yes | Button text. |
action |
object | Yes | The dispatch spec (see below). |
form |
object | No | { fields: [...] } — form fields rendered inside the confirmation dialog, same shape as form fields. |
allow_public |
boolean | No | Allow execution from the public share (additionally gated server-side). |
cooldown_seconds |
number | No | Minimum delay between runs of this widget. |
confirm_message |
string | No | Text shown in the confirmation dialog (fallback: description). |
on_success |
object | No | { refresh?: string[], message?: string } — widget IDs to refresh and a toast message. |
Action kinds
action.kind must be one of run_task, job_run, or connector_method:
| Kind | Required keys | Behavior |
|---|---|---|
run_task |
task |
Starts a task run for the named job task key, using the Job's connector mapping. |
job_run |
— | Starts a Job Run; optional tasks (string[]) selects a subset and skip_deps skips dependency resolution. Does not accept arguments_expr or args — the job runs with its existing arguments and configuration. |
connector_method |
connector, method |
Sanctioned write path through the Job's mapped connector. |
For run_task and connector_method, arguments_expr (JSONata) or a literal args value builds the dispatch arguments. The expression context is { form, job, arguments, job_config, row? } — row is set when an authenticated operator triggers the action from a field_mapping row_action.
- id: invite_user
type: action
label: Invite
form:
fields:
- key: email
type: text
required: true
format: email
action:
kind: run_task
task: invite-user
arguments_expr: '{ "email": form.email, "job_id": job.id }'
allow_public: true
cooldown_seconds: 30
confirm_message: Sends an invite email to this address.
on_success:
refresh: [user_mapping]
message: User invitedSafety: the server deduplicates in-flight executions per widget, applies cooldown_seconds, and records audit rows in dashboard_action_runs.
task_progress
Reads the latest run state for one job task key. No connector call.
| Key | Type | Required | Description |
|---|---|---|---|
task |
string | Yes | Task key within the dashboard's Job. |
stat_expr |
string | No | JSONata over the run and metrics producing a headline number (for example run.item_count). |
- id: migrate_progress
type: task_progress
task: migrate_tickets
refresh_interval_seconds: 5
stat_expr: run.item_countReturns the latest run status, item_count, duration_ms, and per-step counts from metrics_summary.
explorer
A curated data browser: the author pins the connector, resource, and a server-enforced base_query; viewers get paging, filtering, sorting, column selection, and export.
| Key | Type | Required | Description |
|---|---|---|---|
data.connector |
string | Yes | Template connector name. |
data.resource |
string | Yes | Collection or table to browse. |
data.base_query |
object | No | Server-enforced base filter; viewer parameters are always ANDed in and can never remove it. |
default_sort |
object | No | Field → direction applied when the viewer has not sorted. |
page_size |
number | No | Positive number, capped at 100. |
features |
array | No | Any of filter, sort, columns, export, pagination; unknown values are dropped. |
columns |
array | No | { field (required), label?, format?, sortable? }. When declared, columns are the allowlist for viewer filters and projections. |
- id: errored_tickets
type: explorer
data:
connector: mongo
resource: zendesk_tickets
base_query:
filter: { severity: error }
default_sort: { updated_at: -1 }
page_size: 25
features: [filter, sort, columns, export]
columns:
- { field: id, label: ID, sortable: true }
- { field: subject, format: truncate }Sort is always applied server-side. Viewers may sort only on columns marked sortable: true — mark only fields backed by an index; sort requests on other columns are ignored and default_sort stays in effect. Export streams all matching rows as CSV or NDJSON server-side, applying the same merged base_query, scope profile, and column allowlist; omitting export from features disables both the button and the export endpoints.
Public execution gates
Interactive widgets are gated twice on the public share surface:
- Input widgets (
form,field_mapping): the server kill switchENVOY_PUBLIC_DASHBOARD_INPUT_ENABLEDmust be enabled (it defaults off) and the dashboard must setallow_public_input: true. - Action widgets: the server kill switch
ENVOY_PUBLIC_DASHBOARD_ACTIONS_ENABLED=truemust be set and the widget must setallow_public: trueon a public page. Client-suppliedrowcontext is ignored on the public path.
See Authoring dashboards for the full public-share model.
Related
- job_config schema — the schema and stored value shapes input widgets write
- Widgets overview — shared keys and data binding
- Authoring dashboards — public sharing and design guidance