Task Report Tutorial

The walk-through on this page will help you create your first task report. Task reports display task information with a link for users to open each task and begin working on it.

When you save a Tempo report as a task report, it appears on the Tasks tab. Task reports are also used with sites.

For our example, we’ll pull data from the My Tasks process report. We’ll describe how to use the a!queryProcessAnalytics() system function to display data from the process report in a grid. Then, we’ll show you how to create links to tasks and format the data so it looks more user-friendly. Finally, we’ll show you how to add dynamic filters to your report.

Use the data provided to understand how the configurations work. Then, try it with your own data.

The content below assumes a basic familiarity with interfaces, specifically the Paging Grid and Dropdown components, and focuses more on the specifics of designing and creating a task report. Consider going through the SAIL and Grid Tutorials first and taking a look at the Tempo Report Design page before proceeding.

Create the Appian Tutorial Application

The Appian Tutorial application is used to contain the design objects created while working through this tutorial.

The tutorial application only needs to be created once. If you have already created the tutorial application, skip the steps below.

To create the Appian Tutorial application

  1. Log in to Appian Designer (for example, myappiansite.com/suite/design).
  2. Click New Application.
  3. In the Name field, type Appian Tutorial.
  4. Optionally, in the Description field, add a short description.
  5. Click Create.

The application contents view displays. Right now the application is empty. Each design object that you create during the course of this tutorial will appear in this list and be associated with the tutorial application.

Create a Constant for the My Tasks Process Report

Before we create the task report interface, we need to create a constant for the My Tasks process report. This constant will be used in the interface that we will create in the next step.

  1. Navigate to the application contents view of the Appian Tutorial application (if needed).
  2. From the New menu, click Constant. This will open the Create Constant form.
  3. Leave Create from Scratch selected.
  4. Enter MY_TASKS_REPORT in the Name field.
  5. Select Document from the Data Type dropdown.
  6. Enter My Tasks in the Value field and select the document that is suggested. If no suggestions appear for My Tasks, search for and use active_tasks instead.
  7. Enter Examples in the Save In field and select the folder that is suggested.
  8. Click Create.

Create an Interface for the Task Report

Now we will create an interface to be used to display the task report data in a grid. We will use a!queryProcessAnalytics() system function to populate a Paging Grid component with data from the My Tasks process report and create a Tempo task report out of it.

Note that while we are using a built-in report for this example, any process report can potentially be queried.

  1. Navigate to the application contents view of the Appian Tutorial application (if needed).
  2. From the New menu, click Interface. This will open the Create Interface form.
  3. Leave Create from Scratch selected
  4. Enter AT_myTasksReport in the Name field.
  5. Enter Examples in the Save In field and select the folder that is suggested.
  6. Click Create & Edit.

The newly created interface will open in a new tab by default. If you don't see a new tab, check your browser to see if you have pop-ups enabled.

Switch to the Expression Mode using the toggle in the header or by the keyboard shortcut (Ctrl + M).

Now enter the following expression:

1
2
3
4
5
6
a!localVariables(
  local!report: a!queryProcessAnalytics(
    report: cons!MY_TASKS_REPORT
  ),
  a!textField(readOnly: true, value: local!report)
)

The interface's text field will show the text representation of the process report data. You will see something similar to the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[
  startIndex=1,
  batchSize=25,
  sort=[field=c2, ascending=false],
  totalCount=66,
  data=
    [c5:0,c4:1,c3:New PR: Purchase Request Number 68,c8:[Group:6]; [Group:7]; [Group:3],c7:,c2:12/19/2014 2:23 PM GMT+00:00,c0:Review Purchase Request: Purchase Request Number 68,dp0:268440077,dp2:,dp4:,dp3:268435772,dp5:268435772,dp7:,dp8:];
    [c5:0,c4:1,c3:New PR: Purchase Request Number 43,c8:[Group:6],c7:,c2:12/19/2014 2:23 PM GMT+00:00,c0:Approve Purchase Request: Purchase Request Number 43,dp0:268440067,dp2:,dp4:,dp3:268435771,dp5:268435771,dp7:,dp8:],
  identifiers=268440077; 268440067
  name=My Tasks
  description=A list of all tasks for the current user.
  columnConfigs=
    [label:Name,field:c0,drilldownField:dp0,configuredFormatting:NORMAL_TEXT,configuredDrilldown:TASK_DETAILS];
    [label:Received,field:c2,drilldownField:dp2,configuredFormatting:DATE_TIME,configuredDrilldown:];
    [label:Priority,field:c4,drilldownField:dp4,configuredFormatting:PRIORITY_ICON,configuredDrilldown:];
    [label:Process,field:c3,drilldownField:dp3,configuredFormatting:NORMAL_TEXT,configuredDrilldown:PROCESS_DASHBOARD];
    [label:Status,field:c5,drilldownField:dp5,configuredFormatting:TASK_STATUS,configuredDrilldown:PROCESS_DETAILS];
    [label:Deadline,field:c7,drilldownField:dp7,configuredFormatting:DATE_TIME,configuredDrilldown:];
    [label:Assigned To,field:c8,drilldownField:dp8,configuredFormatting:USER_OR_GROUP_NAME,configuredDrilldown:],
  errorMessage=
]

Notice that rows are returned in the data array with each column's cell being represented by a key/value pair. Details about each column, including the key to access that column's data from the data array, are provided in the columnConfigs field.

Let's try displaying the data using a grid instead of a single text field. For this example, we’ll take the columns labeled Name, Process, and Status. To begin, you don't need to use local variables. Insert the query directly into the data parameter of the grid component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  a!gridField(
    label: "My Tasks",
    instructions: "A list of all tasks for the current user",
    labelPosition: "ABOVE",
    data: a!queryProcessAnalytics(
      report: cons!MY_TASKS_REPORT,
      query: a!query(
        pagingInfo: fv!pagingInfo
      )
    ),
    columns: {
      a!gridColumn(
        label: "Name",
        sortField: "c0",
        value: fv!row.c0
      ),
      a!gridColumn(
        label: "Process",
        sortField: "c3",
        value: fv!row.c3
      ),
      a!gridColumn(
        label: "Status",
        sortField: "c5",
        value: fv!row.c5
      ),
    },
    rowHeader: 1
  )

You should see an interface similar to the following (it will vary based on your personal task list):

Before moving on, however, let's save the interface by clicking Save. Keep this window open so you can quickly modify the interface as we continue.

Create and View the Task Report

Now let's save the interface as a task report and view it in Tempo.

  1. From the settings menu (gear icon), click Save as…. This will display the Save Interface As form.
  2. Enter My Tasks in the Report Name field.
  3. Select the Save as Task Report checkbox.
  4. Confirm that the Application field has the value Application Tutorial in it.
  5. Click Save.

Now if you visit the Tasks tab in Tempo, you will see a link for the My Tasks report below the default filters.

Display Tasks with Multiple Assignees

In Appian, tasks can be assigned to multiple people and to groups. If your tasks are assigned to other users too, you may want to see these other assignees in your task list. We need to add a new column to the grid to show this information. To show all of the items in the array, we need to use the looping function a!forEach. The function will go through each item in the array and return the information we're looking for. In this example, that is the user's first and last name. To format the information, we use the concat() function and char(10) to have each item appear on its own line.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  a!gridField(
    label: "My Tasks",
    instructions: "A list of all tasks for the current user",
    labelPosition: "ABOVE",
    data: a!queryProcessAnalytics(
      report: cons!MY_TASKS_REPORT,
      query: a!query(
        pagingInfo: fv!pagingInfo
      )
    ),
    columns: {
      a!gridColumn(
        label: "Name",
        sortField: "c0",
        value: fv!row.c0
      ),
      a!gridColumn(
        label: "Process",
        sortField: "c3",
        value: fv!row.c3
      ),
      a!gridColumn(
        label: "Status",
        sortField: "c5",
        value: fv!row.c5
      ),
!     a!gridColumn(
!       label: "Assignee",
!       sortField: "c8",
!       value: concat(
!         a!forEach(
!           items: fv!row.c8,
!           expression: if(
!             runtimetypeof(fv!item) = 4,
!             /*User is type 4; group is type 5*/
!             user(fv!item, "firstName") & " " & user(fv!item, "lastName") & char(10),
!             /*Adding char(10) adds line breaks to the list of names*/
!             group(fv!item, "groupName")
!            )
!         )
!       )
!     )
    },
    rowHeader: 1
  )

Unlike the process report, the grid we just created only displays the task name. Users have no way to open the task. What we want to do is link the Name column to the task, but the other columns should remain unlinked.

We can do this by updating the column expression with the following definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
a!gridField(
  label: "My Tasks",
  instructions: "A list of all tasks for the current user",
  labelPosition: "ABOVE",
  data: a!queryProcessAnalytics(
    report: cons!MY_TASKS_REPORT,
    query: a!query(
      pagingInfo: fv!pagingInfo
    )
  ),
  columns: {
    a!gridColumn(
      label: "Name",
      sortField: "c0",
!     value: a!linkField(
!       links: a!processTaskLink(
!         label: fv!row.c0,
!         task: fv!identifier
!       )
!     )
    ),
    a!gridColumn(
      label: "Process",
      sortField: "c3",
      value: fv!row.c3
    ),
    a!gridColumn(
      label: "Status",
      sortField: "c5",
      value: fv!row.c5
    ),
  },
  rowHeader: 1
)

Now if you return to your AT_myTasksReport interface, the tasks should be linked. We are now using a!processTaskLink() to create a link for each data point in the column. We set the task property as fv!identifier to designate the task as the link destination. Label is set to fv!row.c0 to show the task's name as the link text.

See also: Process Task Link

Format the Status Column

You may have noticed that the Status column returned numbers instead of the text you normally see in the Portal task report. This is because process reports auto-format some columns, including task status, task priority, users, dates, and more, but we are telling our grid to display every column as text.

We can apply one or more of these formats by using a!forEach() to call a formatting expression if the report column is configured with a relevant formatting type.

This expression uses the task status number as an index into a set of status names. Note that because each data row is a Dictionary that maps keys to values of Any Type, tointeger must be used to convert the cell value from Any Type to Number (Integer).

To store the readable values for each status, we create a local variable local!taskStatuses.

Now we can update the AT_myTasksReport interface rule with the following definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
! a!localVariables(
!  local!taskStatuses: {
!   "Assigned",
!   "Accepted",
!   "Completed",
!   "Not Started",
!   "Cancelled",
!   "Paused",
!   "Unattended",
!   "Aborted",
!   "Cancelled By Exception",
!   "Submitted",
!   "Running",
!   "Error"
! },
      a!gridField(
        label: "My Tasks",
        instructions: "A list of all tasks for the current user",
        labelPosition: "ABOVE",
        data: a!queryProcessAnalytics(
          report: cons!MY_TASKS_REPORT,
          query: a!query(
            pagingInfo: fv!pagingInfo
          )
        ),
        columns: {
          a!gridColumn(
            label: "Name",
            sortField: "c0",
            value: a!linkField(
              links: a!processTaskLink(
                label: fv!row.c0,
                task: fv!identifier
              )
            )
          ),
          a!gridColumn(
            label: "Process",
            sortField: "c3",
            value: fv!row.c3
          ),
          a!gridColumn(
            label: "Status",
            sortField: "c5",
!           value: if(
!             not(isnull(fv!row.c5)),
!             index(
!               local!taskStatuses,tointeger(fv!row.c5)+1,"Other"
!             ),
!             "Other"
!           )
!         ),
        }
      ),
     rowHeader: 1
! )

Now instead of numbers in the status column, there are words like Assigned and Completed. For an example that uses an image column to display an icon for process statuses, see the Display Processes by Process Model with Status Icons Interface Recipe.

Add a Predefined Filter

With process reports, Appian lets users add their own filters to those configured in the report. For task reports, we can add extra filters via the query parameter of a!queryProcessAnalytics(). Then we can connect them to another component so users can use that component to change the filter on the report.

For our example, let’s add a Dropdown component so users can filter the tasks by the most common statuses. To show the dropdown component above the grid, we need to also add a section layout to our interface.

Modify the AT_myTasksReport interface with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
a!localVariables(
! local!statusFilter: null,
  local!taskStatuses: {
    "Assigned",
    "Accepted",
    "Completed",
    "Not Started",
    "Cancelled",
    "Paused",
    "Unattended",
    "Aborted",
    "Cancelled By Exception",
    "Submitted",
    "Running",
    "Error"
  },
! a!sectionLayout(
!   contents:{
!     a!dropdownField(
!       label: "Status",
!       placeholderLabel: "Pick a status",
!       choiceLabels: { "Assigned", "Accepted", "Completed", "Not Started" },
!       choiceValues: enumerate(4),
!       value: local!statusFilter,
!       saveInto: local!statusFilter
!     ),
      a!gridField(
        label: "My Tasks",
        instructions: "A list of all tasks for the current user",
        labelPosition: "ABOVE",
        data: a!queryProcessAnalytics(
          report: cons!MY_TASKS_REPORT,
          query: a!query(
            pagingInfo: fv!pagingInfo,
!           filter: a!queryFilter(
!               field: "c5",
!               operator: "=",
!               value: local!statusFilter,
!               applyWhen: not(
                  isnull(
                    local!statusFilter
                  )
                ),
!             ),
          ),
        ),
        columns: {
          a!gridColumn(
            label: "Name",
            sortField: "c0",
            value: a!linkField(
              links: a!processTaskLink(
                label: fv!row.c0,
                task: fv!identifier
              )
            )
          ),
          a!gridColumn(
            label: "Process",
            sortField: "c3",
            value: fv!row.c3
          ),
          a!gridColumn(
            label: "Status",
            sortField: "c5",
            value: a!forEach(
              items: fv!row.c5,
              expression: if(
                not(isnull(fv!row.c5)),
                fn!index(
                  local!taskStatuses,tointeger(fv!item)+1,"Other"
                ),
                tostring(fv!item)
              )
            )
          )
        },
        rowHeader: 1
      )
!   }
! )
)

In this expression, we pass a filter to a!queryProcessAnalytics() that uses a statusFilter local variable as its value. That variable is set by the Dropdown component, where the task statuses are passed as choiceLabels and the corresponding numeric values are passed as choiceValues. Because the numeric values of these specific statuses are 0, 1, 2, and 3, we can use the enumerate() function to return those values. In the example above, we don't set a default value. Instead, you see all tasks in the grid and "Pick a status" as the placeholder in the dropdown filter. The local variable storing the selection is empty.

When you select Assigned, the value of the filter is to 0 which corresponds to the value of Assigned and only the tasks with that status are returned. If you select a different value from the dropdown, the grid updates to display only tasks that correspond to the selected status.

Click Save. Now go back to Tempo, and see that the filtered task list interface is now available.

FEEDBACK