Use script includes with list component in UI Builder for a landing page

NFGDom
Mega Sage

I'm hoping someone can give a hand, or advice on where I'm at. Maybe I've stared at this too long, maybe I'm missing a knowledge gab - either way, thank you in advance!

Goal: Have a list component using UI Builder where a manager can see all requests or incidents for their group members. Use this list component as a report on a landing page.

Where I'm at: to my knowledge, there is nothing OOB that allows you to do this. So I went down the path of creating script includes to be called as part of the list filter in UI Builder.

The first script include follow's SNGuru's Advanced 'getMyGroup's function. I'm using this in the second script include as a call to return all the members within those groups.

Please see script includes attached.

I've made it as far as trying to call the 'getGroupMembers()' function within background scripts just to make sure it works before I tried it with the UI Builder list component. However, it does not return anything and I'm not sure why.

Again, help and advise is appreciated. Please let me know if I can provide more information or answer any questions.

6 REPLIES 6

Thank you for the information! I believe I'm heading in the right direction and need a little bit more troubleshooting.

First, here are the code snippets of the script includes attached from above.

//getGroupMembers
//Get the current user's groups and the member's of those groups.
// var people = getGroupMembers();
// gs.log("people: " + people, "nf_DA_script_include");

function getGroupMembers(){
var grps = getMyGroupsAdvanced(0);
var mbrs = [];
	
gs.log("Current User sysid" + gs.getUserID(), "nf_DA_script_include");

gs.log("grps: " + grps, "nf_DA_script_include");
gs.log("length " + grps.length, "nf_DA_script_include");

for (var i = 0; i < grps.length; i++) { //for each group obtain the group members
    // gs.log("Group " + i + " is: " + grps[i], 'nf_DA_script_include');
    var gr = new GlideRecord('sys_user_grmember');
    gr.addQuery('group', grps[i]);
    gr.query(); 
    // gs.log("length of group members: " + gr.getRowCount(), "nf_DA_script_include");
    while (gr.next()) { 
        // gs.log("Member Name: " + gr.user, "nf_DA_script_include");
        mbrs.push(gr.user.toString());
    }
}

// gs.log("All Members Array (with dups): " + mbrs, "nf_DA_script_include");

//Remove any duplicates from group string
mbrs = checkDuplicates(mbrs);

// gs.log("All Members Array (with out dups): " + mbrs, "nf_DA_script_include");

return mbrs;

}

function checkDuplicates(a){
   //Check all values in the incoming array and eliminate any duplicates
   var r = [];
   o:for(var i = 0, n = a.length; i < n; i++){
      for(var x = 0, y = r.length; x < y; x++){
         if(r[x]==a[i]){
            continue o;
         }
      }
      r[r.length] = a[i];
   }
   return r;
}
//getMyGroupsAdvanced
//From SN Guru
//https://servicenowguru.com/scripting/script-includes-scripting/advanced-getmygroups-function/
//Maximum number of levels to search for groups.
//No maxDepth returns groups where user is a group member (Same as 'getMyGroups' function)
//maxDepth of 0 returns groups where user is a group member or a manager
//maxDepth greater than 0 returns groups where user is a group member or a manager PLUS all child groups up to 'maxDepth' levels deep
var maxDepth;

var groupArr = [];
var finalArr = [];

function getMyGroupsAdvanced(inputDepth){
   //Set maxDepth to the given depth
   maxDepth = inputDepth;
   //Get the sys_id of the current user
   var uID = gs.getUserID();

   //Get all active groups where user is a member
   var grmember = new GlideRecord('sys_user_grmember');
   grmember.addQuery('user', uID);
   grmember.addQuery('group.active', true);
   grmember.query();
   while(grmember.next()){
      //Push the group sys_id values into the group array
      groupArr.push(grmember.group.toString());
   }

   //If a maxDepth value is given then include groups where user is a manager
   if(maxDepth >= 0){
      //Get all active groups where user is a manager
      var grman = new GlideRecord('sys_user_group');
      grman.addQuery('manager', uID);
      grman.addQuery('active', true);
      grman.query();
      while(grman.next()){
         //Push the group sys_id values into the group array
         groupArr.push(grman.sys_id.toString());
      }
   }

   //Remove any duplicates from group string
   groupArr = checkDuplicates(groupArr);

   //If maxDepth > 0 then check for child groups
   if(maxDepth > 0){
      //Iterate through all of the groups and return all children for each group
      for(var x in groupArr){
         //Only process if group sys_id is not already in the returned array
         if(finalArr.length == 0 || finalArr.join().indexOf(groupArr[x]) == -1){
            finalArr.push(groupArr[x]);
         }
         recursChildGroups(groupArr[x], 0);
      }
   }

   //If we didn't check for child groups then just return the group array
   else{
      finalArr = groupArr;
   }

   //Return the array of group IDs
   return finalArr;
}

function recursChildGroups(group, depth){
   //Increase the current depth
   depth++;
   //If we have gone more than the allowed depth then abort for the given group
   if(depth > maxDepth){
      //('Possible recursive group loop with group ' + group);
      return null;
   }
   //Make sure that we have a valid group ID
   if(group){
      if(group.toString().length == 0){
         return null;
      }
      //Query for the active child groups of this group
      var rec = new GlideRecord('sys_user_group');
      rec.addQuery('parent', group);
      rec.addQuery('active', true);
      rec.query();
         while(rec.next()){
            //If the group has already been added then do not add again
            if(finalArr.join().indexOf(rec.sys_id.toString()) > -1){
               continue;
            }
            //Add the group to the final array
            finalArr.push(rec.sys_id.toString());
            //Find the child groups of this group
            recursChildGroups(rec.sys_id.toString(),depth);
         }
   }
   return null;
}

function checkDuplicates(a){
   //Check all values in the incoming array and eliminate any duplicates
   var r = [];
   o:for(var i = 0, n = a.length; i < n; i++){
      for(var x = 0, y = r.length; x < y; x++){
         if(r[x]==a[i]){
            continue o;
         }
      }
      r[r.length] = a[i];
   }
   return r;
}

To help verify and troubleshoot, here are screenshots corresponding to your steps above. 

4) Data Broker Server Script - this is the same as the getGroupMembers script include.

find_real_file.png

5) Corresponding ACL for above Data Broker Server Script

find_real_file.png

7) Added data source - I think this is where I'm doing something wrong? Not entirely sure.

find_real_file.png

😎 Client State Parameter binding

find_real_file.png

😎 continued - every time I save this, it empties out the initial value. I believe this is my second problem?

find_real_file.png

9) The binding of the client state onto the list filter

find_real_file.png

 

To try and verify this, I created a request where my user was in the requested for field. The list should at least return this request, but does not.

find_real_file.png

Thank you again for the information! I feel that this is closer to what I'm trying to accomplish.

Dom

I am sorry to check it this late. For the issue related to where your output binding is blanking out, it is actually an issue with UI builder. I also face this many times but you need not to worry about it and there are other ways to set it if it doesn't work this way.

On your data source, there is an event which triggers when it executes successfully. On this event you can trigger a page script.

In the page script you can set the client state parameter like below.

var result = api.data.YOUR_DATA_SOURCE.output;

api.setState('yourStateParameter' , result);

Anyways, let's troubleshoot. You are doing most of the things right but your data broker is not returning anything. Add that in your data broker.

Also, did you test your code in background script if it is working fine. If not then check that first.

 

 

Jagjeet Singh
ServiceNow Community Rising Star 2022/2023