Hello Command!¶
This guide will show how to generate a new command, connect it to a handler, and trigger the command from a menu in the table view inside the webclient.
Generate a command¶
The module needs a translation module to exist. In case you don't have that yet in your package or solution, run this command inside your project
Afterwards you can generate a new command
This will generate a command class and its corresponding handler.
The command class
src/commands/hello/hello.command.ts
should look like this:
import { Command } from "@limetech/lime-web-components";
@Command({
id: "my-package.hello",
})
export class HelloCommand {}
The handler
src/commands/hello/hello.handler.ts
should look like this:
import { CommandHandler } from '@limetech/lime-web-components';
import { HelloCommand } from './hello.command';
export class HelloHandler implements CommandHandler {
public handle(command: HelloCommand) {}
}
Implement the handler¶
Our command is only going to show a notification when the command is handled, but a more common use case when it is triggered from a menu is probably to open a dialog.
Let's modify our command handler to be able to show a notification by adding Notifications
to the imports from @limetech/lime-web-components
.
We then need to ensure our CommandHandler can accept the notification service.
Let's add a constructor to our class.
We'll pass in the notification service from our loader component which we'll modify next.
Our handler should now look like this:
import { CommandHandler, Notifications } from '@limetech/lime-web-components';
import { HelloCommand } from './hello.command';
export class HelloHandler implements CommandHandler {
constructor(private notifications: Notifications) {}
public handle(command: HelloCommand) {
this.notifications.notify('Running HelloCommand!');
console.log(command);
}
}
Register the command¶
In order to run this command, we need to register it to the handler when the application starts. A good place to do this is in the Loader
component loaded at the start of a session. In the componentWillLoad
lifecycle hook, we can add the code to register our command and make it useable from within the application.
Open the loader which should be located here
src/components/lwc-my-plugin-loader/lwc-my-plugin-loader.tsx
The default loader for the package should look like this:
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() {}
}
Add CommandBus
, PlatformServiceName
and Notifications
to the imports from @limetech/lime-web-components
import {
CommandBus,
Notifications,
PlatformServiceName,
LimePluginLoader,
LimeWebComponentContext,
LimeWebComponentPlatform,
} from '@limetech/lime-web-components';
import { Component, Prop } from '@stencil/core';
We also need to import our Command class and Handler
import { HelloCommand } from 'src/commands/hello/hello.command';
import { HelloHandler } from 'src/commands/hello/hello.handler';
Let's get both the Notification service and commandBus
private get notificationService(): Notifications {
return this.platform.get(PlatformServiceName.Notification);
}
private get commandBus(): CommandBus {
return this.platform.get(PlatformServiceName.CommandBus);
}
And now let's implement the functionality in the loader by modifying the componentWillLoad()
function
...
export class Loader implements LimePluginLoader {
...
private commandBus: CommandBus;
public componentWillLoad() {
const helloHandler = new HelloHandler(this.notificationService);
this.commandBus.register(HelloCommand, helloHandler);
}
}
Our Loader component should look like this:
import {
LimePluginLoader,
LimeWebComponentContext,
LimeWebComponentPlatform,
CommandBus,
Notifications,
PlatformServiceName,
} from '@limetech/lime-web-components';
import { HelloCommand } from 'src/commands/hello/hello.command';
import { HelloHandler } from 'src/commands/hello/hello.handler';
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() {
const helloHandler = new HelloHandler(this.notificationService);
this.commandBus.register(HelloCommand, helloHandler);
}
public componentWillUpdate() {}
public disconnectedCallback() {}
private get notificationService(): Notifications {
return this.platform.get(PlatformServiceName.Notification);
}
private get commandBus(): CommandBus {
return this.platform.get(PlatformServiceName.CommandBus);
}
}
Trigger the command¶
To trigger the command manually, you can simply send it to the commandbus from another component—say a newly generated one containing a limel-button. We could use the Hello World component that we created in the first tutorial:
Don't forget to import the command
...
import {
CommandBus,
LimeWebComponent,
LimeWebComponentContext,
LimeWebComponentPlatform,
PlatformServiceName,
} from '@limetech/lime-web-components';
import { Component, h, Prop } from '@stencil/core';
import { HelloCommand } from 'src/commands/hello/hello.command';
@Component({
tag: 'lwc-limepkg-cool-package-hello-world',
shadow: true,
styleUrl: 'lwc-limepkg-cool-package-hello-world.scss',
})
export class HelloWorld implements LimeWebComponent {
/**
* @inherit
*/
@Prop()
public platform: LimeWebComponentPlatform;
/**
* @inherit
*/
@Prop()
public context: LimeWebComponentContext;
public render() {
return (
<limel-button
label={'Hello World!'}
outlined={true}
icon={'house_stark'}
onClick={this.handleClick}
/>
);
}
private handleClick = () => {
const command = new HelloCommand();
this.commandBus.handle(command);
};
private get commandBus(): CommandBus {
return this.platform.get(PlatformServiceName.CommandBus);
}
}
...
In order to add it to a menu in the table view inside the webclient, we need to configure the menu on the
Administrators page
to register our command.
This we do by adding an action under the table view for the desired limetype with an id ofmy-package.hello
.
Note
This used to be done, and could be done, by adding the following actions
JSON snippet to the Table
section for the desired limetypes in the View Editor
.
This can also be done inside the plugin's configuration, by providing the corresponding menu in a web-component.