Widget Service Portal - Show Direct Reports Items

Edxavier Robert
Mega Sage

Hi all, 

I'm trying to build a custom widget for the Service Portal. The requirements are to show all direct reports from the logged user in a dropdown menu and once we select a user the request and incidents associated with that user will show up in a table. Is basically what the my_requests_v2 widget is doing. This is what I have so far.

HTML

 

<div class="panel panel-default b" ng-init="c.trackPage()">
<div class="panel-heading">
  <h2 class="panel-title">{{::data.messages.myRequestsTitle}}</h2>
  </div>
 
  <uib-tabset role="tablist">
    <uib-tab role="tab" active="c.data.isDirectReportsTabActive" select="c.changeSelectedTab('direct_reports')" index="direct_reports" class="uib-vis-tab" heading="${Direct Reports}">
        <div ng-include="'directReportsItemsTemplate'"></div>
    </uib-tab>
  </uib-tabset>
</div>
<script type="text/ng-template" id="directReportsItemsTemplate">
<div class="panels-container list-group">
<div class="form-inline control-view" ng-if="c.data.directReports && c.data.directReports.length > 0">
  <label for="directReportSelect">Select Direct Report: &nbsp;</label>
   <select 
   ng-model="c.selectedDirectReport" 
   ng-options="report.name for report in c.data.directReports"
   //ng-options="report as report.name for report in c.data.directReports track by report.sys_id"
   class="form-control" 
   ng-change="c.fetchRequestsForDirectReport()">
   </select>
 </div>
<!-- Message if no direct reports are available -->
<div class="panels-container list-group">
<div ng-if="!c.data.directReports || c.data.directReports.length === 0" class="panel-body panels-container">
     <p>You don't have any direct reports</p>
</div>
<div ng-if="c.data.request && c.data.request.length > 0" class="table-responsive">
  <table class="table ng-scope" role="rowgroup" class="column-headers" aria-hidden="false">
  <tr>
    <th role="columnheader" class="col-xs-6 padder-r-none padder-l-none">Request</th>
    <th role="columnheader" class="col-xs-6 padder-r-none padder-l-none">Short Description</th>
    <th role="columnheader" class="col-xs-6 padder-r-none padder-l-none">Status</th>
    <th role="columnheader" class="col-xs-6 padder-r-none padder-l-none">Updated</th>
  </tr> 
  
  <tr ng-repeat = "req in c.data.request">
    <td>{{req.number}}</td>
    <td>{{req.short_description}}</td>
    <td>{{req.state}}</td>
    <td>{{req.create}}</td>
  </tr>
</table>
</div>

<!-- Message if no requests/incidents are found -->
    <div ng-if="c.data.request.length === 0 && c.selectedDirectReport">
      <p>No requests or incidents found for the selected user.</p>
    </div>
  </div>

  </script>

 

Client Script

 

function () {
  var c = this;
c.fetchRequestsForDirectReport = function () {
    if (!c.selectedDirectReport) {
      alert('No direct report selected.');
      return;
    }
// Show an alert with the selected user's sys_id
    alert('Selected Direct Report sys_id: ' + c.selectedDirectReport.sys_id);
    var input = {
      directReportId: c.selectedDirectReport.sys_id
    };

    $sp.get('new_version_-_5', input).then(function (response) {
			console.log('Server Response:', response);
  alert('Server Response: ' + JSON.stringify(response.data)); // Alert for quick debugging
      c.data.request = response.data.request;
    });
  };
}

 

Server side:

 

(function(){
 
 var msg = data.messages = {};
	msg.myRequestsTitle = options.title ? gs.getMessage(options.title) : gs.getMessage('My Direct Reports Requests');
 
 // Logic for handling "Direct Reports" tab
    var userID = gs.getUser().getID(); // Get the current user's ID
 
// Fetch Direct Reports for the current user
    var gr = new GlideRecord('sys_user');
    gr.addQuery('manager', userID); // Query for users who report to the current user
    gr.query();
		data.directReports = [];
    while (gr.next()) {
        var report = {};
        report.sys_id = gr.getUniqueValue();
        report.name = gr.getDisplayValue('name');
        report.email = gr.getValue('email');
        data.directReports.push(report);
    }
	
 
	// Fetch tasks for the selected direct report (if provided)
  var selectedUserId = input && input.directReportId; // Check if input parameter is passed
	data.request=[];
   if(selectedUserId){
		 var rec= new GlideRecord('task');
	rec.addEncodedQuery('sys_class_name=incident^ORsys_class_name=sc_req_item');
	rec.addQuery('ref_incident.caller_id.manager', userID);
	rec.addQuery('ref_sc_req_item.requested_for.manager', userID);
	rec.query();
	while(rec.next())
		{
			var request_data={};
			request_data.number = rec.getValue('number');
			request_data.state = rec.getDisplayValue('state');
			request_data.create = rec.getDisplayValue('sys_updated_on');
			request_data.short_description = rec.getValue('short_description');
			data.request.push(request_data);
			}
		} 
})();

 

I can see the list of the Direct Reports 

EdxavierRobert_0-1733806264958.png

But once selected it always return 

EdxavierRobert_1-1733806325722.png

Any guidance will be appreciated.

 
 
 
1 ACCEPTED SOLUTION

Edxavier Robert
Mega Sage

I was able to figure out, here is the final code just in case some else is trying the same. Also this could be improved by adding another dropdown to switch between open and close or maybe adding a search option. Also have the ability to open the record once is clicked, but that involve looking into ACL. 

HTML

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Direct Report Requests</h3>
  </div>
  <div class="panel-body">
    <div class="form-group">
      <label for="directReportSelect">Select a Direct Report:</label>
      <select 
        id="directReportSelect" 
        class="form-control" 
        ng-model="c.selectedDirectReport"
        ng-options="report.name for report in c.data.directReports" 
        ng-change="c.fetchRequestsForSelectedUser()">
        <option value="">-- Select --</option>
      </select>
    </div>
    <hr>
    <table class="table" ng-if="c.data.requests.length > 0">
      <thead>
        <tr>
          <th>Request</th>
          <th>Short Description</th>
          <th>Status</th>
          <th>Updated</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="req in c.data.requests">
          <td>{{req.number}}</td>
          <td>{{req.short_description}}</td>
          <td>{{req.state}}</td>
          <td>{{req.updated}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Client Script

function () {
  var c = this;
	
	// Ensure `c.data.requests` is always initialized
  c.data.directReports = c.data.directReports || [];
	c.data.requests = c.data.requests || [];
	
	c.fetchRequestsForSelectedUser = function () {
    if (!c.selectedDirectReport) {
      alert('Please select a direct report.');
      return;
    }
	var input = {
      action: "fetchRequests",
      selectedUserId: c.selectedDirectReport.sys_id
    };

    c.server.get(input).then(function (response) {
      c.data.requests = response.data.requests || []; // Safely handle missing data
      if (c.data.requests.length === 0) {
        console.log("No requests found for the selected user.");
      }
			
    });
  };
	// Log the initial direct reports for debugging
  console.log("Direct Reports:", c.data.directReports);
}

Server Side

(function () {
  data.directReports = [];
	
	var userID = gs.getUser().getID(); // Get the current user's ID

  // Fetch direct reports
  var gr = new GlideRecord('sys_user');
  gr.addQuery('manager', userID); // Fetch users reporting to the current user
  gr.query();
  while (gr.next()) {
    data.directReports.push({
      sys_id: gr.getUniqueValue(),
      name: gr.getDisplayValue('name')
    });
  }
	
	if (data.directReports.length === 0) {
    gs.log("No direct reports found for manager: " + gs.getUserID());
  }

  // Handle input from the client
  if (input && input.action === "fetchRequests") {
    data.requests = [];
    if (input.selectedUserId) {
      var reqGr = new GlideRecord('task');
			reqGr.addEncodedQuery('sys_class_name=incident^ORsys_class_name=sc_req_item^ref_incident.caller_id=' + input.selectedUserId + '^ORref_sc_req_item.requested_for=' + input.selectedUserId);
      reqGr.query();
      while (reqGr.next()) {
        data.requests.push({
          number: reqGr.getValue('number'),
          short_description: reqGr.getValue('short_description'),
          state: reqGr.getDisplayValue('state'),
          updated: reqGr.getDisplayValue('sys_updated_on')
        });
      }
			if(data.requests.length === 0){
				gs.addInfoMessage("No requests or incidents found for the selected user.");
			}
    }
  }
})();

 

View solution in original post

1 REPLY 1

Edxavier Robert
Mega Sage

I was able to figure out, here is the final code just in case some else is trying the same. Also this could be improved by adding another dropdown to switch between open and close or maybe adding a search option. Also have the ability to open the record once is clicked, but that involve looking into ACL. 

HTML

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Direct Report Requests</h3>
  </div>
  <div class="panel-body">
    <div class="form-group">
      <label for="directReportSelect">Select a Direct Report:</label>
      <select 
        id="directReportSelect" 
        class="form-control" 
        ng-model="c.selectedDirectReport"
        ng-options="report.name for report in c.data.directReports" 
        ng-change="c.fetchRequestsForSelectedUser()">
        <option value="">-- Select --</option>
      </select>
    </div>
    <hr>
    <table class="table" ng-if="c.data.requests.length > 0">
      <thead>
        <tr>
          <th>Request</th>
          <th>Short Description</th>
          <th>Status</th>
          <th>Updated</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="req in c.data.requests">
          <td>{{req.number}}</td>
          <td>{{req.short_description}}</td>
          <td>{{req.state}}</td>
          <td>{{req.updated}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Client Script

function () {
  var c = this;
	
	// Ensure `c.data.requests` is always initialized
  c.data.directReports = c.data.directReports || [];
	c.data.requests = c.data.requests || [];
	
	c.fetchRequestsForSelectedUser = function () {
    if (!c.selectedDirectReport) {
      alert('Please select a direct report.');
      return;
    }
	var input = {
      action: "fetchRequests",
      selectedUserId: c.selectedDirectReport.sys_id
    };

    c.server.get(input).then(function (response) {
      c.data.requests = response.data.requests || []; // Safely handle missing data
      if (c.data.requests.length === 0) {
        console.log("No requests found for the selected user.");
      }
			
    });
  };
	// Log the initial direct reports for debugging
  console.log("Direct Reports:", c.data.directReports);
}

Server Side

(function () {
  data.directReports = [];
	
	var userID = gs.getUser().getID(); // Get the current user's ID

  // Fetch direct reports
  var gr = new GlideRecord('sys_user');
  gr.addQuery('manager', userID); // Fetch users reporting to the current user
  gr.query();
  while (gr.next()) {
    data.directReports.push({
      sys_id: gr.getUniqueValue(),
      name: gr.getDisplayValue('name')
    });
  }
	
	if (data.directReports.length === 0) {
    gs.log("No direct reports found for manager: " + gs.getUserID());
  }

  // Handle input from the client
  if (input && input.action === "fetchRequests") {
    data.requests = [];
    if (input.selectedUserId) {
      var reqGr = new GlideRecord('task');
			reqGr.addEncodedQuery('sys_class_name=incident^ORsys_class_name=sc_req_item^ref_incident.caller_id=' + input.selectedUserId + '^ORref_sc_req_item.requested_for=' + input.selectedUserId);
      reqGr.query();
      while (reqGr.next()) {
        data.requests.push({
          number: reqGr.getValue('number'),
          short_description: reqGr.getValue('short_description'),
          state: reqGr.getDisplayValue('state'),
          updated: reqGr.getDisplayValue('sys_updated_on')
        });
      }
			if(data.requests.length === 0){
				gs.addInfoMessage("No requests or incidents found for the selected user.");
			}
    }
  }
})();