Show Global Notification on Load of Model-driven App in Dynamics 365

Global Notification

Previously in the legacy web client, the system administrators used to see the system notification messages as below (which informs us about the mailbox alerts or users without security roles). Occasionally, the customers came up with the requirement to show certain warning message as soon as the user logs in to the system but there was no API for such application-level notification. Most of the time, we have to convince the customer to settle with a solution which involves creating a view for those records that requires the user's attention in a landing dashboard.
Legacy Web Client Messages
In Unified Interface, we can now show such application-level notification using addGlobalNotification client API. This solution is inspired by the blog post about Global Notification written by Priyesh Wagh when the feature was still in preview. A few days ago, @PFEDynamics tweeted about it (I guess that is an announcement of general availability) and I thought for creating a solution with it.

Problem: Even though we now have the client API to show the global notification without form context, we don't have the trigger for a JavaScript at onLoad of the application. The first attempt was to call addGlobalNotification in custom icon column event script of the home page grid view but the method triggers for every record in the grid. The second attempt was to add a new dummy hidden-button in the homepage grid and call the addGlobalNotification in the script of CustomRule of the Enable Rule but it is not triggered when the Dashboard is the default page and a new button in Dashboard Homepage tab is not showing in Unified Interface.

Solution: The solution is to create a hidden button in Global Tab (where the Quick Create, Advanced Find and Settings menu are located) and call the JavaScript function using CustomRule of the button Enable Rule. Use a global variable to make sure the global notification is not being added multiple times and clear the global notification on button click.

🛈 Note

Since the solution below relies on a global variable of JavaScript, the notification shows every time the user opens a new tab/window. If that is not the desired outcome, localStorage can be used to show only once. (or even using a new custom entity to keep track of the notification setting for each user using Xrm.WebApi)

In this blog post, you will learn how to achieve the following using the addGlobalNotification client API in JavaScript.
  • add a button in Global Tab using Ribbon Workbench
  • call JavaScript function using CustomRule of the button Enable Rule
  • retrieve record count using Xrm.WebApi.retrieveMultipleRecords
  • using alternative ConditionOperator for older than current time
  • show global notification using Xrm.App.addGlobalNotification
  • navigate to entity list view using Xrm.App.clearGlobalNotification
  • clear global notification using Xrm.App.clearGlobalNotification
Use Case: If the user has overdue tasks (tasks with a due date earlier than today and status = Open), the system will show the warning notification as soon as the user logs in to the system. The notification will have a button which will redirect the user to "My Tasks" view on click.
Here is the whole JavaScript code for the solution and the detailed explanation for each step of the solution can be found below. You can download the code from my GitHub repository via this link.


Create a new solution and add "Application Ribbons" under the "Client Extensions". Use the Ribbon Workbench tool and open the solution from the previous step. Follow this blog post for more details.
To add a button in the Global Tab, scroll the Home area to the right until you find the Mscrm.GlobalTab. Drag a button and drop into that Mscrm.GlobalTab. (more details here)
Global Tab Ribbon Workbench

Create a new Command (more details here) and add a new enable rule for it.
Command


In the EnableRule, add a new step as CustomRule and select the JavaScript web resource in the library and enter the function name.
Enable Rule


Finally, select the Command created in the first step in the button which was added to the Global Tab.
Button Command Selection


Once added, the button can be visible at the Global Tab area at the top right corner.
Global Tab Button


The GlobalNotificationEnableRule function is triggered via CustomRule.
The purpose of the button is to call the custom script so that the button needs to be hidden all the time.
When the return value of GlobalNotificationEnableRule function is false, the button will be disabled and the system will not show the disabled button in Unified Interface.
At first, retrieveOverdueTasks method will verify if the OverdueTaskNotificationId is null or not. This is to prevent multiple notifications when the same function is triggered multiple times.
 GlobalNotificationEnableRule: function ()  
 {  
   this.retrieveOverdueTasks();  
   return false;  
 },  
 retrieveOverdueTasks: function ()  
 {  
   if (LZW.Xrm.ApplicationRibbon.OverdueTaskNotificationId === null)  
   {  

Xrm.WebApi.retrieveMultipleRecords is used to retrieve the task records. The record count is required as a return value. If there is no column specified in the select query, retrieveMultipleRecords function will return all columns. Which is why activityid is added in the retrieve query. The filter conditions are
  • Owner Equals Current User
  • scheduledend (Due Date) is in the last 99 years (older than the current time)
  • statecode (Statue) Equals 0 (Active)
If you are not familiar with the conditions for WebAPI, you can use the FetchXML Builder for XrmToolBox to convert the FetchXML to WebAPI query.
 Xrm.WebApi.retrieveMultipleRecords("task", "?$select=activityid  
 &$filter=Microsoft.Dynamics.CRM.EqualUserId(PropertyName='ownerid')   
 and Microsoft.Dynamics.CRM.LastXYears(PropertyName='scheduledend',PropertyValue=99)   
 and statecode eq 0")  

On Success of the WebApi call from the previous step, use addGlobalNotification to show the Global Notification if there is any overdue task.
In the code below, set the notification value
  • type = 2 which is the only supported type for now
  • level = 3 which is for warning icon
  • message includes the number of overdue tasks
  • showCloseButton = true which allows the user to close the notification
  • action will show a button at the right side of the notification (the details of the viewTaskAction object will be explained in the next step)
For more details of the parameters, check out the Microsoft Docs site.
On Success of the addGlobalNotification call, it will return the GUID value is passed to uniquely identify the notification which can later be used to close the notification using the clearGlobalNotification method. (which is also used to prevent multiple notifications in step 3 in this solution)
 var notification = {  
      type: 2,  
      level: LZW.Xrm.ApplicationRibbon.NotificationLevel.Warning,  
      message: `You have(${taskCount}) overdue task(s).`,  
      showCloseButton: true,  
      action: viewTaskAction  
 };  
 Xrm.App.addGlobalNotification(notification).then(  
 function success(result)  
 {  
      LZW.Xrm.ApplicationRibbon.OverdueTaskNotificationId = result;  
 },  


In the previous code, the action attribute of the notification property in addGlobalNotification can be set to add a button and specify the function to execute when the action label is clicked.
The object for the action attribute contains actionLabel (which is the label of the button) and the eventHandler.
Action Button
In the code below, the eventHandler is navigating to "My Tasks" view and close the notification using the GUID value from the previous step.
 var viewTaskAction = {  
      actionLabel: "View My Tasks",  
      eventHandler: function ()  
      {  
           var pageInput = {  
                pageType: "entitylist",  
                entityName: "task",  
                viewId: "6cf285aa-eb20-4277-925a-3e9735411ff0" // My Tasks View  
           };  
           Xrm.Navigation.navigateTo(pageInput, { target: 1 });  
           Xrm.App.clearGlobalNotification(LZW.Xrm.ApplicationRibbon.OverdueTaskNotificationId);  
      }  
 };  

Summary
By calling addGlobalNotification client API from the Custom Enable Rule of the hidden button in Global Tab, we can show the startup notification to the user as soon as the user logs in to the model-driven app.

Comments

Popular Posts

[Power Automate] How to Set Lookup Field Value in Common Data Service (current environment) Flow Connector

[Power Automate] List Records - Use Expand Query to Retrieve Related Data in flow

[Power Apps] Using Common Data Service's Lookup Data Type Field in Canvas App

[Bug] Using the ClearCollect() Function in PowerApps does not Pull any Lookup Columns from Common Data Service (CDS) Data Source

Pass Parameters to Quick Create Form in Dynamics 365 using formContext.data.attributes

Getting the Lookup Attribute of the Parent Record in Power Apps Canvas App Development with Common Data Service (CDS)

Send Email from Dynamics 365/CDS with Attachment from Notes Using Flow

[Power Automate] Find out how to include a link to the record (Record URL) when sending an email from Dynamics 365/CDS using flow

Build Efficient Flows Using Filter Expression in CDS (current environment) Trigger

[Power Apps] New improvements in Embedded Canvas Apps which are undocumented / unannounced