Display Interaction → Case → Request → RITM hierarchy as a tree on all 4 record pages in UI Builder

ArshadHussA
Tera Contributor

 

Requirement

In a custom CSM workspace I want a tree view in the side panel of each record page showing the full hierarchy:

ArshadHussA_0-1779694795701.png

 

 
 

Tables / relations:

  • Interaction: u_interactionTable
  • Case: u_caseTable u_interaction references Interaction
  • Request: sc_request  parent references the Case
  • RITM: sc_req_item  request references the Request

The same tree should render on all four record pages (Interaction, Case, Request, RITM), with the current record highlighted and node clicks navigating within the workspace.

Release: Zurich

Thanks! 🙌

1 REPLY 1

BibinGokuldas13
ServiceNow Employee

Hi  ,

You can choose to use the : Content Tree Component + Custom Data Resource

Custom Component (optional wrapper) -> Content Tree component -> Data Resource (Scripted / Transform) -> Hierarchy Builder (Script Include / Server Script).
 
You need a script include to fetch the hierarchy:
var InteractionHierarchyUtil = Class.create();
InteractionHierarchyUtil.prototype = {

    getHierarchy: function(recordSysId, tableName) {

        var result = {};

        // 1. Resolve root Interaction
        var interaction = this._getInteraction(recordSysId, tableName);

        if (!interaction)
            return {};

        result = {
            id: interaction.sys_id + '#u_interaction',
            label: 'Interaction: ' + interaction.number,
            children: this._getCases(interaction.sys_id)
        };

        return result;
    },

    _getInteraction: function(sysId, table) {
        if (table == 'u_interaction') {
            return new GlideRecord('u_interaction').get(sysId) && this._cloneGR('u_interaction', sysId);
        }
        if (table == 'u_case') {
            var gr = new GlideRecord('u_case');
            if (gr.get(sysId))
                return this._cloneGR('u_interaction', gr.u_interaction);
        }
        if (table == 'sc_request') {
            var req = new GlideRecord('sc_request');
            if (req.get(sysId)) {
                var caseGR = new GlideRecord('u_case');
                if (caseGR.get(req.parent))
                    return this._cloneGR('u_interaction', caseGR.u_interaction);
            }
        }
        if (table == 'sc_req_item') {
            var ritm = new GlideRecord('sc_req_item');
            if (ritm.get(sysId)) {
                var req = new GlideRecord('sc_request');
                if (req.get(ritm.request)) {
                    var caseGR = new GlideRecord('u_case');
                    if (caseGR.get(req.parent))
                        return this._cloneGR('u_interaction', caseGR.u_interaction);
                }
            }
        }
        return null;
    },

    _getCases: function(interactionSysId) {
        var arr = [];
        var gr = new GlideRecord('u_case');
        gr.addQuery('u_interaction', interactionSysId);
        gr.query();

        while (gr.next()) {
            arr.push({
                id: gr.sys_id + '#u_case',
                label: 'Case: ' + gr.number,
                children: this._getRequests(gr.sys_id)
            });
        }
        return arr;
    },

    _getRequests: function(caseSysId) {
        var arr = [];
        var gr = new GlideRecord('sc_request');
        gr.addQuery('parent', caseSysId);
        gr.query();

        while (gr.next()) {
            arr.push({
                id: gr.sys_id + '#sc_request',
                label: 'Request: ' + gr.number,
                children: this._getRITMs(gr.sys_id)
            });
        }
        return arr;
    },

    _getRITMs: function(requestSysId) {
        var arr = [];
        var gr = new GlideRecord('sc_req_item');
        gr.addQuery('request', requestSysId);
        gr.query();

        while (gr.next()) {
            arr.push({
                id: gr.sys_id + '#sc_req_item',
                label: 'RITM: ' + gr.number
            });
        }
        return arr;
    },

    _cloneGR: function(table, sysId) {
        var gr = new GlideRecord(table);
        if (gr.get(sysId))
            return gr;
    }
};

 

Create a data resource in UI builder

-> Create a scripted data resource 

-> Call the script include which is mentioned above

The output format should match 

{
  "id": "sys_id#table",
  "label": "Display value",
  "children": []
}

 

Add the content tree to side panel

Next step is to Bind the data:

-> Content tree exposes selection event: event: Item clicked

Client Script as below:

 

function handler({api, event}) {

    var val = event.payload.item.id;
    var parts = val.split('#');

    var sysId = parts[0];
    var table = parts[1];

    api.emit('NAVIGATE', {
        route: {
            page: 'record',
            params: {
                table: table,
                sys_id: sysId
            }
        }
    });
}

 

Store the current record:

 

api.setState('currentNode', current.sys_id + '#' + current.table);

 

Bind this to :  selectedItemId = @STate.currentNode

 

For Performance ensure you follow the same

-> Consider not to fully load the tree blindly, use lazy load.

 

Content Tree Reference

 

 

Hope so it helps

 

Regards

Bibin