How to create a shopping list app with Kendraio App

Darren Mothersele
Kendraio
Published in
7 min readJul 31, 2020

Kendraio App is a customisable bi-directional data browser that allows you to interact with any data source. Users can download and install adapters and workflows that are completely customisable. A workflow is made up of configurable steps that perform various tasks, or display user interface widgets such as forms, data-grids, and charts. A workflow is a sequence of tasks that execute in order, with the data output from each task becoming the input for the next task.

In this example, we demonstrate some of the available features by building a shopping list, specifically:

  • Using a spreadsheet as a data source — in this case, a list of products
  • Visualising the data as an advanced data grid with item selection and filtering
  • Creating a custom form for capturing data — the quantities to purchase
  • Mapping and transforming data — calculating the order total

This guide will also demonstrate how to:

  • Use the workflow builder to create a workflow from scratch
  • Use the Debug block to visualise the structure of data
  • Edit block configurations to harness the full power of Kendraio App workflows

A common pattern is to configure a data source (like a database, API, form, or spreadsheet), then use a Mapping to transform the data so it can be used. This pattern will be demonstrated twice in this example. The output from the grid is transformed with a Mapping to become the input to a Form, and the output of the Form is transformed with a Mapping to apply a calculation for the order total.

You can find the final workflow from this tutorial here.

The end product
The end product

Step 0: Create a new Adapter and empty Workflow

  • Go to https://app.kendra.io select Adapters then New Adapter
  • Edit the metadata for the Adapter then click the New Adapter submit button
  • On the Adapters page, under Installed Adapters, click View to view your new adapter details
  • Under Workflows click the New Workflow button
  • Edit the Workflow details (the Adapter name has been pre-filled and does not require editing) and click Add Workflow
  • Return to the Adapter info page for your Adapter and click View on your new Workflow. You will find yourself on a blank page with a new empty Workflow configuration. Click the cog in the top right-hand corner to access the Workflow editing tools

Step 1: Setup the spreadsheet data source

  • In order to configure your Google Sheet as a data source, you need to convert your XLS file to a Google Sheet, publish the sheet and generate the URL using the share button. For more detailed instructions, read our docs at https://kendraio-app.readthedocs.io/en/latest/workflow/blocks/gsheet.html
  • Add a Google Spreadsheet block to the Workflow. Add ‘simple: true’ to the block configuration
{
"type": "gsheet",
"simple": true,
"key": "https://docs.google.com/spreadsheets/d/1pROEg6WMQNcsR4QFMQJyDuGO67JKscCgacnOi8rivCM/edit?usp=sharing"
}
  • Add a Debug block to see the structure of the data

If you have a Google Sheet with only one tab you can set the simple option to true. The data output from the block will then be an array list with an item for each row in the table. For sheets with multiple tabs, the simple option is not used and instead an object is output with all properties from all tabs for mapping. More information is available in the TableTop.js documentation.

  • To save the workflow click the Save button in the toolbar inside the workflow config

Step 2: Configure a data grid to show the products

  • Remove the Debug block
  • Add a Data Grid block
  • Configure the grid options however you want; you can set pagination, filters, and row selection options
  • Add a columnDef for the checkbox selection
  • Add a columnDef for each column, including the filter parameters
  • Add a custom Value Formatter to display prices
{
"type": "grid",
"gridOptions": {
"floatingFilter": true,
"pagination": true,
"paginationPageSize": 20,
"rowSelection": "multiple",
"suppressRowClickSelection": true
},
"columnDefs": [
{
"width": 50,
"resizable": false,
"checkboxSelection": true
},
{
"headerName": "Description",
"field": "Description",
"filter": "agTextColumnFilter",
"filterParams": {
"applyButton": true,
"resetButton": true
}
},
{
"headerName": "Department",
"field": "Department",
"filter": "agTextColumnFilter",
"filterParams": {
"applyButton": true,
"resetButton": true
}
},
{
"headerName": "Size / Weight",
"field": "Size / Weight",
"filter": "agTextColumnFilter",
"filterParams": {
"applyButton": true,
"resetButton": true
}
},
{
"headerName": "Price",
"field": "Price",
"width": 150,
"filter": "agNumberColumnFilter",
"valueFormatter": "join('', ['£', value])",
"filterParams": {
"applyButton": true,
"resetButton": true
},
"cellClass": "text-right"
}
]
}

The Value Formatter is a JMESPath expression, more about that next…

Configuration within Kendraio App

Step 3: Map the table selection to an object

A form will be needed to capture the required quantities for the shopping list. The output of the grid is the data in the rows that the user selects but in the form of a list. Because the form will require an object as the input, we use a Mapping to transform the format of the data. A full explanation of JMESPath can be found here. This Mapping is just a simple “object projection” that creates an object with one key called “items” which is set to the “data” (where “data” represents the data input to the Mapping which, in this case, will be the selected rows from the data grid).

  • Add a Mapping block with the following Mapping:
{
"type": "mapping",
"mapping": "{ items: data }"
}
  • Add a Debug block to see the new format for the data
Mapping in Kendraio App

Step 4: Create a form to capture the quantities required

In Kendraio App, forms are generated automatically from JSON Schema representations of the data model. JSON Schema is a standardised way of defining JSON data models as defined here https://json-schema.org . The UI for the form can be customised using UI Schema. UI Schema is a non-standard format for customising the generated schema-driven form. Kendraio App includes an implementation that is based on the popular React Schema Form.

  • Remove the Debug block
  • Add a Form block
  • Enter the JSON Schema that matches the format of the object being passed into the form
  • Add the extra quantity field
  • Customise the UI of the form by using UI Schema
  • Add a Debug block to see what is being output by the form
{
"type": "form",
"label": "Recalculate",
"jsonSchema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Description": {
"type": "string"
},
"Department": {
"type": "string"
},
"Size / Weight": {
"type": "string"
},
"Quantity": {
"type": "number",
"title": "Quantity",
"default": 1
}
}
}
}
}
},
"uiSchema": {
"items": {
"ui:widget": "table",
"colHeadings": [
"Description",
"Department",
"Size / Weight",
"Quantity"
],
"allowAdd": false,
"allowRemove": false,
"items": {
"Description": {
"ui:widget": "readonly"
},
"Department": {
"ui:widget": "readonly"
},
"Size / Weight": {
"ui:widget": "readonly"
}
}
}
}
}

Step 5: Calculate the total

This Mapping uses an object projection to copy across the data items from the form and add in the total. The total is calculated using JMESPath functions, and formatted for display using the currency() function.

  • Add a Mapping block with the following mapping defined
  • Move the Debug block to the bottom of the workflow
{
"type": "mapping",
"mapping": "{ items: data.items, total: currency(product(sum(data.items[].product(product(to_number(Price), `100`), Quantity) || `[]`), `0.01`), 'en-GB', 'GBP') }"
}

Step 6: Output the shopping list

The final step is to output the shopping list in a user-friendly format using a template. In this example, the template block is wrapped in a card block to separate it visually from the rest of the workflow:

  • Remove the Debug block
  • Add a Card block. This is a block that contains an inner workflow (in the Block’s property)
  • The editor does not currently support embedded workflows, so manually add a Template block to the inner workflow
  • The Template block supports handlebars for customisation of the output: https://handlebarsjs.com
{
"type": "card",
"blocks": [
{
"type": "template",
"template": "<p>Hello,</p><p>Here is my order:</p><ul>{{#each data.items}}<li><b>{{Quantity}} x</b> {{Description}} ({{Department}}) - {{\"Size / Weight\"}} - &pound;{{Price}}</li>{{/each}}</ul><p>I make that a total of {{data.total}}</p><p>Thanks!</p>"
}
]
}

Kendraio App is a project by Kendraio, the interoperability advocacy initiative. Kendraio App is an open-source dashboard application currently focused on music/media creators, copyright and related rights owners. The app was developed to investigate how the transformative benefits of interoperability can improve existing processes — and to demonstrate how they can impact business, personal and public life.

Subscribe to the Kendraio newsletter here.

--

--