Actions
We can tied "action" to Behavior, Layout, or Widget components
. Actions required target
, and additional options can be feeded into options
parameter. Action could also be conditional, we can apply rule to when this action can appear by defining condition.rule
parameter.
Actions below can be used as onClick
.
{
"onClick": {
"target": ":: Action ::",
"options": {
"foo": "one",
"bar": "two"
},
"condition": {
"rule": "data.someKey exists"
}
}
}
- viewMedia
General options
Properties | Description |
---|---|
splash |
configure splash effect |
splash.variant |
standard - use splash effect |
splash.background |
optional background color for the splash |
splash.accent |
optional accent for the splash |
options.close |
boolean; close context when action completes |
options.validation |
validation |
Validation
Validation allows a rule and message to check before executing the action.
{
"options:" {
"validation": {
"rule": "data.address exists",
"message": "Please provide a valid address"
}
}
}
Effects
Haptic
Vibrate the device
Properties | Description |
---|---|
options.haptic |
light | medium | heavy | selection |
Audio
Play a sound
Properties | Description |
---|---|
options.audio |
audio sound id |
Audio sounds available:
- bell-1, bell-2
- error-1
- gong-1,
- happy-1
- notice-1, notice-2, notice-3, notice-4, notice-5, notice-6, notice-7
- notify
- receive-1, receive-2
- send-1
- success-1, success-2, success-3, success-4, success-5
- timer-checkpoint, timer-complete, timer-ending, timer-ends, timer-start
- whoosh-1, whoosh-2, whoosh-3
Content status dirty / pristine
Set content status
Properties | Description |
---|---|
options.notify |
dirty | pristine |
Attributes
Update attributes of an entity
Properties | Description |
---|---|
target | updateAttributes |
options.id | id of the entity to be update |
options.path | path of attribute to be updated, e.g. $.profile |
options.data | a map of key/value pair of data to be updated |
Example
{
"component": "button",
"text": "Save",
"onClick": {
"target": "updateAttributes",
"options": {
"id": "{user.id}",
"path": "$.profile",
"data": {
"jersey": "{data.attributes.profile.jersey}",
"name": "{data.attributes.profile.name}"
}
}
}
}
Scripting
- invokeScript - invoke a server side script (Lua https://www.lua.org/)
- dynamic - run a client side script (Hetu https://hetu.dev/docs/en-US/grammar/)
Invoke Script
invokeScript
Properties | Description |
---|---|
options.handle |
Script to invoke |
...properties | All additional properties will be sent to the script as parameters |
{
target: "invokeScript",
options: {
"handle": "test-script"
}
}
Client side script
dynamic
Properties | Description |
---|---|
options.body |
Script to run |
Language reference available at Hetu https://hetu.dev/docs/en-US/grammar/.
Dispatch
- createDispatch - create a new post (dispatch)
- editDispatch - edit an existing post
- viewDispatch - view an existing post
- deleteDispatch - delete an existing post
- createOrView | createOrUpdate - create a new post or view / edit the existing post
- submitTrackerDispatch - submit action when using tracker widget with form = inline
- viewOrLayout - view an existing post or go to a layout
Create
Supported by createDispatch | createOrView | createOrUpdate
Properties | Description |
---|---|
options.id |
Dispatch id |
options.date |
dispatch date |
options.accountId |
Account id |
options.tracker |
Tracker id or handle |
options.swimlane |
Swimlane handle |
options.recipient |
Recipient user id |
options.recipients |
list of recipients ids |
options.accountId |
dispatch author account id |
options.showDate |
true / false; show date |
options.date |
date for the dispatch; if not provided will use the context date |
options.mode |
interactive (default) | silent |
options.data |
Seed data to pass to the dispatch; use data! if values should overwrite edit |
options.refreshPage |
true / false; refresh page |
options.programStatus |
program status for display |
options.programId |
program id |
options.serviceId |
service id for unique dispatch creation |
options.bucketInfo |
bucket id to automatically add to dispatch bucket |
options.batchId |
batch id for series creation |
options.linkedId |
linked dispatch id |
options.allow |
options for type of attachments to allow: photo, video, file, audio |
options.____ |
camera, library, or choose , see media action mode below |
Media actions
Mode | Description |
---|---|
camera | launch camera and take a photo |
library | launch library for user to select photo |
choose | launch bottom menu that let user chooser camera or library |
Edit
Properties | Description |
---|---|
options.id |
Dispatch id |
options.allowSidebar |
Edit mode; allow side bar menu |
options.showDate |
true / false; show date |
options.data |
Seed data to pass to the dispatch; use data! if values should overwrite edit |
options.refreshPage |
true / false; refresh page |
View
Properties | Description |
---|---|
options.id |
Dispatch id |
options.showTitle |
true or false, default to true |
options.showCommentBar |
true or false, default to true |
options.showSideBar |
true or false, default to true |
options.styles |
map additional styles for the container |
Example
{
"onClick": {
"target": "createDispatch",
"options": {
"tracker": "<tracker id or handle>",
"features": {...},
"showDate": true/false,
"refreshPage": true/false,
...same options as Create Dispatch menu
}
}
}
View or layout
Supported by viewOrLayout
Properties | Description |
---|---|
options.dispatchId |
Dispatch id |
Layout options | If dispatch id is null |
Dispatch view options | If dispatch id is present |
Labels
Supported by addDispatchLabel | removeDispatchLabel
Properties | Description |
---|---|
options.dispatchId |
Dispatch id |
options.handle |
Label to add or remove |
User / org context
- changeOrg - change org
- editAvatar - edit user avatar
- editProfile - edit context user profile
- editAccount - edit account profile
- changeUser - change context user (restricted to approved related users)
- resetUserContext - reset to session user
- restartSession - restart session by reload org, groups, etc., can be used when user groups is changed
- createOrUpdateRelatedUser - create or update related user (e.g. children)
- removeRelatedUser - remove related user
Change user
changeUser
Properties | Description |
---|---|
options.user |
user id to switch context to, if not provided, we are using the current widget user context (which can be different from the page user context) |
options.persistence |
how persistence is the changed user context (session or restart , default to restart ). When set to session , the user context only survive session and will not survive restart. |
Change org
changeOrg
Properties | Description |
---|---|
target | changeOrg |
options.id |
id of the org we want to switch to |
Payments
- payment
- manageSubscription: manage InApp subscription using appropriate store
Screens and menus
- layout - open a layout in a new screen
- popup - open a layout in a popup
- openBrowser - open a web page
- popupMessage - show a modal dialog
- bottomActions - - show a bottom menu
- display - hide or show the current component
- menu - display a menu
- wiki - open a wiki page
- chat - open chat
Layout
layout
Properties | Description |
---|---|
options.id |
Id or handle for the layout |
options.transition |
slide, fade - default is fade |
options.dispatchId |
dispatch id |
options.parameters |
optional, JSON block of arguments for the page; available at the root |
options.title |
optional string, title of appbar |
options.confirm |
true or false , default to false , if true , when user pressed the exit button, user will be asked to confirm |
options.timer |
optional string, if defined, will start a timer using this value as id of the timer |
options.styles.padding |
padding for the container wrapper (default to 10px), eg. "padding": "10px 20px" or "padding": "10px" |
options.styles.backgroundColor |
optional backgrdound color |
options.styles.systemOverlayStyle |
light or dark (default to null) |
options.styles.appBar.visibility |
show or hide , default to show |
options.styles.appBar.backgroundColor |
background color for the app bar |
options.styles.appBar.icon.text |
icon used in place of default app bar leading icon |
options.styles.appBar.icon.color |
color used in place of default color for the app bar leading icon |
options.styles.appBar.cancel.text |
if options.confirm is true, cancel action text, default to KEEP EDITING |
options.styles.appBar.cancel.icon |
if options.confirm is true, cancel action icon, default o reply icon |
options.styles.appBar.timer |
if set to show , will display timer as time in the header/app bar |
Example
"onClick": {
"target": "popup",
"options": {
"parameters": "{data.$}",
"id": "workout-info"
}
}
Notifications
- Scheduled local notifications
scheduleReminder
Properties | Description |
---|---|
options.title | title to display in the notification |
options.body | body to display |
options.at | ISO date time string; if no timezone is specified it will be the local timezone for the user |
Example
{
"component": "button",
"kind": "primary",
"text": "Test scheduler",
"onClick": {
"target": "scheduleReminder",
"options": {
"title": "You have a session starting now",
"body": "Your session with some person",
"at": "2024-03-04 17:32:00"
}
}
}
State
- Update state
Update state
updateState
Properties | Description |
---|---|
options.update | list of map with "key" and "value" |
options.notify.id | if provided, we notify listeners with the provided id of changed so listeners can choose what to do |
options.mode | if set to global , update top most level parent page |
Update state listener
Any widget that wants to subscribe to changes made by updateState
Properties | Description |
---|---|
options.listen.id | listen to changes made by the specific id |
Example
Notifier
{
"target": "updateState",
"options": {
"update": [
{
"key": "someKey",
"value": "someValue"
}
],
"notify": {
"id": "selected-waypoint"
}
}
}
Stepper
- incrementStep
- decrementStep
- resetStep
- updateStep
- mergeStep
Options will update the stepper state.
Inbox
- advanceInbox - advance an workflow step
- updateInboxStatus - update inbox status
Advance
advanceInbox
Properties | Description |
---|---|
options.id |
inbox id |
options.from |
from step |
options.to |
to step |
Update status
updateInboxStatus
Properties | Description |
---|---|
options.id |
inbox id |
options.status |
deleted, archived, active |
Example
Advancing an inbox step with id of id
, from from
step to to
step.
{
...
"onClick": {
"target": "advanceInbox",
"options": {
"id": "123a-4567-..."
"from": "start",
"to": "finish"
}
}
}
Utility and app navigation
- media - trigger media action (camera to take picture, library, choose)
- clipboard - copy content to clipboard
- primary - navigate to a primary tab
- secondary - navigate to secondary menu option
- messageEvent - send a message evant
- updateState - update state for the current context
- scan - scan QR code
Video calls
- meeting
Map features
- navigate - open map to address or long/lat coordinates
- shareLocation - share user current location (for user with map) where user location will be displayed on a map
Listener
{
"component": "grid",
"options": {
"listen": {
"id": "selected-waypoint",
"autofocus": true
}
}
}
Clipboard
clipboard
Properties | Description |
---|---|
options.source |
template to evaluate and place in device clipboard, if not provided copy widget's text |
options.duration |
duration in ms to display copied message |
options.message |
message to display as snackbar when content is copied |
(https://hetu.dev/docs/en-US/)[https://hetu.dev/docs/en-US/]
Manage subscription
manageSubscription
Properties | Description |
---|---|
options.sku |
subscription's id |
options.package |
app packag name |
Navigate
navigate
Properties | Description |
---|---|
options.mode |
coordinates or address . If coordinates , longitude and latitude must be provided. If address , provide the address |
options.longitude |
required if mode is coorindates |
options.latitude |
required if mode is coorindates |
options.address |
required if mode is address |
options.directionMode |
driving, walking, transit, bicycling |
options.allowInAppNavigation |
boolean, default to false, if true, allow use of in app navigation |
options.channelId |
string, location sharing channel id, if exists will send user location to this channel as well as subscribe to this channel for other users location update |
options.ad.direction |
ad placement, valid values are top, bottom , ads only would appear if this is configured, default to no ads |
options.ad.minHeight |
minimum height for ads, default to 80px |
options.ad.maxHeight |
maximum height for ads, default to 120px |
options.ad.condition.rule |
rule to evaluate of when to show ads, if not defined, show ads |
Popup
popup
Display a bottom sheet
Properties | Description |
---|---|
options.id |
layout id |
options.margin |
margin for the bottom sheet |
options.dispatchId |
dispatch id |
options.parameters |
optional, json block of arguments for the page |
Message event
messageEvent
Properties | Description |
---|---|
options.eventName |
Event to send |
options.targetId |
optional; target component |
options.data |
optional; data to send |
Events
dispatchDeleted | dispatchUpdated | dispatchListUpdated | dispatchActionStatusUpdated | dispatchMetricReset | profileUpdated | orgChanged | packetDeleted | packetUpdated | sendPacket | incomingPacket | insertThreadPacket | dispatchSaveSucceed | toggleUserDirectory | addUserDirectoryUser | toggleRequireResponse | dispatchResponseUpdate | layoutDataChanged | bucketDataChanged | newForumAnswer | newForumComment | dispatchCommentTap | dispatchForum | dispatchLatestChange | inboxLatestChange | votingChanged | navigationChange | dispatchFlowSelection | dispatchFlowAdvance | attachmentUploadStarted | filterChanged | shareStart | shareStop | tabNavigationChanged | trackerMetricChanged | channelChanged | refreshSource | notifySink | notifySource | dateChanged
Triggers
Create / update user trigger
Create or update user trigger ("target": "createOrUpdateUserTrigger target"
)
Options
Properties | Description |
---|---|
id | (optional) id of the trigger, if exists this is an update, if not exists, a new trigger will be created |
name | name of current trigger |
description | description of trigger |
behaviorKind | script, workflow |
behaviorId | behavior id |
behaviorHandle | behavior handle |
triggerKind | trigger kind, action, group, inbox, label, meeting, moderation, participant, payment, schedule, tracker, tunnel, user |
triggerHandle | trigger handle |
status | trigger status (active, retired) |
cron | the schedule time in min hour day month weekday format |
timezone | timezone |
forUser | the user id of the user that this trigger is for |
"onClick": {
"target": "createOrUpdateUserTrigger",
"options": {
"id": "496a57dc-60e7-4403-af27-718a64a471cc",
"name": "foobar",
"description": "do something",
"status": "active"
}
}
Remove user trigger
removeUserTrigger
Remove a user trigger ("target":"removeUserTrigger"
)
Properties | Description |
---|---|
id | (required) id of the trigger that you want to remove |
forUser | user id |
"onClick": {
"target": "removeUserTrigger",
"options": {
"id": "496a57dc-60e7-4403-af27-718a64a471cc",
}
}
Popup Message
- popupMessage
- options: map
- text: message to display
- options: map
Scan
- scan
- behavior: script | (...) - behavior to run with the scan result
- handle: handle of the behavior to run
Wiki
- wiki
- options must include wiki page id
Chat
- chat
- options: map
- id: chat channel id
- userId: user Id for DM
- kind: channel kind of
self, direct, dispatch, ad-hoc, org, group, managed, inbox
; optional if id is provided
- options: map
Bottom Actions
- bottomActions
- options: map
- actions: list of actions
- icon: icon to display
- text: label/text of the action
- color: optional hex string, default to black
- action: any of the actions listed here (
invokeScript
, etc)
Share location
- shareLocation: share user current location (for user with map) where user location will be displayed on a map
- options
- channelId: location data channel id where we will send location to
- notifyMode:
all, none, some, followers, channel
- notifyUsers: list of users id if
notifyMode
issome
- warningMessage: message to display before actually share user live location
- updateInterval: how often should we updated user live location (in seconds), default to 30 seconds
Display
- display: hide or show the current component
- options
- value:
hide, show
- value:
Edit account
- editAccount: edit account profile
- id: account id
Edit avatar
- editAvatar: edit user avatar
- id: user id to edit
Create or edit related user
- createOrUpdateRelatedUser: create or edit related user
- id: optional, related user id to edit
- email: user email
- first: user first
- last: user last
- name: user name
- gender: user geneder (male, female, other)
- genderDetail: if gender is other, this value will identify the gender of the user
- dob: user date of birth
- group: group handle that user should be assigned to
-
relation (or child): relationship
-
removeRelatedUser: remove related user options
- id: related user to remove
- confirm: Optional confirm message
Secondary
- secondary
- route: one of available route names
Supported routes
- chat
- channelList
- managedChannels
- groupChannelList
- dispatchChannel
- inboxEntries
- editAccount (requires account id)
- editProfile
- about
- search
- stream
Bottom actions
{
"onClick": {
"target": "bottomActions",
"options": {
"actions": [
{
"icon": "far fa-check",
"text": "Approve",
"onClick": {
"target": "invokeScript",
"options": {
"handle": "someScriptHandle",
"bucketName": "approved",
"campaignId": "<some id>",
"dispatchId": "<some dispatch id>"
}
}
},
{
"icon": "far fa-xmark",
"text": "Decline",
"color": "#ff0000",
"onClick": {
"target": "invokeScript",
"options": {
"handle": "someScriptHandle",
"bucketName": "declined",
"campaignId": "<some id>",
"dispatchId": "<some dispatch id>"
}
}
},
{
"icon": "far fa-xmark",
"text": "Cancel"
}
]
}
}
}
Chat
{
"onClick": {
"target": "chat",
"options": {
"channelId": "<chat channel id>"
}
}
}
Change user
{
"onClick": {
"target": "changeUser",
"options": {
"user": "<user id>",
"persistence": "restart"
}
}
}
Reset user context
{
"onClick": {
"target": "resetUserContext"
}
}
Close
{
"onClick": {
"target": "close"
}
}
Conditional actions
Apply different actions to the same widget pending on condition
"onClick": {
"doA": {
"condition": {
"rule": "$source.myReview.data.score exists"
},
"onClick": {
"target": "viewDispatch",
"options": {
"id": "{dispatch.id}"
}
}
},
"doB": {
"condition": {
"rule": "$source.myReview.data.score undefined"
},
"onClick": {
"target": "createDispatch",
"options": {
"tracker": "1234....."
}
}
}
}
EditDispatch
{
"onClick": {
"target": "editDispatch",
"options": {
"id": "<dispatch id>",
"refreshPage": true/false,
}
}
}
Edit avatar
{
"onClick": {
"target": "editAvatar",
"options": {
"id": "{user.id}"
}
}
}
Insomnia
{
"onClick": {
"target": "insomnia",
"options": {
"wake": true
}
}
}
InvokeScript
{
"onClick": {
"target": "invokeScript",
"options": {
"handle": "<script handle>",
...other options for scripting
}
}
}
Layout
Launch a layout and passing parameters to the layout, parameters are available via data.param...
{
"onClick": {
"target": "layout",
"options": {
"id": "<layout id>",
"parameters": {
...params for layout
},
}
}
}
Meeting
{
"onClick": {
"target": "meeting",
"options": {
...
}
}
}
Menu
{
"onClick": {
"target": "menu",
"options": {
"actions": [
{
"icon": "<icon name>",
"label": "<label for the icon>",
"target": "<action target>",
"options": {
...any of the actions options
}
}
]
}
}
}
MessageEvent
{
"onClick": {
"target": "messageEvent",
"options": {
"eventName": "<name of event>",
...events data
}
}
}
Navigate
{
"onClick": {
"target": "navigate",
"options": {
"mode": "coordinates",
"longitude": -45.123,
"latitude": 44.1463
}
}
}
OpenBrowser
{
"onClick": {
"target": "openBrowser",
"options": {
"url": "<url to launch>"
}
}
}
Payment
"onClick": {
"target": "payment",
"options": {
"title": "Checkout",
"message": {
"confirmTitle": "Confirm your order",
"confirmBody": "Subtotal: {values.total|numeral:$0.00}",
"thankyou": "Payment is processed!"
},
"backgroundColor": "#333",
"data": {
"amount": "{values.total}",
"ccy": "USD",
"symbol": "$"
},
"save": {
"tracker": "6a8a5db9-ab7d-4b5a-b488-38458cd21c71",
"body": "Your order is submitted!",
"description": "The glam daily cart checkout"
},
"providers": [
{
"providerName": "Stripe",
"key": "pk_test_CyocRGjl6i8mTTpydniZVujq",
"handle": "stripe-test"
}
]
}
}
Popup layout
Dislay a layout as a popup
{
"target": "popup",
"onClick": {
"target": "popup",
"options": {
"id": "campaign-user-detail",
"dispatchId": "{dispatch.id}",
"backgroundColor": "#F6E8FF"
}
},
}
Popup message
{
"onClick": {
"target": "popupMessage",
"options": {
"text": "some message to display"
}
}
}
Share location
{
"onClick": {
"target": "shareLocation",
"options": {
"channelId": "75e9ae06-42b7-4bc0-88d0-0efb52caa9c4",
"notifyMode": "some",
"warningMessage": "You are about to share your live location with everyone who are on this trip",
"notifyUsers": [
"97acba99-f4bf-4b46-b0fa-b308d9c849f7",
"dd8d8612-a5b8-4212-a2cb-bc8966e53611"
]
}
}
}
Tracker layout
Create dispatch layout using tracker widget
"onClick": {
"target": "layout",
"options": {
"id": "campaign-apply",
"hideAppBar": true
}
}
Tracker layout (edit)
Edit dispatch layout using tracker widget. Please note that the same layout can be used for edit or create. By passing dispatch
, the layout will knows to open the dispatch in edit mode.
"onClick": {
"target": "layout",
"options": {
"id": "campaign-apply",
"dispatchId": "{data.dispatchId}",
"hideAppBar": true,
"parameters": {
"campaignId": "{values.campaignId}"
}
}
}
ViewDispatch
{
"onClick": {
"target": "viewDispatch",
"options": {
"id": "<dispatch id>",
"showTitle": true,
"showCommentBar": true,
"showSideBar": true,
"styles: {
"backgroundColor": "<color>"
}
}
}
}
Wiki
{
"onClick": {
"target": "wiki",
"options": {
"id": "<some wiki page id>"
}
}
}
Dynamic
{
"component": "grid",
"direction": "column",
"justifyContent": "center",
"alignItems": "center",
"description": "Timer",
"styles": {
"backgroundColor": "#aaffffff",
"height": "50vw",
"width": "66vw",
"borderRadius": "30px",
"margin": "0 20px"
},
"onClick": {
"target": "dynamic",
"options": {
"body": "external fun at\nexternal fun call\nvar s = at(\"ws.set\", 1, 'int')\nvar m = at(\"$.final.sets\", 1, 'int')\nif ( s < m ) {\n call('updateStep', {'set': s + 1})\n} else {\n call('incrementStep', {})\n}"
}
}
}