diff --git a/cypress/e2e/context_and_state.ts b/cypress/e2e/context_and_state.ts index 014c3b6f7..4f41dbe3e 100644 --- a/cypress/e2e/context_and_state.ts +++ b/cypress/e2e/context_and_state.ts @@ -73,7 +73,7 @@ describe('Kendraio context and state', () => { // "showContext": false, // "showState": false, // "blockComment": "" - //}, + //}, { "type": "context-save", "key": "state.global.term", diff --git a/docs/workflow/blocks/actions.rst b/docs/workflow/blocks/actions.rst index c6f983daf..5e4904ab5 100644 --- a/docs/workflow/blocks/actions.rst +++ b/docs/workflow/blocks/actions.rst @@ -77,6 +77,7 @@ In this example, we are specifying which flow to load when the button is clicked You can find this example on the `Flow Cloud `, in the list of workflows. .. code-block:: json + { "type": "actions", "buttons": [ @@ -94,7 +95,7 @@ You can find this example on the `Flow Cloud ` can be used to create links using a subset of HTML, though it is not styled as a button by default. -For links to other Flows, the :doc:`Link Action Block ` allows opening links in another window or tab, with only one block needed, which is styled as a button (just like an Actions block). \ No newline at end of file +For links to other Flows, the :doc:`Link Action Block ` allows opening links in another window or tab, with only one block needed, which is styled as a button (just like an Actions block). diff --git a/docs/workflow/blocks/debug.rst b/docs/workflow/blocks/debug.rst index f317dabac..4cbc260d7 100644 --- a/docs/workflow/blocks/debug.rst +++ b/docs/workflow/blocks/debug.rst @@ -27,3 +27,46 @@ Supported properties block is shown. Set this to true to enable debugging of context values too. - showState (default = false): Set this to true to enable to display of state. - enabledGetter : When set the enabledGetter should contain a JMESPath expression that returns true/false to enable or disable the debug block. + + +Debug in nested blocks or Flows +-------------------------------- + +It is possible to use the Debug block in nested Flows or nested blocks. +For example while working with the :doc:`uiSchema `, it is possible to use the debugger within the list of items as seen in the following example. + +.. code-block:: json + + [...] + "ui:widget": "blocks", + "blocksConfig": { + "blocks": [ + { + "type": "context-save", + "contextKey": "defaultValue" + }, + { + "type": "db", + "skipFirst": false, + "operation": "get", + "adapterName": "culturebanked", + "schema": "party" + }, + { + "type": "debug", + "consoleLog": true, + "showData": true, + "showState": true, + "showContext": true + }, + { + "type": "reference", + "fieldLabel": "Select beneficiary", + "labelGetter": "name", + "valueField": "uuid", + "outputGetter": "uuid" + } + ] + } + [...] + diff --git a/docs/workflow/blocks/form.rst b/docs/workflow/blocks/form.rst index 1a481e10d..571e7690a 100644 --- a/docs/workflow/blocks/form.rst +++ b/docs/workflow/blocks/form.rst @@ -4,6 +4,7 @@ Form Display a form for data entry or editing. Forms are displayed based on the UI Schema and JSON Schema provided. These can be provided inline within the block configuration, or loaded from an adapter. +Kendraio Form is built on top of Angular Formly https://formly.dev/. Most of the form properties and functionalities can be found in Formly. Default config -------------- @@ -61,6 +62,15 @@ The fields of the form can be populated in two ways: manually writing fields or Here's an example of creating a form by manually writing fields and configuring it: .. code-block:: json + + + // data + { + "name": `John`, + "lastname": `Doe` + } + + // Form config { "type": "form", "hasSubmit": "true", @@ -81,21 +91,22 @@ Here's an example of creating a form by manually writing fields and configuring } }, "uiSchema": {} -} + } Dynamic data and field titles ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To generate fields form given data, the data needs to be in a format readable by the form block. +To generate fields from given data, the data must be in a format that the form block can read. + It is possible to transform the data into the format that the form expects with the help of a mapping block. + Is also possible to use generated data to dynamically display the title of a field .. code-block:: json - - // generated data + // data { - "name": `John`, - "surname": `Doe` + "user_name": `John`, + "user_surname": `Doe` } // Form config @@ -111,17 +122,229 @@ Is also possible to use generated data to dynamically display the title of a fie "user_name": { "type": "string", "title": "name", - "default": "The title of this field comes from dynamic data" + "default": "The value of this field comes from dynamic data" }, "user_surname": { "type": "string", "title": "surname", - "default": "The title of this field comes from dynamic data" + "default": "The value of this field comes from dynamic data" } } }, "uiSchema": {} -} + } + +Select Input +^^^^^^^^^^^^ +Display a field that allows the user to select an item from a list of options. + +The options have to be listed in a property called `enum` as array. + +To have a label, the `default` property can be used. To prefill the select with a specific option, +a string with the same name property and same value has to be passed in as data. +The `enum` property works just with hardcoded data, as per example. + +.. code-block:: json + + // data + { + "name": `John`, + "lastname": `Doe`, + "age": `+21` + } + + // Form config + { + "type": "form", + "hasSubmit": "true", + "label": "Click to submit", + "jsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "default": "" + }, + "lastname": { + "type": "string", + "title": "Last name", + "default": "" + }, + "age": { + "type": "string", + "title": "Age", + "enum": [ + "0-16", + "16-18", + "18-21", + "+21" + ] + }, + "status": { + "type": "string", + "title": "Civil Status", + "default": "Pick a status" + "enum": [ + "single", + "married", + "widow", + "divorced" + ] + } + } + }, + "uiSchema": {} + } + +Select with Dynamic data +^^^^^^^^^^^^^^^^^^^^^^^^ +If the options displayed in the select input come dynamically (maybe from a mapping block or from an API), +then we will need to use the `$ref` property and the passed data must have a specific structure: with `anyOf`, `title` and `const`. +It is also possible to use the :doc:`reference ` + +.. code-block:: json + + // data + { + "name": `John`, + "status": { + "anyOf": + [ + { + "title": `Single`, + "const": `1` + }, + { + "title": `Divorce`, + "const": `2` + } + ] + } + } + + // Save these data to a context, under the name `civilStatusData` + + // Form config + { + "type": "form", + "hasSubmit": "true", + "label": "Click to submit", + "jsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "default": "" + }, + "status": { + "title": "Civil Status", + "$ref": "#/definitions/context/civilStatusData" + } + }, + "uiSchema": {} + } + +If you want to prefill the field with a specific option, you need to pass the corresponding `const` value +as data, right before the Form block. + + +.. code-block:: json + + // data + { + "name": `John`, + "status": { + "anyOf": + [ + { + "title": `Single`, + "const": `1` + }, + { + "title": `Divorce`, + "const": `2` + } + ] + } + } + + // Save these data to a context, under the name `civilStatusData` + { + "type": "context-save", + "key": "civilStatusData" + } + + // Pass the selected option + { + "status": `2` + } + + + // Form config + { + "type": "form", + "hasSubmit": "true", + "label": "Click to submit", + "jsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name", + "default": "" + }, + "status": { + "title": "Civil Status", + "$ref": "#/definitions/context/civilStatusData" + } + }, + "uiSchema": {} + } + +In the above example, as soon as the Flow is open, it should show a select input with `Divorce` already selected, and the option to change it to `Single`. + + + +Special UI: Card to add and remove items dynamically +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +type: array displays a special UI that allows the user to dynamically add or delete the specified field with the specified properties. + +In the example below, two fields are created: a number and a string. Since we are using type: array, these two fields are grouped together and treated as one unit. Each unit has a remove button. + +The UI card also displays an add button. Clicking on it will add a new unit containing the two fields. + +An example of the array type in action is `here `_ + +.. code-block:: json + + { + "type": "form", + "label": "Search", + "jsonSchema": { + "type": "object", + "properties": { + "lineup": { + "type": "array", + "title": "Lineup", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + } + } + } + } + } + }, + "uiSchema": {} + } + Read-only @@ -179,9 +402,9 @@ A simple search form without a submit button. Using a schemaGetter ^^^^^^^^^^^^^^^^^^^^ -The simplest way to use a schemaGetter is the load-schema block. -:ref:`load_schema` -The load-schema block can turn an object generated by the schema builder into a JSON schema, and can combine multiple existing schemas. +The simplest way to use a schemaGetter is the :doc:`load_schema` block. + +The load-schema block can turn an object generated by the `schema builder `_ into a JSON schema, and can combine multiple existing schemas. .. code-block:: javascript @@ -221,7 +444,9 @@ Using data saved from context blocks ------------------------------------ JSON Schema supports references to transclude content. + Context is injected into a definitions section, that references can use. + In the example below, a mapping has a default value, which is saved using the context block, and the default value is set to "injected". .. code-block:: javascript diff --git a/docs/workflow/blocks/http.rst b/docs/workflow/blocks/http.rst index 38d454a2a..0de927c8d 100644 --- a/docs/workflow/blocks/http.rst +++ b/docs/workflow/blocks/http.rst @@ -52,7 +52,11 @@ Examples **Dynamic data** If the endpoint needs to be constructed from data, the endpoint can be specified as an object with a "valueGetter" attribute. -"valueGetter" can only get data from the context. +"valueGetter" can only get data from the context, it does not work with static data. If the values come from the context, they must be specified inside the "valueGetter" +property. You cannot retrieve any values from the context in any other property of the endpoint. +There are two ways of using "valueGetter". +- **valueGetter** - Retrieve one value from the context that creates the whole endpoint. +- **valueGetters** - Retrieve different values from the context that specify properties like "pathname" or "query", which together will create the final endpoint. .. code-block:: json @@ -160,12 +164,13 @@ Pagination If a HTTP API returns paginated results with a standard link header, to fetch paginated API results, set the followPaginationLinksMerged option to true. This will fetch all pages of results and return the combined set of results from all the pages. With a proxy: -```json -{ - "type": "http", - "method": "GET", - "endpoint": "https://example.com/paginated", - "useProxy": true, - "followPaginationLinksMerged": true -} -``` + +.. code-block:: json + + { + "type": "http", + "method": "GET", + "endpoint": "https://example.com/paginated", + "useProxy": true, + "followPaginationLinksMerged": true + } diff --git a/docs/workflow/blocks/reference.rst b/docs/workflow/blocks/reference.rst index fc12e6b9a..7dd8b299a 100644 --- a/docs/workflow/blocks/reference.rst +++ b/docs/workflow/blocks/reference.rst @@ -27,3 +27,6 @@ input data items have a field called ``label`` you can omit these options. You can also set the ``required`` status of the input select list. This defaults to ``false``. + +At the moment, it does not seem possible to prefill the field with a selected value. +There is a property called `defaultValue` which currently doesn't seems to work.