Skip to content

Commit c45dde4

Browse files
committed
Creating Process flow in service portal
In this snippet you will create a custom process flow with a custom page and populated with standard widgets.
1 parent 533989c commit c45dde4

File tree

6 files changed

+307
-0
lines changed

6 files changed

+307
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
var PortalUtils = Class.create();
2+
PortalUtils.prototype = Object.extendsObject(PortalUtilsBase, {
3+
initialize: function() {
4+
},
5+
type: 'PortalUtils'
6+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
var PortalUtilsBase = Class.create();
2+
PortalUtilsBase.prototype = {
3+
initialize: function() {
4+
},
5+
6+
getProcessFlows: function(data,table,newRecord, grRecord){
7+
data.processFlow = {show:false, items:[]};
8+
9+
var grProcessStates = new GlideRecord('sys_process_flow');
10+
grProcessStates.addQuery("table", table);
11+
grProcessStates.addQuery("active",true);
12+
grProcessStates.orderByDesc('order');
13+
grProcessStates.query();
14+
15+
var matchingFound = false;
16+
17+
while(grProcessStates.next()) {
18+
data.processFlow.show = true;
19+
20+
var item = {};
21+
22+
item.label = grProcessStates.getValue("label");
23+
24+
if(newRecord){
25+
item.class_name = "disabled";
26+
}else if(GlideFilter.checkRecord(grRecord,grProcessStates.getValue("condition"))){
27+
item.class_name = "completed active";
28+
matchingFound = true;
29+
}else{
30+
if(matchingFound)
31+
item.class_name = "completed active";
32+
else
33+
item.class_name = "disabled";
34+
}
35+
36+
data.processFlow.items.unshift(item);
37+
}
38+
39+
if(newRecord && data.processFlow.show && data.processFlow.items.length > 0){
40+
data.processFlow.items[0].class_name = "active";
41+
}
42+
},
43+
44+
type: 'PortalUtilsBase'
45+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="container">
2+
<div class="process">
3+
<div class="process-row">
4+
<div class="process-step" ng-repeat="stateItem in data.processFlow.items">
5+
<button type="button" disabled="disabled" class="btn btn-default btn-circle" ng-if="c.data.currentValue!=stateItem"><i class="fa fa-check fa-3x" aria-hidden="true"></i></button>
6+
<button type="button" disabled="disabled" class="btn btn-success btn-circle" ng-if="c.data.currentValue==stateItem"><i class="fa fa-check fa-3x" aria-hidden="true"></i></button>
7+
<p>{{stateItem.label}}</p>
8+
</div>
9+
</div>
10+
</div>
11+
</div>
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Creating Process flow in service portal
2+
## Introduction
3+
In this snippet you will create a custom process flow with a custom page and populated with standard widgets.
4+
5+
## Step 1: Create a new Widget
6+
***Go to Service Portal > Widget > Click New***
7+
- Name: Process Flow
8+
- Id: process-flow
9+
- Click on `submit`
10+
11+
***Body HTML template***
12+
- Copy and paste below `HTML Code` in Widget's HTML Template section
13+
```HTML
14+
<div class="container">
15+
<div class="process">
16+
<div class="process-row">
17+
<div class="process-step" ng-repeat="stateItem in data.processFlow.items">
18+
<button type="button" disabled="disabled" class="btn btn-default btn-circle" ng-if="c.data.currentValue!=stateItem"><i class="fa fa-check fa-3x" aria-hidden="true"></i></button>
19+
<button type="button" disabled="disabled" class="btn btn-success btn-circle" ng-if="c.data.currentValue==stateItem"><i class="fa fa-check fa-3x" aria-hidden="true"></i></button>
20+
<p>{{stateItem.label}}</p>
21+
</div>
22+
</div>
23+
</div>
24+
</div>
25+
```
26+
27+
***CSS/SCSS***
28+
- Copy and paste below `CSS` in Widget's CSS/SCSS Section
29+
```CSS
30+
.btn-circle {
31+
width: 40px;
32+
height: 40px;
33+
text-align: center;
34+
padding: 6% 0;
35+
font-size: 6px;
36+
line-height: 0.6;
37+
border-radius: 100%;
38+
}
39+
40+
.process-row {
41+
display: table-row;
42+
}
43+
44+
.process {
45+
display: table;
46+
width: 100%;
47+
position: relative;
48+
}
49+
50+
.process-step button[disabled] {
51+
opacity: 1 !important;
52+
filter: alpha(opacity=100) !important;
53+
}
54+
55+
.process-row:before {
56+
top: 20px;
57+
bottom: 0;
58+
position: absolute;
59+
content: " ";
60+
width: 100%;
61+
height: 1px;
62+
background-color: #ccc;
63+
z-order: 0;
64+
65+
}
66+
67+
.process-step {
68+
display: table-cell;
69+
text-align: center;
70+
position: relative;
71+
padding-left: 0%;
72+
padding-right: 5%;
73+
}
74+
75+
.process-step p {
76+
margin-top:10px;
77+
78+
}
79+
80+
.btn-circle.active {
81+
border: 2px solid #cc0;
82+
}
83+
84+
```
85+
86+
***Server Side Scripts***
87+
- Copy and Paste below `Server-Side Script` in Widget's Server Side Section
88+
```javascript
89+
(function() {
90+
/* populate the 'data' object */
91+
/* e.g., data.table = $sp.getValue('table'); */
92+
93+
data.table = $sp.getParameter("table");
94+
data.sys_id = $sp.getParameter("sys_id");
95+
96+
var gr = new GlideRecord(data.table);
97+
gr.get(data.sys_id);
98+
99+
var spUtils = new PortalUtils();
100+
spUtils.getProcessFlows(data,data.table,(data.sys_id == -1),gr);
101+
102+
```
103+
104+
## Step 2: Create a Script Include
105+
***Go to Script Includes (System Definition) > Click New***
106+
- Name: PortalUtils
107+
- Accessible from: This application scope only
108+
- Copy and Paste below Server-Side Script in Script Section:
109+
```javascript
110+
111+
var PortalUtils = Class.create();
112+
PortalUtils.prototype = Object.extendsObject(PortalUtilsBase, {
113+
initialize: function() {
114+
},
115+
type: 'PortalUtils'
116+
});
117+
```
118+
- Click on `Submit` button.
119+
120+
***Go to Script Includes (System Definition) > Click New***
121+
- Name: PortalUtilsBase
122+
- Accessible from: This application scope only
123+
- Copy and Paste below Server-Side Script in Script Section:
124+
```javascript
125+
var PortalUtilsBase = Class.create();
126+
PortalUtilsBase.prototype = {
127+
initialize: function() {
128+
},
129+
130+
getProcessFlows: function(data,table,newRecord, grRecord){
131+
data.processFlow = {show:false, items:[]};
132+
133+
var grProcessStates = new GlideRecord('sys_process_flow');
134+
grProcessStates.addQuery("table", table);
135+
grProcessStates.addQuery("active",true);
136+
grProcessStates.orderByDesc('order');
137+
grProcessStates.query();
138+
139+
var matchingFound = false;
140+
141+
while(grProcessStates.next()) {
142+
data.processFlow.show = true;
143+
144+
var item = {};
145+
146+
item.label = grProcessStates.getValue("label");
147+
148+
if(newRecord){
149+
item.class_name = "disabled";
150+
}else if(GlideFilter.checkRecord(grRecord,grProcessStates.getValue("condition"))){
151+
item.class_name = "completed active";
152+
matchingFound = true;
153+
}else{
154+
if(matchingFound)
155+
item.class_name = "completed active";
156+
else
157+
item.class_name = "disabled";
158+
}
159+
160+
data.processFlow.items.unshift(item);
161+
}
162+
163+
if(newRecord && data.processFlow.show && data.processFlow.items.length > 0){
164+
data.processFlow.items[0].class_name = "active";
165+
}
166+
},
167+
168+
type: 'PortalUtilsBase'
169+
};
170+
```
171+
- Click on `Submit` button.
172+
173+
## Step 3: Create a new Page
174+
***Go to Service Portal > Page > Click New***
175+
- Name: process_flow - Test Page
176+
- ID: process_flow
177+
- Click on `Submit` button.
178+
- Once submitted, Click on `Open in Page Designer` related link
179+
- In Page designer, Place `Process Flow` widget inside a container > row > Column at top location.
180+
- View paget from following link `http://instance-name.service-now.com/sp?id=process_flow`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(function() {
2+
/* populate the 'data' object */
3+
/* e.g., data.table = $sp.getValue('table'); */
4+
5+
data.table = $sp.getParameter("table");
6+
data.sys_id = $sp.getParameter("sys_id");
7+
8+
var gr = new GlideRecord(data.table);
9+
gr.get(data.sys_id);
10+
11+
var spUtils = new PortalUtils();
12+
spUtils.getProcessFlows(data,data.table,(data.sys_id == -1),gr);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
.btn-circle {
2+
width: 40px;
3+
height: 40px;
4+
text-align: center;
5+
padding: 6% 0;
6+
font-size: 6px;
7+
line-height: 0.6;
8+
border-radius: 100%;
9+
}
10+
11+
.process-row {
12+
display: table-row;
13+
}
14+
15+
.process {
16+
display: table;
17+
width: 100%;
18+
position: relative;
19+
}
20+
21+
.process-step button[disabled] {
22+
opacity: 1 !important;
23+
filter: alpha(opacity=100) !important;
24+
}
25+
26+
.process-row:before {
27+
top: 20px;
28+
bottom: 0;
29+
position: absolute;
30+
content: " ";
31+
width: 100%;
32+
height: 1px;
33+
background-color: #ccc;
34+
z-order: 0;
35+
36+
}
37+
38+
.process-step {
39+
display: table-cell;
40+
text-align: center;
41+
position: relative;
42+
padding-left: 0%;
43+
padding-right: 5%;
44+
}
45+
46+
.process-step p {
47+
margin-top:10px;
48+
49+
}
50+
51+
.btn-circle.active {
52+
border: 2px solid #cc0;
53+
}

0 commit comments

Comments
 (0)