Skip to content

Data Lists

Lists allow you to store, manage, and display multiple items of data that match a common shape or pattern, and then display them in your apps as a list or table.

Lists are an extremely powerful feature on App Maker, and are one of the key ways to build genuinely valuable tools inside your Jira site.

Example Use-case:

Imagine you want to display a dashboard in your Jira project of all the open Pull Requests in your GitHub repository.

With standard webhooks or even App Makers own Custom Data feature, the best you would be able to do is display data from whatever the most recent PR to be updated was. This is because as each new event or piece of data comes in, it would overwrite the previous data that you had stored.

With Lists, you can store each PR as a separate record as they are created, update those records when the data in Github changes and is sent to your App via webhook, and remove them when the PR closes. Once you have the data being correctly managed in the list, you can display all those PR's in a table in your app in real-time, showing the most up-to-date data from external tool.

Working with Lists:

Lists feel just like Custom Data to work with, but with a few key differences.

When working with a list, you don't really ever need to think about the list itself, just the individual records within it. Each action you complete with a list is done on a single record, either adding/updating that record in the list, or removing the record from the list. If you add a record to a list that doesn't exist yet, App Maker automatically creates the list for you. Similarly, if you remove the last record from a list, App Maker will automatically delete the list for you.

List Update Objects (used when adding or updating a record in a list) have three main differences compared to Custom Data:

  1. The action property does not use set or delete, instead it uses add or remove, to indicate whether you are adding or removing the record from the list.
    • Note that the add action will also update the record if it already exists in the list.
  2. There is a top level property called listItemKey, this is the name of the property in the List Item itself that App Maker will use as the unique identifier for each record in the list.
    • This is used to identify whether an item already exists in the list when the add action is used, or to identify which item in the list to remove when the remove action is used.
  3. Finally, there is the listItem itself, which is the actual data object that you want to add or update in the list.
    • This property is basically identical to the customData object in Custom Data, except there will be multiple similar shaped items within each list.
      • Every item added to a list should be the same "shape" (meaning they have the same set of properties with the same names, but different values).
      • Every item added to a list must also have a property with a name that matches the value set in listItemKey. Otherwise App Maker won't be able to identify the item in the list.

Example Workflow:

  • We're going to implement a basic system that mimics the Github PR example from above.
  • We won't be using real Github PR webhooks or data, but we will create out own fake versions of them, to demonstrate how you would work with Lists in a real-world scenario.
  • The technique we use here can be applied to any external tool that you want to display data from in your Jira site.

Creating the PR Table:

  • First, we need to make a request to the UI Update endpoint to set up the Table UI component that will display the PR data.
  • We're going to add this component to the jira:globalPage modules so we can access it from anywhere in the Jira site.
    • You might also want to add this to a project specific module if you wanted to have different Github repos for different projects.
  • We'll use a DynamicTable component, and define the columns we want to display.
  • We'll also use the list: Template Function to fetch the PR data from the List, and display it in the table.
json
{
  "action": "set",
  "resourceType": "site",
  "title": "pr-table",
  "module": "jira:globalPage",
  "componentData": {
    "type": "TabPanel",
    "tabTitle": "Github Pull Requests",
    "children": [
      {
        "type": "FullPageSection",
        "title": "Github Pull Requests",
        "children": [
          {
            "type": "ParagraphMedium",
            "content": "This table displays all the open Pull Requests in the Github repository."
          },
          {
            "type": "DynamicTable",
            "columnHeaders": [
                {
                  "type": "TableHeader",
                    "title": "PR Title",
                    "valuePath": "title",
                    "linkPath": "link"
                },
                {
                  "type": "TableHeader",
                    "title": "Author",
                    "valuePath": "author"
                },
                {
                  "type": "TableHeader",
                    "title": "Status",
                    "valuePath": "status",
                    "fieldType": "lozenge",
                    "appearanceMap": {
                    "discovery": ["Open", "open"],
                    "success": ["Closed", "closed"]
                    }
                }
            ],
            "tableRows": "{{list: lists.site.github-prs}}"
          }
        ]
      }
    ]
  }
}
  • Once complete, head over to Jira and click on the "Apps" dropdown in the top navigation bar, and then click on the "Custom Apps" option to load App Maker in the "Jira Global Page".
  • You should see on that page, a new tab called "Github Pull Requests", with an empty table that has no data in it yet. Jira Global Page with empty PR Table

Adding PR Data to the List:

  • Next, we're going to manually create some fake PR data and add it to the list via the list-update endpoint.
    • If you were using real Github PR data, you would be doing this via a webhook that sends the data to App Maker whenever PR's are updated.
    • You would also want to use a Webhook Transform to transform the incoming data into the shape that you want to store in the list (assuming you don't want to use the raw Github objects, which is also an option).
  • Head over to your API Client where you just added the new UI component, and update the URL path, swapping ?path=ui-update for ?path=list-update.
    • e.g https://some-big-uuid.hello.atlassian-dev.net/x1/some-app-id?path=list-update
  • Now, in the body of the request, we're going to add a new PR record to the list.
    • We're going to use the add action because we want to add something to the list.
    • We're going to set the title as github-prs and the resourceType as site, to match the value we templated into our table.
    • We're also going to specify the listItemKey as id, so that we can give each PR a unique identifier, so we can make changes to them later.
    • Finally, we're going to provide a listItem object that contains the data for the PR we want to add (with properties matching the columnHeaders from our table).
json
{
  "action": "add",
  "resourceType": "site",
  "title": "github-prs",
  "listItemKey": "id",
  "listItem": {
    "id": 12345,
    "title": "Add PR Table to Jira",
    "author": "John Doe",
    "status": "Open",
    "link": "https://google.com"
  }
}
  • Once you've sent the request, you should get a response that looks like:
json
{
	"outcome": "list-updated",
	"data": {
		"resourceType": "site",
		"module": "",
		"resourceKey": "",
		"title": "github-prs",
		"lastUpdated": 1725957033,
		"list": [
			{
				"id": 12345,
				"title": "Add PR Table to Jira",
				"author": "John Doe",
				"status": "Open",
				"link": "https://google.com"
			}
		],
		"listItemKey": "id"
	},
	"dbKey": "list-update_site_github-prs"
}
  • Now head back over to the Jira Global Page, and hit refresh. You should see the PR you just added in the table. Jira Global Page with PR Table and one PR
  • Now, lets add another PR with a different id,title, author, and status so that we have a bit more data to work with (you can leave the link the same).
json
{
  "action": "add",
  "resourceType": "site",
  "title": "github-prs",
  "listItemKey": "id",
  "listItem": {
    "id": 54321,
    "title": "Update PR Table to Jira",
    "author": "Jane Doe",
    "status": "Closed",
    "link": "https://google.com"
  }
}
  • Head back to Jira, refresh, and you should now have two PR's in the table. Jira Global Page with PR Table and two PRs

Updating Records in the List:

  • Next, we're going to update the status of the first PR we added to the list and set its status to Closed.
  • To update records you use the same action as you do for adding them. This way, you don't need to know if a record already exists in the list or not when you get data from an external tool, you just use the add action and App Maker will figure out the rest.
  • Head back over to your API client, and update the body of the request:
    • Everything except the status field is going to be the same, which we're going to set to Closed.
json
{
  "action": "add",
  "resourceType": "site",
  "title": "github-prs",
  "listItemKey": "id",
  "listItem": {
    "id": 12345,
    "title": "Add PR Table to Jira",
    "author": "John Doe",
    "status": "Closed",
    "link": "https://google.com"
  }
}
  • Then send the request, and head back over to Jira and refresh the page. You should see that the status of the first PR has been updated to Closed. Updated PR status
  • How this works is App Maker uses the value of the property specified by listItemKey to identify the record in the list, and then updates the rest of the properties with the values you provide in the listItem object.

Removing Records from the List:

  • Finally, we're going to remove all the PR's we added to the list.
  • To remove records, you simply set the action to remove, and provide a value for whatever property you specified as the listItemKey (id in our case).
    • App Maker will then find the record in the list with that value, and remove it.
  • Once the last record is removed from a list, the list itself will also be removed.
    • Don't worry, if you need to add more records later, App Maker will automatically recreate the list as soon as the first record is added.
  • Head back over to your API client, update the body of the request, and send it:
json
{
  "action": "remove",
  "resourceType": "site",
  "title": "github-prs",
  "listItemKey": "id",
  "listItem": {
    "id": 12345
  }
}
  • Now, head back to Jira and refresh the page. You should see that the first PR is now gone from the table. Removed first PR
  • Finally, remove the second PR from the list by sending the same request, but with the id set to 54321.
json
{
  "action": "remove",
  "resourceType": "site",
  "title": "github-prs",
  "listItemKey": "id",
  "listItem": {
    "id": 54321
  }
}
  • Once you've sent the request, head back to Jira and refresh the page. You should now have an empty table again. Removed all PRs

Advanced Use-Cases:

Make sure you've read the documentation on Webhook Transforms, as that will show you how you can transform the data from incoming webhooks into whatever shape you want it to be. This enables you to setup webhooks from other tools, aimed at App Maker, and then transform the data they include into the shape you want to store in a list.

When using Webhook Transforms to track the state of records in other systems, you will usually need two separate Transforms set up for each List you are managing:

  1. Create and Update webhook events can both be mapped to an add action in the List Update Object created by your Webhook Transform.
  2. Delete webhook events can be mapped to a remove action in the List Update Object created by your Webhook Transform.

In the future, we will be publishing full detailed walkthroughes of how to set up Lists with real-world tools like Github, Bitbucket, and others, so keep an eye out for those.