
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 03-13-2018 10:15 AM
"If you were told to build a house, but you could only use one tool...which tool would you pull out of your toolbox?"
As an ambitious and curious person, I am forever asking myself, ‘What if?’ What if I decided one day I wanted a portal page that had a look and feel of something I’m more familiar with as a consumer? What if I wanted to use other libraries that seem unconventional in ServiceNow, but are widely accepted throughout the web app development community? What if I just went…rogue and did things my way?
As I was dreaming of the possibilities I stumbled on a workflow that seems to work for me. To that end, my disclaimer is that this may or may not work for you, but maybe it will spark new ideas.
The Problem Set
One of the first things that are made blatantly clear when you embark on your first Service Portal adventure is that the environment is primarily geared to the ‘No Code/Low Code’ audience. There’s nothing wrong with this, however it does create a few challenges when trying to take things to the next level.
The built-in IDE is actually quite elegant in its simplicity. Allowing me to edit HTML, CSS, client & server side scripting in segregated panes is a awesome. Once you realize that the scripting panes are really a bootstrapped Angular controller with a ready-made model things begin to look a little more familiar.
Additionally, HTML is everything you expect. Because widgets are pre-made Angular directives, essentially the rest of your HTML composition is already created. You are free to treat your widget like a DIV with a conceptual ‘CLASS’ of ‘body’ or ‘main-body’. Any attributes you may need in the header or predetermined tags you can add using JavaScript.
The Project: Live Admin Portal Page
For this example, I wanted to create a more versatile administrative portal homepage. I wanted access to cleaner, more robust UI features. Because I’m not inherently a UI designer, I wanted access to the world of UI templates that exist.
So I found a template I really liked packed with a ton of JavaScript features and decided to see if I could competently incorporate it into my company’s applications.
Here’s the template I went with: Dee Admin
We are currently leveraging the main dashboard and the calendar. We have three instances of the calendar (SDLC, High Priority Incidents, and SNOW Admin events). Calendars are driven by SNOW data. Many parts of the dashboard are driven by real-time listeners so that we can leave the dashboard up at all times and get real-time incident feeds and so on.
Main Portal Page
- Top 10 Unassigned Incidents: This is a live (filtered) update using AngularJS. When an P1 or P2 incident arrives, they are automatically pushed to the top of the list and have a flashing red (P1) or yellow (P2) icon to grab the viewer's attention.
- Incidents Trending: This is one of a...I can't tell you now many graphs. There are a ton of graphing options you can connect to real data.
- Today's Events: This is actually a widget from the Full Calendar library. The cool feature here is that the feed is an aggregate from two different calendar sources. Sources can come from anywhere (SNOW internal...or even Google).
- All other stats: These are generated strictly from GlideRecord queries
- Everything is a link: Every stat you see is a hyperlink that opens a list view or the actual record so it can be actioned.
- Left Navigation: You can place anything you want here. I've chosen to place various Admin/Dev resources for quick access.
- Data: While it's feasible to place all data scripting in the server-side portion of this widget, I chose to utilize a single script include class with the prototype method. All of my Glide queries and aggregates are done in the script include and I'm simply returning 'data.whatever' which I then using in the client scripting or directly in the Angular template.
- Use OOB Widget snippets: You can use OOB widget code as well. I've taken the user profile widget data and incorporated in the top-left corner of the page. You can do this with anything that currently exists.
Full Calendar JS library
This calendar example is a simple example I created for the admin/dev team. This is connected directly to a custom table inside SNOW, and if you have further ambitions there's nothing to stop you from creating Business Rules to activate recurrence (every day, week, once a month, every other Monday....etc.).
In some of our other instances are pulling directly from the incident table to display various high priority incident events and their related changes (if there are any). We have further enhanced this by coding in conditional color schemes.
You can feed the calendar any hex color code you desire based on any GlideRecord condition. Consequently, not only will the events show up in their respective colors, when you open the event it will display that color in the modal.
- Mobile First: The best part is that everything is designed in Bootstrap, so it goes without saying that the entire template was built with 'mobile first' in mind.
- Security: Like anything else in SNOW, you can show/hide any aspect of the UI based on role/access. The 'edit calendar' feature under 'Tools' is only available to admins and developers on our team.
Single Widget Concept
Everything you see above is in two widgets. One widget for the dashboard and one widget for the calendar. Each widget has a dedicated script include and its own class of methods. These provide the model/data for the views. Using script includes keeps my code compartmentalized and clean. Using a custom class and methods allows me to keep my code functional and scalable.
The best approach to executing this from a library perspective is to keep it as traditional as possible. At the start I attempted to roll in JS and CSS files as ServiceNow suggests, but I ended up with more collisions than I could count. Instead I created a theme, and attached all library files to the theme.
Inside my widget I simply create the script & css links like you would for a traditional application or web page build out, but for the href/source I referenced the sys_attachment sys_id for each library file.
Additionally, for CSS I actually chose to use the OOB CSS IDE pane but add '@import' to bring in my other CSS files on top of the widget's CSS code.
In this manner I was able to control the environment and build exactly what I wanted.
In your widget, you will also want to ensure you use a full-width column in a single container. You should set your container to 'fluid'. Once you establish your widget, just drag it into the column and basically you'll never need to go back into the page design view again for that page.
I have successfully built two large projects in this manner. I have not witnessed any performance drawbacks apart from forgetting to filter my real-time update listeners. Once these were filtered everything flies as fast as any other portal page pulling lots of data.
Dream Big!
Keep in mind, I have used this method with two different themes I've purchased from 'out there'. You can do this with ANY HTML theme you find. This allows you to capitalize on the aesthetics from a true UI developer so you can focus on data delivery.
Everything you see above took me about a week to code in my spare time.
Thanks for stopping by!