xcelerate-ui
v0.0.6
Published
An NPM package that I can install in my Twilio plugin which will give me access to several Xcelerate 3.x features.
Downloads
8
Maintainers
Readme
xcelerate-ui
UI wrapper for Xcelerate's portal framework.
Table of Contents
Requirements
- Xcelerate 3.x. This package is only compatible with Xcelerate 3.x. Because this uses Flex UI 2.x.x.
- NPM version 8 or later. Type
npm -v
in your terminal to check which version you have. - Node version 16. Type
node -v
in your terminal to check which version you have. - Twilio CLI 5 or later. Refer to the Twilio CLI Quick Start Guide for installation instructions. (If you're using a Mac, use NPM for the CLI installation:
npm install twilio-cli -g
) - Flex Plugins CLI. Refer to the Flex Developer Documentation for installation instructions, and the Plugins CLI Reference for available commands. Mainly plugin-flex v6.x.x.
Installation
npm install xcelerate-ui --save
Usage
The purpose of this library is to expose:
- enums in conjunction with the Twilio Actions Framework
- a
<Portal>
wrapper for use with custom Twilio Flex plugins
It primarily utilizes four methods:
- registerAction - used to register your own action
- invokeAction - used to invoke an action
- addListener - used before or after an action is invoked
- replaceAction - used when an action is already registed in Xcelerate, to customize an existing action with your own logic
The container-ids file exposes the following enums: ContainerIds
, RegistrableActions
, and InvocableActions
. (From the root directory: src > enums > container-ids.)
- ContainerIds identify the container in which the plugin will be injected. A ContainerId is a required attribute of the
<Portal>
wrapper. - RegistrableActions are Xcelerate versions of existing actions in the Twilio Actions Framework. These actions are already registered with Xcelerate and perform the original action. Functionality for any action can be replaced with the
.replaceAction()
method. - InvocableActions are custom actions within Xcelerate.
Example 1
This example uses minimal copy-and-paste code for a sample plugin. It does not exemplify use of the <Portal>
wrapper. For a more involved example, see Example 2.
- Create a sample Twilio Flex plugin. This generates a boilerplate with generic files, some of which are unused by this example and can be ignored or removed. Please note this example uses TypeScript.
# Start with a TypeScript template plugin with the create command
twilio flex:plugins:create plugin-sample-1 --install --typescript
- Copy and paste the code below into
SamplePlugin.tsx
. (From root: plugin-sample-1 > src > SamplePlugin.tsx. )
import React from "react";
import * as Flex from "@twilio/flex-ui";
import { RegistrableActions, InvocableActions } from "@xcelerate-ui/core";
import { FlexPlugin } from "flex-plugin";
const PLUGIN_NAME = "SamplePlugin";
Flex.Actions.replaceAction(
RegistrableActions.SELECT_TASK,
(payload: any, original: any) => {
return new Promise<void>((resolve, reject) => {
console.log(">>>>>xcelerateSelectTask", { payload });
Flex.Actions.invokeAction(
InvocableActions.UPDATE_IFRAME_URL,
`https://loremipsum.io?sid=${payload.sid}`
);
resolve();
});
}
);
Flex.Actions.replaceAction(
RegistrableActions.WRAPUP_TASK,
(payload: any, original: any) => {
return new Promise<void>((resolve, reject) => {
console.log(">>>>>xcelerateWrapupTask", { payload });
Flex.Actions.invokeAction(
InvocableActions.UPDATE_IFRAME_URL,
`https://waterfieldtech.com`
);
resolve();
});
}
);
export default class SamplePlugin extends FlexPlugin {
constructor() {
super(PLUGIN_NAME);
}
/**
* This code is run when your plugin is being started
* Use this to modify any UI components or attach to the actions framework
*
* @param flex { typeof Flex }
* @param manager { Flex.Manager }
*/
async init(flex: typeof Flex, manager: Flex.Manager): Promise<void> {
// this.registerReducers(manager);
const options: Flex.ContentFragmentProps = { sortOrder: -1 };
}
}
Example 2
This second example uses containers and components more intricately and exemplifies use of the <Portal>
wrapper. It models a more complex, more organized folder structure, generally appropriate for Flex plugins.
- Create a sample Twilio Flex plugin. This generates a boilerplate with generic files, some of which are unused by this example and can be ignored or removed. Please note this example uses TypeScript.
# Start with a TypeScript template plugin with the create command
twilio flex:plugins:create plugin-sample-2 --install --typescript
- Copy and paste the code below into
SamplePlugin.tsx
. (From root: plugin-sample-2 > src > SamplePlugin.tsx. )
import React from "react";
import * as Flex from "@twilio/flex-ui";
import { FlexPlugin } from "flex-plugin";
import { SamplePluginInit } from "./init/SamplePluginInit";
const PLUGIN_NAME = "SamplePlugin";
export default class SamplePlugin extends FlexPlugin {
constructor() {
super(PLUGIN_NAME);
}
/**
* This code is run when your plugin is being started
* Use this to modify any UI components or attach to the actions framework
*
* @param flex { typeof Flex }
* @param manager { Flex.Manager }
*/
init(flex: typeof Flex, manager: Flex.Manager) {
new SamplePluginInit({ flex, manager });
}
}
- Within the plugin-sample-2 > src directory, create an init directory. Within init, create a
SamplePluginInit.tsx
file. Copy and paste the code below intoSamplePluginInit.tsx
.
import React from "react";
import * as Flex from "@twilio/flex-ui";
import { RegistrableActions, InvocableActions } from "@xcelerate-ui/core";
import { ExampleComponentContainer } from "../components/ExampleComponent/ExampleComponent.Container";
interface SamplePluginInitProps {
flex: typeof Flex;
manager: Flex.Manager;
}
class SamplePluginInit {
props: SamplePluginInitProps;
constructor(props: SamplePluginInitProps) {
this.props = props;
this.initializeExampleComponent();
this.updateIframeUrlOnSelectTask();
}
initializeExampleComponent = () => {
// inject the ExampleComponentContainer into the DOM
this.props.flex.AgentDesktopView.Panel2.Content.add(
<ExampleComponentContainer key="main-example-component"></ExampleComponentContainer>,
{ sortOrder: -1 }
);
};
updateIframeUrlOnSelectTask = () => {
// create custom logic for xcelerateSelectTask
this.props.flex.Actions.replaceAction(
RegistrableActions.SELECT_TASK,
(payload: any, original: any) => {
return new Promise<void>((resolve, reject) => {
// see payload associated with the selected task on the console
console.log(">>>>>xcelerateSelectTask", { payload });
// update the iframe url upon selecting the task
Flex.Actions.invokeAction(
InvocableActions.UPDATE_IFRAME_URL,
`https://loremipsum.io?sid=${payload.sid}`
);
resolve();
});
}
);
};
}
export { SamplePluginInit };
- Within the plugin-sample-2 > src > components directory, create an ExampleComponent directory. Within ExampleComponent, create an
ExampleComponent.Container.ts
file. Copy and paste the code below intoExampleComponent.Container.ts
.
import { connect } from "react-redux";
import { ExampleComponent } from "./ExampleComponent";
export const ExampleComponentContainer = connect()(ExampleComponent);
//mapStateToProps,
//mapDispatchToProps
- Within ExampleComponent directory, create an
ExampleComponent.tsx
file. Copy and paste the code below intoExampleComponent.tsx
.
import React from "react";
import { ContainerIds, Portal } from "@xcelerate-ui/core";
interface ConfigState {
loaded: boolean;
[key: string]: boolean;
}
export class ExampleComponent extends React.Component<any> {
render(): JSX.Element {
// Portal a 'Hello world!' div into the RIGHT_PANEL ContainerId
return (
<>
<Portal
reduxKey="enableExampleComponent"
reduxValue={true}
containerId={ContainerIds.RIGHT_PANEL}
config={{ loaded: true, enableExampleComponent: true } as ConfigState}
>
<div>Hello world!</div>
</Portal>
<div id={ContainerIds.RIGHT_PANEL}></div>
</>
);
}
}
Local Development and Deployment
Refer to the Flex Plugins CLI documentation to run your plugin locally and to deploy and release your plugin.