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 throughout Appian tutorials. Skip the steps in this section if you've already created this application in another tutorial.
To begin with, we need to create an application to contain our design objects.
We will be creating the Appian Tutorial application for this tutorial. All of Appian's tutorials use the Appian Tutorial application as the reference application. After completing this tutorial, you can reuse this application as you work through other Appian tutorials.
To create the Appian Tutorial application:
In the Create New Application dialog, configure the following properties:
Property | Description |
---|---|
Name | Enter Appian Tutorial . |
Prefix | Keep the default prefix, AT , which Appian constructs using the initial characters of each word you entered in the Name parameter. We'll be following the recommended naming standard, and using this short, unique prefix whenever we name an object in this application. |
Description | Leave blank. It's normally a best practice to add descriptions to all design objects. However, to save a little time during this tutorial, we'll skip adding descriptions unless the description displays to the end user. |
Generate groups and folders to secure and organize objects | Keep this checkbox selected, so that Appian will automatically generate standard groups and folders and assign default security groups for this application. |
In the Review Application Security dialog, keep the default security settings. Because we selected the Generate groups and folders option in the previous step, Appian automatically uses the AT Users and AT Administrator groups it generated to set our application security appropriately.
The security of the application object is unrelated to the security of each of the objects contained within the application. This means that you will need to set security permissions for every object in an application in addition to the application object itself. For more information about security permissions for the application object, see Application Security.
Click SAVE. The application view appears.
Right now, the application contains the folders and groups Appian generated automatically. 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.
AT_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!AT_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!AT_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!AT_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!AT_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!AT_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!AT_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.