Action Buttons

In the previous sections, we have learned about creating contextual bars and the list of building blocks available in the UIKit. Let's add to this knowledge and see how to create interactive buttons and handle the interactions.

Action buttons are UIKit elements that when registered, can be displayed and used in different contexts within the Rocket.Chat UI to trigger or initiate a set of actions. The Action button context for example is MESSAGE_ACTION, ROOM_ACTION, MESSAGE_BOX_ACTION, etc.

To demonstrate this, we will create an action button on a message context that will simply display a text to let us know that the interaction was received.

Register a button

Action buttons are registered during the extendConfiguration lifecycle method. The code snippet is as follows:

protected async extendConfiguration(configuration: IConfigurationExtend, environmentRead: IEnvironmentRead): Promise<void> {
    configuration.ui.registerButton({
        actionId: 'my-action-id', // this identifies your button in the interaction event
        labelI18n: 'my-action-name', // key of the i18n string containing the name of the button
        context: UIActionButtonContext.MESSAGE_ACTION, // the context in which the action button will be displayed on the UI
    });
}

Registering a button requires ui.registerButton permission. Add it to your app manifest file (app.json) as shown below:

app.json
{
    "id": "some-app-id",
    "name": "App Name",
    // ... other definitions
    "permissions": [
        { "name": "ui.registerButtons" }
    ]
}

For more information, see App Permission System.

Deploy your app to test and you can see that the button gets added to the list of options against the context specified, in this case, a message.

Click on the options icon across any message and you will see the action we just created as seen below:

Handle an interaction

After registering the button, we can see the button but cannot take any actions with it. Now whenever the user clicks the action button, we want the app to receive an interaction event.

Here is an example of how to handle it:

export class MyApp extends App implements IUIKitInteractionHandler {
    public async executeActionButtonHandler(
        context: UIKitActionButtonInteractionContext,
        read: IRead,
        http: IHttp,
        persistence: IPersistence,
        modify: IModify
    ): Promise<IUIKitResponse> {
        const { 
            buttonContext, 
            actionId, 
            triggerId, 
            user, 
            room, 
            message,
        } = context.getInteractionData();

        // If you have multiple action buttons, use `actionId` to determine 
        // which one the user interacted with
        if (actionId === 'my-action-id') {
            const blockBuilder = modify.getCreator().getBlockBuilder();
            
            return context.getInteractionResponder().openModalViewResponse({
                title: blockBuilder.newPlainTextObject('Interaction received'),
                blocks: blockBuilder.addSectionBlock({
                    text: blockBuilder.newPlainTextObject('We received your interaction, thanks!')
                }).getBlocks(),
            });
        }

        return context.getInteractionResponder().successResponse();
    }

}

Now deploy and test the app again. You will see that when you click the action button that we had registered, a modal named Interaction received opens with the message We received your interaction, thanks!. You can also view the Logs tab of your app for details.

Choose when your button is displayed

Most of the time you will have an action button that does something specific and should not be displayed everywhere the context is available. For that, you can use the when prop while registering the button as follows:

protected async extendConfiguration(configuration: IConfigurationExtend, environmentRead: IEnvironmentRead): Promise<void> {
    await configuration.ui.registerButton({
        actionId: 'my-action-id',
        labelI18n: 'my-action-name',
        context: UIActionButtonContext.MESSAGE_ACTION,
        // If you want to choose `when` the button should be displayed
        when: {
            roomTypes: [
                RoomTypeFilter.PUBLIC_CHANNEL, 
                RoomTypeFilter.PRIVATE_CHANNEL, 
                RoomTypeFilter.DIRECT,
            ],
            hasOnePermission: ['create-d'],
            hasAllRoles: ['admin', 'moderator'],
        }
    });
}

Now the button can only be seen in public and private channels and direct messages, by users that have the create-d permission and the admin role. The user must also be a moderator of the channel to see the action button for messages in that channel.

Add localization

Localization for your app is important to better suit different users. To add localization to your app, create an i18n folder in the project's root directory and add .json files for the various languages.

For this example, let us add an en.json file with the content as follows:

en.json
{
    "my-action-name": "Test UI Action"
}

This code will create a reference for the English language against the labelI18n value we specified when we registered the button in the Register a buttonsection previously.

With these changes, deploy the app again and this time you will see something like the screenshot below when the button is clicked.

With this example, we know how to handle interactions using action buttons and specify when the button should be displayed. We've also taken a look at defining localization files here.

To create such interfaces with Apps-Engine for the Rocket.Chat UI, you need to follow some guidelines. In the next topic, you will find detailed guidelines for menus, messages, chatbots, and so on.

Last updated

Rocket.Chat versions receive support for six months after release.