Skip to content

Hello Event!

This guide illustrates how to replace the default dialog for creating new Limeobjects with a custom one.

Generate a new component

First of all, we need to generate a new web component with lime-project that will hold the new dialog we want to be displayed in place of the default one.

lime-project generate web-component custom-dialog

The custom dialog will typically need some added functionality. However, this is outside of the scope of this guide, therefore we will only render a "proof of concept" dialog displaying a message. Feel free to add something more interesting!

As before, our component will be generated with some code that we won't need for the purposes of this tutorial.
Go ahead and modify the component removing the unnecessary code.

Our dialog component should look like this:

import {
    LimeWebComponent,
    LimeWebComponentContext,
    LimeWebComponentPlatform,
} from '@limetech/lime-web-components';
import { Component, h, Prop } from '@stencil/core';

@Component({
    tag: 'lwc-limepkg-my-package-custom-dialog',
    shadow: true,
})
export class CustomDialog implements LimeWebComponent {
    /**
     * @inherit
     */
    @Prop()
    public platform: LimeWebComponentPlatform;

    /**
     * @inherit
     */
    @Prop()
    public context: LimeWebComponentContext;

    public render() {
        return (
            <limel-dialog open={true} onClose={this.handleClose}>
                <h1>My custom dialog!</h1>
            </limel-dialog>
        );
    }

    private handleClose = () => {}
}

Listen for command events

To prevent the default dialog from appearing when a new Limeobject is created, we need to listen for a command.received event and check if it is a CreateLimeobjectDialogCommand that has been received.

The code to listen for such an event should be added in the loader, the component that gets constructed shortly after the start of a session meant to run code intended to be run once, when the application starts.

Here's what the initial loader looks like:

import {
    LimePluginLoader,
    LimeWebComponentContext,
    LimeWebComponentPlatform,
} from '@limetech/lime-web-components';
import { Component, Prop } from '@stencil/core';

// NOTE: Do NOT remove this component, it is required to run the plugin correctly.
// However, if your plugin has any code that should run only once when the application
// starts, you are free to use the component lifecycle methods below to do so.
// The component should never render anything, so do NOT implement a render method.

@Component({
    // ⚠️ WARNING! Do not change the tag name of this component unless you also
    // change the name of the package. The tag name should be
    // lwc-<package-name>-loader, e.g. lwc-limepkg-cool-package-loader
    tag: 'lwc-limepkg-cool-package-loader',
    shadow: true,
})
export class Loader implements LimePluginLoader {
    /**
     * @inherit
     */
    @Prop()
    public platform: LimeWebComponentPlatform;

    /**
     * @inherit
     */
    @Prop()
    public context: LimeWebComponentContext;

    public connectedCallback() {}

    public componentWillLoad() {}

    public componentWillUpdate() {}

    public disconnectedCallback() {}
}

Let's start modifying it.

We're going to add a listener to the eventDispatcher so that we can intercept the command when it is received.

Let's start by getting the EventDispatcher service from the platform. We'll first add PlatformServiceName to the imports from @limetech/lime-web-components.

import {
    LimePluginLoader,
    LimeWebComponentContext,
    LimeWebComponentPlatform,
    PlatformServiceName,
} from '@limetech/lime-web-components';

Next, within the componentWillLoad function we'll define our eventDispatcher and add our listener,
we'll also add a small function called handleCommandReceived that we'll leave empty for now:

public componentWillLoad() {
    const eventDispatcher = this.platform.get(
        PlatformServiceName.EventDispatcher
    );
    eventDispatcher.addListener(
        CommandEventName.Received,
        this.handleCommandReceived
    );
}

private handleCommandReceived = (event: CustomEvent) => {};

Now, handleCommandReceived will be invoked each time a command is being handled by the commandbus.

We should now
(1) listen for the command we are interested in,
(2) prevent the default action from happening and instead display the custom dialog.

We can also add other checks. Maybe we only want to handle a specific limetype.

Add CommandEventName, CreateLimeobjectDialogCommand and getCommandId to the imports from @limetech/lime-web-components.

import {
    LimePluginLoader,
    LimeWebComponentContext,
    LimeWebComponentPlatform,
    PlatformServiceName,
    CommandEventName,
    CreateLimeobjectDialogCommand,
    getCommandId,
} from '@limetech/lime-web-components';

And let's add the functionality into our handleCommandReceived function:

    private handleCommandReceived = (event: CustomEvent) => {
        const command = event.detail.command;
        if (
            getCommandId(command) !==
            getCommandId(CreateLimeobjectDialogCommand)
        ) {
            return;
        }

        if (command.limetype.name !== 'deal') {
            return;
        }

        event.preventDefault();
        const dialogService = this.platform.get(PlatformServiceName.Dialog);
        dialogService.create('lwc-limepkg-my-package-custom-dialog');
    }

Now we have successfully added a custom dialog that will be displayed in place of the default one each time a deal is being created!

Trigger the original command

Another use case might be to display our custom dialog, and after that display the original populated with some data gathered from our first one. To do this, we need to dispatch the original command again but also add a flag to it so we know not to intercept it repeatedly.

private handleCommandReceived = (event: CustomEvent) => {
    ...
    // Check if our custom flag has been set, if so don't do anything
        // eslint-disable-next-line no-underscore-dangle
        if (command._useOriginalHandler) {
            return;
        }

        // Set our custom flag so we don't handle this command again
        // eslint-disable-next-line no-underscore-dangle
        command._useOriginalHandler = true;

    event.preventDefault();
    const dialogService = this.platform.get(PlatformServiceName.Dialog);
    dialogService.create('lwc-my-plugin-custom-dialog', { command });
}

In our dialog component, we can dispatch it once more

import {
    CreateLimeobjectDialogCommand,
    LimeWebComponent,
    LimeWebComponentContext,
    LimeWebComponentPlatform,
    PlatformServiceName,
} from '@limetech/lime-web-components';



export class CustomDialog implements LimeWebComponent {
    @Prop()
    public command: CreateLimeobjectDialogCommand;

    private handleClose = () => {
        // Add custom data to display in the original dialog
        this.command.limeobject = {
            name: 'The one big deal!'
        };

        // Handle the original command again
        const commandBus = this.platform.get(PlatformServiceName.CommandBus);
        commandBus.handle(this.command);
    }
}

Now the custom dialog will be displayed every time a new deal is created, and when we close the dialog, it will trigger the original one to open populated with our custom data!