Creating Custom Widgets
In addition to creating a widget using widget generation wizard, you can implement your own custom widgets and use them within the Dashboard portal.
If you want to refer the source of a sample widget to develop your custom widget, you can find the available sample widgets here.
This section explains:
How to write a custom widget for the Dashboard portal
The features that are provided for widget developers in the Dashboard portal
A widget in Dashboard portal is a simple ReactJS component that can be used to visualize information. This widget functions as a chart, table, set of components to interact with, etc.
In order to identify a particular ReactJS component as a widget by the dashboard portal, it needs to register itself as a widget in the portal.
Let’s have a look at a simple widget, Hello World.
Creating HelloWorld widget
The directory structure of your HelloWorld widget source s as follows
HelloWorld (referred as <WIDGET_ROOT>)
├── package.json
├── src
│ ├── HelloWorld.jsx
│ └── resources
│ └── widgetConf.json
└── webpack.config.js
Copy following content to
package.jsonandwebpack.config.jsrespectively. Webpack is required for building a widget.package.json
{ "name": "hello-world-widget", "version": "1.0.0", "private": true, "dependencies": { "react": "^16.1.1", "react-dom": "^16.1.1" }, "scripts": { "build": "webpack -p" }, "devDependencies": { "webpack": "^3.5.6", "ajv": "^5.2.2", "babel-core": "^6.25.0", "babel-loader": "^7.1.1", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-register": "^6.26.0", "copy-webpack-plugin": "^4.2.0", "node-sass": "^4.5.3", "sass-loader": "^6.0.6" } }webpack.config.js
const path = require('path'); const webpack = require('webpack'); const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { context: path.resolve(__dirname, './src'), entry: { index: './HelloWorld.jsx' }, output: { path: path.resolve(__dirname, './dist/HelloWorld/'), filename: 'HelloWorld.js' }, module: { loaders: [ { test: /\.html$/, use: [{loader: 'html-loader'}] }, { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', query: { presets: ['es2015', 'react'] } } ] }, { test: /\.(png|jpg|svg|cur|gif|eot|svg|ttf|woff|woff2)$/, use: ['url-loader'] }, { test: /\.jsx?$/, exclude: /(node_modules)/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.scss$/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'sass-loader'}] } ] }, plugins: [ new CopyWebpackPlugin([ {from: path.resolve(__dirname, './src/resources/')} ]) ], resolve: { extensions: ['.js', '.json', '.jsx', '.scss'] } };Now copy the following content into
HelloWorld.jsxundersrcdirectory. This contains all the logic for our widget.HelloWorld.jsx
import React, { Component } from 'react'; class HelloWorld extends Component { render() { return ( <h1>Hello, World!</h1> ); } } global.dashboard.registerWidget('HelloWorld', HelloWorld);Dashboard portal requires few meta information regarding the widget in order to identify it.
<WIDGET_ROOT>/src/resources/widgetConf.jsonfile contains this meta information. When building the widget this configuration file gets copied into the final widget directory. Add the following content into thewidgetConf.jsonfile.widgetConf.json
{ "name": "HelloWorld", "id": "HelloWorld", "thumbnailURL": "", "configs": {} }Now the source of the widget is complete. To install the dependencies required to to build your widget, navigate to the
<WIDGET_ROOT>directory and issue the following command.npm installGo to the
<WIDGET_ROOT>directory and issue the following command to build the widget.npm run buildOnce the build is successful the final widget directory is created in the
<WIDGET_ROOT>/distdirectory. Copy the<WIDGET_ROOT>/dist/HelloWorlddirectory into the<SP_HOME>/wso2/dashboards/deployment/web-ui-apps/portal/extensions/widgetsdirectory.Restart WSO2 Stream Processor.
Now log in to the Dashboard portal and create a new dashboard .
You can view the newly createdHelloWorldwidget in the widget listing panel of the Dashboard Designer.
Now you understand how to develop a widget and get it rendered in the Dashboard portal.
Let's improve this widget to add more interactive elements to it.
Clone the WSO2 carbon-dashboards repository to your machine.
Copy the
HelloWorldwidget you created to thecarbon-dashboards/samples/widgetsdirectory.To import the channel manager to access the database, you need to use the
WidgetChannelManager. To do this, create a separate file namedExtendedWidgetas shown below.
import React from 'react'; import Widget from '@wso2-dashboards/widget'; import WidgetChannelManager from '../../../../components/dashboards-web-component/src/utils/dashboard-channel/WidgetChannelManager'; let widgetChannelManager = null; export default class ExtendedWidget extends Widget { constructor(props) { super(props); } getWidgetChannelManager() { if(!widgetChannelManager) { widgetChannelManager=new WidgetChannelManager(); } return widgetChannelManager; } }Update the
HelloWorld.jsxfile as shown below.
import React, { Component } from 'react'; import ExtendedWidget from './ExtendedWidget'; import VizG from 'react-vizgrammar'; class HelloWorld extends ExtendedWidget { constructor(props) { super(props); this.tableConfig = { //add table configues }; this.metadata = { //add meta data }; this.data = [ //add table data here ]; this.handleData = this.handleData.bind(this); } render() { return ( <VizG config={this.tableConfig} data={this.data} metadata={this.metadata} onClick={this.handleData} /> ); } handleData(row) { console.info(row); } } global.dashboard.registerWidget('HelloWorld', HelloWorld); //(widgetId,reactComponent)If you consider the publisher-subscriber concept, the widget with the table is a publisher and the widget that triggers the table action with a row click is a subscriber. To define this:
Open the
widgetConf.jsonfile of the publisher widget and change thepubsubtype topublisheras shown below.{ "name": "HelloWorld", "id": "HelloWorld", "thumbnailURL": "", "configs": { "pubsub": { "types": ["publisher"] } } }Similarly open the
widgetConf.jsonfile of the subscriber widget and change the pubsub type tosubscriber.
Navigate to the
<WIDGET_ROOT>directory and issue the following command to build the widget.
npm run buildOnce the build is successful, the widget is created in the<WIDGET_ROOT>/distdirectory.Copy the
<WIDGET_ROOT>/dist/HelloWorlddirectory and place it in the<SP_HOME>/wso2/dashboards/deployment/web-ui-apps/portal/extensions/widgetsdirectory.
The Dashboard portal also provides additional capabilities to widget developers by providing a set of APIs via a base widget component. Please follow the step below to extend your widget from the base widget component.
Extending from base widget component
To extend from the base widget component, follow the steps below:
The base widget version compatible with WSO2 SP 4.2.0 is @wso2-dashboards/widget: 1.2.2.
Add base widget as a dependency in your
package.jsonfile.'dependencies': { ... '@wso2-dashboards/widget': '1.1.1.', ... },Import base widget in your widget source file.
import Widget from '@wso2-dashboards/widget';Extend the base widget.
class MyWidget extends Widget { ... }