Alerts
Alerts views and bell button — current alerts, historical log, and header alarm indicator
@tetherto/mdk-react-devkit/foundation
Alerts components cover the full alarm surface: AlarmsBellButton in the app header, the Alerts feature composite (current + historical tabs), and the standalone HistoricalAlerts table. Pair with the dashboard for live context.
Prerequisites
Components
| Component | Description |
|---|---|
HistoricalAlerts | Historical alerts log with date-range picker and data table |
AlarmsBellButton | Top-bar bell button with three-line severity alarm badge |
Alerts | Current and historical alerts log view |
Alerts
Full-page alerts surface combining current and historical alert tabs. Consumes alarm data from the MDK adapter store.
Full-page alerts surface that wraps CurrentAlerts and (when isHistoricalAlertsEnabled) HistoricalAlerts, coordinating their shared filter state, date range, and alert click handling. Must be rendered inside <MdkProvider>. It manages:
- Current alerts (
devices,isCurrentAlertsLoading): raw devices payload and loading flag passed toCurrentAlerts. - Historical alerts (
historicalAlerts,isHistoricalAlertsLoading,isHistoricalAlertsEnabled): log data and visibility toggle. - Filtering (
selectedAlertId,initialSeverity,typeFiltersForSite): deep-link focus, severity pre-selection, and site type filters. - Callbacks (
onAlertClick,onDateRangeChange): row navigation and date range updates. - Sound (
isSoundEnabled,isDemoMode): critical-alert beep toggle and demo/preview mode. - Layout (
header,className): optional header slot and root class.
Import
import { Alerts } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
devices | Optional | Device[][] | none | Raw devices payload for current alerts (see useCurrentAlertDevices) |
isCurrentAlertsLoading | Optional | boolean | false | When true, shows the loading state in CurrentAlerts |
historicalAlerts | Optional | Alert[] | none | Pre-fetched historical alerts (see useHistoricalAlerts) |
isHistoricalAlertsLoading | Optional | boolean | false | When true, shows the loading state in HistoricalAlerts |
isHistoricalAlertsEnabled | Optional | boolean | false | When true, renders the historical alerts log section |
selectedAlertId | Optional | string | none | Focuses the table on a single alert (deep-link from URL) |
initialSeverity | Optional | string | none | Pre-selects a severity filter (typically from a ?severity= URL param) |
onAlertClick | Optional | function | none | Called with device id and alert uuid when the user opens an alert row |
onDateRangeChange | Optional | function | none | Called when the user picks a new date range in the historical log |
dateRange | Optional | HistoricalAlertsRange | last 14 days | Controlled date range ({ start: number, end: number } in ms) |
isSoundEnabled | Optional | boolean | false | Enables the critical-alert audible beep when a critical alert is present |
isDemoMode | Optional | boolean | false | When true, skips sound notifications (safe for preview environments) |
typeFiltersForSite | Optional | CascaderOption[] | none | Site-specific overrides for the TagFilterBar type filter |
header | Optional | ReactNode | none | Optional header (e.g. breadcrumbs) rendered above the alerts tables |
className | Optional | string | none | Root class name from the host app |
Hook integration
Wire Alerts with the MDK adapter hooks for live data:
import { useDevices } from '@tetherto/mdk-react-adapter'
import { useCurrentAlertDevices, useHistoricalAlerts } from '@tetherto/mdk-react-adapter'
import { Alerts } from '@tetherto/mdk-react-devkit/foundation'
function AlertsPage() {
const { filterTags } = useDevices()
const devices = useCurrentAlertDevices({ filterTags })
const [range, setRange] = useState(() => getDefaultHistoricalAlertsRange())
const historical = useHistoricalAlerts(range)
return (
<Alerts
devices={devices.data}
isCurrentAlertsLoading={devices.isLoading}
historicalAlerts={historical.data}
isHistoricalAlertsLoading={historical.isLoading}
isHistoricalAlertsEnabled
dateRange={range}
onDateRangeChange={setRange}
onAlertClick={(id, uuid) => router.push(`/alerts/${uuid}`)}
/>
)
}See useCurrentAlertDevices and useHistoricalAlerts for hook options.
CurrentAlerts
Sortable, searchable data table of active alerts derived from a raw devices payload. Plays an audible beep when a critical alert is present and sound notifications are enabled — after the user confirms via AlertConfirmationModal. The Alerts feature wrapper manages all state for most use cases; use CurrentAlerts directly when you need a standalone current-alerts table.
Import
import { CurrentAlerts } from '@tetherto/mdk-react-devkit/foundation'
import type { CurrentAlertsProps, AlertLocalFilters } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
localFilters | Required | AlertLocalFilters | none | Controlled filter state shared with other alerts components (see type) |
onLocalFiltersChange | Required | function | none | Called with the updated AlertLocalFilters when filters change |
filterTags | Required | string[] | none | Active search tags; mirrors the devices-store tag slice |
onFilterTagsChange | Required | function | none | Called with updated tags when the user adds or removes a search chip |
devices | Optional | Device[][] | none | Raw devices payload; drives alert row derivation |
isLoading | Optional | boolean | false | When true, shows the table loading state |
selectedAlertId | Optional | string | none | Focuses the table on a single alert |
onAlertClick | Optional | function | none | Called with device id and alert uuid when the user opens an alert row |
isSoundEnabled | Optional | boolean | false | Enables the critical-alert audible beep |
isDemoMode | Optional | boolean | false | When true, skips sound notifications |
typeFiltersForSite | Optional | CascaderOption[] | none | Site-specific overrides for the type filter in TagFilterBar |
className | Optional | string | none | Root class name from the host app |
AlertLocalFilters type
type AlertLocalFilters = {
severity?: string[] | string
status?: string[]
type?: string[]
id?: string[]
thing?: { id?: string }
[key: string]: unknown
}Basic usage
import { CurrentAlerts } from '@tetherto/mdk-react-devkit/foundation'
import type { AlertLocalFilters } from '@tetherto/mdk-react-devkit/foundation'
function AlertsView({ devices, isLoading }) {
const [localFilters, setLocalFilters] = useState<AlertLocalFilters>({})
const [filterTags, setFilterTags] = useState<string[]>([])
return (
<CurrentAlerts
devices={devices}
isLoading={isLoading}
localFilters={localFilters}
onLocalFiltersChange={setLocalFilters}
filterTags={filterTags}
onFilterTagsChange={setFilterTags}
onAlertClick={(id, uuid) => console.log('Alert clicked', id, uuid)}
/>
)
}HistoricalAlerts
Renders the historical alerts log as a sortable data table, with a date-range picker in the title row for adjusting the query window. Shares filter state with the current alerts view.
Import
import { HistoricalAlerts } from '@tetherto/mdk-react-devkit/foundation'
import type { HistoricalAlertsProps, HistoricalAlertsRange } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
alerts | Optional | Alert[] | [] | Pre-fetched historical alert entries |
isLoading | Optional | boolean | false | Show table loading state |
localFilters | Required | AlertLocalFilters | none | Filters and search state shared with CurrentAlerts |
filterTags | Required | string[] | none | Active filter tags |
dateRange | Required | HistoricalAlertsRange | none | Controlled start/end timestamps (ms) |
onDateRangeChange | Required | function | none | Fires when the user picks a new range |
onAlertClick | Optional | function | none | Row click handler |
className | Optional | string | none | Additional CSS class |
HistoricalAlertsRange type
type HistoricalAlertsRange = {
start: number
end: number
}Basic usage
<HistoricalAlerts
alerts={historicalAlerts}
localFilters={localFilters}
filterTags={filterTags}
dateRange={{ start: rangeStart, end: rangeEnd }}
onDateRangeChange={({ start, end }) => setRange({ start, end })}
onAlertClick={(id, uuid) => console.log('Alert clicked', id, uuid)}
/>Loading state
<HistoricalAlerts
alerts={[]}
isLoading
localFilters={localFilters}
filterTags={filterTags}
dateRange={dateRange}
onDateRangeChange={onDateRangeChange}
/>Behavior notes
- The component wires a
DateRangePickerinto the table title viaAlertsTableTitle, so date range changes come back throughonDateRangeChange. - Rows are sorted by severity (descending) then creation date (descending) by default.
- Timestamps are formatted through
useTimezoneFormatter()'sgetFormattedDate.
TagFilterBar
Strip of removable filter chips and a tag-input search field for narrowing the alerts table by severity, status, type, and device tags. Used as the subtitle slot of AlertsTableTitle inside CurrentAlerts.
Import
import { TagFilterBar } from '@tetherto/mdk-react-devkit/foundation'
import type { TagFilterBarProps } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
filterTags | Required | string[] | none | Active search tag chips |
localFilters | Required | AlertLocalFilters | none | Controlled filter state (severity, status, type) |
onSearchTagsChange | Required | function | none | Called with updated tags when the user adds or removes a chip |
onLocalFiltersChange | Required | function | none | Called with updated AlertLocalFilters when a cascader selection changes |
typeFiltersForSite | Optional | CascaderOption[] | default filter list | Site-specific overrides for the "Type" cascader children |
placeholder | Optional | string | none | Placeholder text for the tag-input field |
className | Optional | string | none | Root class name from the host app |
Basic usage
import { TagFilterBar } from '@tetherto/mdk-react-devkit/foundation'
<TagFilterBar
filterTags={filterTags}
localFilters={localFilters}
onSearchTagsChange={setFilterTags}
onLocalFiltersChange={setLocalFilters}
/>AlertsTableTitle
Heading strip for an alerts table — renders the section title and an optional subtitle slot (typically used for TagFilterBar or DateRangePicker). Used internally by CurrentAlerts and HistoricalAlerts.
Import
import { AlertsTableTitle } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
title | Required | ReactNode | none | Section heading content |
subtitle | Optional | ReactNode | none | Optional content rendered below the title (e.g. TagFilterBar or DateRangePicker) |
className | Optional | string | none | Root class name from the host app |
Basic usage
import { AlertsTableTitle, TagFilterBar } from '@tetherto/mdk-react-devkit/foundation'
<AlertsTableTitle
title="Current Alerts"
subtitle={
<TagFilterBar
filterTags={filterTags}
localFilters={localFilters}
onSearchTagsChange={setFilterTags}
onLocalFiltersChange={setLocalFilters}
/>
}
/>AlertConfirmationModal
One-time consent dialog that appears before critical-alert sound notifications are activated. Renders a non-dismissible Dialog with an "Understood" button. Once confirmed (tracked in sessionStorage), CurrentAlerts begins playing the beep.
Import
import { AlertConfirmationModal } from '@tetherto/mdk-react-devkit/foundation'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
isOpen | Required | boolean | none | Controls modal visibility |
onOk | Required | function | none | Called when the user clicks "Understood" |
Basic usage
import { AlertConfirmationModal } from '@tetherto/mdk-react-devkit/foundation'
<AlertConfirmationModal
isOpen={showConfirmation}
onOk={() => setShowConfirmation(false)}
/>Next steps
- For live incident context, see
ActiveIncidentsCardon the dashboard Feeds page - For alert data hooks, see
useCurrentAlertDevicesanduseHistoricalAlerts