Service Portal Header Menu: always show My Tickets, but hide My Surveys unless >0

JP-ODU
Tera Guru

We were using the out of the box Service Portal>Widgets>Header Menu, which has two menu items: My Tickets and My Surveys and hides them unless >0. I was asked to always show My Tickets.

To do so, I did the following:

1. Go to Service Portal>Widgets>Header Menu
2. Clone Header Menu, name "Header Menu always show My Tickets"
3. Change the client controller script at line 41 to: 

if (item.items || (item.scriptedItems && item.scriptedItems.count >= 0))

4. Go to sp_ng_template.list and change the Widget for menuTemplate, item-added-tooltip.html, and spDropdownTreeTemplate to "Header Menu always show My Tickets"

5. Update the code of menuTemplate to: 

	<a role="menuitem" ng-if="item.items.length == 0 && !item.scriptedItems" ng-href="{{::item.href}}" ng-click="collapse()" target="{{::item.url_target}}" title="{{::item.hint}}">
	  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
	  <span ng-bind-html="::item.label"></span>
	</a>
	<a role="menuitem" aria-haspopup="true"  ng-if="item.items.length > 0" href class="dropdown-toggle sp-menu-has-items" data-toggle="dropdown" aria-controls="{{::item.label.split(' ').join('')}}" aria-haspopup="true" title="{{::item.hint}}">
	  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
	  <span ng-bind-html="::item.label"></span> <span class="caret"></span>
	</a>
	<ul ng-if="item.items.length > 0" class="dropdown-menu" role="group" id="{{::item.label.split(' ').join('')}}">
	  <li ng-repeat="item in item.items" ng-include="'menuTemplate'" />
	</ul>
	<a role="menuitem" aria-haspopup="true" ng-if="item.scriptedItems.count >= 0" href data-toggle="dropdown" aria-label="{{::item.label}} : {{item.scriptedItems.count}}" title="{{::item.hint}}">
	  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
	  <span ng-bind-html="::item.label"></span>
	  <span ng-if="::!item.scriptedItems.omitBadge" class="label label-as-badge label-primary sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
	</a>
<sp-dropdown-tree role="menu" aria-label="{{::item.label}}" ng-if="item.scriptedItems.count >= 0" items="item.scriptedItems.items" />

6. Go to Service Portal>Menus and open the Instance with Menu record titled "SP Header Menu" and set the widget as "Header Menu always show My Tickets"

Challenge: this means that My Tickets and My Surveys *both* always show up and I've been told that we really want to always see My Tickets, but only see My Surveys if >0... anyone know how I can update the above scripting to split the two? It seems to me that I need to call something other than item.scriptedItems? Or perhaps change a list that refers to somewhere?

1 ACCEPTED SOLUTION

@JP-ODU 

Hi,

You may try below.

 

1.Navigate to Service Portal --> Portals and open your service portal record where you are displaying the menu.

2. Click on information icon placed next to "Main Menu" and click on "Open Record" button.

find_real_file.png

3. Now, scroll down to the related list "Menu Items", click on "New" button

Label: Incident List

Type: Scripted List

Condition: gs.isLoggedIn()

Server Script:

// maximum number of entries in this Menu
var max = 10;

var t = data; 
t.items = [];

var u = gs.getUser().getID();

// use record watchers to tell header when to update dropdown counts
t.record_watchers = [];
t.record_watchers.push({'table':'incident','filter':'active=true^caller_id=' + u});

var z = new GlideRecord('incident');
z.addActiveQuery();
z.addQuery('caller_id', gs.getUserID()).addOrCondition('opened_by',gs.getUserID());
z.orderByDesc('sys_updated_on');
z.setLimit(max);
z.query();
while (z.next()) {
  var a = {};
  $sp.getRecordValues(a, z, 'short_description,sys_id,number,sys_updated_on');
  if (z.short_description.nil())
    a.short_description = "(No description)";
  a.__table = z.getTableName();
  a.type = 'record';
  a.sortOrder = z.sys_updated_on.getGlideObject().getNumericValue();
  t.items.push(a);
}
var incCount = 0;
var incRec = new GlideAggregate('incident');
incRec.addQuery('caller_id', gs.getUserID()).addOrCondition('opened_by',gs.getUserID());
incRec.addActiveQuery();
incRec.addAggregate('COUNT');
incRec.query();
if(incRec.next())
{
incCount = incRec.getAggregate('COUNT');
}

t.items.sort(function(a, b) {
  return b.sortOrder - a.sortOrder;
});
t.items = t.items.slice(0, max); // only want first 30
t.count = incCount;
if(incCount == 0)
{
t.count = 'O';
}

var link = {title: gs.getMessage('View All Reported Issues'), type: 'link', href: '?id=list&table=incident', items: []};
t.items.unshift(link); 

4. Submit or Save the record

View solution in original post

16 REPLIES 16

Great idea, doesn't work unfortunately, it needs to be numeric.

Laukik Udpikar
Tera Expert

I tried this, but it did not work for me.

Please help.

Hi,

You may try below.

 

1.Navigate to Service Portal --> Portals and open your service portal record where you are displaying the menu.

2. Click on information icon placed next to "Main Menu" and click on "Open Record" button.

find_real_file.png

3. Now, scroll down to the related list "Menu Items", click on "New" button

Label: Incident List

Type: Scripted List

Condition: gs.isLoggedIn()

Server Script:

// maximum number of entries in this Menu
var max = 10;

var t = data; 
t.items = [];

var u = gs.getUser().getID();

// use record watchers to tell header when to update dropdown counts
t.record_watchers = [];
t.record_watchers.push({'table':'incident','filter':'active=true^caller_id=' + u});

var z = new GlideRecord('incident');
z.addActiveQuery();
z.addQuery('caller_id', gs.getUserID()).addOrCondition('opened_by',gs.getUserID());
z.orderByDesc('sys_updated_on');
z.setLimit(max);
z.query();
while (z.next()) {
  var a = {};
  $sp.getRecordValues(a, z, 'short_description,sys_id,number,sys_updated_on');
  if (z.short_description.nil())
    a.short_description = "(No description)";
  a.__table = z.getTableName();
  a.type = 'record';
  a.sortOrder = z.sys_updated_on.getGlideObject().getNumericValue();
  t.items.push(a);
}
var incCount = 0;
var incRec = new GlideAggregate('incident');
incRec.addQuery('caller_id', gs.getUserID()).addOrCondition('opened_by',gs.getUserID());
incRec.addActiveQuery();
incRec.addAggregate('COUNT');
incRec.query();
if(incRec.next())
{
incCount = incRec.getAggregate('COUNT');
}

t.items.sort(function(a, b) {
  return b.sortOrder - a.sortOrder;
});
t.items = t.items.slice(0, max); // only want first 30
t.count = incCount;
if(incCount == 0)
{
t.count = 'O';
}

var link = {title: gs.getMessage('View All Reported Issues'), type: 'link', href: '?id=list&table=incident', items: []};
t.items.unshift(link); 

4. Submit or Save the record

This does not seem to work anymore - at least not for me. Here's my script:

 

// maximum number of entries in this Menu
var max = 30;

var count = 0;

var t = data; // shortcut
t.items = [];

var u = gs.getUser().getID();

// use record watchers to tell header when to update dropdown counts
t.record_watchers = [];
t.record_watchers.push({'table':'incident','filter':'active=true^caller_id=' + u +'^ORopened_by=' + u});
t.record_watchers.push({'table':'sc_req_item','filter':'active=true^request.requested_for=' + u});


var z = new GlideRecord('incident');
z.addEncodedQuery('active=true^caller_idDYNAMIC90d1921e5f510100a9ad2572f2b477fe^ORopened_byDYNAMIC90d1921e5f510100a9ad2572f2b477fe');
//z.addActiveQuery();
//z.addQuery('caller_id', gs.getUserID());
z.orderByDesc('sys_updated_on');
z.setLimit(max);
z.query();
while (z.next()) {
if (!z.canRead())
continue;

var a = {};
count += 1;
$sp.getRecordValues(a, z, 'short_description,sys_id,number,sys_updated_on');
if (z.short_description.nil())
a.short_description = "(No description)";
a.__table = z.getTableName();
a.type = 'record';
a.sortOrder = z.sys_updated_on.getGlideObject().getNumericValue();
t.items.push(a);
}

var z = new GlideRecord('sc_req_item');
z.addEncodedQuery('active=true^request.requested_forDYNAMIC90d1921e5f510100a9ad2572f2b477fe^ORrequest.opened_byDYNAMIC90d1921e5f510100a9ad2572f2b477fe');
//z.addActiveQuery();
//z.addQuery('request.requested_for', gs.getUserID());
z.orderByDesc('sys_updated_on');
z.setLimit(max);
z.query();
while (z.next()) {
if (!z.canRead())
continue;

var a = {};
count +=1;
$sp.getRecordValues(a, z, 'short_description,sys_id,number,sys_updated_on');
if (z.short_description.nil())
a.short_description = "(No description)";
a.__table = z.getTableName();
a.type = 'record';
a.sortOrder = z.sys_updated_on.getGlideObject().getNumericValue();
t.items.push(a);
}

t.items.sort(function(a, b) {
return b.sortOrder - a.sortOrder;
});
t.items = t.items.slice(0, max); // only want first 30
t.count = t.items.length;

if (t.count == 0){
gs.log('count '+t.count + ' length '+t.items.length);
t.count = 'o';
gs.log('count '+t.count + ' length '+t.items.length);
}

var link = {title: gs.getMessage('View all tickets'), type: 'link', href: '?id=my_tickets', items: []};
t.items.unshift(link); // put 'View all requests' first

 

Could it be the way that I'm getting the count that's causing this issue or could it be because of the way some of the other aspects of the portal are configured?

I actually had to do a couple of further steps to achieve this, incorporating the above.

First, in the Scripted List script, I've included a custom element:

 

t.type = 'resource';

 

Then in the Angular ng-template called 'menuTemplate' on the main header Menu widget, I have made some changes to cater for my "special case" by adding the following to two places:

|| item.scriptedItems.type == 'resource'"

 

Here is my full Angular template:

<a role="menuitem" ng-if="item.items.length == 0 && !item.scriptedItems" ng-href="{{::item.href}}" ng-click="collapse()" target="{{::item.url_target}}" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
</a>
<a role="menuitem" aria-haspopup="true" aria-expanded="false" ng-if="item.items.length > 0" href class="dropdown-toggle sp-menu-has-items" data-toggle="dropdown" aria-controls="{{::item.label.split(' ').join('')}}" aria-haspopup="true" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span> <span class="caret"></span>
</a>
<ul ng-if="item.items.length > 0" class="dropdown-menu" role="menu" id="{{::item.label.split(' ').join('')}}">
  <li ng-repeat="item in item.items" ng-include="'menuTemplate'" role="presentation" />
</ul>
<a role="menuitem" aria-haspopup="true" aria-expanded="false" ng-if="item.scriptedItems.count > 0 || item.scriptedItems.type == 'resource'" href data-toggle="dropdown" aria-label="{{::item.label ? item.label + ': ' : ''}}{{::item.hint ? item.hint + ': ' : ''}}{{item.scriptedItems.count}}" title="{{::item.hint}}">
  <fa ng-if="::item.glyph" name="{{::item.glyph}}"></fa>
  <span ng-bind-html="::item.label"></span>
  <span ng-if="::!item.scriptedItems.omitBadge && item.scriptedItems.count != 'O'" class="label label-as-badge label-primary sp-navbar-badge-count">{{item.scriptedItems.count}}</span>
</a>
<sp-dropdown-tree role="menu" aria-label="{{::item.label}}" ng-if="item.scriptedItems.count > 0 || item.scriptedItems.type == 'resource'" items="item.scriptedItems.items" />