Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Client-Side Components/UI Actions/Kill flow timers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# UI Action to kill flow timers

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.

## How to use

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()*
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
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

![image](timer.png)

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//Onlick: openTimerDialog()

//open dialog using glidemodal and timer_kill_dialog ui page, pass in current sys_flow_context sysid
function openTimerDialog() {
var dialog = new GlideModal("timer_kill_dialog");
dialog.setTitle("Kill timers");
dialog.setPreference('sysparm_id', g_form.getUniqueValue());
dialog.render();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//name: timer_kill_dialog

//HTML:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:evaluate var="jvar_timers" object="true">
// executed server side, gets wait jobs for current flow context and returns object with information about timers
var array = [];
var waitJob = new GlideRecord("sys_trigger");
waitJob.addQuery("state", "0")
.addCondition("name", "flow.fire")
.addCondition("script", "CONTAINS", RP.getParameterValue("sysparm_id"));
waitJob.query();
while (waitJob.next()) {
var obj = {};
obj.sys_id = waitJob.getUniqueValue();
obj.waitUntil = waitJob.getValue("next_action");
var now = new GlideDateTime()
obj.timeLeft = GlideDateTime.subtract(now, new GlideDateTime(waitJob.getValue("next_action"))).getDisplayValue()
array.push(obj)
}
array;
</g:evaluate>

<style>
table td {
padding: 8px;
}

table thead td {
font-weight: bold;
background-color: #f0f0f0;
}
</style>

<!-- submittable form that shows the wait jobs in [sys_trigger] for context and a checkbox to select timers to kill -->
<g:ui_form>
<input type="hidden" id="sysids" name="sysids" value="" />
<div style="padding: 20px; font-family: sans-serif;">
<table>
<tbody>
<thead>
<td>timer sys_id</td>
<td>next action</td>
<td>time left</td>
<td>kill?</td>
</thead>
<j:forEach var="jvar_timer" items="${jvar_timers}">
<tr>
<td>
${jvar_timer.sys_id}
</td>
<td>
${jvar_timer.waitUntil}
</td>
<td>
${jvar_timer.timeLeft}
</td>
<td>
<g:ui_checkbox name="${jvar_timer.sys_id}">
</g:ui_checkbox>
</td>
</tr>
</j:forEach>
</tbody>
</table>
<g:dialog_buttons_ok_cancel ok="return okDialog()" />
</div>
</g:ui_form>
</j:jelly>

//Client script:
// handler for clicking ok on modal. gathers the sys_ids for the timers that have checked checkbox
function okDialog() {
var c = gel('sysids');
var sysids = [];
$j('input[type="checkbox"]:checked').each(function () {
var checkboxId = $j(this).attr('id').replace("ni.", "");
sysids.push(checkboxId);
});
c.value = sysids.toString();
return true;
}

//Processing script:
// queries for timer jobs and sets the job and new flow.fire event to process instantly -> timer on flow completes
var waitJob = new GlideRecord("sys_trigger");
waitJob.addQuery("sys_id", "IN", sysids);
waitJob.query();
while (waitJob.next()) {
var currentScript = waitJob.getValue("script");
var now = new GlideDateTime().getValue();
var replaceScript = currentScript.replace(/gr\.setValue\('process_on',\s*'[^']*'\)/, "gr.setValue('process_on','" + now + "')");
waitJob.setValue("script", replaceScript);
waitJob.setValue("next_action", now);
waitJob.update();
}
//redirect back to bottom of nav stack
var urlOnStack = GlideSession.get().getStack().bottom();
response.sendRedirect(urlOnStack);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading