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

Offical Documentation

Official Docs: