Guided tours in Dynamics 365 extensions V2
I have been working with the modern dev environment for Dynamics 365 Business now for a while and have been trying to get walkthroughs our guided tours setup for apps. The issue with the V2 extensions is that they are not completely ready yet and therefore, it is a bit difficult.
As you probably know, .Net Interop will not be supported anymore, which means that we won’t be able to easily add guided tours anymore the same way they were done in V1 extensions, since we cannot use the “guilded tour” .Net dlls that are used in Microsoft’s guided tour.
What are my options?
Notifications and wizards
I have created an example to show what can be done with just existing functionality in the AL development environment. Unfortunately, it doesn’t go as far as you would like it to go, but some nice things can be done and they are very easy to do. I have developed this as an example for the partner conference Directions NA, which you will see in the code and screenshots.
When your app is just installed and the user logs back on, you can easily show a notification on the top asking the user, if they want to go through a tour.
I have added this in a very flexible way using the discovery event pattern. You can find the complete project at the end of the blog, but here is the code snippet that is needed to get the tour started
[EventSubscriber(ObjectType::Table, Database::"Directions Walkthrough Tour", 'OnRegisterWalkthroughs', '', true, true)] local procedure DirectionsWalkthroughTourOnRegisterWalkthroughs(var TempWalkthrough : Record "Directions Walkthrough Tour"; CurrentPageId : Integer); var CustomerWalkthrough : Codeunit "Directions Customer Walkthru"; RecId : RecordId; begin case CurrentPageId of Page::"O365 Activities": TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 1, MyWalkthroughNameLbl, 0, Page::"Directions My Walkthrough Tour", '', RecId, Page::"O365 Activities", true, true, true, false, false); 0, Page::"Customer Card": begin TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 2, CustomerWalkthroughLbl, 0, 0, '', RecId, Page::"Customer Card", true, true, true, false, false); TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 3, NewCustomerLbl, 2, Codeunit::"Directions My Walkthrough", 'NewCustomer', RecId, Page::"Customer Card", false, false, true, true, false); TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 4, NewCustomerFieldsLbl, 2, 0, '', RecId, Page::"Customer Card", false, false, true, true, false); TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 5, NewCustomerFieldsCreditLimitLbl, 2, 0, '', RecId, Page::"Customer Card", false, false, true, true, false); TempWalkthrough.AddWalkthrough(MyWalkthroughGuidTok, 6, CompletedWalkthroughLbl, 0, 0, '', RecId, Page::"Customer Card", false, false, false, false, true); end; end; end;
As you can see, the code is subscribing to an event to register a specific walkthrough or tour. In this case, I am showing the above notification when the “Business Manager” role center opens, to be more accurate, when the “O365 Activities” part of the role center opens (since you cannot subscribe to role center events – at least they behave differently). It will show the above message and then start the page “Directions My Walkthrough Tour”, which is a wizard that can walk the user through some things, can explain fundamentals, or gather some information. For instance, it is also good practice to add a notification to start the assisted setup wizard of your app this way.
The user gets a few options, “Yes” starts the tour. “No” will hide the notification until the user opens the role center again. “Don’t show anymore” will permanently disable the tour. You could integrate this into the Notification Management via “My Settings”, but I have opted not to do this, since it’s just an example.
This wizard only shows some notifications and, when you press finish, launches the customer card (the tour here is “how to add a new customer”). You can, however, do anything you want with this wizard.
When the customer card opens, you will see another notification asking the user, if they want a walkthrough on how to create a new customer.
You can see this in the second part of the case statement in the code above. It basically just registers another “tour” for the customer card page. This time, the tour consists of several steps, all of those are registered. Most steps don’t have any objects to run, because they only display notifications. One of the steps is running a method in a codeunit to create a new customer.
When the user clicks on “Yes”, the walkthrough starts:
Once the user selects the template, the customer is created and shown on the page. The walkthrough then informs the user about different fields that need to be entered and then completes the walkthrough.
To get this wizard working, we need to add a couple more event subscribers, in addition to the event subscriber to the “OnRegisterWalkthroughs” event. Additionally, you also have to provide the “response functions” to the notifications – remember, one of the steps creates a new customer, so you have to implement this functionality in a “notification response”.
Here are first the additional event subscribers to start the walkthroughs:
EventSubscriber(ObjectType::Page, Page::"O365 Activities", 'OnOpenPageEvent', '', true, true)] local procedure O365OnOpenPageEvent(var Rec : Record "Activities Cue"); var Walkthrough : Codeunit "Directions Walkthrough"; begin Walkthrough.RunWalkthrough(Page::"O365 Activities"); end; [EventSubscriber(ObjectType::Page, Page::"Customer Card", 'OnOpenPageEvent', '', true, true)] local procedure CustomerCardOnOpenPage(var Rec: Record Customer); var Walkthrough : Codeunit "Directions Walkthrough"; begin Walkthrough.RunWalkthrough(Page::"Customer Card"); end;
The only code that has to be added to the “OnOpenPageEvent” for the pages you want to show notifications is the line to run the walkthrough (RunWalkthrough) with the page number to invoke the proper steps.
Now, the next implementation is a global function with a parameter of type “Notification” that corresponds to the method we defined as the “execution method” on the “new customer” walkthrough. Since the “NewCustomerFromTemplate” functionality is currently marked as internal, I had to copy the functionality into this extension and called it then in a local method. The proper way for extension development would have been to request from Microsoft to make this function external.
procedure NewCustomer(sender : Notification); var Cust : Record Customer; WalkthroughStatus : Record "Directions Walkthrough Status"; Walkthrough : Codeunit "Directions Walkthrough"; CurrentStep : Integer; begin if not sender.HasData('CurrentStep') then CurrentStep := 1 else if not Evaluate(CurrentStep, sender.GetData('CurrentStep')) then CurrentStep := 1; WalkthroughStatus.SetStatus(sender.Id, CopyStr(UserId, 1, 50), CurrentStep, WalkthroughStatus."Tour Status"::"In Progress"); Commit; Cust.Init; Cust.SetInsertFromTemplate(true); NewCustomerFromTemplate(Cust); Page.Run(Page::"Customer Card",Cust); Walkthrough.RunWalkthrough(Page::"Customer Card"); end;
The actual “Walkthrough Helper” objects are two tables, one for the actual walkthroughs and one to capture the walkthrough status and the current step. The “Walkthrough Tour” table should only be used as temporary and exposes the “OnRegisterWalkthroughs” event to implement the discovery event pattern. Walkthroughs subscribe to this event to add their data to the table and then allow the execution of the walkthrough at the proper timing. This is done by using the “AddWalkthrough” function.
The “Walkthrough Status” table has a function to update the status. This is a table that is not only used as a temporary table. It stores the status information of a walkthrough and allows the notifications only to be displayed when the walkthrough wasn’t completed or even started yet.
One codeunit is also included that handles the walkthrough processing. The interesting function is “RunWalkthrough”, which allows invoking a walkthrough from your own objects.
I have the entire project added here as a zip file – however, I left the json files and the actual app out. Just open it in VSCode with the September 2017 or later update of AL and then create the package and execute it.