Name
global.FlowDesignerRecommendations
Description
No description available
Script
var FlowDesignerRecommendations = Class.create();
FlowDesignerRecommendations.prototype = {
TYPE_ACTION: "action",
TYPE_SUBFLOW: "subflow",
TYPE_FLOW_LOGIC: "flowlogic",
NAME_FIELD: "name",
SYS_SCOPE_FIELD: "sys_scope",
SYS_UPDATED_ON_FIELD: "sys_updated_on",
SYS_ID: "sys_id",
SYS_HUB_ACTION_TYPE_DEF_TABLE: "sys_hub_action_type_definition",
SYS_HUB_FLOW_TABLE: "sys_hub_flow",
initialize: function() {
this.itemsRecommended = [];
this.itemsRecommendedForUi = [];
this.itemsRecommendedForUiObject = {};
this.scopesList = [];
this.itemsRecommendedObject = {};
this.scopes = {};
},
processResponse: function(response) {
var scopesList = this.scopesList;
if (!(response && response["fOutputs"] && response["fOutputs"][0] && response["fOutputs"][0][1] &&
response["fOutputs"][0][1][0] && response["fOutputs"][0][1][0])) {
throw new Error("Unexpected response from prediction server");
}
this.itemsRecommended = JSON.parse(response["fOutputs"][0][1][0]["result"]["NextSteps"]);
var itemsRecommended = this.itemsRecommended;
var itemsRecommendedForUiObject = this.itemsRecommendedForUiObject;
var itemsRecommendedForUi = this.itemsRecommendedForUi;
var itemsRecommendedObject = this.itemsRecommendedObject;
// provide ability to display more recommendations on UI
// if predictor starts recommending more than 5 items in the future.
var maxRecommendationsToDisplay = gs.getProperty('sn_flow_designer.max_recommendations_to_display') || 5;
// if there are lesser items recommended and property value is higher,
// use the lower value
if (maxRecommendationsToDisplay > itemsRecommended.length) {
maxRecommendationsToDisplay = itemsRecommended.length;
}
for (var i = 0; i < maxRecommendationsToDisplay; i++) {
var currentItem = itemsRecommended[i];
var currentItemName = currentItem.name;
if (!currentItemName) {
continue;
}
if (currentItem.scopeName) {
itemsRecommendedObject[currentItemName] = {
scope: currentItem.scopeName,
rank: i + 1
};
scopesList.push(currentItem.scopeName);
} else {
var itemForUiObject = {
name: currentItemName,
sys_id: '',
scope: '',
type: this.TYPE_FLOW_LOGIC,
rank: i + 1
};
itemsRecommendedForUiObject[currentItemName] = itemForUiObject;
}
}
this.processTableData(this.SYS_HUB_ACTION_TYPE_DEF_TABLE, this.TYPE_ACTION);
if (Object.keys(this.itemsRecommendedForUiObject).length < this.itemsRecommended.length) {
this.processTableData(this.SYS_HUB_FLOW_TABLE, this.TYPE_SUBFLOW);
}
this.getScopeLogos();
for (var key in this.itemsRecommendedForUiObject) {
this.itemsRecommendedForUi.push(itemsRecommendedForUiObject[key]);
}
// sort items based on the rank of recommendations
this.itemsRecommendedForUi.sort(function(a, b) {
if (a.rank > b.rank) return 1;
if (a.rank < b.rank) return -1;
return 0;
});
return {
scopes: this.scopes,
itemsRecommendedForUi: this.itemsRecommendedForUi
}
},
buildQuery: function(list) {
var builtQuery = "";
for (var j = 0; j < list.length; j++) {
if (j === 0) {
builtQuery = "name=" + list[j];
} else {
builtQuery += "^ORname=" + list[j];
}
}
return builtQuery;
},
processTableData: function(table_name, type) {
var itemsRecommendedObject = this.itemsRecommendedObject;
var itemsRecommendedForUiObject = this.itemsRecommendedForUiObject;
var tableGlideRecord = new GlideRecord(table_name);
var itemNames = Object.keys(itemsRecommendedObject);
var buildQueryItems = this.buildQuery(itemNames);
if (type === this.TYPE_SUBFLOW) {
tableGlideRecord.addEncodedQuery('active=true^type=subflow^' + buildQueryItems);
} else {
tableGlideRecord.addEncodedQuery('active=true^' + buildQueryItems);
}
tableGlideRecord.query();
while (tableGlideRecord.next()) {
try {
var itemName = tableGlideRecord.getValue(this.NAME_FIELD);
var scopeName = tableGlideRecord.getDisplayValue(this.SYS_SCOPE_FIELD);
if (!itemsRecommendedObject[itemName] || scopeName.toUpperCase() !== itemsRecommendedObject[itemName].scope.toUpperCase()) {
continue;
}
var canReadItem = tableGlideRecord.canRead();
var actionUpdatedOn = tableGlideRecord.getValue(this.SYS_UPDATED_ON_FIELD);
if (type === this.TYPE_SUBFLOW) {
var masterSnapshotId = tableGlideRecord.getValue("master_snapshot");
var latestSnapshotId = tableGlideRecord.getValue("latest_snapshot");
if (masterSnapshotId == null && latestSnapshotId == null) {
continue;
}
}
if (canReadItem && itemsRecommendedObject[itemName]) {
if (itemsRecommendedForUiObject[itemName] && itemsRecommendedForUiObject[itemName].scope === scopeName) {
var dateOfPrevItem = new Date(itemsRecommendedForUiObject[itemName].updated);
var dateOfCurrentItem = new Date(actionUpdatedOn);
if (dateOfPrevItem > dateOfCurrentItem) {
continue;
}
}
var itemForUi = {
name: itemName,
sys_id: tableGlideRecord.getValue(this.SYS_ID),
scope: scopeName,
updated: actionUpdatedOn,
rank: itemsRecommendedObject[itemName].rank
};
if (type === this.TYPE_ACTION) {
itemForUi['type'] = this.TYPE_ACTION;
} else if (type === this.TYPE_SUBFLOW) {
itemForUi['type'] = this.TYPE_SUBFLOW;
itemForUi['masterSnapshotId'] = masterSnapshotId;
itemForUi['latestSnapshot'] = latestSnapshotId;
}
itemsRecommendedForUiObject[itemName] = itemForUi;
}
} catch (e) {
gs.log("Exception thrown while building items from table" + e);
}
}
},
getScopeLogos: function() {
var scopesRecord = new GlideRecord(this.SYS_SCOPE_FIELD);
var builtQueryScopes = this.buildQuery(this.scopesList);
scopesRecord.addEncodedQuery(builtQueryScopes);
scopesRecord.query();
while (scopesRecord.next()) {
var currentScopeName = scopesRecord.getValue(this.NAME_FIELD);
var currentScopeLogo = scopesRecord.getValue("logo");
this.scopes[currentScopeName] = currentScopeLogo ? currentScopeLogo + '.iix' : null;
}
},
type: 'FlowDesignerRecommendations'
};
Sys ID
e3964856432621100b7b5586bab8f210