Alerts & Notifications
Centralized alert management system for monitoring water-related anomalies, threshold violations, leakage detection, and offline devices with search, filtering, sorting, and acknowledgment capabilities.
Overview
The Alerts system provides real-time notifications for critical water management events including leakage detection, threshold crossings, device offline status, quality parameter violations, and energy consumption anomalies. Users can view, search, filter, acknowledge, and resolve alerts through an intuitive interface.
Location: libs/alerts/
Route: /alerts
Permission Required: ALERTS
Key Features
1. Alert Type Tabs
Multiple Alert Categories:
Consumption Alerts
- Query Key:
consumption - Triggers:
- Daily threshold exceeded
- Hourly threshold exceeded
- Unusual consumption patterns
- Icon: Water drop with warning
- Color: Orange/Red
Leakage Alerts
- Query Key:
leakageorstable_flow - Triggers:
- Continuous stable flow detected (leakage indicator)
- Flow pattern anomalies
- Icon: Leakage indicator
- Color: Dark red (#8C0000)
Offline Alerts
- Query Key:
offline - Triggers:
- Device connectivity lost
- Sensor not responding
- Icon: Offline indicator
- Color: Grey (#747474)
Quality Alerts
- Query Key:
quality - Triggers:
- pH, TDS, Turbidity outside safe range
- Water quality parameters violated
- Icon: Quality warning
- Color: Red
Energy Alerts (if enabled)
- Query Key:
energy - Triggers:
- Energy consumption threshold exceeded
- Power usage anomalies
- Icon: Energy indicator
- Color: Yellow
Tab Features:
- Unread Count Badge: Shows new alerts
(+5) - Real-time Updates: Badge updates as alerts come in
- Tab Switching: Instant filter by alert type
2. Search & Filter
Search Bar:
- Debounced search (1 second delay)
- Search across:
- Unit names
- Category names
- Alert descriptions
- Placeholder: "Search alerts here"
Filters:
alertConfig = {
selectedAlertType: 'consumption',
selectedSortedOption: 'sort_date',
showResolved: false, // Hide/show resolved alerts
showRead: false, // Hide/show read alerts
showOnline: true, // Show only online units
searchKey: null,
alertUnitFilterList: {} // Unit-specific filters
};
3. Sort Options
Sort By:
- Date (Default):
sort_date- Newest first - Severity:
sort_severity- Critical → High → Medium → Low - Unit Name:
sort_unit- Alphabetical - Category:
sort_category- Group by category
4. Alert Card Display
Each Alert Shows:
- Unit/Device Name
- Alert Type (Leakage, Threshold, Offline, etc.)
- Timestamp (relative: "2 hours ago" or absolute: "25/02/2026 10:30 AM")
- Alert Message (detailed description)
- Severity Indicator (color-coded border/icon)
- Status Badge:
- New (unread)
- Read
- Acknowledged
- Resolved
Action Buttons:
- View Details - Navigate to unit monitoring page
- Acknowledge - Mark alert as seen
- Resolve - Mark alert as fixed
- Dismiss - Hide alert
5. Real-Time Notifications
Browser Push Notifications:
- Requests permission on first visit
- Shows desktop notifications for new alerts
- Click notification to navigate to alert details
In-App Notifications:
- Badge count in header/sidebar
- Toast notifications for critical alerts
- Real-time updates via WebSocket
6. URL Deep Linking
Support for Direct Alert Navigation:
/alerts?alertType=leakage&alertId=alert_12345
Query Parameters:
alertType- Pre-select alert categoryalertId- Scroll to and highlight specific alertenergyEnabled- Show energy tab if enabled
Architecture
Data Flow
Key Components
1. AlertsStoreContextProvider
- Purpose: Global state for alerts data
- Location:
libs/shared/src/store/AlertsStore.js - State Variables:
notificationData- All alerts dataparams- Query parameters (alert_type, date)loading- Loading statetodaysUnread- Unread alert counts by type
Context Value:
{
notificationData: {
todaysUnread: {
consumption: 5,
leakage: 2,
offline: 3,
quality: 1
},
alerts: [
{
id: 'alert_123',
type: 'leakage',
unitId: 'UNIT_1',
unitName: 'Borewell 1',
categoryName: 'Borewells',
message: 'Continuous stable flow detected',
timestamp: '2026-02-25T10:30:00Z',
severity: 'high',
isRead: false,
isAcknowledged: false,
isResolved: false
}
]
},
params: { alert_type: 'consumption', date: '25/02/2026' },
loading: false,
setParams: (params) => {},
setNotificationData: (data) => {}
}
2. AlertsPage
- Purpose: Main alerts page container
- Location:
libs/alerts/src/AlertsPage.jsx - Features:
- Fixed header with title
- Alert type tabs
- Search bar
- Sort dropdown
3. AlertsToggleTypeHeader
- Purpose: Tab navigation and search
- Features:
- Dynamic tab generation from AlertsHelper
- Unread count badges
- Debounced search
- Sort options
4. AlertTabView
- Purpose: Display filtered alerts
- Location:
libs/alerts/src/components/AlertTabView.jsx - Features:
- Alert cards rendering
- Filter application
- Infinite scroll/pagination
5. AlertsSortList
- Purpose: Sort dropdown menu
- Location:
libs/alerts/src/components/AlertsSortList.jsx
6. AlertsHelper
- Purpose: Alert type configuration and utilities
- Location:
libs/shared/src/helper/alertHelperInstance.js - Defines: Alert types, query keys, response keys
API Integration
Get Alerts
GET /alerts
Params: {
alert_type: 'consumption', // or 'leakage', 'offline', 'quality'
date: '25/02/2026'
}
Response: {
todaysUnread: {
consumption: 5,
leakage: 2,
offline: 3,
quality: 1
},
alerts: [
{
id: 'alert_123',
type: 'leakage',
unitId: 'UNIT_1',
unitName: 'Borewell 1',
categoryId: 'CAT_1',
categoryName: 'Borewells',
message: 'Continuous stable flow detected - possible leakage',
timestamp: '2026-02-25T10:30:00Z',
severity: 'high',
isRead: false,
isAcknowledged: false,
isResolved: false,
value: 1250.5,
threshold: 1000,
siUnit: 'kL'
}
]
}
Acknowledge Alert
POST /alerts/acknowledge
Request Body: {
alertId: 'alert_123',
action: 'acknowledge' // or 'resolve', 'dismiss'
}
Response: {
status: 200,
message: 'Alert acknowledged successfully'
}
Get Alert Unit Graph
GET /alerts/unitGraph
Params: {
unitId: 'UNIT_1',
alertId: 'alert_123',
startDate: '25/02/2026',
endDate: '25/02/2026'
}
Response: {
graph: [
{ x: '00:00', y: 950, threshold: 1000 },
{ x: '01:00', y: 1050, threshold: 1000 }, // Threshold crossed
{ x: '02:00', y: 1100, threshold: 1000 }
]
}
Usage Examples
1. Access Alerts Data
import { useContext } from 'react';
import { AlertsStoreContext } from '@aquagen-mf-webapp/shared/store/AlertsStore';
function AlertsWidget() {
const alertStore = useContext(AlertsStoreContext);
const { notificationData, loading } = alertStore;
if (loading) return <Loader />;
const unreadCount = Object.values(notificationData.todaysUnread).reduce(
(sum, count) => sum + count,
0
);
return (
<div>
<h3>Unread Alerts: {unreadCount}</h3>
{notificationData.alerts.map(alert => (
<AlertCard key={alert.id} alert={alert} />
))}
</div>
);
}
2. Switch Alert Type
const handleAlertTypeChange = (newAlertType) => {
alertStore.setParams({
...alertStore.params,
alert_type: AlertsHelper.i.alertTypes[newAlertType].queryApiKey
});
};
// Usage
<Tab
value="leakage"
onClick={() => handleAlertTypeChange('leakage')}
label="Leakage Alerts"
/>
3. Acknowledge Alert
const handleAcknowledge = async (alertId) => {
const response = await AlertsController.acknowledgeAlert({
alertId: alertId,
action: 'acknowledge'
});
if (response.status === 200) {
// Refresh alerts list
alertStore.init();
}
};
4. Search Alerts (Debounced)
import { debounce } from 'lodash';
const debouncedHandleSearchChange = useMemo(
() =>
debounce((searchKey) => {
setAlertConfig((prev) => ({
...prev,
searchKey: searchKey
}));
}, 1000),
[]
);
<TextField
placeholder="Search alerts here"
onChange={(e) => debouncedHandleSearchChange(e.target.value)}
/>
5. Deep Link to Specific Alert
import { useSearchParams } from 'react-router-dom';
const [searchParams] = useSearchParams();
useEffect(() => {
const alertId = searchParams.get('alertId');
if (alertId) {
// Scroll to alert
document.getElementById(alertId)?.scrollIntoView({ behavior: 'smooth' });
// Mark as read
setAlertConfig(prev => ({ ...prev, showRead: true }));
}
}, [searchParams]);
Alert Helper Configuration
AlertsHelper.i.alertTypes = {
consumption: {
id: 'consumption',
displayName: 'Consumption',
queryApiKey: 'consumption',
responseApiKey: 'consumption'
},
leakage: {
id: 'leakage',
displayName: 'Leakage',
queryApiKey: 'stable_flow',
responseApiKey: 'leakage'
},
offline: {
id: 'offline',
displayName: 'Offline',
queryApiKey: 'offline',
responseApiKey: 'offline'
},
quality: {
id: 'quality',
displayName: 'Quality',
queryApiKey: 'quality',
responseApiKey: 'quality'
}
};
Best Practices
1. Handle Loading States
if (alertStore.loading) {
return <Loader />;
}
<Tab disabled={alertStore.loading} label="Alerts" />
2. Show Unread Counts
<If condition={!!alertStore?.notificationData?.todaysUnread.consumption}>
<Typography component="span" sx={{ color: 'red' }}>
(+{alertStore.notificationData.todaysUnread.consumption})
</Typography>
</If>
3. Use Debounced Search
Always debounce search input to avoid excessive API calls:
debounce((searchKey) => { ... }, 1000)
4. Preserve Alert Type in URL
const newSearchParams = {
alertType: alertType.queryApiKey
};
setSearchParams(newSearchParams);
Troubleshooting
Alerts Not Loading
Cause: Missing alert_type parameter Solution: Ensure alert type is set in params
alertStore.setParams({
alert_type: AlertsHelper.i.alertTypes.consumption.queryApiKey
});
Unread Counts Not Updating
Cause: Not refreshing after acknowledgment Solution: Call init() after alert actions
await acknowledgeAlert(alertId);
alertStore.init(); // Refresh
Deep Link Not Working
Cause: Alert ID not found or read filter active Solution: Enable showRead when alertId in URL
showRead: searchParams.get('alertId') ? true : false
Analytics Tracking
// Page view
AnalyticsService.sendEvent(AnalyticEvents.PAGE_VIEW, {}, true);
// Alert type change
AnalyticsService.sendEvent(AnalyticEvents.ALERT_TYPE_CHANGE, {
alertType: newAlertType
});
// Alert acknowledgment
AnalyticsService.sendEvent(AnalyticEvents.ALERT_ACKNOWLEDGED, {
alertId: alertId,
alertType: alert.type
});
Related Documentation
- Water Flow Monitoring - Leakage alerts originate here
- Water Quality - Quality alerts
- Dashboard - Alert summary on dashboard
- Permissions - ALERTS permission required
Last Updated: February 2026
Module Location: libs/alerts/