Widget Menu Section¶
The Widget Menu Section component can be used to add menus to section headers:
The menu is designed to collapse into a dropdown menu on smaller screens:
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:
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.
useWidgetMenuSectionQuerySelect
useWidgetMenuSectionSelect
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.