Custom Banner Message Plugin

Banner messages are rectangular messages that occupy a portion of an app’s layout. They stay on screen while users are interacting with the app, anchored at either the top or bottom of the screen, and can be static or animated. These custom banner messages can appear differently depending on the region and their colors can vary based on maintenance activities.

Since there are no out-of-the-box banner message features available, we can create a custom scrolling banner on the IIQ UI page. The custom scrolling banner would be visible on every page and easily accessible to end users after they log in.

Steps to Implement the Banner Solution:

We will use a plugin to create the Banner feature, allowing us to easily extend functionalities without needing to modify any out-of-the-box (OOTB) code.

Folder structure of Banner plugin:
image

Manifest file: The existing manifest file specifies essential parameters for the plugin, such as settings, REST web services, minSystemVersion, and snippets. This file must be included in the plugin ZIP folder and updated to reflect the new functionality of the plugin.

In the manifest file, it is necessary to specify a ‘regexPattern’ to indicate where the banner message should appear, along with the scripts to be injected when loading the IIQ page. In this example, we have specified ‘.*home.jsf’, so the scrolling banner will be displayed only on the Home page. You can customize the ‘regexPattern’ to include other ‘.jsf’ pages or apply it to all pages using ‘*’

<!DOCTYPE Plugin PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Plugin certificationLevel="None"
        name="AnnouncementPlugin"
        displayName="Announcements"
        minSystemVersion="8.1"
        version="1.0">
    <Attributes>
    <Map>
    <entry key="minUpgradableVersion" value="1.0" />  
	<entry key="restResources">
        <value>
          <List>
            <String>com.impact.banner.rest.BannerRestController</String>
          </List>
        </value>
     </entry>    
    <entry key="snippets">
        <value>
          <List>
            <Snippet regexPattern=".*home.jsf" >
              <Scripts>
                <String>ui/js/snippets/messageinner.js</String>
              </Scripts>
            </Snippet>           
          </List>
        </value>
    </entry>   
	<entry key="settings">
       <value>
         <List>       
         </List>
       </value>
     </entry>	
    </Map>
  </Attributes>
</Plugin>

Snippets Script: The new JavaScript file containing the configurable code, which is used to inject code into IIQ interface pages during page load, should be placed in the ‘\ui\js’ folder within the plugin ZIP structure.

The color in this snippet is determined by the REST web service response, based on the region identity and message type.

var url=PluginHelper.getPluginRestUrl("announcementMessage/getNoticeMessage");
var fetcheddata = '';
var fetchColor = '';
var xhttp = new XMLHttpRequest();
xhttp.open("GET", url, true);
xhttp.setRequestHeader("X-XSRF-TOKEN", Ext.util.Cookies.get('CSRF-TOKEN'));
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send();

xhttp.onreadystatechange = function()
	{
	if(this.readyState == 4){
	if(this.status == 200)
		{
		var jsonData = JSON.parse(this.responseText);
		fetcheddata = jsonData["_message"];
		
		fetchColor = jsonData["_color"];   
			if(fetcheddata != '' && fetcheddata != undefined) {
				jQuery(document).ready(function(){
					jQuery("nav.navbar")
						.before('<marquee><span style="color:'+fetchColor+';">'+fetcheddata+'</span><marquee>'
						);
				});
			}
		}
	}
}

REST Web Service Classes: This new file, developed using REST web services, should be placed in the ‘\src’ folder within the plugin ZIP structure. The Banner module relies on REST classes to fetch response messages, utilizing a custom object to retrieve messages specific to a region.

ImpactBannerRestController java: This REST web service controller is called during the loading of the SailPoint IIQ home page. It invokes the service classes to determine which announcement message and color should be displayed based on the identity’s region attribute.

	// getting announcement message
	@GET
	@Path("getNoticeMessage")
	@Produces("application/json")
	@AllowAll
	public Map<String, String> getAnnouncements() {
		log.debug("Class = BannerServices || Method = getAnnouncements || start");

		Map<String, String> announcementMap = new HashMap<String, String>();

		announcementMap = service.getAnnouncements();

		log.debug("Class = BannerServices || Method = getAnnouncements || return value = " + announcementMap
				+ " || Exit");
		return announcementMap;
	}
}

ImpactBannerServices.java: Service classes invoke the custom object to determine which message and color to display based on the identity’s region. These service classes are called by the REST web service controller. Alternatively, instead of using a custom object, we can also utilize plugin settings to read the attributes value.

public static Map<String, String> getAnnouncements() {
		log.debug("Class = BannerServices || Method = getAnnouncements || start");

		String color = "black";
		String message = "";
		String region=null;
		SailPointContext context = SailPointFactory.peekCurrentContext();
		Custom custom = null;
		Map<String, String> announcementMap = new HashMap<String, String>();

		try {
			String identityName=context.getUserName();
			Identity identity = context.getObjectByName(Identity.class, identityName);
	        if(identity != null)
				region = identity.getStringAttribute("region");
			custom = context.getObjectByName(Custom.class, "IMPACT-Banner-CustomObject");
			Attributes attributes = custom.getAttributes();
			if (attributes!=null)
			{
			Map mapCustom = (Map) attributes.getMap();
			if (mapCustom != null) {
			Map regionMap = (Map) mapCustom.get(region);
			if (regionMap != null && !regionMap.isEmpty()) {
			message = (String)regionMap.get("announcements");
			color = (String)regionMap.get("fontColor");
			}
			}
			}
			if (message == null)
				message = "";
			if (color == null)
				color = "black";
		} catch (Exception ex) {
			log.debug("Class = ImpactBannerRestController || Method = getAnnouncements || Error = " + ex.getMessage());
			message = "";
			color = "black";
		}

		announcementMap.put("_message", message);
		announcementMap.put("_color", color);

		log.debug("Class = ImpactBannerServices || Method = getAnnouncements || return value = " + announcementMap
				+ " || Exit");
		return announcementMap;

	}

Custom Object: This new file should be located in the ‘\import\install’ directory. It defines which messages will display for each region of the organization, such as ‘System Maintenance Alerts’ or ‘Application Downtime’. This custom object can be called by the service classes. Alternatively, plugin settings can be used in place of this custom object.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Custom PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Custom name="Impact-Banner-CustomObject">
  <Attributes>
    <Map>
	  <entry key="US">
	  <value>
          <Map>
            <entry key="announcements" value=""/>
			<entry key="fontColor" value=""/>
          </Map>
	  </value>
	  </entry>

	  <entry key="UK">
	  <value>
          <Map>
            <entry key="announcements" value=""/>
			<entry key="fontColor" value=""/>
          </Map>
	  </value>
	  </entry>
    </Map>
  </Attributes>
</Custom>

Successfully Integrated Scrolling Banner into SailPoint IdentityIQ UI: Enhanced Communication and Real-Time Updates Displayed

Various banners can be displayed, such as:

System Maintenance Alerts: “The system will be inaccessible tomorrow due to maintenance and upgrade activities. Please plan accordingly for this downtime.”

Application Downtime Notices: “Attention: Workday authoritative application is undergoing maintenance. Onboarding, mover, and leaver processes may experience delays. Thank you for your patience.”

2 Likes

Thank you for providing this. I followed it, and it is currently working well for our implementation.

Where is the sourcecode for this plugin.