Workflow Actions (user‑triggered)
Workflow actions let users perform configurable multi‑step operations with a single click. Unlike actions for lifecycle hooks, these actions run only when explicitly requested. They are configured centrally in Spring/YAML and executed by the same ActionsRunner engine.
1. Enabling workflow actions
Add or override the following in any Spring configuration file (commonly
application.yml
). Hook‑based actions (enabled
) and workflow actions
(wfEnabled
) can be toggled separately.
hanami:
features:
actions:
enabled: false # lifecycle hooks
wfEnabled: true # workflow actions ➜ ON
When wfEnabled: false
no workflow buttons are shown in the UI and API calls
will return 404 – unknown action.
2. Where to put the configuration
workflow.actions
is an array that can live in any Spring YAML file. We
recommend a dedicated file per domain—for example customer-workflow.yml
.
# ext/config/customer-workflow.yml
workflow:
actions:
- id: …
Multiple files merge automatically as long as each id
is unique.
3. Top‑level keys
Key | Type | Required | Description |
---|---|---|---|
id | string | ✓ | Unique slug. Also used in REST endpoints and permission rules. |
scope | string | ✕ (default is item only supported) | . Determines where the button appears. |
icon | string | ✕ | UI icon name (Material icons palette). |
validationQuery | string | ✓ | SPARQL ASK executed against the item (or collection/workspace) graph. Must return true for the action to become clickable. |
jobs | list of strings | ✓ | One or more action‑job IDs executed sequentially. Same semantics as actions/*.yml . |
excludeJobs | list of strings | string | ✕ | Comma‑separated or YAML list of hook job IDs to suppress during this workflow. Useful to avoid infinite loops when using itemUpdateQueryStep . |
i18n | map | ✕ | Keys pointing to the translation bundle (see §5). |
4. Execution order & exclusion logic
- UI/API calls
/workflow/{id}
withitemUri
(or collection/workspace id). - Engine evaluates
validationQuery
(templated via SpEL)—if false → HTTP 409. - Provided jobs run through
ActionsRunner
withon=workflow
. - During nested
beforeSave/onSave/…
executions, any job whoseid
matchesexcludeJobs
is skipped.
The exclusion list is checked by string containment—so
dataset‑reset
will also skipdataset‑reset-onsave
.
5. Internationalisation
The i18n
map carries keys (not literal text) so UIs can fetch translations via
react-intl
, Angular i18n, etc.
Key | Used for |
---|---|
actionLabel | Text in the dropdown menu. |
confirmationTitle , confirmationBody , confirmationOk | Modal dialog shown before execution. |
successLabel | Toast/snackbar after successful run. |
6. Complete example (item scope)
hanami:
features:
actions:
enabled: false
wfEnabled: true
workflow:
actions:
- id: dataset-publish
icon: publish
validationQuery: |
PREFIX adms: <http://www.w3.org/ns/adms#>
PREFIX dcat: <http://www.w3.org/ns/dcat#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX status: <https://data.in.ep.europa.eu/def/asset-status/>
ASK WHERE {
GRAPH <#{[graphUri]}> {
?dataset a dcat:Dataset .
?record a dcat:CatalogRecord ;
foaf:primaryTopic ?dataset ;
adms:status ?status .
FILTER(?status IN (status:under-review, status:deprecated))
}
}
jobs:
- dataset-publish-action # ← defined in ext/collections/.../actions
excludeJobs: dataset-reset-onsave
i18n:
actionLabel: customer.workflow_actions.datasets.publish.action_label
confirmationTitle: customer.workflow_actions.datasets.publish.confirmation_title
confirmationBody: customer.workflow_actions.datasets.publish.confirmation_body
confirmationOk: customer.workflow_actions.datasets.publish.confirmation_ok
successLabel: customer.workflow_actions.datasets.publish.success_label