Action Sidebar Pattern
Overview
The Action Sidebar has been refactored to be automatically included in all pages through the Page component. This eliminates code duplication and provides a consistent pattern for handling both global and page-specific actions.
How It Works
Global Actions (Always Present)
The Action Sidebar automatically includes these global actions:
- Theme Switch: Toggle between light/dark themes
- Configuration: Open site configuration modal
Page-Specific Actions
Pages can add their own action items by passing them to the Page component.
Usage Examples
Basic Page (Global Actions Only)
import Page from '../components/Page';
export default function AboutPage() {
return (
<Page title="About">
{/* Page content */}
</Page>
);
}
Page with Additional Actions
import Page from '../components/Page';
import { ACTION_BAR_ICONS, ACTION_BAR_TEXT } from '../constants';
export default function MapPage() {
const [tooltipEnabled, setTooltipEnabled] = useState(true);
const handleActionBarClick = (action) => {
switch (action.text) {
case ACTION_BAR_TEXT.GeoLocator:
setGeoLocatorOpen(true);
break;
case ACTION_BAR_TEXT.TooltipOn:
case ACTION_BAR_TEXT.TooltipOff:
setTooltipEnabled(!tooltipEnabled);
break;
default:
break;
}
};
return (
<Page
title="Map"
actionItems={[
{ icon: ACTION_BAR_ICONS.GeoLocator, text: ACTION_BAR_TEXT.GeoLocator },
{
icon: tooltipEnabled ? ACTION_BAR_ICONS.TooltipOff : ACTION_BAR_ICONS.TooltipOn,
text: tooltipEnabled ? ACTION_BAR_TEXT.TooltipOff : ACTION_BAR_TEXT.TooltipOn
},
]}
onActionBarClick={handleActionBarClick}
>
{/* Page content */}
</Page>
);
}
Page Without Action Sidebar
import Page from '../components/Page';
export default function FullScreenPage() {
return (
<Page
title="Full Screen"
showActionBar={false} // Disable the action sidebar
>
{/* Full screen content */}
</Page>
);
}
Page Component Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | '' | Page title (used for document title) |
actionItems | array | undefined | Array of action items to add to the sidebar (optional) |
onActionBarClick | function | undefined | Callback for action button clicks (optional) |
showActionBar | boolean | true | Whether to show the action sidebar |
children | node | - | Page content |
Action Item Structure
Each action item should have this structure:
{
icon: string, // Iconify icon name
text: string // Action text (used for tooltip and click handling)
}
Migration Guide
Before (Old Pattern)
return (
<Page title="My Page">
<Grid container direction="row" justifyContent="space-between" alignItems="flex-start" sx={{ width: '100%' }}>
<Grid sx={{ flex: 1, pr: 6 }}>
{/* Page content */}
</Grid>
<Grid>
<ActionSideBar
actionItems={actionItems}
handleButtonClick={handleActionBarClick}
/>
</Grid>
</Grid>
</Page>
);
After (New Pattern)
For pages with only global actions:
return (
<Page title="My Page">
{/* Page content */}
</Page>
);
For pages with additional actions:
return (
<Page
title="My Page"
actionItems={actionItems}
onActionBarClick={handleActionBarClick}
>
{/* Page content */}
</Page>
);
Benefits
- Reduced Code Duplication: No need to manually include ActionSideBar in every page
- Consistent Layout: All pages automatically get the same layout structure
- Easier Maintenance: Global actions are managed in one place
- Flexible: Pages can still add their own actions or disable the sidebar entirely
- Better Separation of Concerns: Page components focus on content, not layout
- Cleaner API: Pages that only need defaults don't need to pass empty props
Available Action Constants
Icons (ACTION_BAR_ICONS)
BasemapLayersPropertiesGeoLocatorEntitySearchTooltipOn/TooltipOff- And more...
Text (ACTION_BAR_TEXT)
Set BasemapToggle LayersModify PropertiesSearch for a LocationSearch for an AssetEnable Tooltips/Disable Tooltips- And more...