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.
The Appian Tutorial application is used to contain the design objects created while working through this tutorial.
To create the Appian Tutorial application
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.
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.
MY_TASKS_REPORT
in the Name field.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.Examples
in the Save In field and select the folder that is suggested.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.
AT_myTasksReport
in the Name field.Examples
in the Save In field and select the folder that is suggested.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.
Now let's save the interface as a task report and view it in Tempo.
My Tasks
in the Report Name field.Now if you visit the Tasks tab in Tempo, you will see a link for the My Tasks report below the default filters.
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
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
58
59
60
! a!localVariables(
! local!taskStatuses: {
! "Assigned",
! "Accepted",
! "Completed",
! "Not Started",
! "Cancelled",
! "Paused",
! "Unattended",
! "Aborted",
! "Cancelled By Exception",
! "Submitted",
! "Running",
! "Error",
! "Other",
! "Other",
! "Skipped"
! },
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.
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
83
84
85
a!localVariables(
! local!statusFilter: null,
local!taskStatuses: {
"Assigned",
"Accepted",
"Completed",
"Not Started",
"Cancelled",
"Paused",
"Unattended",
"Aborted",
"Cancelled By Exception",
"Submitted",
"Running",
"Error",
"Other",
"Other",
"Skipped"
},
! a!sectionLayout(
! contents:{
! a!dropdownField(
! label: "Status",
! placeholder: "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.