Apply IR template to existing Incident record
Hi,
Working with a customer who wants to replicate the task from the Service Manager console whereby you can apply an existing template to an Incident record. Eg. Open an Incident record and apply the 'Major Incident' template. Can this be accomplished in the Cireson portal?
Thanks
Steve
Best Answers
-
Geoff_Ross Cireson Consultant O.G.Sorry Steve, just realised I forgot to bookmark this one so I didn't see your request for more detail.
So, if you still need (or for anyone else including @Magnus_Andersson)...
You would need to create a custom task that does to following,- Loads all the templates of the specific class via the portal API
- Pops open a window allowing the user to select a template from a drop down.
- When the user clicks OK, grab the template object they selected
- *** NB All of the above can be copied from the SR - IR example
- From the template object, copy the fields required into the view model
- Call the page save function to save your work item with the new values.
6 -
Olena_Prychyna Customer IT Monkey ✭
customtasks.applytemplate.html:
<div> <!--Make sure you have an outer div if you are putting this in a kendo window-->
<div id="commentHTML" class="form-horizontal">
<div>
<div class="col-group">
<div class="inline-spacing">
<label>Please select a template to apply:</label>
</div>
<div class="inline-spacing">
<select id="templateselected" data-role="dropdownlist" data-bind="source: dropDownData, events: { change: valueChanged, dataBound: valueChanged }" data-text-field="Name" data-value-field="Id"/>
</div>
</div>
<div class="window-buttons">
<button data-role="button"
class="btn btn-primary"
data-bind="enabled: okEnabled, events: { click: okClick }">
OK
</button>
<button data-role="button"
class="btn btn-primary"
data-bind=" events: { click: cancelClick }">
Cancel
</button>
</div>
</div>
</div>
</div>5
Answers
Yes, this can be done. In very brief terms, (anyone reading this let me know if you want more detail) you need to use the get templates API call, work out which one you need, then copy properties one by one to the view model and then commit it.
Geoff
So, is it alot of work to get this to work?
So, if you still need (or for anyone else including @Magnus_Andersson)...
You would need to create a custom task that does to following,
- Loads all the templates of the specific class via the portal API
- Pops open a window allowing the user to select a template from a drop down.
- When the user clicks OK, grab the template object they selected
- *** NB All of the above can be copied from the SR - IR example
- From the template object, copy the fields required into the view model
- Call the page save function to save your work item with the new values.
GeoffJust curious if anybody has developed this functionality and is willing to share their code? Thanks!
Geoff, we followed your steps and this code works for us:
custom.js:
/* ------------------------------------------------------------------------------------------- */
/* ----------- Incident - Apply Template ----------------------------------------------------- */
/* - Task is available only for New incident (before it is submitted) */
/* - Analyst comment will be in the Incident comment field, so they can manually add it to IR */
/*Problems: */
/* - TemplateApplied log is created as EndUserComments, but not as ActionLog */
/* -------------------------------------------------------------------------------------------- */
//show task only for New IR
app.custom.formTasks.add('Incident', null, function (formObj, viewModel) {
formObj.boundReady(function(){
//If the incident is not New don't show the Apply Template task
if(window.location.href.indexOf("Incident/New")== -1){
$("li[class='link']:contains('Apply Template')").hide();
}
});
});
//Incident - Apply Template - add task
app.custom.formTasks.add('Incident', "Apply Template", function (formObj, viewModel) {
var classid = "a604b942-4c7b-2fb2-28dc-61dc6f465c68";
$.ajax({
url: "/api/V3/Template/GetTemplates",
data: {classId: classid},
type: "GET",
success: function (data) {
console.log (data)
//Call the loadTemplates Function and send it the PR Template Names and Id's
loadTemplates(data);
}
});
function loadTemplates (templateData){
//use requirejs to load the HTML template first
require(["text!/CustomSpace/customtasks.applytemplate.html"],
function (htmlTemplate) {
//make a jQuery obj
templateObj = $(htmlTemplate);
//create a view model to handle the UX
var dataItem;
var _vmWindow = new kendo.observable({
dropDownData: templateData,
valueChanged : function(e) {
dataItem = e.sender.dataItem();
// console.log (dataItem.Id)
},
okClick: function () {
var tempId = dataItem.Id //$("#templateselected option:selected").val();
var tempName = dataItem.Name //$("#templateselected option:selected").text();
updateIncident(tempId,tempName );
customWindow.close();
},
cancelClick: function () {
customWindow.close();
}
});
//create the kendo window
customWindow = templateObj.kendoWindow({
title: "Apply Template",
resizable: false,
modal: true,
viewable: false,
width: 500,
height: 300,
close: function () {
},
activate: function () {
//on window activate bind the view model to the loaded template content
kendo.bind(templateObj, _vmWindow);
}
}).data("kendoWindow");
//now open the window
customWindow.open().center();
}
);
}
function updateIncident(selectedTempId, selectedTempName) {
//selectedTemp is a json object
var incident = pageForm.viewModel;
//get template content and save every property into pageForm
$.ajax({
url: "/api/V3/Projection/CreateProjectionByTemplate",
data: {id: selectedTempId, createdById: session.user.Id},
type: "GET",
success: function (data) {
//Copy properties from Projection into current IR
incident.set("Title",data.Title);
var oldDescr='';
if(incident.Description){oldDescr = incident.Description + '\n' ;}
var newDescr = oldDescr + data.Description;
incident.set("Description",newDescr);
incident.set("Source",data.Source);
incident.set("TierQueue",data.TierQueue);
incident.set("HasCreatedKnowledgeArticle",data.HasCreatedKnowledgeArticle);
incident.set("Classification",data.Classification);
incident.set("CauseCode",data.CauseCode);
incident.set("Impact",data.Impact);
incident.set("Urgency",data.Urgency);
//show Analyst Comment in comment field, so they can add it manually
var commentBox = $("div[class=form-group]").find("textarea");
commentBox.focus();
commentBox.val(data.AppliesToTroubleTicket[0].Comment);
commentBox.keyup();
//add relationships
//functions-helpers
var isDuplicate = function (idToAdd) {
var n = false;
$.each(boundArray, function (i, item) {
if (item.BaseId == idToAdd) {
n = true;
}
});
return n;
}
var addAffectedItem = function (baseId ) {
if (isDuplicate(baseId)) { return; }
$.getJSON('/ConfigItems/GetAffectedItem', { id: baseId }, function (json) {
var item = {
BaseId: baseId,
DisplayName: json.DisplayName,
Path: json.Path,
AssetStatus: { Name: !_.isUndefined(json.AssetStatus) ? json.AssetStatus : "" },
Status: { Name: !_.isUndefined(json.Status) ? json.Status : "" }
};
boundArray.push(item);
});
}
//--end of functions-helpers
//init incident.HasRelatedWorkItems array - need it for incident.AppliesToTroubleTicket to work - ?
if (_.isUndefined(incident.HasRelatedWorkItems)) {
incident.set('HasRelatedWorkItems', new kendo.data.ObservableArray([]));
}
var boundArray = incident.get('HasRelatedWorkItems');
for(var i=0; i < data.HasRelatedWorkItems.length; i++){
addAffectedItem(data.HasRelatedWorkItems[i].BaseId);
};
//add action logs
//template applied - wrong log type ?
incident.AppliesToTroubleTicket.push({
"ActionType": "EndUserComment", //not in Action Log
"EnteredBy": session.user.Name,
"Title": "EndUserComment",
"EnteredDate": new Date().toISOString().split(".")[0],
"LastModified": new Date().toISOString().split(".")[0],
"Description": "Template applied: " + selectedTempName,
"Image": "/Content/Images/Icons/ActionLogIcons/recordopened/templateapplied.png",
"LastUpdatedDisplay": null
});
}
});
}
});
customtasks.applytemplate.html:
<div> <!--Make sure you have an outer div if you are putting this in a kendo window-->
<div id="commentHTML" class="form-horizontal">
<div>
<div class="col-group">
<div class="inline-spacing">
<label>Please select a template to apply:</label>
</div>
<div class="inline-spacing">
<select id="templateselected" data-role="dropdownlist" data-bind="source: dropDownData, events: { change: valueChanged, dataBound: valueChanged }" data-text-field="Name" data-value-field="Id"/>
</div>
</div>
<div class="window-buttons">
<button data-role="button"
class="btn btn-primary"
data-bind="enabled: okEnabled, events: { click: okClick }">
OK
</button>
<button data-role="button"
class="btn btn-primary"
data-bind=" events: { click: cancelClick }">
Cancel
</button>
</div>
</div>
</div>
</div>
Thanks for this! - I'm attempting to do this myself and it's working very well with one exception. When the Apply Template option is picked - it shows blocks in the empty white space.
See below
I have tried some things to resolve but nothing has worked so far. Any ideas on why it's doing this? This happens on any browser I test it on
thanks
However I have been struggling to also get it to set the 'Assigned To' from the template. I added incident.set("AssignedTo",data.AssignedTo); to the custom.js but it doesn't add the data from the template.
To set the "Assigned To" field from template:
incident.AssignedWorkItem.set("DisplayName", data.AssignedWorkItem.DisplayName);
incident.AssignedWorkItem.set("BaseId", data.AssignedWorkItem.BaseId);
@Olena_Prychyna I saw your post and have a few questions.
Where do you put the file with your code customtasks.applytemplate.html:, and where do you insert the "Assigned To" code to your code?
Karen_Bruster1 you should add the code into custom.js file. We have it in: C:\inetpub\CiresonPortal\CustomSpace\custom.js
As you see in the code the location of .html file is specified in:
function loadTemplates (templateData){
require(["text!/CustomSpace/customtasks.applytemplate.html"], ...
so it is also in C:\inetpub\CiresonPortal\CustomSpace\
@Olena_Prychyna Where in the custom.js would you add this?
And I noticed you have this setup to work with New IR's but what if you want to use it for already Active IRs?
Karen_Bruster1, we tried to reproduce the Console behavior where Apply Template works only for new IR. But I think it should work for an Active IR as well. We did not test it though.
For that you should replace Incident/New with Incident/Edit in code:
if(window.location.href.indexOf("Incident/New")== -1){
I know this is an older post, but is there a way to have this task also apply any activities in the template?