Intents

Overview

In certain workflow scenarios, your app may need to start (or activate) a specific app. For instance, you may have an app showing client portfolios with financial instruments. When the user clicks on an instrument, you want to start an app which shows a chart for that instrument. In other cases, you may want to present the user with several options for executing an action or handling data from the current app.

The Intents API makes all that possible by enabling apps to register, find and raise Intents.

The case with the "Portfolio" and the "Chart" app above can be implemented in the following way:

  1. The "Chart" apps registers an Intent called "ShowChart", specifying the data type (predefined data structure) that it works with - e.g., "Instrument".

  2. When the user clicks on on instrument, the "Portfolio" app raises the "ShowChart" Intent, optionally specifying an Intent target, data type and app start up options.

This way, the "Portfolio" and "Chart" apps can be completely decoupled. If later the "Chart" app needs to be replaced, the new app for showing charts only needs to register the same Intent in order to replace the old one (provided that it works with the "Instrument" data structure as well).

Another case where the Intents API can be useful is if you want to find (and possibly filter) all apps that have registered a certain Intent. This may be because you want to present the user with all available (or appropriate) options for executing an action or handling data - e.g., on hover over an instrument or when clicking an instrument, the user sees a menu with all apps that have registered the Intent "ShowChart" and can work with the "Instrument" data structure:

  1. All apps that can visualize data in charts register an Intent called "ShowChart", specifying the data structure they work with. Some of them work with "Instrument" data type, others work with different data types.

  2. When the user clicks on an instrument in the "Portfolio" app, the "Portfolio" app searches for all registered Intents with a name "ShowChart" and filters them by the data type they work with.

  3. The user sees a menu built on the fly which shows all currently available apps for visualizing charts that work with "Instrument" data type.

Defining Intents

Intents are either defined through the app configuration, or dynamically at runtime. Intents are configured under the intents top-level key of the app configuration object defined in the Main app.

It is possible for different apps to register an Intent with the same name, which is useful when several apps perform the same action or work with the same data structure. This allows for easy replacement of apps. You may have an old app that has registered an Intent called "ShowChart" which you want to replace with a new app. Your new app only needs to register the same Intent (you can either remove the old app or leave it as an additional option for the users who prefer it). No changes to the calling app are necessary - when it raises the "ShowChart" Intent, the new app will be called.

Use the intents top-level key in the app configuration to define an Intent:

import GlueWebPlatform from "@glue42/web-platform";

const config = {
    applications: {
        local: [
            {
                name: "Instrument Chart",
                details: {
                    url: "http://localhost:4242/chart"
                },
                // Intent definitions.
                intents: [
                    {
                        name: "ShowChart",
                        displayName: "BBG Instrument Chart",
                        contexts: ["Instrument"]
                    }
                ]
            }
        ]
    }
};

const { glue } = await GlueWebPlatform(config);
Property Description
name Required. The name of the Intent.
displayName The human readable name of the Intent. Can be used in context menus, etc., to visualize the Intent.
contexts The type of predefined data structures with which the app can work.

Finding Intents

The Intents API is accessible through the glue.intents object.

To find all registered Intents, use the all() method:

const allIntents = await glue.intents.all();

To get a collection of all Intents that fit certain criteria, use the find() method:

const intents = await glue.intents.find("ShowChart");

The find() method accepts a string or an IntentFilter object as an optional argument. The IntentFilter has the following optional properties:

Property Description
name Name of the Intent for which to search.
contextType Context type (pre-defined data structure - e.g., "Instrument") with which the Intent handler works.

If no filter is supplied, find() returns all registered Intents.

Raising Intents

To raise an Intent, use the raise() method:

await glue.intents.raise("ShowChart");

The raise() method accepts an Intent name as a string or an IntentRequest object as a required argument. The only required property of the IntentRequest object is intent which must specify the name of the Intent to be raised.

Targeting Intent Handlers

When raising an Intent, optionally target one or more Intent handlers using the target property of the IntentRequest object:

const intent = await glue.intents.find("ShowChart")[0];
const intentHandler = intent.handlers[0];

const intentRequest = {
    intent: "ShowChart",
    target: { app: intentHandler.applicationName }
}

await glue.intents.raise(intentRequest);

The target property of the IntentRequest object accepts the following values:

Value Description
"startNew" Will start a new instance of the first available Intent handler.
"reuse" Will reuse the first available running instance of an Intent handler or will fall back to "startNew" if there are no running instances available.
{ app?: string, instance?: string} An object with optional app and instance properties. The app property accepts an app name, the instance property - an ID of a running app instance. Provide a value for the app property to start a new instance of a specific Intent handler app. The app name is available in the applicationName property of the IntentHandler object. Provide a value for the instance property to reuse a specific running instance of an Intent handler. The ID of an Intent handler instance is available in the instanceId property of the IntentHandler object. Using this targeting option gives you full control over the choice of an appropriate Intent handler.

The default value for the target property is "startNew" when the Intent has been defined in an app configuration. If the Intent has been registered dynamically, the default value is "reuse".

The IntentHandler object has a type property which shows whether the Intent handler is an app that will be started (type: "app"), or an already running instance of an Intent handler (type: "instance").

Note that in order for the running Intent handler instance to be registered as type "instance", the app must use the addIntentListener() method in its code to handle context updates (see Handling Context Updates) or to register an Intent at runtime (see Registering Intents at Runtime). Otherwise, the running Intent handler instance will be of type "app".

Context

Passing Initial Context

To pass initial context to the Intent handler, use the context property of the IntentRequest object. It accepts an IntentContext object as a value:

const intentRequest = {
    intent: "ShowChart",
    target: "startNew"
    context: {
        type: "Instrument",
        data: {
            // Context for the started app.
            RIC: "MSFT"
        }
    },
    // Specify app start options for the Intent handler.
    options: {
        width: 300,
        height: 200
    }
}

await glue.intents.raise(intentRequest);

The type property of the IntentContext object is required and specifies the structure of the context object. The data property is the actual data to be passed to the Intent handler.

The options property of the IntentRequest object is used to pass custom ApplicationStartOptions to the Intent handler.

Handling Context Updates

To handle the context data passed when an Intent is raised and targeted at your app, use the addIntentListener() method. It has two required parameters - an Intent name and a context handler definition:

// Context handler definition.
function contextHandler (context) {
    // Check the context type.
    const contextType = context.type;

    if (contextType === "Instrument") {
        // Extract the context data.
        const data = context.data;
        // Аpplication specific logic for handling the new context data.
    };
};

glue.intents.addIntentListener("ShowChart", contextHandler);

Registering Intents at Runtime

To register an Intent at runtime, use the addIntentListener() method. Besides an Intent name, this method also accepts an object describing an Intent as a first required parameter:

// Intent definition.
const intent = {
    intent: "ShowChart",
    contextTypes: ["Instrument"],
    displayName: "Fidessa Instrument Chart",
    icon: "https://example.com/resources/icon.ico"
};

// Context handler.
function contextHandler (context) {
    // Check the context type.
    const contextType = context.type;

    if (contextType === "Instrument") {
        // Extract the context data.
        const data = context.data;
        // Аpplication specific logic for handling the new context data.
    };
};

glue.intents.addIntentListener(intent, contextHandler);

Note that when you register an Intent only at runtime (the Intent isn't defined in an app configuration), your app must be running in order to handle the Intent and it will always be of type "instance". If your app isn't running when this Intent is raised, it won't be available as a possible Intent handler.

Live examples for Intents coming soon.

Reference

For a complete list of the available Intents API methods and properties, see the Intents API Reference Documentation.