Skip to main content

Service Portal Widget: a 'my issues' widget


 

HTML

<!-- https://xd.adobe.com/view/0305f2c4-d644-4abb-8558-269aab4c658c-5656/screen/8b567bfc-4a32-4b17-9a2c-19e137f1e779/specs/ --> <div class="mi-container"> <div> <!-- your widget template --> <h1 class="mi1"> My Issues</h1> <!-- current user: {{data.sysUserID}}--> </div> <div class="mi-openclosed"> <div class="mi-padded"> <div class="mi-center"> <button id="mi-button-open" autofocus class="btn btn-default" ng-click="mi_showOpen()">Open Issues</button>&nbsp; <button id="mi-button-closed" class="btn btn-default" ng-click="mi_showClosed()">Closed Issues</button> </div> <div class="typea"> <widget id="typeahead-search" options=data.search_options></widget> </div> </div> </div> <div class="panel-heading break-word"> <h2 id="mi-total-panel-title" class="h4 panel-title">{{c.resultsList}} <span class="issues-total">{{c.totalTickets}}</span> {{c.cellPadder}}<span class="sortby-small">Sorted by: {{c.sortedBy}}</span> <span class="issues-sort" >Sort by: <button id="mi-button-sort-1" class="btn btn-default" ng-click="mi_sort_last_updated()">Last updated</button> <button id="mi-button-sort-2" class="btn btn-default" ng-click="mi_sort_created_date()">Created date</button> <button id="mi-button-sort-3" class="btn btn-default" ng-click="mi_sort_status()">Status</button> </span> </h2> </div> <div id="mi-open-tickets" ng-model = "c.openList" ng-hide="{{c.data.showOpen}}"> <!-- <div ng-repeat="openTicket in ::data.openIssuesList" >--> <div ng-repeat="openTicket in c.openTickets" > <div class="panel-body b-b result-item" style="background-color:#F2FBFE"> <a href="?id=form&sys_id={{openTicket.sys_id}}&table=incident"><span>{{openTicket.short_description}}</span> <span id="mi-priority-o" style="font-weight:{{c.highlightColor5}}"> - Priority: {{openTicket.priority}}</span> </a><br/> <span class="mi-fi">Issue Number: {{openTicket.number}}</span> {{c.cellPadder}}<span id="mi-fi-created-o-{{openTicket.number}}" style="font-weight:{{c.highlightColor1}}" class="mi-fi">Created: {{openTicket.sys_created_on}}</span> {{c.cellPadder}}<span id="mi-fi-updated-o-{{openTicket.number}}" style="font-weight:{{c.highlightColor2}}" class="mi-fi">Updated: {{openTicket.sys_updated_on}}</span> {{c.cellPadder}}<span id="mi-fi-updated-o-{{openTicket.number}}" style="font-weight:normal" class="mi-fi">Agent: {{openTicket.assigned_to}}</span> <button class="btn btn-default" style="float: right;background-color:#145896;color:#F2FBFE;font-size:14px" ng-click="mi_viewRecord(${openTicket.sys_id})">View issue</button> </div> <div class="mi-spacer"></div> </div> </div> <!--<div id="mi-closed-tickets" ng-hide="{{c.data.showClosed}}" ng-model = "c.closedList">CLOSED TICKETS--> <div id="mi-closed-tickets" style="display:none" ng-model = "c.closedList"> <!--<div ng-repeat="closedTicket in ::data.closedIssuesList" >--> <div ng-repeat="closedTicket in c.closedTickets" > <div class="panel-body b-b result-item" style="background-color:#F2FBFE"> <a href="?id=form&sys_id={{closedTicket.sys_id}}&table=incident"><span class="mi-sd">{{closedTicket.short_description}}</span> <span id="mi-priority-c" style="font-weight:{{c.highlightColor5}}"> - Priority: {{closedTicket.priority}}</span> </a><br/> <span class="mi-fi">Issue Number: {{closedTicket.number}}</span> {{c.cellPadder}}<span id="mi-fi-created-c-{{closedTicket.number}}" style="font-weight:{{c.highlightColor3}}" class="mi-fi">Created: {{closedTicket.sys_created_on}}</span> {{c.cellPadder}}<span id="mi-fi-updated-c={{closedTicket.number}}" style="font-weight:{{c.highlightColor4}}" class="mi-fi">Updated: {{closedTicket.sys_updated_on}}</span> {{c.cellPadder}}<span id="mi-fi-updated-c-{{openTicket.number}}" style="font-weight:normal" class="mi-fi">Agent: {{closedTicket.assigned_to}}</span> <button class="btn btn-default" style="float: right;background-color:#145896;color:#F2FBFE;font-size:14px" ng-click="mi_viewRecord(${closedTicket.sys_id})">View issue</button> </div> </div> <div class="mi-spacer"></div> </div> </div>
</div>




CLIENT SCRIPT

function($scope) { /* widget controller */ var c = this; c.data.showOpen = false; c.data.showClosed = true; c.resultsList = 'Total open issues: '; c.totalTickets = c.data.totalOpenIssues; c.openTickets = c.data.openIssuesList; c.closedTickets = c.data.closedIssuesList; c.sortedBy = c.data.sortedBy; //angular.element($('#mi-button-sort-1')).style.backgroundColor='#145896'; document.getElementById("mi-button-sort-1").style.backgroundColor = "#145896"; document.getElementById("mi-button-sort-1").style.color = "#F2FBFE"; var sPad = ''; for (ic = 0; ic < 3; ic++) { sPad += String.fromCharCode(160); } c.cellPadder = sPad; //--show open button clicked------------------- $scope.mi_showOpen = function() { document.getElementById("mi-button-sort-1").style.backgroundColor = "#145896"; document.getElementById("mi-button-sort-1").style.color = "#F2FBFE"; c.server.get({ action: "sort_updated", msg: "Sorting issues by updated date...", customQuery: angular.element($('#custom_query')).val() }).then(function(r) { c.openTickets = r.data.openIssuesList; c.closedTickets = r.data.closedIssuesList; c.sortedBy = r.data.sortedBy; }); c.data.showOpen = false; c.resultsList = 'Total open issues: '; c.totalTickets = c.data.totalOpenIssues; document.getElementById("mi-closed-tickets").style.display = "none"; document.getElementById("mi-open-tickets").style.display = "block"; c.highlightColor1 = 'normal'; c.highlightColor3 = 'normal'; c.highlightColor2 = 'bold'; c.highlightColor4 = 'bold'; c.highlightColor5 = 'normal'; } //--show open closed clicked------------------- $scope.mi_showClosed = function() { document.getElementById("mi-button-sort-1").style.backgroundColor = "#145896"; document.getElementById("mi-button-sort-1").style.color = "#F2FBFE"; c.server.get({ action: "sort_updated", msg: "Sorting issues by updated date...", customQuery: angular.element($('#custom_query')).val() }).then(function(r) { c.openTickets = r.data.openIssuesList; c.closedTickets = r.data.closedIssuesList; c.sortedBy = r.data.sortedBy; }); c.resultsList = 'Total closed issues: '; c.totalTickets = c.data.totalClosedIssues; document.getElementById("mi-closed-tickets").style.display = "block"; document.getElementById("mi-open-tickets").style.display = "none"; c.highlightColor1 = 'normal'; c.highlightColor3 = 'normal'; c.highlightColor2 = 'bold'; c.highlightColor4 = 'bold'; c.highlightColor5 = 'normal'; } //--view record button clicked------------------- $scope.mi_viewRecord = function(issueSYSID) { var sLink = "?id=form&sys_id=" + issueSYSID + "&table=incident"; //alert(sLink); window.open(sLink, '_self'); } //----------------sort by UPDATED button clicked---------------------- $scope.mi_sort_last_updated = function() { document.getElementById("mi-button-sort-1").style.backgroundColor = "#145896"; document.getElementById("mi-button-sort-1").style.color = "#F2FBFE"; c.server.get({ action: "sort_updated", msg: "Sorting issues by updated date..." }).then(function(up) { c.openTickets = up.data.openIssuesList; c.closedTickets = up.data.closedIssuesList; c.sortedBy = up.data.sortedBy; }); c.highlightColor2 = 'bold'; c.highlightColor4 = 'bold'; c.highlightColor1 = 'normal'; c.highlightColor3 = 'normal'; c.highlightColor5 = 'normal'; } //----------------sort by CREATED button clicked---------------------- $scope.mi_sort_created_date = function() { document.getElementById("mi-button-sort-1").style.backgroundColor = "#F2FBFE"; document.getElementById("mi-button-sort-1").style.color = "#145896"; c.server.get({ action: "sort_created", msg: "Sorting issues by created date..." }).then(function(cr) { c.openTickets = cr.data.openIssuesList; c.closedTickets = cr.data.closedIssuesList; c.sortedBy = cr.data.sortedBy; }); c.highlightColor1 = 'bold'; c.highlightColor3 = 'bold'; c.highlightColor2 = 'normal'; c.highlightColor4 = 'normal'; c.highlightColor5 = 'normal'; } //----------------sort by PRIORITY button clicked---------------------- $scope.mi_sort_status = function() { document.getElementById("mi-button-sort-1").style.backgroundColor = "#F2FBFE"; document.getElementById("mi-button-sort-1").style.color = "#145896"; c.server.get({ action: "sort_status", msg: "Sorting issues by priority..." }).then(function(pr) { c.openTickets = pr.data.openIssuesList; c.closedTickets = pr.data.closedIssuesList; c.sortedBy = pr.data.sortedBy; }); c.highlightColor1 = 'normal'; c.highlightColor3 = 'normal'; c.highlightColor2 = 'normal'; c.highlightColor4 = 'normal'; c.highlightColor5 = 'bold'; } }
}

















SERVER SCRIPT

(function() { /* populate the 'data' object */ /* e.g., data.table = $sp.getValue('table'); */ var sMsgPadder = "*********************************** MSG: "; data.sysUserID = $sp.getParameter("sys_id"); if (!data.sysUserID) { data.sysUserID = gs.getUser().getID(); } data.search_options = '{"contextual_search_sources": { "value": "d12dd5cadb8d6c10f04aad050596195c", "displayValue": "My Incidents" }}'; var sOrderByField = 'sys_updated_on'; data.sortedBy = 'updated'; var sOB_descAsc = 'desc'; //--order by priority if (input && input.action === "sort_status") { sOrderByField = 'priority'; data.sortedBy = 'priority'; sOB_descAsc = 'asc'; } //--order by created if (input && input.action === "sort_created") { sOrderByField = 'sys_created_on'; data.sortedBy = 'created'; sOB_descAsc = 'desc'; } //default--order by updated /*if (input && input.action === "sort_updated") { }*/ //gs.addInfoMessage(sMsgPadder + sOrderByField + ';' + data.sortedBy + ';' + sOB_descAsc); var sQuery = 'caller_id=' + data.sysUserID + '^ORu_logged_on_behalf=' + data.sysUserID; var iLimit = 5; data.openIssuesList = []; var grIncsOpen = buildIncGR(sOB_descAsc, sOrderByField, true, sQuery, 0); iLimit = grIncsOpen.getRowCount(); //--uncomment if want to limit to initial iLimit value data.totalOpenIssues = iLimit; while (grIncsOpen.next()) { var object_o = buildUpIncArr(grIncsOpen); data.openIssuesList.push(object_o); } data.closedIssuesList = []; var grIncsClosed = buildIncGR(sOB_descAsc, sOrderByField, false, sQuery, 0); iLimit = grIncsClosed.getRowCount(); //--uncomment if want to limit to initial iLimit value data.totalClosedIssues = iLimit; while (grIncsClosed.next()) { var object_c = buildUpIncArr(grIncsClosed); data.closedIssuesList.push(object_c); } })(); function buildUpIncArr(grInc) { var objArr = {}; objArr.number = grInc.number + ""; objArr.sys_id = grInc.sys_id + ""; objArr.short_description = grInc.short_description + ""; //--created on: var sCrOn = grInc.getDisplayValue('sys_created_on'); var sCrOn_Arr = sCrOn.split(' '); objArr.sys_created_on = sCrOn_Arr[0] + ""; //--updated on: var sUpdOn = grInc.getDisplayValue('sys_updated_on'); var sUpdOn_Arr = sUpdOn.split(' '); objArr.sys_updated_on = sUpdOn_Arr[0] + ""; objArr.assigned_to = grInc.getDisplayValue('assigned_to') + ""; objArr.priority = grInc.getDisplayValue('priority') + ""; return objArr; } function buildIncGR(orderByAscOrDesc, orderByField, activeQuery, query, iLimit) { var grInc = new GlideRecord('incident'); if (activeQuery) { grInc.addActiveQuery(); } if (!activeQuery) { grInc.addInactiveQuery(); } if (iLimit > 0) { grInc.setLimit(iLimit); } if (orderByField != '' && orderByAscOrDesc!='') { if (orderByAscOrDesc == "desc") { grInc.orderByDesc(orderByField); } if (orderByAscOrDesc == "asc") { grInc.orderBy(orderByField); } } grInc.addQuery(query); grInc.query(); return grInc; }

})();































CS

CSS

/*the typeahead input within the embedded widget*/ input[name="q"] { border-radius: 50px; height:100%; } button[name="search"] { border-radius: 50px; height:100%; } button[class="input-group-btn"]{ border-radius: 50px; } div.typea{ width: 380px; float: right; padding: 15px; } /*end typeahead*/ h1.mi1{ color:#003057; background-color:#F5F6F8; font-size:25px; } div.mi-openclosed{ background-color:#145896; color:white; height: 70px; } div.mi-center{ margin: 0; position: absolute; margin-top: 12px; } div.mi-padded{ padding-left: 20px !important; } div.mi-spacer{ height:10px; background-color:#F5F6F8; } div.mi-container{ /* min-height: 703px; */ } span.mi-fi{ font-size:14px; color:#003057; } span.mi-sd{ font-size:16px; } span[id^='mi-priority']{ font-weight:normal; } span.issues-total{ color:#145896; font-size:16px; } span.issues-sort{ color:#145896; font-size:16px; float: right; } span.sortby-small{ color:#2A363B; font-size:14px; } span[id^='mi-fi-updated-o'] { font-weight:bold; } span[id^='mi-fi-updated-c'] { font-weight:bold; } #mi-total-panel-title{ color:#2A363B; font-size:16px; } #mi-button-open {background-color:#F2FBFE; color:#145896; font-size:18px; } #mi-button-open:focus { background-color:#145896; color:#F2FBFE; opacity: 1; font-size:18px; } #mi-button-closed { /*background-color: white;*/ background-color:#F2FBFE; color:#145896; /*opacity: 1;*/ font-size:20px; } #mi-button-closed:focus { background-color:#145896; /*color:white;*/ color:#F2FBFE; opacity: 1; font-size:20px; } button[id^='mi-button-sort'] { background-color:#F2FBFE; color:#145896; } button[id^='mi-button-sort']:focus { background-color:#145896; color:#F2FBFE; opacity: 1; }

Comments

Popular posts from this blog

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){

Service Catalog: variable advanced reference qualifiers

Call a script include to apply a reference qualifier on a catalog item variable: - variable reference qualifier dependent on another variable selection, in this case a variable referencing sys_user (requested_for) On the catalog item form. variable name to apply ref qual filter : retail_equipment variable reference qualifier (on cmdb table ): javascript : new  refqual_functions (). lostStolen_getAssignedCIs (); client-callable script include ( refqual_functions)  function : lostStolen_getAssignedCIs : function (){         //--called from variable set client script, for lost/stolen request (service catalog)     gs . log ( current . variables . requested_for , 'retail_lostStolen_getAssignedCIs' );         return ( 'install_statusNOT IN8,7^owned_by=' + current . variables . requested_for );             //owned_by=1269b79937f1060041c5616043990e41^install_statusNOT IN8,7            },

Get URL Parameter - server side script (portal or classic UI)

Classic UI : var sURL_editparam = gs . action . getGlideURI (). getMap (). get ( ' sysparm_aparameter ' ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); } Portal : var sURL_editparam = $sp . getParameter ( " sysparm_aparameter " ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); }