Appearance
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:
- The
action
property does not useset
ordelete
, instead it usesadd
orremove
, 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.
- Note that the
- 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 theremove
action is used.
- This is used to identify whether an item already exists in the list when the
- 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.
- This property is basically identical to the
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.
- If you're not sure how to do this, check out the Getting Started guide.
- 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.
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
- e.g
- 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
asgithub-prs
and theresourceType
assite
, to match the value we templated into our table. - We're also going to specify the
listItemKey
asid
, 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 thecolumnHeaders
from our table).
- We're going to use the
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.
- Now, lets add another PR with a different
id
,title
,author
, andstatus
so that we have a bit more data to work with (you can leave thelink
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.
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 theadd
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 toClosed
.
- Everything except the
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
. - 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 thelistItem
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
toremove
, and provide a value for whatever property you specified as thelistItemKey
(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.
- Finally, remove the second PR from the list by sending the same request, but with the
id
set to54321
.
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.
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:
- Create and Update webhook events can both be mapped to an
add
action in the List Update Object created by your Webhook Transform. - 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.