Escalation Action on Standard Ticket Incident Form

tsutherland
Kilo Sage

We are using the "Standard Ticket Configuration" that was new with the Paris release. On an incident in the portal, there are Actions OOB that include Resolve, Close, and Reopen.

find_real_file.png

Has anyone successfully created an Escalation action? I know there were lots of folks who did it in the older ticket display, but I'm trying to figure out how to create one in the Standard Ticket page.

I edited the (cloned) widget for the "Incident Standard Ticket Actions."

Server Script:

(function() {
    var incidentGr = new GlideRecord('incident');
	var incidentSysId = options.sys_id;
	
	if (!incidentSysId && $sp.getParameter('table') == 'incident')
		incidentSysId = $sp.getParameter('sys_id');
	
	if (!incidentSysId && $sp.getParameter('table') == 'universal_request') {
		var urGr = new GlideRecord('universal_request');
		urGr.get($sp.getParameter('sys_id'));
		incidentSysId = urGr.primary_task + "";
	}
	
	/* Actions - Start */
    if (input && input.action == 'resolveIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.RESOLVED;
		incidentGr.state = global.IncidentState.RESOLVED;
		incidentGr.resolved_by = gs.getUserID();
		incidentGr.update();
    }
	
	if (input && input.action == 'reopenIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.IN_PROGRESS;
		incidentGr.state = global.IncidentState.IN_PROGRESS;
		incidentGr.comments = "Ticket reopened. Caller did not feel the issue had been resolved.";
		incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Request reopened"));
    }
	
	if (input && input.action == 'closeIncident' && incidentGr.get(incidentSysId)) {
		incidentGr.incident_state = global.IncidentState.CLOSED;
		incidentGr.state = global.IncidentState.CLOSED;
		incidentGr.update();
    }
	if (input && input.action == 'escalateIncident' && incidentGR.get(incidentSysID)) {
		incidentGr.incident_impact = high;
		incidentGr.incident_urgency = high;
		incidentGr.incident_priority = high;
		incidentGr.comments = "Please escalate the priority of this incident.";
		incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Incident Escalated"));
	}

   /* Actions - End */
	

	/* Load incident data */
    if (incidentGr.get(incidentSysId)) {
		var incidentUtils = new global.IncidentUtils();
		data.canResolve = incidentUtils.canResolveIncident(incidentGr);
		data.canReopen = incidentUtils.canReopenIncident(incidentGr);
		data.canClose = incidentUtils.canCloseIncident(incidentGr);
		data.canEscalate = incidentUtils.canEscalateIncident(incidentGr);
		data.showActions = data.canResolve || data.canReopen || data.canClose || data.canEscalate;
    }

    data.i18n = {};

})();

and the client controller: 

function incidentTicketActions($scope, $http, spUtil, $timeout, spModal, i18n, $window, $uibModal) {
    /* widget controller */
    var c = this;
    c.doneLoading = false;

    var MOBILE_DEVICE_SCREEN_WIDTH = 767;
    $scope.mobileDevice = c.data.isMobile || ($window.innerWidth < MOBILE_DEVICE_SCREEN_WIDTH);


	$scope.resolveIncident = function() {
        $scope.data.action = 'resolveIncident';
        $scope.server.update(init);
    };
	
	$scope.closeIncident = function() {
		$scope.data.action = 'closeIncident';
        $scope.server.update(init);
	};

    $scope.reopenIncident = function() {
        $scope.data.action = 'reopenIncident';
        $scope.server.update(init);
    };
	
	$scope.escalateIncident = function() {
		$scope.data.action = 'escalateIncident';
		$scope.server.update(init);
	};

    function init() {}
	
    $(document).on('click', 'div.modal-footer button.btn, ul#child-case-tabs .dropdown-menu', function(e) {
        e.stopPropagation();
    });

    $(document).bind('dragover drop', function(event) {
        event.preventDefault();
        return false;
    });

    $scope.$on('sp_loading_indicator', function(e, value) {
        if (!value && !c.doneLoading) {
            c.doneLoading = true;
        }
    });


}

Here is the IncidentUtils Script Include:

var IncidentUtils = Class.create();
IncidentUtils.prototype = Object.extendsObject(IncidentUtilsSNC, {
    initialize: function() {
	IncidentUtilsSNC.prototype.initialize.call(this);
    },
    /***************Custom changes****************/	
	canReopenIncident: function(current){
	return current.incident_state == IncidentState.RESOLVED && !this._isMajorIncident(current);
    },
	canEscalateIncident: function(current){
		return current.incident_state == IncidentState.Active || IncidentState.New || IncidentState.OnHold;
	},
	
    type: 'IncidentUtils'	
});

IncidentUtils.isCopyIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCopyIncidentFlagValid();
	
};

IncidentUtils.isCreateChildIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCreateChildIncidentFlagValid();
	
};

I'm not confident coding on my own, obviously I just copied and edited what was there. I feel like I'm missing something about the action and maybe the scope, but I don't know where to start.

Thanks in advance for your advice.

1 ACCEPTED SOLUTION

Hi,

You have done most of the things right. However I'll share the complete working code here.

Here is what you need to change.

Open the widget- "Incident Standard Ticket Actions"

Body HTML Template:

<div>
    <div class="dropdown" id="child-case-tabs" ng-if="data.showActions">
        <button type="button" id="actions-button" class="btn btn-default dropdown-toggle action-btn" data-toggle="dropdown" style="width : 100%" aria-haspopup="true" ng-init="setFocusOnActionButtons()">
            ${Actions}
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu pull-right" id="actionList">
            <li>
                <a ng-if="data.canResolve" href="javascript:void(0)" ng-click="$event.stopPropagation();resolveIncident()">${Resolve}</a>
            </li>
            <li>
                <a ng-if="data.canReopen" href="javascript:void(0)" ng-click="$event.stopPropagation();reopenIncident()">${Reopen}</a>
            </li>
            <li>
                <a ng-if="data.canClose" href="javascript:void(0)" ng-click="$event.stopPropagation();closeIncident()">${Close}</a>
            </li>
          <li>
                <a ng-if="data.canEscalate" href="javascript:void(0)" ng-click="$event.stopPropagation();escalateIncident()">${Escalate}</a>
            </li>
        </ul>
    </div>
  
</div>

CSS - No change

Server Script:

(function() {
    var incidentGr = new GlideRecord('incident');
	var incidentSysId = options.sys_id;
	
	if (!incidentSysId && $sp.getParameter('table') == 'incident')
		incidentSysId = $sp.getParameter('sys_id');
	
	if (!incidentSysId && $sp.getParameter('table') == 'universal_request') {
		var urGr = new GlideRecord('universal_request');
		urGr.get($sp.getParameter('sys_id'));
		incidentSysId = urGr.primary_task + "";
	}
	
	/* Actions - Start */
    if (input && input.action == 'resolveIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.RESOLVED;
		incidentGr.state = global.IncidentState.RESOLVED;
		incidentGr.resolved_by = gs.getUserID();
		data.isIncidentResolved = incidentGr.update();
    }
	
	if (input && input.action == 'reopenIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.IN_PROGRESS;
		incidentGr.state = global.IncidentState.IN_PROGRESS;
		data.isIncidentReopened = incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Request reopened"));
    }
	
	if (input && input.action == 'closeIncident' && incidentGr.get(incidentSysId)) {
		incidentGr.incident_state = global.IncidentState.CLOSED;
		incidentGr.state = global.IncidentState.CLOSED;
		data.isIncidentClosed = incidentGr.update();
    }
	
	if (input && input.action == 'escalateIncident' && incidentGr.get(incidentSysId)) {
		incidentGr.work_notes = "Escalated"; //Here I am just adding work notes to test, you can set the value of escalate field true or false or whatever required
		data.isIncidentEscalated = incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Incident Escalated"));
    }
	

   /* Actions - End */
	
	/* Load incident data */
    if (incidentGr.get(incidentSysId)) {
		var incidentUtils = new global.IncidentUtils();
		data.canResolve = incidentUtils.canResolveIncident(incidentGr);
		data.canReopen = incidentUtils.canReopenIncident(incidentGr);
		data.canClose = incidentUtils.canCloseIncident(incidentGr);
		data.canEscalate = incidentUtils.canEscalateIncident(incidentGr);
		data.showActions = data.canResolve || data.canReopen || data.canClose || data.canEscalate;
    }

    data.i18n = {};

})();

 

Client controller:

function incidentTicketActions($scope, $http, spUtil, $timeout, spModal, i18n, $window, $uibModal, spAriaUtil) {
    /* widget controller */
    var c = this;
    c.doneLoading = false;
    c.resolvedIncidentMsg = "${Resolved Incident}";
    c.closedIncidentMsg = "${Closed Incident}";
    c.reopenedIncidentMsg = "${Reopened Incident}";
    c.escalateIncidentMsg = "${Escalated Incident}";

    var MOBILE_DEVICE_SCREEN_WIDTH = 767;
    $scope.mobileDevice = c.data.isMobile || ($window.innerWidth < MOBILE_DEVICE_SCREEN_WIDTH);

    $scope.resolveIncident = function() {
        $scope.data.action = 'resolveIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentResolved)
                spAriaUtil.sendLiveMessage(c.resolvedIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };

    $scope.closeIncident = function() {
        $scope.data.action = 'closeIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentClosed)
                spAriaUtil.sendLiveMessage(c.closedIncidentMsg);
        });
        var elm = document.getElementById('short-desc');
        elm.focus();
    };

    $scope.reopenIncident = function() {
        $scope.data.action = 'reopenIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentReopened)
                spAriaUtil.sendLiveMessage(c.reopenedIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };

    $scope.escalateIncident = function() {
        $scope.data.action = 'escalateIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentEscalated)
                spAriaUtil.sendLiveMessage(c.escalateIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };


    function init() {}

    $(document).on('click', 'div.modal-footer button.btn, ul#child-case-tabs .dropdown-menu', function(e) {
        e.stopPropagation();
    });

    $(document).bind('dragover drop', function(event) {
        event.preventDefault();
        return false;
    });

    $scope.$on('sp_loading_indicator', function(e, value) {
        if (!value && !c.doneLoading) {
            c.doneLoading = true;
        }
    });
}

Script Include : IncidentUtils

var IncidentUtils = Class.create();
IncidentUtils.prototype = Object.extendsObject(IncidentUtilsSNC, {
    initialize: function() {
	IncidentUtilsSNC.prototype.initialize.call(this);
    },
    /***************Custom changes****************/	
	
	canEscalateIncident: function(current){
        if (current.incident_state == 1 || current.incident_state == 2) //checking if state is New or In progress, Add one more condition to check if escalte is set to true already with the use of current object. This is required if you want to hide the button if the incident is already escalated.
            return true;
            },
	
    type: 'IncidentUtils'	
});

IncidentUtils.isCopyIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCopyIncidentFlagValid();
	
};

IncidentUtils.isCreateChildIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCreateChildIncidentFlagValid();
	
};

 

Mark my response correct if it worked for you. 🙂

Ask for more help if required.

Jagjeet Singh
ServiceNow Community Rising Star 2022/2023

View solution in original post

7 REPLIES 7

JagjeetSingh
Kilo Sage
Kilo Sage

Hi,

Show me the html part of your widget. You need to make some changes there as well.

 

Jagjeet Singh
ServiceNow Community Rising Star 2022/2023

@Jagjeet Singh Here is the html

<div>
    <div class="dropdown" id="child-case-tabs" ng-if="data.showActions">
        <button type="button" class="btn btn-default dropdown-toggle action-btn" data-toggle="dropdown" style="width : 100%">
            ${Actions}
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" id="actionList">
            <li>
                <a ng-if="data.canResolve" href="javascript:void(0)" ng-click="$event.stopPropagation();resolveIncident()">${Resolve}</a>
            </li>
            <li>
                <a ng-if="data.canReopen" href="javascript:void(0)" ng-click="$event.stopPropagation();reopenIncident()">${Reopen}</a>
            </li>
            <li>
                <a ng-if="data.canClose" href="javascript:void(0)" ng-click="$event.stopPropagation();closeIncident()">${Close}</a>
          </li>
          <li>
            <a ng-if="data.canEscalate" href="javascript:void(0)" ng-click="$event.stopPropagation();escalateIncident()">${Escalate}</a>
            </li>
        </ul>
    </div>
  
</div>

Thanks!

Hi,

You have done most of the things right. However I'll share the complete working code here.

Here is what you need to change.

Open the widget- "Incident Standard Ticket Actions"

Body HTML Template:

<div>
    <div class="dropdown" id="child-case-tabs" ng-if="data.showActions">
        <button type="button" id="actions-button" class="btn btn-default dropdown-toggle action-btn" data-toggle="dropdown" style="width : 100%" aria-haspopup="true" ng-init="setFocusOnActionButtons()">
            ${Actions}
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu pull-right" id="actionList">
            <li>
                <a ng-if="data.canResolve" href="javascript:void(0)" ng-click="$event.stopPropagation();resolveIncident()">${Resolve}</a>
            </li>
            <li>
                <a ng-if="data.canReopen" href="javascript:void(0)" ng-click="$event.stopPropagation();reopenIncident()">${Reopen}</a>
            </li>
            <li>
                <a ng-if="data.canClose" href="javascript:void(0)" ng-click="$event.stopPropagation();closeIncident()">${Close}</a>
            </li>
          <li>
                <a ng-if="data.canEscalate" href="javascript:void(0)" ng-click="$event.stopPropagation();escalateIncident()">${Escalate}</a>
            </li>
        </ul>
    </div>
  
</div>

CSS - No change

Server Script:

(function() {
    var incidentGr = new GlideRecord('incident');
	var incidentSysId = options.sys_id;
	
	if (!incidentSysId && $sp.getParameter('table') == 'incident')
		incidentSysId = $sp.getParameter('sys_id');
	
	if (!incidentSysId && $sp.getParameter('table') == 'universal_request') {
		var urGr = new GlideRecord('universal_request');
		urGr.get($sp.getParameter('sys_id'));
		incidentSysId = urGr.primary_task + "";
	}
	
	/* Actions - Start */
    if (input && input.action == 'resolveIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.RESOLVED;
		incidentGr.state = global.IncidentState.RESOLVED;
		incidentGr.resolved_by = gs.getUserID();
		data.isIncidentResolved = incidentGr.update();
    }
	
	if (input && input.action == 'reopenIncident' && incidentGr.get(incidentSysId)) {
        incidentGr.incident_state = global.IncidentState.IN_PROGRESS;
		incidentGr.state = global.IncidentState.IN_PROGRESS;
		data.isIncidentReopened = incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Request reopened"));
    }
	
	if (input && input.action == 'closeIncident' && incidentGr.get(incidentSysId)) {
		incidentGr.incident_state = global.IncidentState.CLOSED;
		incidentGr.state = global.IncidentState.CLOSED;
		data.isIncidentClosed = incidentGr.update();
    }
	
	if (input && input.action == 'escalateIncident' && incidentGr.get(incidentSysId)) {
		incidentGr.work_notes = "Escalated"; //Here I am just adding work notes to test, you can set the value of escalate field true or false or whatever required
		data.isIncidentEscalated = incidentGr.update();
		gs.addInfoMessage(gs.getMessage("Incident Escalated"));
    }
	

   /* Actions - End */
	
	/* Load incident data */
    if (incidentGr.get(incidentSysId)) {
		var incidentUtils = new global.IncidentUtils();
		data.canResolve = incidentUtils.canResolveIncident(incidentGr);
		data.canReopen = incidentUtils.canReopenIncident(incidentGr);
		data.canClose = incidentUtils.canCloseIncident(incidentGr);
		data.canEscalate = incidentUtils.canEscalateIncident(incidentGr);
		data.showActions = data.canResolve || data.canReopen || data.canClose || data.canEscalate;
    }

    data.i18n = {};

})();

 

Client controller:

function incidentTicketActions($scope, $http, spUtil, $timeout, spModal, i18n, $window, $uibModal, spAriaUtil) {
    /* widget controller */
    var c = this;
    c.doneLoading = false;
    c.resolvedIncidentMsg = "${Resolved Incident}";
    c.closedIncidentMsg = "${Closed Incident}";
    c.reopenedIncidentMsg = "${Reopened Incident}";
    c.escalateIncidentMsg = "${Escalated Incident}";

    var MOBILE_DEVICE_SCREEN_WIDTH = 767;
    $scope.mobileDevice = c.data.isMobile || ($window.innerWidth < MOBILE_DEVICE_SCREEN_WIDTH);

    $scope.resolveIncident = function() {
        $scope.data.action = 'resolveIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentResolved)
                spAriaUtil.sendLiveMessage(c.resolvedIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };

    $scope.closeIncident = function() {
        $scope.data.action = 'closeIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentClosed)
                spAriaUtil.sendLiveMessage(c.closedIncidentMsg);
        });
        var elm = document.getElementById('short-desc');
        elm.focus();
    };

    $scope.reopenIncident = function() {
        $scope.data.action = 'reopenIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentReopened)
                spAriaUtil.sendLiveMessage(c.reopenedIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };

    $scope.escalateIncident = function() {
        $scope.data.action = 'escalateIncident';
        $scope.server.update(init).then(function(response) {
            if (response.isIncidentEscalated)
                spAriaUtil.sendLiveMessage(c.escalateIncidentMsg);
        });
        $scope.$emit('focusOnActions', {
            "isFocusRequired": true
        });
    };


    function init() {}

    $(document).on('click', 'div.modal-footer button.btn, ul#child-case-tabs .dropdown-menu', function(e) {
        e.stopPropagation();
    });

    $(document).bind('dragover drop', function(event) {
        event.preventDefault();
        return false;
    });

    $scope.$on('sp_loading_indicator', function(e, value) {
        if (!value && !c.doneLoading) {
            c.doneLoading = true;
        }
    });
}

Script Include : IncidentUtils

var IncidentUtils = Class.create();
IncidentUtils.prototype = Object.extendsObject(IncidentUtilsSNC, {
    initialize: function() {
	IncidentUtilsSNC.prototype.initialize.call(this);
    },
    /***************Custom changes****************/	
	
	canEscalateIncident: function(current){
        if (current.incident_state == 1 || current.incident_state == 2) //checking if state is New or In progress, Add one more condition to check if escalte is set to true already with the use of current object. This is required if you want to hide the button if the incident is already escalated.
            return true;
            },
	
    type: 'IncidentUtils'	
});

IncidentUtils.isCopyIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCopyIncidentFlagValid();
	
};

IncidentUtils.isCreateChildIncidentEnabled = function(current) {
	var incidentUtils = new IncidentUtils();
	return incidentUtils.isCreateChildIncidentFlagValid();
	
};

 

Mark my response correct if it worked for you. 🙂

Ask for more help if required.

Jagjeet Singh
ServiceNow Community Rising Star 2022/2023

Here is how it looks.

find_real_file.png

 

 

 

Jagjeet Singh
ServiceNow Community Rising Star 2022/2023