Skip to content

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).

An Example of creating a Table Widget

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:

  1. 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.

  2. 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"
            }
        },
        ...
    
  3. 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 in create-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 as group_by and order_by, so make sure your form fields are named appropriately. You can check the existing widget forms for examples.

  4. 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>;
    }
    
  5. 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.