Skip to content

Widget Menu Section

The Widget Menu Section component can be used to add menus to section headers:

Widget Menu Section

The menu is designed to collapse into a dropdown menu on smaller screens:

Widget Menu Section

The section menu folder contains components, for example checkbox components or 'select' components, that have been built for use in the Widget Menu Section only, to accommodate the collapse on smaller screens.

The Widget Menu Section accepts a list of 'sections' as a prop. Each section may have an optional title, and on smaller screens each section will be divided by a horizontal line:

Widget Menu Section

Each 'section' in the sections prop must be an object containing the following:

{
    title: // an optional title for the section
    menus: [
        // an array of menu objects:
        {
            menu: // the menu component e.g. WidgetMenuSectionCheckbox
            request: // the Section Dashboard request object generated by the menu component
            status: // the status of the request used to fetch the data to display in the menu component, e.g. a list of dropdown items
        }
    ]
}

Hooks

We have a series of hooks that can assist with building section menus. You will likely need to call these hooks inside your dashboard's Context file. Each component within a section menu has its own hook which can keep track of the filters generated by that menu, as well as returning the menu itself.

There are three types of Section Menus on our system.

  1. useWidgetMenuSectionQuerySelect
  2. useWidgetMenuSectionSelect
  3. useWidgetSectionQuerySelectInfinite

useWidgetMenuSectionQuerySelect Hook

If we have query data from the backend API we can use useWidgetMenuSectionQuerySelect, for example:

const mySelectMenu = useWidgetMenuSectionQuerySelect({
    query: goalsQuery, // The 'react-query' query used to fetch the dropdown items
    dropdownField: fields.FIELD, // The field that represents the dropdown items being displayed e.g. fields.PRODUCT
    includeAllOption: true, // Indicate if we would like an 'all' option in the menu e.g. 'All Goals'
}),

const myCheckbox =  useWidgetMenuSectionCheckbox({
    filterField: fields.REFERER, // The field that represents the checkbox
    filterOperator: FilterOperator.EQUALS, // The operator that represents how the checkbox will filter the data e.g. If checked - filter by Channel EQUALS 'Direct'
    filterValue: filterUnknownRegex, // The value to filter by, e.g. 'Direct'
}),

useWidgetMenuSectionSelect Hook

If we have predefined values for dropdownRequestOption, we can utilize the useWidgetMenuSectionSelect hook, for example:

export const visitorTypeDropdownRequest = {
    status: RequestStatus.SUCCESS,
    options: [
        {
            label: 'First Visit',
            value: 'First Visit',
            field: fields.NEW_VISITS,
        },
        {
            label: 'Returning Visit',
            value: 'Returning Visit',
            field: fields.REPEAT_VISITS,
        },
    ],
};

useWidgetMenuSectionSelect({
    dropdownRequestOption: visitorTypeDropdownRequest, // Hardcoded Request data
    dropdownField: fields.VISIT_TYPE, // The field that represents the dropdown items being displayed e.g. fields.VISIT_TYPE
    includeAllOption: true, // Indicate if we would like an 'all' option in the menu e.g. 'All Goals'
}),

The hooks above will return an object containing the menu and the filters. We can then place the menu wherever required in the dashboard, and add the filters to the useResource requests as necessary.

The object returned by the hooks will look something like below:

{
    menu: <WidgetMenuSectionCheckbox  />,
    request: {
        sectionFilters: {
           [
            {
                field: fields.REFERER,
                operator: 'equals',
                filterValue: 'Direct'
            }
           ]
        },
    },
    status: RequestStatus.SUCCESS,
}

We also have a hook useWidgetMenuSection that can help us combine multiple menus, and return a single 'request' object ready to use in the useResource hooks:

const myMenu = useWidgetMenuSection({
    sections: [
        {
            title: 'Filters',
            menus: [
                useWidgetMenuSectionQuerySelect({
                    query: goalsQuery,
                    dropdownField: fields.PRODUCT,
                    includeAllOption: true,
                    label: 'Goal', // optional - if we don't provide a label the 'select' component label will default to the field displayName
                }),
                useWidgetMenuSectionQuerySelect({
                    query: subchannelQuery,
                    dropdownField: fields.SUBCHANNEL_NAME,
                    includeAllOption: true,
                    label: 'Subchannel',
                }),
                useWidgetMenuSectionQuerySelect({
                    query: otherQuery,
                    dropdownField: fields.OTHERFIELD,
                    includeAllOption: true,
                }),
                useWidgetMenuSectionSelect({
                    dropdownRequestOption: visitorTypeDropdownRequest, // Hardcoded Request data
                    dropdownField: fields.VISIT_TYPE, // The field that represents the dropdown items being displayed e.g. fields.VISIT_TYPE
                    includeAllOption: true, // Indicate if we would like an 'all' option in the menu e.g. 'All Goals'
                }),
            ],
        },
        {
            menus: [
                useWidgetMenuSectionCheckbox({
                    filterField: fields.FIELD,
                    filterOperator: FilterOperator.EQUALS,
                    filterValue: 'Direct',
                }),
            ],
        },
    ],
});

We can use the filters generated by this hook when calling useResource:

const myResource = useResource({
    resource: resources.RESOURCE,
    request: {
        groupBy: fields.FIELD,
        orderBy: fields.FIELD,
        ...myMenu.request,
    },
});

And we can place the menu component itself into a section in the dashboard's config file:

const config = {
     context: () => {
        const menuContext = useContext(MyContext); // The dashboard's Context
        return { menuContext };
    },
    layouts: {
        xs: {
            sections: [
                 {
                    title: 'My Section Title',
                    menu: (): JSX.Element => config.context().menuContext.myMenu.menu,
                    grid: ...
                },
            ]
        }
    }
}

useWidgetSectionQuerySelectInfinite Hook

If we have query data from the backend API and it has a lots of data then we can use useWidgetSectionQuerySelectInfinite, for example:

const myInfiniteMenu = useWidgetSectionQuerySelectInfinite({
    query: geolocationDropdownQuery({ // The 'react-query' query used to fetch the dropdown items
        field: selectedLevel.field,
        offset: 0,
        limit: 100,
    }),
    dropdownField: fields.Field, // The field that represents the dropdown items being displayed e.g. fields.PRODUCT
    includeAllOption: true, // Indicate if we would like an 'all' option in the menu e.g. 'All Goals'
    label: 'Country', // optional - if we don't provide a label the 'select' component label will default to the field displayName
    allLabel: 'Countries', // optional - if we don't provide a allLabel the 'select' component label will default to the field displayName
}),

When we scroll to the bottom of the menu list, it will automatically start to get next data set until the end.