Skip to main content

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: leakage or stable_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 category
  • alertId - Scroll to and highlight specific alert
  • energyEnabled - 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 data
    • params - Query parameters (alert_type, date)
    • loading - Loading state
    • todaysUnread - 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)}
/>
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>

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

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
});


Last Updated: February 2026 Module Location: libs/alerts/