Create a Widget¶
When we create a widget, We must first select the type of visualisation we want to use. Each 'visualisation' represents a Section Dashboard Widget, for example 'Table' or 'Big Number'. Each widget has its own form to fill in, depending on the information each widget needs to properly display. For example, the table widget needs a dimension (the first column), as well as one or more fields/metrics (subsequent columns) to display properly, along with a default order by (the column the table will be ordered by on first load).
Resources¶
We can make resources available to the dashboard builder widgets by flagging them as ‘dashboard builder enabled’ in the resources.ts
file. We must also list the dimensions and metrics that are available in this resource so that the dashboard builder is aware of which table columns are available in the resource model:
// resources.ts
export const REPORT_MCS_CHANNEL: CubedResource = {
category: 'report',
id: 'report-mcs-channel',
displayName: 'Channels',
dateDimension: fields.SALES_DATE_DATETIME,
defaultDimensions: [fields.REFERER],
dimensions: [fields.REFERER, fields.SUBCHANNEL_NAME],
defaultOrderBy: fields.FM_SALES,
dashboardBuilderEnabled: true, // Enable this resource in the dashboard builder
metrics: [fields.FM_SALES, fields.FM_REVENUE, fields.COST, fields.VISITS], // List the available metrics
};
When we start building a widget, at first we will have several possible resources (database tables) that the widget could read data from. Most of the widgets will need a dimension and one or more metrics to be selected, and as we select dimensions and metrics the dashboard builder will automatically narrow down the available resources until we only have one possible resource that we could use for that widget.
Once we have narrowed down to a single resource, this resource, along with the dimension, metrics and any other configuration information, is saved in the dashboard_builder_widget-request_config
table, ready to be retrieved by the widget when it is displayed in a dashboard.
Adding a New Widget¶
To add a new widget to the dashboard builder, there are a few steps to follow:
-
Ensure that the widget has been created as part of the Section Dashboard. The widget will need to built in Storybook, ensuring the widget’s appearance works at every dashboard breakpoint size, and you will also need to create a ‘comparison’ version of the widget for comparison enabled dashboards. You will also need to create a hook for the widget, which can read the resource data and return the data in a format the widget can use. You can read more about writing hooks for the widgets here, and look at the existing widgets for examples.
-
To add a widget to the Layout Builder, you will first need to add the widget type to the fixtures in
dashboard_builder.json
file:... { "model": "client.dashboardbuilderwidgettype", "pk": 10, "fields": { "name": "myNewWidget", "display_name": "My New Widget" } }, ...
-
Next, you will need to create a form for the widget in the
create-a-widget/forms
folder, comprising all the information you need to collect to display the widget properly, for example dimension, metrics, colours, configuration, etc. You will need to add the form to the switch statement increate-a-widget-form.tsx
:const renderVisualisationForm = () => { switch (formValues.visualisation) { ... case 'myNewWidget': return <CreateAWidgetFormMyNewWidget />; default: return null; } };
The
useResource
hooks will be expecting particular values, such asgroup_by
andorder_by
, so make sure your form fields are named appropriately. You can check the existing widget forms for examples. -
You will need to create a preview file for the widget in the
dashboard-builder/widgets
folder. This preview file will be used to display the widget throughout the Dashboard Builder, such as in the ‘Create A Widget’ preview, the ‘Create a Dashboard’ preview, and when we view the custom dashboards in the browser. Inside the preview file, gather all the data input from the form, and then call the required hooks to receive the data from the database in the format required by the widget, as we would normally do in a Section Dashboard configuration file.const WidgetPreviewMyNewWidget = ({ config }: { config: WidgetConfig }) => { // Get the request values from the widget const resource = getResource(config.resource); const groupByField = getField(config.group_by); const orderByField = getField(config.order_by); const orderByDirection = config.order_by_direction.direction; const resourceData = useResource({ resource: request.groupBy && request.orderBy ? resource : undefined, request: request, }); const widgetData = useResourceMyNewWidget({ resourceData: resourceData, }); if (config.group_by.length > 0 && config.order_by.length > 0) { return <WidgetMyNewWidget title={config.widget.title} data={tableData} />; } return ( <CreateAWidgetPreviewMessage message="Please select a dimension and at least one column to preview the new widget" /> ); };
Add the preview file to the switch statement in the
get-widget-preview.tsx
helper function:switch (type) { ... case 'myNewWidget': return <WidgetPreviewMyNewWidget config={config} />; default: return <StyledError>No preview available for this widget.</StyledError>; }
-
Add a suitable icon for the widget in the
widget-icon.tsx
file.
The new widget should now appear as a visualisation option in the ‘Create a Widget’ page.