Skip to content

Commit e679717

Browse files
authored
Ui action to kill flow timers (#2127)
* Create UI action.js * Create UI page for ui action.js * Create README.md * Add files via upload * Rename image.png to timer.png * Update README.md
1 parent 7b51f11 commit e679717

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# UI Action to kill flow timers
2+
3+
UI page that shows you all timers that a flow context [sys_flow_context] is waiting for. Shows sys_id of the sys_trigger, the datetime when the wait will finish and how long until that time. Select the checkbox and submit the modal form to kill that timer.
4+
5+
## How to use
6+
7+
1. Create ui action on [sys_flow_context] and input the script from *UI action.js* in the script field. Check client and set Onclick as *openTimerDialog()*
8+
2. Create ui page with name *timer_kill_dialog* and copy the HTML, client script and processing script from the *UI page for ui action.js* file
9+
3. Navigate to active flow context that is waiting for timers and click the ui action from step 1 and kill timer/s. Flow will progress as soon as the flow engine processes the flow.fire events
10+
11+
![image](timer.png)
12+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//Onlick: openTimerDialog()
2+
3+
//open dialog using glidemodal and timer_kill_dialog ui page, pass in current sys_flow_context sysid
4+
function openTimerDialog() {
5+
var dialog = new GlideModal("timer_kill_dialog");
6+
dialog.setTitle("Kill timers");
7+
dialog.setPreference('sysparm_id', g_form.getUniqueValue());
8+
dialog.render();
9+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//name: timer_kill_dialog
2+
3+
//HTML:
4+
<?xml version="1.0" encoding="utf-8" ?>
5+
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
6+
<g:evaluate var="jvar_timers" object="true">
7+
// executed server side, gets wait jobs for current flow context and returns object with information about timers
8+
var array = [];
9+
var waitJob = new GlideRecord("sys_trigger");
10+
waitJob.addQuery("state", "0")
11+
.addCondition("name", "flow.fire")
12+
.addCondition("script", "CONTAINS", RP.getParameterValue("sysparm_id"));
13+
waitJob.query();
14+
while (waitJob.next()) {
15+
var obj = {};
16+
obj.sys_id = waitJob.getUniqueValue();
17+
obj.waitUntil = waitJob.getValue("next_action");
18+
var now = new GlideDateTime()
19+
obj.timeLeft = GlideDateTime.subtract(now, new GlideDateTime(waitJob.getValue("next_action"))).getDisplayValue()
20+
array.push(obj)
21+
}
22+
array;
23+
</g:evaluate>
24+
25+
<style>
26+
table td {
27+
padding: 8px;
28+
}
29+
30+
table thead td {
31+
font-weight: bold;
32+
background-color: #f0f0f0;
33+
}
34+
</style>
35+
36+
<!-- submittable form that shows the wait jobs in [sys_trigger] for context and a checkbox to select timers to kill -->
37+
<g:ui_form>
38+
<input type="hidden" id="sysids" name="sysids" value="" />
39+
<div style="padding: 20px; font-family: sans-serif;">
40+
<table>
41+
<tbody>
42+
<thead>
43+
<td>timer sys_id</td>
44+
<td>next action</td>
45+
<td>time left</td>
46+
<td>kill?</td>
47+
</thead>
48+
<j:forEach var="jvar_timer" items="${jvar_timers}">
49+
<tr>
50+
<td>
51+
${jvar_timer.sys_id}
52+
</td>
53+
<td>
54+
${jvar_timer.waitUntil}
55+
</td>
56+
<td>
57+
${jvar_timer.timeLeft}
58+
</td>
59+
<td>
60+
<g:ui_checkbox name="${jvar_timer.sys_id}">
61+
</g:ui_checkbox>
62+
</td>
63+
</tr>
64+
</j:forEach>
65+
</tbody>
66+
</table>
67+
<g:dialog_buttons_ok_cancel ok="return okDialog()" />
68+
</div>
69+
</g:ui_form>
70+
</j:jelly>
71+
72+
//Client script:
73+
// handler for clicking ok on modal. gathers the sys_ids for the timers that have checked checkbox
74+
function okDialog() {
75+
var c = gel('sysids');
76+
var sysids = [];
77+
$j('input[type="checkbox"]:checked').each(function () {
78+
var checkboxId = $j(this).attr('id').replace("ni.", "");
79+
sysids.push(checkboxId);
80+
});
81+
c.value = sysids.toString();
82+
return true;
83+
}
84+
85+
//Processing script:
86+
// queries for timer jobs and sets the job and new flow.fire event to process instantly -> timer on flow completes
87+
var waitJob = new GlideRecord("sys_trigger");
88+
waitJob.addQuery("sys_id", "IN", sysids);
89+
waitJob.query();
90+
while (waitJob.next()) {
91+
var currentScript = waitJob.getValue("script");
92+
var now = new GlideDateTime().getValue();
93+
var replaceScript = currentScript.replace(/gr\.setValue\('process_on',\s*'[^']*'\)/, "gr.setValue('process_on','" + now + "')");
94+
waitJob.setValue("script", replaceScript);
95+
waitJob.setValue("next_action", now);
96+
waitJob.update();
97+
}
98+
//redirect back to bottom of nav stack
99+
var urlOnStack = GlideSession.get().getStack().bottom();
100+
response.sendRedirect(urlOnStack);
44 KB
Loading

0 commit comments

Comments
 (0)