Enhancing User Experience: The Power of Application Areas in System Development

4 minute read

Introduction

Application Area gives us the ability to define differentiated user experiences. They are mapped to controls to show or hide them on page objects to enable more or fewer business scenarios.

As you know, we can extend the application areas in Business Central1 by extending the Application Area Setup table:

tableextension 60200 ApplicationAreaSetupExt extends "Application Area Setup"
{
    fields
    {
        field(60200; "Trading"; Boolean) { }
    }
}

Spaces in the field name are omitted in the ApplicationArea property.

Then we can set the ApplicationArea property2 to our newly created application area, as in the following pagefield example:

field(TradingViewEnabled; Rec."Trading View Enabled")
{
    ApplicationArea = Trading;
    ToolTip = 'Specifies if the trading view is enabled.';
}

However, we can not enable/disable an application area out of the box. This is where the Experience Tier comes into play.

Extend the Experience Tier Setup

By adding experience tiers we allow the users to choose which set of application areas they want to enable in their specific company. We can change the User Experience on the Company Information page.

The way it works is the same as extending the Application Area Setup, except this time it extends the Experience Tier Setup. Let’s look at an example:

tableextension 60201 ExperienceTierSetupExt extends "Experience Tier Setup"
{
    fields
    {
        field(50100; Ultimate; Boolean)
        {
        }
        field(50101; Platinum; Boolean)
        {
        }
        field(50102; VIP; Boolean)
        {
        }
    }
}

Enable application areas

To enable application areas in a custom experience tier we need to subscribe to the event “OnSetExperienceTier” from the “Application Area Mgmt. Facade” codeunit.

codeunit 60200 EnableApplicationArea
{
    Access = Internal;
    InherentEntitlements = X;
    InherentPermissions = X;
    SingleInstance = true;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt. Facade", 'OnSetExperienceTier', '', false, false)]
    local procedure EnableAdvancedApplicationAreaOnSetExperienceTier(experienceTierSetup: Record "Experience Tier Setup"; var tempApplicationAreaSetup: Record "Application Area Setup" temporary; var applicationAreasSet: Boolean)
    begin
        if experienceTierSetup.Ultimate then begin
            tempApplicationAreaSetup.Basic := true;
            tempApplicationAreaSetup.Suite := true;
            tempApplicationAreaSetup.Service := true;
        end;
    end;
}

For an overview, which application areas are enabled in the current company, search for Application Area via Tell Me:

Application Area

Refresh experience tier of current company

There is still one more thing left to do: set the experience tier of the current company. This is done when installing the extension as in the following example:

codeunit 60201 InstallApplicationArea
{
    Subtype = Install;

    trigger OnInstallAppPerCompany()
    var
        applicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade";
    begin
        applicationAreaMgmtFacade.RefreshExperienceTierCurrentCompany();
    end;
}

As you have already noticed, it’s necessary to update our AL code whenever there are new Application Areas added to our solution.

Enable the Application Area via Setup page

Since we can design module-driven in Business Central, I think that enabling the Application Area in a setup page makes sense. It gives the administrators the ability to enable/disable the module for specific companies without switchting the Experience Tier.

The following example Module Setup table just goes to show how this can be done. This time we refresh the experience tier on validating the Application Area Enabled field.

table 60200 "Module Setup"
{
    Caption = 'Module Setup';

    fields
    {
        field(1; "Primary Key"; Code[10])
        {
            Caption = 'Primary Key';
        }
        field(10; "Application Area Enabled"; Boolean)
        {
            Caption = 'Application Area Enabled';

            trigger OnValidate()
            var
                applicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade";
            begin
                applicationAreaMgmtFacade.RefreshExperienceTierCurrentCompany();
            end;
        }
    }
}

This triggers our event subscribers so that we can activate the application area depending on the value of the Boolean.

if moduleSetup.Get() then
    tempApplicationAreaSetup.Trading := moduleSetup."Application Area Enabled";

To cover every aspect, here’s a full example:

codeunit 50103 EnableApplicationArea
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt.", 'OnGetBasicExperienceAppAreas', '', false, false)]
    local procedure EnableModuleOnGetBasicExperienceAppAreas(var tempApplicationAreaSetup: Record "Application Area Setup" temporary)
    begin
        EnableApplicationArea(tempApplicationAreaSetup);
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt.", 'OnGetEssentialExperienceAppAreas', '', false, false)]
    local procedure EnableModuleOnGetEssentialExperienceAppAreas(var tempApplicationAreaSetup: Record "Application Area Setup" temporary)
    begin
        EnableApplicationArea(tempApplicationAreaSetup);
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt.", 'OnGetPremiumExperienceAppAreas', '', false, false)]
    local procedure EnableOnGetPremiumExperienceAppAreas(var tempApplicationAreaSetup: Record "Application Area Setup" temporary)
    begin
        EnableApplicationArea(tempApplicationAreaSetup);
    end;

    local procedure EnableApplicationArea(var tempApplicationAreaSetup: Record "Application Area Setup" temporary)
    var
        moduleSetup: Record "Module Setup";
    begin
        if moduleSetup.Get() then
            tempApplicationAreaSetup.Trading := moduleSetup."Application Area Enabled";
    end;
}

A complete list of the state of all application areas per company would be appreciated. This would give a quick overview of the modules used in each company, and it would even be possible to activate/deactivate them without having to change companies from time to time.

Conclusion

We tend to use ApplicationArea = All; always and everywhere without thinking about whether the customer will use the module in the company at all. Giving them the ability to determine it themselves makes for a great user experience, which we should enable whenever possible.

This is especially true for ISVs. When developing directly for a customer, it tends to downplay this feature because the new fields should always be displayed until they realize they are not needed in other companies. Then they would hide them if needed through individual personalization.

I would not extend the Experience Tier as I would leave it to the specific licensing scenario Essential or Premium which should be activated. Remember to enable your custom application area to one or both of these experience tiers and allow the user to toggle the Application Area for the specific companies.

Hope you learned something new.

See you around 🦦