- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-09-2023 04:34 AM
Hello everyone,
In the Service Portal I have 3 widgets "Data table from instance definition" one for RITMS, one for Incidents and one for REQS (example below).
And I want the badge count of the incidents, RITMs and REQs to appear on the menu label (My actions), is there any way to make this happen?
Thanks a lot!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-19-2023 01:06 AM
Hello everyone,
I finally got it, thanks to all who helped.
My solution was as follows:
// only show 30 in header menu dropdown
var max = 30;
var t = data;
t.items = [];
t.count = 0;
var u = gs.getUserID();
// Retrieve incidents assigned to the current user
var incidentGr = new GlideRecord('incident');
incidentGr.addQuery('assigned_to', u);
incidentGr.addQuery('active', true);
incidentGr.orderByDesc('sys_updated_on');
incidentGr.setLimit(max);
incidentGr.query();
var incidentLink = {};
incidentLink.title = gs.getMessage('View all actions');
incidentLink.type = 'link';
incidentLink.href = '?id=view_all_actions';
incidentLink.items = [];
t.items.push(incidentLink);
while (incidentGr.next()) {
var incident = {};
incident.short_description = incidentGr.short_description + "";
$sp.getRecordValues(incident, incidentGr, 'sys_id,sys_updated_on');
incident.number = incidentGr.number;
incident.__table = incidentGr.getRecordClassName();
incident.type = 'incident';
t.items.push(incident);
t.count++;
}
// Retrieve sc_req_item records assigned to the current user
var scReqItemGr = new GlideRecord('sc_req_item');
scReqItemGr.addQuery('assigned_to', u);
scReqItemGr.addQuery('active', true);
scReqItemGr.orderByDesc('sys_updated_on');
scReqItemGr.setLimit(max - t.count); // Adjust the limit based on the count of incidents
scReqItemGr.query();
while (scReqItemGr.next()) {
var scReqItem = {};
scReqItem.short_description = scReqItemGr.short_description + "";
$sp.getRecordValues(scReqItem, scReqItemGr, 'sys_id,sys_updated_on');
scReqItem.number = scReqItemGr.number;
scReqItem.__table = scReqItemGr.getRecordClassName();
scReqItem.type = 'sc_req_item';
t.items.push(scReqItem);
t.count++;
}
// Retrieve sc_request records assigned to the current user
var scRequestGr = new GlideRecord('sc_request');
scRequestGr.addQuery('assigned_to', u);
scRequestGr.addQuery('active', true);
scRequestGr.orderByDesc('sys_updated_on');
scRequestGr.setLimit(max - t.count); // Adjust the limit based on the count of incidents and sc_req_items
scRequestGr.query();
while (scRequestGr.next()) {
var scRequest = {};
scRequest.short_description = scRequestGr.short_description + "";
$sp.getRecordValues(scRequest, scRequestGr, 'sys_id,sys_updated_on');
scRequest.number = scRequestGr.number;
scRequest.__table = scRequestGr.getRecordClassName();
scRequest.type = 'sc_request';
t.items.push(scRequest);
t.count++;
}
// Calculate badge count
var incidentCount = t.items.filter(function(item) {
return item.type === 'incident';
}).length;
var scReqItemCount = t.items.filter(function(item) {
return item.type === 'sc_req_item';
}).length;
var scRequestCount = t.items.filter(function(item) {
return item.type === 'sc_request';
}).length;
if (t.count === 1) {
data.badgeHint = gs.getMessage(
'{0} open incident, {1} requested item, {2} requested',
[incidentCount, scReqItemCount, scRequestCount]
);
} else if (t.count > 1) {
data.badgeHint = gs.getMessage(
'{0} open incidents, {1} requested items, {2} requested',
[t.count, incidentCount, scReqItemCount, scRequestCount]
);
} else {
data.badgeHint = gs.getMessage('No open incidents, requested items, or requests');
}
Best regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-09-2023 06:42 AM
You haven't removed/deleted the out-of-box Menu Item "Approvals" for the SP Service Portal, take a look at that. It should give you an idea on how to do it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-12-2023 10:58 PM
In case you wanted a more in depth explanation the following will be two ways to set this up.
The menu item is a "Scripted List" type for both ways. The explanation of what is going on is in the code comments
First way:
Display links that go to the page. The links will have a title plus the count of how many records
- In the server script field
//Since this is server side it uses "data" object in Widget. Here d is equivalent to the widget server data object
var d = data;
//Adds items as a property that is an array
d.items = [];
//This count is what is going to be placed in the badge
d.count = 0;
// use record watchers to tell header when to update dropdown counts. This will update the badge
// when a listed table is updated matching the filter
d.record_watchers = [];
//Since your widgets have data tables looking at incidents, RITMS, and requests, those are the table to be watched
Array.prototype.push.apply(d.record_watchers,[
{'table':'incident','filter':'active=true^caller_idDYNAMIC90d1921e5f510100a9ad2572f2b477fe'},
{'table':'sc_req_item','filter':'request.requested_forDYNAMIC90d1921e5f510100a9ad2572f2b477fe^active=true'},
{'table':'sc_request','filter':'requested_forDYNAMIC90d1921e5f510100a9ad2572f2b477fe^active=true'}
]);
//Depending upon what you want listed in your drop down those objects would be pushed into the t.items array.
//For simplicity we'll just make it point to the list of different pages depending upon the record type
/*** basic model based on the Out-of-box setup
*** {
*** title: "",
*** type: "",
*** href: "",
*** items: [] (if it's has subdropdown
*** }
***/
//Incidents link
var inc = {};
inc.title = "My Incidents";
inc.type = "link";
inc.href = "?inc_data";
inc.target = "_blank";
inc.items = [];
//ritm link
var ritm = {};
ritm.title = "My RITMS";
ritm.type = "link";
ritm.href = "?ritm_data";
ritm.items = [];
//reqs link
var reqs = {};
reqs.title = "My Requests";
reqs.type = "link";
reqs.href = "?req_data";
reqs.items = [];
//Push each link into the items. These are the links that will display
Array.prototype.push.apply(d.items, [inc, ritm, reqs]);
d.count = d.record_watchers.reduce(getCounts, 0);
//callback function for the reduce. This will add all the records together to get the total count
function getCounts(acc, item){
var rec = new GlideAggregate(item.table);
rec.addEncodedQuery(item.filter);
rec.addAggregate('COUNT');
rec.query();
if(rec.next()){
var count = rec.getAggregate('COUNT');
if(item.table == "incident")
inc.title += " ( " + count + " )";
if(item.table == "sc_req_item")
ritm.title += " ( " + count + " )";
if(item.table == "sc_request")
reqs.title += " ( " + count + " )";
acc += Number(count);
}
return acc;
}
- Example:
Second Way: Very similar but this time display the types and list the records under
- Server Script
//Since this is server side it uses "data" object in Widget. Here d is equivalent to the widget server data object
var d = data;
//Adds items as a property that is an array
d.items = [];
//This count is what is going to be placed in the badge
d.count = 0;
// use record watchers to tell header when to update dropdown counts. This will update the badge
// when a listed table is updated matching the filter
d.record_watchers = [];
//Since your widgets have data tables looking at incidents, RITMS, and requests, those are the table to be watched
Array.prototype.push.apply(d.record_watchers,[
{'table':'incident','filter':'active=true^caller_idDYNAMIC90d1921e5f510100a9ad2572f2b477fe'},
{'table':'sc_req_item','filter':'request.requested_forDYNAMIC90d1921e5f510100a9ad2572f2b477fe^active=true'},
{'table':'sc_request','filter':'requested_forDYNAMIC90d1921e5f510100a9ad2572f2b477fe^active=true'}
]);
//Depending upon what you want listed in your drop down those objects would be pushed into the t.items array.
//For simplicity we'll just make it point to the list of different pages depending upon the record type
/*** basic model based on the Out-of-box setup
*** {
*** title: "",
*** type: "",
*** href: "",
*** items: [] (if it's has subdropdown
*** }
***/
//Incidents link
var inc = {};
inc.title = "My Incidents";
//set type to menu so that it acts like a label instead of a clickable link
inc.type = "menu";
inc.href = "?inc_data";
inc.target = "_blank";
inc.items = [];
d.items.push(inc);
//pushes records to display as links and to make the "menu" for incs render
getRecords(d.record_watchers[0].table, d.record_watchers[0].filter);
//ritm link
var ritm = {};
ritm.title = "My RITMS";
//set type to menu so that it acts like a label instead of a clickable link
ritm.type = "menu";
ritm.href = "?ritm_data";
ritm.items = [];
d.items.push(ritm);
//pushes records to display as links and to make the "menu" for ritms render
getRecords(d.record_watchers[1].table, d.record_watchers[1].filter);
//reqs link
var reqs = {};
reqs.title = "My Requests";
//set type to menu so that it acts like a label instead of a clickable link
reqs.type = "menu";
reqs.href = "?req_data";
reqs.items = [];
d.items.push(reqs);
//pushes records to display as links and to make the "menu" for reqs render
getRecords(d.record_watchers[2].table, d.record_watchers[2].filter);
function getRecords (table, filter){
var rec = new GlideRecord(table);
rec.addEncodedQuery(filter);
rec.query();
var recList = [];
while(rec.next()){
var obj = {};
$sp.getRecordValues(obj, rec, 'sys_id,sys_updated_on');
obj.number = " " + rec.number.toString();
obj.__table = rec.getRecordClassName();
obj.type = "record";
obj.__page = table == "sc_request" ? "order_status": "ticket";
if(table == "incident")
inc.items.push(obj);
if(table == "sc_req_item")
ritm.items.push(obj);
if(table == "sc_request")
reqs.items.push(obj);
d.items.push(obj);
d.count++;
}
return recList;
}
- Example:
I'm sure there is a more elegant way of doing this but this was just an example to describe how it works.
I hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-12-2023 11:19 PM
@RforNewbie Open your portal record and open main menu
Update the menu you have added to "Filtered List" or "Scripted List" type. In below image i have added a filtered list.
Please mark as correct answer if this solves your issue.
ServiceNow Community Rising Star, Class of 2023
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-19-2023 01:06 AM
Hello everyone,
I finally got it, thanks to all who helped.
My solution was as follows:
// only show 30 in header menu dropdown
var max = 30;
var t = data;
t.items = [];
t.count = 0;
var u = gs.getUserID();
// Retrieve incidents assigned to the current user
var incidentGr = new GlideRecord('incident');
incidentGr.addQuery('assigned_to', u);
incidentGr.addQuery('active', true);
incidentGr.orderByDesc('sys_updated_on');
incidentGr.setLimit(max);
incidentGr.query();
var incidentLink = {};
incidentLink.title = gs.getMessage('View all actions');
incidentLink.type = 'link';
incidentLink.href = '?id=view_all_actions';
incidentLink.items = [];
t.items.push(incidentLink);
while (incidentGr.next()) {
var incident = {};
incident.short_description = incidentGr.short_description + "";
$sp.getRecordValues(incident, incidentGr, 'sys_id,sys_updated_on');
incident.number = incidentGr.number;
incident.__table = incidentGr.getRecordClassName();
incident.type = 'incident';
t.items.push(incident);
t.count++;
}
// Retrieve sc_req_item records assigned to the current user
var scReqItemGr = new GlideRecord('sc_req_item');
scReqItemGr.addQuery('assigned_to', u);
scReqItemGr.addQuery('active', true);
scReqItemGr.orderByDesc('sys_updated_on');
scReqItemGr.setLimit(max - t.count); // Adjust the limit based on the count of incidents
scReqItemGr.query();
while (scReqItemGr.next()) {
var scReqItem = {};
scReqItem.short_description = scReqItemGr.short_description + "";
$sp.getRecordValues(scReqItem, scReqItemGr, 'sys_id,sys_updated_on');
scReqItem.number = scReqItemGr.number;
scReqItem.__table = scReqItemGr.getRecordClassName();
scReqItem.type = 'sc_req_item';
t.items.push(scReqItem);
t.count++;
}
// Retrieve sc_request records assigned to the current user
var scRequestGr = new GlideRecord('sc_request');
scRequestGr.addQuery('assigned_to', u);
scRequestGr.addQuery('active', true);
scRequestGr.orderByDesc('sys_updated_on');
scRequestGr.setLimit(max - t.count); // Adjust the limit based on the count of incidents and sc_req_items
scRequestGr.query();
while (scRequestGr.next()) {
var scRequest = {};
scRequest.short_description = scRequestGr.short_description + "";
$sp.getRecordValues(scRequest, scRequestGr, 'sys_id,sys_updated_on');
scRequest.number = scRequestGr.number;
scRequest.__table = scRequestGr.getRecordClassName();
scRequest.type = 'sc_request';
t.items.push(scRequest);
t.count++;
}
// Calculate badge count
var incidentCount = t.items.filter(function(item) {
return item.type === 'incident';
}).length;
var scReqItemCount = t.items.filter(function(item) {
return item.type === 'sc_req_item';
}).length;
var scRequestCount = t.items.filter(function(item) {
return item.type === 'sc_request';
}).length;
if (t.count === 1) {
data.badgeHint = gs.getMessage(
'{0} open incident, {1} requested item, {2} requested',
[incidentCount, scReqItemCount, scRequestCount]
);
} else if (t.count > 1) {
data.badgeHint = gs.getMessage(
'{0} open incidents, {1} requested items, {2} requested',
[t.count, incidentCount, scReqItemCount, scRequestCount]
);
} else {
data.badgeHint = gs.getMessage('No open incidents, requested items, or requests');
}
Best regards,