Skip to main content

Notifications

Overview

Notifications represent events important enough to be brought to the attention of the user. Some examples are:

  • an alert from an app for an automatic machine restart, or from a metrics monitoring tool for a system running hot;
  • a trade order execution notification from an Order Management System;
  • a workflow task assigned to a user or a group of users that can optionally need a response - e.g., a change of client address;
  • an activity that is forwarded or re-assigned to a user - e.g., handling a client call;

io.Connect Desktop provides a notification service that normalizes and consolidates notifications from different apps and delivers them directly to the user on the desktop in a customizable UI as both toasts and ordered lists in a Notification Panel.

The notification toasts and the Notification Panel are configurable and completely customizable system apps.

Interop-enabled apps can use the io.Connect Notification APIs to raise notifications dynamically.

Using Notifications

io.Connect Desktop shows notifications on the desktop using notification toasts and a Notification Panel:

Notification Toasts

Notifications can be shown on the desktop as notification toasts. You can close them manually, snooze them, or interact directly with them by clicking on the notification or on an action button in it. Toasts expire based on configuration and hide automatically after the specified time has elapsed:

Notification toasts can be configured from the Notification Settings panel to group automatically in stacks by app or by severity. This improves the user experience and saves space on the screen. When you click on a notification stack, it expands and displays all notification toasts in it. You can then interact with the notifications in it, clear the entire stack, or collapse it by clicking on a notification in it:

Notification Panel

The Notification Panel is accessible via the io.Connect launcher and contains all received notifications that haven't been closed or acknowledged by the user. Notifications in it can be sorted by date, severity, snoozed status, read or unread status. You can close notifications individually. snooze them, or interact with them by clicking on the notification or on an action button in it. You can use the "Clear All" button to clear all notifications from the Notification Panel:

Notification Settings

The Notification Panel has a "Settings" button that opens a panel with notification settings. You can use it to enable or disable notifications globally or per app and provide various settings for the Notification Panel and the notification toasts:

After selecting the desired settings, close the Notification Settings panel and your changes will be saved automatically.

Snoozing Notifications

Available since io.Connect Desktop 9.3

Notifications can be snoozed from the UI and programmatically. Snoozed notifications will be shown to the user again as notification toasts after the specified snooze duration has elapsed. To snooze a notification manually, hover over a notification toast or a notification inside the Notification Panel and click the "Snooze" button that appears on hover. You can set the snooze duration from the Notification Settings panel:

Notification Badges

Notification badges will appear on the io.Connect Desktop icon in the Windows taskbar (or the Dock on macOS) and the system tray icon when there are pending notifications, so that the user won't miss them. The badge on the taskbar icon shows the number of notifications that the user hasn't seen yet, while the system tray icon badge simply alerts the user that there is at least one new notification:

Notification Badge

Configuration

By default, notifications are enabled in io.Connect Desktop. To specify global notification settings, use the "notifications" top-level key in the system.json system configuration file of io.Connect Desktop.

The "notifications" object has the following properties:

Property Type Description
"closeNotificationOnClick" boolean If true, when the user clicks on the body of a notification in the Notification Panel, the notification will be removed from the list. Set to false if you want users to be able to click on the notification body (e.g., to copy text) without the notification disappearing from the Notification Panel. Available since io.Connect Desktop 9.6.
"enabled" boolean If true (default), will enable all notifications - notification toasts and notifications in the Notification Panel.
"enableToasts" boolean If true (default), will enable notification toasts.
"placement" object Placement settings for the Notification Panel and the notification toasts. Available since io.Connect Desktop 9.2.
"showNotificationBadge" boolean If true, will enable showing a notification badge on the tray menu icon, in the "Notifications" section of the io.Connect launcher, and on the shell app icon in the Windows taskbar (or the Dock on macOS). Available since io.Connect Desktop 9.4.
"snooze" object Settings for snoozing notifications. Available since io.Connect Desktop 9.3.
"sourceFilter" object Filter with names of apps that are allowed or not allowed to raise notifications.
"toastExpiry" number Interval in milliseconds after which the notification toasts will be hidden. Defaults to 15000.
"toasts" object Settings for the notification toasts.

The "snooze" object has the following properties:

Property Type Description
"duration" number Interval in milliseconds for which the notifications will be snoozed. Defaults to 60000.
"enabled" boolean If true, will enable snoozing notifications. Defaults to false.

The "placement" object has the following properties:

Property Type Description
"panel" "left" | "right" Sets the position of the Notification Panel on the screen - left or right. Defaults to "right".
"toasts" "top-left" | "top-right" | "bottom-left" | "bottom-right" Sets the position of the notification toasts on the screen - top right, top left, bottom right or bottom left. Defaults to "bottom-right".

The "sourceFilter" object has the following properties:

Property Type Description
"allowed" string[] Names of apps allowed to raise notifications. Defaults to [].
"blocked" string[] Names of apps not allowed to raise notifications. Defaults to [].

The "toasts" object has the following properties:

Property Type Description
"mode" "single" | "stacked" Mode for the notification toasts. Notification toasts can appear individually, or can be stacked together based on a criterion (severity or app that has raised the notification). Defaults to "single".
"stackBy" "severity" | "application" Criterion for stacking the notification toasts. Defaults to "severity".

The following is an example configuration for notifications:

{
    "notifications": {
        "enabled": true,
        "enableToasts": true,
        "sourceFilter": {
            "allowed": ["*"]
        },
        "toastExpiry": 15000
    }
}

Custom Notification Apps

io.Connect Desktop shows notifications by using two system apps - an app that shows the notification toasts and an app that shows the Notification Panel. Both apps are built with the components provided by the IONotifications object of the @interopio/components-react library. You can use the same components to create custom notification apps and replace either or both of the default apps.

To create custom notification apps:

  1. Implement the apps with the <Toasts /> and <Panel /> components.
  2. Configure the apps as notification apps of io.Connect Desktop.
  3. Customize the app styles.

The <Toasts /> and <Panel /> components render fully functional notification toasts and Notification Panel without the need for any additional configuration. Use their components prop to replace the default components that they render. Use the hooks exported by IONotifications to read and change the notifications and the notification settings from your own components.

Setup

Render the notification apps within the <IOConnectProvider /> component of the @interopio/react-hooks library. Initialize the @interopio/desktop library with the apps property set to true to enable the Apps API, which the notification components use for retrieving and starting apps.

The notification apps depend on a set of React context providers from @interopio/components-react. They supply the theme, notifications, notification settings, and Notification Panel state that the notification apps require to operate properly. If a provider is missing, the functionality that depends on it won't work. You must render the <Toasts /> and <Panel /> components within all of them, in the order demonstrated in the following examples.

You must also import the CSS files for the notifications and for the UI components that they use.

The following example demonstrates how to render the default Notification Panel app:

import { IOConnectProvider } from "@interopio/react-hooks";
import IODesktop from "@interopio/desktop";
import { ThemeProvider, IONotifications } from "@interopio/components-react";
import "@interopio/theme";
import "@interopio/components-react/dist/styles/components/ui/dropdown-menu.css";
import "@interopio/components-react/dist/styles/components/ui/overlay-scrollbars-container.css";
import "@interopio/components-react/dist/styles/features/notifications/styles.css";

const {
    NotificationsProvider,
    NotificationsPanelProvider,
    Panel,
    useNotificationsContext,
    useShowHidePanelWindow,
    useHidePanelOnKeyUp,
    useHidePanelOnFocusLost
} = IONotifications;

const settings = {
    desktop: {
        factory: IODesktop,
        config: {
            apps: true
        }
    }
};

const NotificationPanel = () => {
    const { settings: { autoHidePanel } } = useNotificationsContext();

    useShowHidePanelWindow();
    useHidePanelOnKeyUp();
    useHidePanelOnFocusLost(autoHidePanel);

    return <Panel />;
};

const App = () => {
    return (
        <IOConnectProvider settings={settings}>
            <ThemeProvider>
                <NotificationsProvider>
                    <NotificationsPanelProvider>
                        <NotificationPanel />
                    </NotificationsPanelProvider>
                </NotificationsProvider>
            </ThemeProvider>
        </IOConnectProvider>
    );
};

export default App;

The Notification Panel app must show and hide its own window when the user opens or closes the Notification Panel. The hooks used in the example handle this.

The following example demonstrates how to render the default notification toasts app. The app will show its window only while there are active notifications, and will start the Notification Panel app when the user opens the Notification Panel:

import { useContext, useEffect } from "react";
import { IOConnectProvider, IOConnectContext } from "@interopio/react-hooks";
import IODesktop from "@interopio/desktop";
import {
    ThemeProvider,
    IONotifications,
    useShowHideWindow
} from "@interopio/components-react";
import "@interopio/theme";
import "@interopio/components-react/dist/styles/components/ui/dropdown-menu.css";
import "@interopio/components-react/dist/styles/components/ui/overlay-scrollbars-container.css";
import "@interopio/components-react/dist/styles/features/notifications/styles.css";

const {
    NotificationsProvider,
    NotificationsPanelProvider,
    Toasts,
    useNotificationsContext,
    useNotificationsPanelContext
} = IONotifications;

const settings = {
    desktop: {
        factory: IODesktop,
        config: {
            apps: true
        }
    }
};

const PANEL_APP_NAME = "io-connect-notifications-panel-application";

const NotificationToasts = () => {
    const io = useContext(IOConnectContext);
    const { notifications, settings: { enabledToasts } } = useNotificationsContext();
    const { isPanelVisible } = useNotificationsPanelContext();
    const hasActiveNotifications = notifications.some(notification => notification.state === "Active");

    // Show the window without focusing it.
    useShowHideWindow(hasActiveNotifications, false);

    useEffect(() => {
        if (!isPanelVisible) {
            return;
        }

        const startPanelApp = async () => {
            const panelApp = await io.apps.registry.get({ name: PANEL_APP_NAME });

            if (!panelApp || panelApp.instances.length > 0) {
                return;
            }

            await io.apps.instances.start({ name: PANEL_APP_NAME });
        };

        startPanelApp().catch(console.error);
    }, [io, isPanelVisible]);

    if (!enabledToasts || isPanelVisible) {
        return null;
    }

    return <Toasts />;
};

const App = () => {
    return (
        <IOConnectProvider settings={settings}>
            <ThemeProvider>
                <NotificationsProvider>
                    <NotificationsPanelProvider>
                        <NotificationToasts />
                    </NotificationsPanelProvider>
                </NotificationsProvider>
            </ThemeProvider>
        </IOConnectProvider>
    );
};

export default App;

Notification Panel

The <Panel /> component renders the Notification Panel. It has the following props:

Prop Type Description
autoPlacement boolean If true (default), the Notification Panel will set the size and the position of its window based on the placement settings for the Notification Panel. Set to false to manage the placement of the window yourself. Available since @interopio/components-react 5.0.1.
components object Components to render instead of the default components of the Notification Panel.
onClose function Callback invoked when the user clicks the "Close" button of the Notification Panel. Replaces the default behavior, which hides the Notification Panel.
settings object Components to render instead of the default components of the Notification Settings panel. Available since @interopio/components-react 5.0.1.
title string Title for the Notification Panel. Defaults to "Notifications".

The components object has the following properties:

Property Description
Body Body of the Notification Panel. Renders the <NotificationsList /> component with the notifications filtered and sorted by the user.
Header Header of the Notification Panel. Renders the caption, the search field, the actions, and the bulk actions.
HeaderActionClear Button for clearing all notifications.
HeaderActionEdit Button for showing the bulk actions.
HeaderActions Area with the <HeaderActionSort />, <HeaderActionView />, <HeaderActionClear />, and <HeaderActionEdit /> components.
HeaderActionSort Dropdown for sorting the notifications.
HeaderActionView Dropdown for filtering the notifications by state - all, read, unread, or snoozed.
HeaderBulkActionClear Button for clearing the selected notifications.
HeaderBulkActionClose Button for hiding the bulk actions.
HeaderBulkActionMarkAsRead Button for marking the selected notifications as read.
HeaderBulkActionMarkAsUnread Button for marking the selected notifications as unread.
HeaderBulkActions Area with the bulk actions. The bulk actions will be available only if the platform supports them.
HeaderBulkActionSelect Checkbox for selecting all notifications.
HeaderBulkActionSelectDropdown Dropdown for selecting notifications by state.
HeaderBulkActionSnooze Button for snoozing the selected notifications.
HeaderCaptionButtonClose Button for closing the Notification Panel.
HeaderCaptionButtonSettings Button for opening the Notification Settings panel.
HeaderCaptionCount Number of the notifications in the Notification Panel.
HeaderCaptionTitle Title of the Notification Panel.
HeaderSearch Search field for filtering the notifications.
Notification Component for rendering each notification.
NotificationsList List of notifications. Receives the notifications to render in its notifications prop and the component for rendering each notification in its Notification prop.

If you don't set a property, the Notification Panel will render the default component for it. To remove a component, set its property to a component that returns null. The default <Header />, <HeaderCaptionTitle />, and <Body /> components are exported by IONotifications as <PanelHeader />, <PanelHeaderCaptionTitle />, and <PanelBody />, so you can combine them with your own components.

The following example demonstrates creating a Notification Panel with a custom title and without the search field:

import { IONotifications } from "@interopio/components-react";

const { Panel } = IONotifications;

const HeaderSearch = () => null;

// Define the components outside the render function to prevent unnecessary re-mounting.
const components = { HeaderSearch };

const MyPanel = () => <Panel title="Messages" components={components} />;

The Notification Panel app must also handle the visibility of its window. Use the following hooks in the component that renders the <Panel /> component:

Hook Description
useHidePanelOnFocusLost() Hides the Notification Panel when its window loses focus. Accepts a Boolean argument that enables or disables this behavior. Pass the autoHidePanel property of the notification settings to respect the user setting.
useHidePanelOnKeyUp() Hides the Notification Panel when the user presses a key. Accepts the name of the key as an argument. Defaults to "Escape".
useShowHidePanelWindow() Shows or hides the window of the Notification Panel app when the user opens or closes the Notification Panel. Accepts a Boolean argument that specifies whether to focus the window when it's shown. Defaults to true.

Notification Toasts

The <Toasts /> component renders the notification toasts. It has the following props:

Prop Type Description
autoPlacement boolean If true (default), the notification toasts will set the size and the position of their window based on the placement settings for the toasts. Set to false to manage the placement of the window yourself. Available since @interopio/components-react 5.0.1.
components object Components to render instead of the default components of the notification toasts.
maxToasts number Maximum number of notification toasts to show at a time. Defaults to 10. Pass a negative value to show all active notifications.

The components object has the following properties:

Property Description
Body Body of the notification toasts. Receives all notifications in its notifications prop and the value of the maxToasts prop in its maxToasts prop. Renders the active notifications by using the <NotificationsList /> component.
Footer Component to render after the notification toasts. Not rendered by default.
Header Component to render before the notification toasts. Not rendered by default.
Notification Component for rendering each notification.
NotificationsList List of notifications. If notification stacking is enabled in the notification settings, will render the notification stacks.

The following example demonstrates creating notification toasts that show up to three notifications at a time and have a custom header:

import { IONotifications } from "@interopio/components-react";

const { Toasts } = IONotifications;

const Header = () => <div>Latest Notifications</div>;

// Define the components outside the render function to prevent unnecessary re-mounting.
const components = { Header };

const MyToasts = () => <Toasts maxToasts={3} components={components} />;

Notifications

The <Notification /> component renders a single notification in the Notification Panel and in the notification toasts. It has the following props:

Prop Type Description
components object Components to render instead of the default components of the notification.
notification object Required. The notification to render.

The components object has the following properties:

Property Description
Body Body of the notification. Renders the <BodyIcon />, <BodyTitle />, and <BodyDescription /> components.
BodyDescription Text of the notification. Receives it in its text prop.
BodyIcon Icon of the notification. Receives it in its icon prop.
BodyTitle Title of the notification. Receives it in its text prop.
Footer Footer of the notification. Renders a <FooterButton /> component for each notification action.
FooterButton Button for a notification action. Receives the action in its notificationAction prop.
Header Header of the notification. Renders the <HeaderBadge />, <HeaderCount />, <HeaderTitle />, <HeaderTimestamp />, <HeaderButtonSnooze />, and <HeaderButtonClose /> components.
HeaderBadge Badge that shows the notification severity.
HeaderButtonClose Button for closing the notification.
HeaderButtonSnooze Button for snoozing the notification.
HeaderCount Number of notifications in a notification stack.
HeaderTimestamp Time when the notification was raised.
HeaderTitle Title of the app that has raised the notification.

The <Header /> component and all components in it receive the notification in their notification prop. All default components are exported by IONotifications with the Notification prefix (e.g., <NotificationHeaderTitle />, <NotificationBodyIcon />), so you can combine them with your own components.

To use a custom notification, pass it as the Notification property of the components prop of the <Panel /> or the <Toasts /> component. The following example demonstrates creating a notification in the Notification Panel whose header title changes its color depending on the notification severity:

import { IONotifications } from "@interopio/components-react";

const { Panel, Notification } = IONotifications;

const severityColors = {
    Low: "#0066c0",
    Medium: "#43a047",
    High: "#f9a825",
    Critical: "#ff511f"
};

const HeaderTitle = ({ notification }) => {
    return <div style={{ color: severityColors[notification.severity] }}>{notification.appTitle}</div>;
};

// Define the components outside the render function to prevent unnecessary re-mounting.
const notificationComponents = { HeaderTitle };

const CustomNotification = (props) => <Notification {...props} components={notificationComponents} />;

const components = { Notification: CustomNotification };

const MyPanel = () => <Panel components={components} />;

Notification Settings

The "Settings" button in the Notification Panel opens the Notification Settings panel. To replace components in it, use the settings prop of the <Panel /> component. The settings object has the following properties:

Property Description
Body Body of the Notification Settings panel. Renders the <General />, <Stacking />, <Placement />, <Snooze />, and <Subscriptions /> components.
General Section with the general settings. Renders the <AllowNotifications />, <AllowNotificationToasts />, <ShowNotificationBadge />, <CloseNotificationOnClick />, <PanelAutoHide />, and <HideToastsAfter /> components.
Placement Section with the placement settings. Renders the <PlacementPanel /> and <PlacementToasts /> components.
Snooze Section with the snooze settings. Renders the <SnoozeDuration /> component.
Stacking Section with the settings for stacking notification toasts. Renders the <ToastStacking /> and <ToastStackBy /> components.
Subscriptions Section with the settings that specify which apps can raise notifications. Renders the <SubscribeAll />, <SubscribeApp />, <SubscribeMuteAll />, and <SubscribeMuteApp /> components.

Each component that a section renders is also a property of the settings object. All default components are exported by IONotifications with the Settings prefix (e.g., <SettingsGeneral />, <SettingsPlacementPanel />), so you can combine them with your own components.

The following example demonstrates creating a Notification Panel whose Notification Settings panel doesn't show the placement settings:

import { IONotifications } from "@interopio/components-react";

const { Panel } = IONotifications;

const Placement = () => null;

// Define the components outside the render function to prevent unnecessary re-mounting.
const settings = { Placement };

const MyPanel = () => <Panel settings={settings} />;

Notifications State

The IONotifications object exports hooks for reading and changing the notifications, the notification settings, and the state of the Notification Panel. Use them in components that you render within the notification providers.

The useNotificationsContext() hook returns an object with the following properties:

Property Type Description
allApplications number Number of all available apps.
allApps object[] Array of objects describing all available apps.
allowedApplications number Number of the apps that are allowed to raise notifications.
clearAll function Clears all notifications.
clearAllOld function Clears all notifications that the user has already seen.
clearMany function Accepts an array of notification IDs. Clears the specified notifications.
configuration object The current notification configuration.
hidePanel function Hides the Notification Panel.
isBulkActionsSupported boolean Flag indicating whether the platform supports bulk actions for notifications.
notifications object[] Array of objects describing all notifications.
notificationsCount number Number of the notifications shown in the Notification Panel after filtering.
notificationStacks object[] Array of objects describing the notification stacks.
onClose function Accepts a notification ID. Closes the specified notification.
saveFilter function Accepts an object with allowed and blocked properties that hold the names of the apps that are allowed and aren't allowed to raise notifications. Saves the filter.
saveSetting function Accepts an object with notification settings (same shape as the settings property). Saves the specified settings.
selectAllNotifications function Accepts a state ("all", "read", "unread", or "snoozed") and a Boolean value. Selects or deselects all notifications in the specified state.
selectedNotifications string[] IDs of the selected notifications.
selectNotification function Accepts a notification ID and a Boolean value. Selects or deselects the specified notification.
setState function Accepts a notification ID and a notification state. Sets the state of the specified notification.
setStates function Accepts an array of notification IDs and a notification state. Sets the state of the specified notifications.
settings object The current notification settings. Has enabledNotifications, enabledToasts, toastStacking, stackBy, showNotificationBadge, toastExpiry, placement, snooze, closeNotificationOnClick, and autoHidePanel properties.
showPanel function Shows the Notification Panel.
snooze function Accepts a notification ID and a duration in milliseconds. Snoozes the specified notification.
snoozeMany function Accepts an array of notification IDs and a duration in milliseconds. Snoozes the specified notifications.

Each object in the allApps array has the following properties:

Property Type Description
name string Name of the app.
title string Title of the app.
allowed boolean Flag indicating whether the app is allowed to raise notifications.
muted boolean Flag indicating whether the notifications of the app are muted.

Each object in the notificationStacks array has the following properties:

Property Type Description
key string Name of the app or the severity by which the notifications are stacked.
items object[] Array of objects describing the notifications in the stack.

The useNotificationsPanelContext() hook returns an object with the following properties:

Property Type Description
hideBulkActions function Hides the bulk actions in the Notification Panel.
isBulkActionsVisible boolean Flag indicating whether the bulk actions are visible.
isPanelVisible boolean Flag indicating whether the Notification Panel is visible.
searchQuery string Text in the search field of the Notification Panel.
setSearch function Accepts a string. Sets the text in the search field.
setSortBy function Accepts "newest", "oldest", or "severity". Sorts the notifications in the Notification Panel.
setViewBy function Accepts "all", "read", "unread", or "snoozed". Filters the notifications in the Notification Panel by state.
showBulkActions function Shows the bulk actions in the Notification Panel.
sortNotificationsBy string Current sorting of the notifications.
viewNotificationsBy string Current filter by state of the notifications.

Configuration

The default notification apps are defined in the notifications.json app definition file located in the <installation_location>/config/apps folder. The file contains the following app definitions:

App Name Description
"io-connect-notifications-application" App that shows the notification toasts. Starts automatically with io.Connect Desktop.
"io-connect-notifications-panel-application" App that shows the Notification Panel. Started by the notification toasts app when the user opens the Notification Panel.

To use a custom notification app, set the "url" property of the "details" top-level key in the respective app definition to the URL of your app. Keep the app name and the other properties of the app definition, so that the app window remains hidden, frameless, and on top of other windows:

{
    "name": "io-connect-notifications-panel-application",
    "details": {
        "url": "https://my-notification-panel.com"
    }
}

The notification toasts app starts the Notification Panel app by its name. The default notification toasts app expects the Notification Panel app to be named "io-connect-notifications-panel-application". To use another name, set the "panelApplicationName" property of the "customProperties" top-level key in the app definition of the notification toasts app:

{
    "name": "io-connect-notifications-application",
    "customProperties": {
        "panelApplicationName": "my-notification-panel"
    }
}

By default, the <Panel /> and <Toasts /> components set the size and the position of their windows based on the placement settings for notifications. To set the position of the window from the app definition instead, set the autoPlacement prop of the component to false and use the "placement" property of the "details" top-level key. The following example places the Notification Panel on the left of the screen:

{
    "details": {
        "placement": {
            "snapped": true,
            "horizontalAlignment": "left",
            "verticalAlignment": "stretch",
            "width": 350
        }
    }
}

ℹ️ For more details on io.Connect Window placement, see the Developers > Configuration > Application > Placement section.

Styles

Available since io.Connect Desktop 9.10 & @interopio/components-react 0.8

To customize the styles of the notifications, the Notification Panel, the notification toasts, and the Notification Settings panel, use the CSS variables provided by the io.Connect themes.