Dashboards
Dashboards is used to present information in a easy way. It can contain information from multiple sources and gives the user a good overview for eg. an employee or a customer. Onify includes a dashboard editor where customers can design their own dashboards.
Create new dashboard
Create empty dashboard template
For more information about form templates, see sections below.
- Go to dashboard templates resources (/admin/resources?activedirectory=templates%2Fdashboard&isdirectoryopen=true)
- Right click on dashboard folder and click Create new file
- Pick a name for the dashboard template (eg. mydashboard.pug)
- Copy this text
extends ../views/dashboard/default-dashboard
to first row of file - Click Save
Create dashboard configuration
- Go to dashboard configuration page (/admin/configuration/dashboards)
- Click Create new button
- Enter Slug (url friendly name, eg.
mydashboard
) - Enter Title (eg.
My Dashboard
) - Enter Description (optional)
- Select Template (eg.
mydashboard.pug
)
That was the minimum setup for a dashboard...
Dashboard templates
For every dashboard, we need dashboard templates (pug). These templates should be placed in the customer-{customer code}-hub-app
GitHub repo in /templates/dashboard folder.
Example dashboard
extends ../views/dashboard/default-dashboard
block append dashboardConfig
+dashboardOptions({
width: "large"
})
block dashboardContent
+dashboardElement({
name: "image",
layout: {
x: '1',
y: '0',
width: '3',
height: '3'
},
type: "image",
nodatamessage: "",
config: {
url: "{{user.custom.pictureurl}}"
}
})
+dashboardElement({
name: "name",
type: "standardheader",
layout: {
x: '1',
y: '4',
width: '3',
height: '1'
},
config: {
header: "{{user.name}}",
subheader: "{{user.email}}"
}
})
Dashboard options
Dashboard options are optional options/config.
width
(default: "standard") - The width of the dashboard. Choose betweensmall
,standard
orlarge
.dashboardTitle
(default: dashboard title) - The dashboard titledashboardDescription
(default: dashboard description) - The dashboard description
_Example: Custom title and description and large dashboard
+dashboardOptions({
width: "large",
dashboardTitle: "Test",
dashboardDescription: "This is a test"
})
Dashboard elements
Elements are widgets that should show on the Dashboard.
General settings
Here are some settings that can be defined for all elements.
name
- Unique name/id for the elementtype
- What type of element it istitle
(default: none) - Title for the elementdescription
(default: none) - Description for the elementclass
(default: none) - Specify a custom css class for the elementlayout.*
- Placement and size of the element, see details belowconfig.*
- Element type specific configuration, see each dashboard element type for more detailslookup.*
- See Lookups section (Lookups)[#lookups]
Layout
layout.x
- is used for left positionlayout.y
- is used for top positionlayout.width
- element widthlayout.height
- element height
Example: Header element that uses lookup to get item data
+dashboardElement({
name: "element1",
type: "standardheader",
layout: {
x: '0',
y: '0',
width: '6',
height: '1'
},
lookup: {
"type": "item",
"key": "{{item.key}}"
},
config: {
header: "{{item.attribute['display_name']}}",
subheader: "{{item.attribute['email_address']}}"
}
})
Standard header element
Settings
config.header
- Widget headerconfig.subheader
(default: none) - Widget sub-header
Example: Simple header with current logged in users name
+dashboardElement({
name: "name",
type: "standardheader",
layout: {
x: '0',
y: '0',
width: '8',
height: '1'
},
config: {
header: "{{user.name}}"
}
})
Image element
Settings
config.url
- Widget header
Example: Get users custom profile picture
+dashboardElement({
name: "image",
layout: {
x: '0',
y: '0',
width: '3',
height: '3'
},
type: "image",
nodatamessage: "",
config: {
url: "{{user.custom.pictureurl}}"
}
})
KPI element
More docs coming soon...
Example: Number style
+dashboardElement({
"title" : "Active assets",
"data" : {
"activeassets" : "{{config.api.url}}/api/v1/my/items/itam?term=*&filter=status.name:In%20use&filter=tag:asset",
},
"widget" : "kpi",
"config" : {
"style" : "number",
"showmore" : {
"link" : "/"
},
"expression" : "{{activeassets.totalresults}}",
"color" : {
"green" : "< 50",
"red" : ">= 50",
"yellow" : "> 5000"
}
}
})
Example: Percent style
+dashboardElement({
"data" : {
"activeassets" : "{{config.api.url}}/api/v1/my/items/itam?term=*&filter=status.name:In%20use&filter=tag:asset",
"totalassets" : "{{config.api.url}}/api/v1/my/items/itam?term=*&filter=tag:asset"
},
"widget" : "kpi",
"config" : {
"style" : "percent",
"showmore" : {
"text" : "Active Assets",
"link" : "/"
},
"expression" : "{{activeassets.totalresults}} / {{activeassets.totalresults}} * 100",
"color" : {
"#555" : "< 50",
"#999" : ">= 50"
}
}
})
Conversation element
More docs coming soon...
Example: Get events (like comments) for specific item
+dashboardElement({
name: "conversation_1",
title: "Conversation element from result",
layout: {
x: '0',
y: '0',
width: '4',
height: '5'
},
"lookup": {
"type": "events",
"workspace": "{{item.workspace}}",
"query": "Lorem",
"item": "{{item.key}}",
"sort": ["category,asc", "level,desc"],
"level": "info",
"tag": "consent",
"pagesize": 10
},
"type": "conversation",
"config": {
"fields": [{
"name": "align",
"value": "{{event.level}}"
}, {
"name": "class",
"value": "{{event.category}}"
}, {
"name": "text",
"value": "{{event.meta.details}}"
}, {
"name": "footer",
"value": "{{event.timestamp}}"
}, {
"name": "maxwords",
"value": "100"
}]
}
})
Example: Static example
+dashboardElement({
name: "conversation",
title: "Conversation element static",
layout: {
x: '5',
y: '0',
width: '4',
height: '5'
},
"type": "conversation",
"config": {
"conversations": [{
"align": "left",
"class": "test-class-left",
"text": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
"footer": "Test footer left"
}, {
"align": "right",
"class": "test-class-right",
"text": "Test text right",
"footer": "Test footer right",
"maxwords": 100
}, {
"align": "center",
"class": "test-class-center",
"text": "This is **help** _text_ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
"footer": "Test footer center",
"maxwords": 100
}, {
"text": "Test text center",
"footer": "Test footer center"
}, {
"text": "This is **help** _text_"
}]
}
})
Actions element
Example: List item actions
+dashboardElement({
name: "actions",
class: "transparent",
layout: {
x: '0',
y: '8',
width: '8',
height: '1'
},
"lookup": {
"type": "item",
"key": "{{user.key}}"
},
"type": "actions",
"nodatamessage": "",
"config": {
"target": "_self",
"actions": "item.action | prepareAction : item.key"
}
})
Example: Advanced example with translations, excluding actions and adding custom actions
+dashboardElement({
name: "element6",
layout: {
x: '6',
y: '2',
width: '6',
height: '2'
},
"title": "<%app.actions%>",
"lookup": {
"type": "item",
"key": "{{item.key}}"
},
"type": "actions",
"nodatamessage": "<%app.filters%> {{item.name}}",
"config": {
"target": "_self",
"exclude": ["dashboard"],
"actions": "item.action | prepareAction : item.key",
"custom": [
{
"name": "Reset password",
"url": "/form/demo-passwordreset?item={{item.key}}&workspace={{item.workspace}}",
"order": 1,
"target": "_blank",
"role": [
"servicedesk",
"admin"
]
}
]
}
})
Attachments element
Example: List item attachments
+dashboardElement({
name: "attachments",
layout: {
x: '6',
y: '4',
width: '4',
height: '2'
},
"lookup": {
"type": "item",
"key": "{{item.key}}"
},
"type": "attachments",
"nodatamessage": "",
"config": {
"attachments": "item.attachment | getField"
}
})
Attributes element
Example: List specific item attributes
+dashboardElement({
name: "general",
layout: {
x: '1',
y: '12',
width: '10',
height: '3'
},
"title": "GENERAL",
"lookup": {
"type": "item",
"key": "{{item.key}}",
"workspace": "my-workspace"
},
"type": "attributes",
"config": {
"attributes": [
{
"name": "first name",
"value": "{{item.attribute.firstname}}"
},
{
"name": "last name",
"value": "{{item.attribute.lastname}}"
},
{
"name": "user type",
"value": "{{item.attribute.user_type}}"
},
{
"name": "username",
"value": "{{item.attribute.adaccount}}"
},
{
"name": "status",
"value": "{{item.status}}"
},
{
"name": "Employee id",
"value": "{{item.attribute.employee_id}}"
},
{
"name": "company",
"value": "{{item.attribute.company}}"
},
{
"name": "email",
"type": "link",
"link": "mailto:{{item.attribute.email}}",
"value": "{{item.attribute.email}}"
},
{
"name": "mobile phone",
"type": "link",
"link": "tel:{{item.attribute.mobilephone}}",
"value": "{{item.attribute.mobilephone}}"
}
]
}
})
Form element
Example: Embed form and inlcude form parms
+dashboardElement({
name: "element11",
layout: {
x: '0',
y: '10',
width: '12',
height: '3'
},
"type": "form",
"config": {
"form": "demo-createincident",
"parms": "title=Problem%20with%20printer&item={{item.key}}&workspace={{item.workspace}}&css=widget-form&embed=embed-page-form-inner"
}
})
HTML element
Example: Show item description
+dashboardElement({
name: "description",
layout: {
x: '4',
y: '1',
width: '6',
height: '1'
},
"type": "html",
"lookup": {
"type": "item",
"key": "{{item.key}}"
},
"nodatamessage": "",
"config": {
"content": "{{item.description}}"
}
})
Example: Simple HTML text
+dashboardElement({
name: "element8",
layout: {
x: '0',
y: '6',
width: '3',
height: '2'
},
"title": "Custom HTML/TEXT",
"type": "html",
"config": {
"content": "<span>Custom html</span>"
}
})
Example: List with custom classes
+dashboardElement({
name: "address",
title: "Adress",
class: "address",
layout: {
x: '4',
y: '5',
width: '4',
height: '4'
},
"type": "html",
"config": {
"content": `
<div class="visiting-element">
<div class="attr">
<ul>
<li>
<span class="name">Address</span>
<span class="value">{{item.attribute.visitingaddress}}</span>
</li>
<li>
<span class="name">Zip</span>
<span class="value">{{item.attribute.visitingzipcode}}</span>
</li>
<li>
<span class="name">City</span>
<span class="value">{{item.attribute.visitingcity}}</span>
</li>
</ul>
</div>
</div> `
}
})
Tags element
Example: List tags for item
+dashboardElement({
name: "tags",
layout: {
x: '1',
y: '15',
width: '10',
height: '1'
},
"lookup": {
"type": "item",
"key": "{{item.key}}"
},
"type": "tags",
"config": {
"tags": "item.tag | prepareFilter : 'tag'"
}
})
Trafficlight element
Example: Show item status based on custom color
+dashboardElement({
name: "status",
layout: {
x: '10',
y: '0',
width: '1',
height: '1'
},
"type": "trafficlight",
"lookup": {
"type": "item",
"key": "{{item.key}}"
},
"nodatamessage": "",
"config": {
"color": "{{result.item.attribute._status_color}}",
"message": "{{result.item.status}}"
}
})
Listitems element
Example: List tickets for specific person (item)
+dashboardElement({
name: "tickets",
layout: {
x: '1',
y: '1',
width: '10',
height: '3'
},
"title": "Tickets (Open)",
"lookup": {
"type": "items",
"workspace": "{{item.workspace}}",
"query": "filter=tag:incident&filter=owner:{{item.key}}&filter=!status:Closed",
"term": "*",
"sort": "key,asc",
"pagesize": 3
},
"type": "listitems",
"config": {
"style": "table",
"showmore": {
"text": "<%app.seemore%>",
"link": "/workspace/{{item.workspace}}/search?term=*&filter=tag:incident&filter=owner:{{item.key}}&filter=!status:Closed&filter=!status:On Hold&sort=key,asc"
},
"fields": [{
"name": "number",
"type": "link",
"link": "/workspace/{{item.workspace}}/search?term={{result.item.key}}",
"value": "{{result.item.key}}"
}, {
"name": "title",
"value": "{{result.item.name}}"
}, {
"name": "priority",
"value": "{{result.item.attribute.priority}}",
"class": "{{result.item.attribute._priority_class}}"
}, {
"name": "action",
"type": "link",
"link": "/form/demo-itemcomment?title=Comment {{result.item.key}}&description=Incident title: {{result.item.name}}&header=Please%20enter%20comment&button=Add%20comment",
"value": "Add comment",
"target": "_blank"
}
]
}
})
Updated about 1 year ago