Global Menu Component
Build full-page views in the top navigation
Global Menu Component
Global Menu components appear in Fireberry's top navigation bar and render as full-page views. They're ideal for dashboards, admin panels, and standalone tools that need dedicated space.
When to Use
- Dashboards with metrics and charts
- Admin or settings panels
- Reports and analytics
- Standalone tools not tied to specific records
Manifest Configuration
components:
- type: global-menu
title: "Analytics Dashboard"
id: "analytics-uuid"
path: static/dashboard/build
settings:
displayName: "Analytics"Settings
| Setting | Type | Required | Description |
|---|---|---|---|
displayName | string | Yes | Text shown in the navigation bar |
displayName
The label that appears in the top navigation. Keep it short — one or two words works best.
Good examples: Analytics, Dashboard, Reports, Admin, Settings
Context Access
Global Menu components have access to user context only — not record context:
import FireberryClientSDK from "@fireberry/sdk/client";
const client = new FireberryClientSDK();
await client.initializeContext();
const { user } = client.context;
console.log(user.id); // "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
console.log(user.fullName); // "John Doe"
// record is NOT available in Global Menu components
// client.context.record will be emptyExample: Dashboard
A simple dashboard with statistics:
import { useEffect, useState } from "react";
import FireberryClientSDK from "@fireberry/sdk/client";
import { DSThemeContextProvider, Typography, Button } from "@fireberry/ds";
function Dashboard() {
const [client] = useState(() => new FireberryClientSDK());
const [stats, setStats] = useState({ total: 0, active: 0, completed: 0 });
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadStats() {
await client.initializeContext();
// Fetch counts
const [total, active, completed] = await Promise.all([
client.api.query(1, { fields: "id", query: 'id != ""' }),
client.api.query(1, { fields: "id", query: 'status = "active"' }),
client.api.query(1, { fields: "id", query: 'status = "completed"' }),
]);
setStats({
total: Array.isArray(total.data) ? total.data.length : 1,
active: Array.isArray(active.data) ? active.data.length : 1,
completed: Array.isArray(completed.data) ? completed.data.length : 1,
});
setLoading(false);
}
loadStats();
}, [client]);
if (loading) return <div>Loading...</div>;
return (
<DSThemeContextProvider isRtl={false}>
<div style={{ padding: 32, maxWidth: 1200, margin: "0 auto" }}>
<Typography type="h1">Dashboard</Typography>
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
gap: 24,
marginTop: 32,
}}
>
<StatCard label="Total" value={stats.total} />
<StatCard label="Active" value={stats.active} />
<StatCard label="Completed" value={stats.completed} />
</div>
</div>
</DSThemeContextProvider>
);
}
function StatCard({ label, value }) {
return (
<div
style={{
padding: 24,
border: "1px solid #E2E3E9",
borderRadius: 8,
backgroundColor: "#fff",
}}
>
<Typography type="caption" color="neutral">
{label}
</Typography>
<Typography type="h1">{value}</Typography>
</div>
);
}Example: Settings Panel
An admin settings page:
import { useState, useEffect } from "react";
import FireberryClientSDK from "@fireberry/sdk/client";
import {
DSThemeContextProvider,
Typography,
Toggle,
Button,
} from "@fireberry/ds";
function SettingsPanel() {
const [client] = useState(() => new FireberryClientSDK());
const [settings, setSettings] = useState({
notifications: true,
autoSave: false,
});
useEffect(() => {
client.initializeContext();
}, [client]);
const toggle = (key) => {
setSettings((prev) => ({ ...prev, [key]: !prev[key] }));
};
return (
<DSThemeContextProvider isRtl={false}>
<div style={{ padding: 32, maxWidth: 600, margin: "0 auto" }}>
<Typography type="h1">Settings</Typography>
<div style={{ marginTop: 32 }}>
<div style={{ marginBottom: 24 }}>
<Typography type="text">Enable Notifications</Typography>
<Toggle
isSelected={settings.notifications}
onChange={() => toggle("notifications")}
/>
</div>
<div style={{ marginBottom: 24 }}>
<Typography type="text">Auto-Save</Typography>
<Toggle
isSelected={settings.autoSave}
onChange={() => toggle("autoSave")}
/>
</div>
<Button label="Save" color="success" variant="primary" />
</div>
</div>
</DSThemeContextProvider>
);
}Use Cases
| Use Case | Description |
|---|---|
| Dashboard | Metrics, KPIs, overview |
| Reports | Data visualization |
| Admin Panel | System configuration |
| Import/Export | Bulk data operations |
| Help Center | Documentation |
Validation Errors
| Error | Solution |
|---|---|
displayName is required | Add displayName to settings |
Next Steps
- Record Component — Record-specific views
- Side Menu Component — Slide-out panels
- SDK — Learn more about context and API
Updated 4 days ago
