@boomerang-io/carbon-addons-boomerang-react
Version:
Carbon Addons for Boomerang apps
155 lines (148 loc) • 7.97 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var stompjs = require('@stomp/stompjs');
var PlatformNotification = require('./PlatformNotification.js');
var cx = require('classnames');
var settings = require('../../internal/settings.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
var cx__default = /*#__PURE__*/_interopDefault(cx);
/*
IBM Confidential
694970X, 69497O0
© Copyright IBM Corp. 2022, 2024
*/
class PlatformNotificationsContainer extends React__default.default.Component {
ws;
articleRef = React__default.default.createRef();
state = {
error: false,
currentNotifications: this.props.initialNotifications ?? [],
numNotifications: this.props.initialNotifications?.length ?? 0,
};
componentDidMount() {
const brokerURL = `${this.props.baseServicesUrl}/notifications/ws`
.replace("https://", "wss://")
.replace("http://", "ws://");
this.ws = new stompjs.Client({
brokerURL,
reconnectDelay: 10000,
});
this.ws.onConnect = this.connect;
this.ws.activate();
}
connect = () => {
this.ws.subscribe("/user/queue/notifications", this.receiveNewNotifications);
this.ws.subscribe("/user/queue/reply", this.replyRead);
this.ws.subscribe("/user/queue/all", this.recieveAllUnreadNotifications);
this.ws.publish({ destination: "/app/all", body: {} });
};
componentWillUnmount() {
this.ws.deactivate();
}
/**
* recieve x amount of new notifications and pass them into state of current notifications
*
*/
receiveNewNotifications = (incomingNotifications) => {
if (incomingNotifications.body) {
const data = [JSON.parse(incomingNotifications.body)];
if (data.length > 0) {
this.props.setHasNewNotifications(true);
}
this.setState((prevState) => ({
currentNotifications: [...data, ...prevState.currentNotifications],
numNotifications: prevState.numNotifications + data.length,
}), () => {
this.props.setNotificationsCount(this.state.numNotifications);
});
}
else {
this.setState({
error: true, // TOOD something here related to the error
});
}
};
/**
* overwrite current notifications, the param represents all unread notifications
*/
recieveAllUnreadNotifications = (incomingNotifications) => {
if (incomingNotifications.body) {
const jsonData = JSON.parse(incomingNotifications.body);
const data = jsonData.records;
if (data.length > 0) {
this.props.setHasNewNotifications(true);
}
else {
// This has to be declared because this function can be triggered from the notification page in Launchpad
this.props.setHasNewNotifications(false);
}
this.setState({
currentNotifications: data,
numNotifications: data.length,
}, () => {
this.props.setNotificationsCount(this.state.numNotifications);
});
}
else {
this.setState({
error: true, // TOOD something here related to the error
});
}
};
/**
* @param {Object} readResponse - list of notificationIds that have been read
* the function removes the notifications from current state that are returned as "read"
*/
replyRead = (readResponse) => {
const readIdList = JSON.parse(readResponse.body);
this.setState((prevState) => ({
currentNotifications: prevState.currentNotifications.filter((el) => readIdList.indexOf(el.id) === -1),
numNotifications: prevState.numNotifications - readIdList.length,
}), () => {
if (this.state.numNotifications === 0) {
this.props.setHasNewNotifications(false);
this.props.setNotificationsCount(0);
// when we clear out notifications, check to to see if there are new notifications available
this.ws.publish({ destination: "/app/all", body: {} });
}
});
};
/**
* notificationId - a single notification that the user has marked as read
* @returns {Function} - makes network request, then after waiting for it to return, setState is called to update currentNotifications and numNotifications
*/
handleReadNotification(notificationId) {
this.ws.publish({
destination: "/app/read",
body: JSON.stringify([notificationId]),
});
}
/**
* @returns {Function} - makes network request with all remaining notification IDs, then after waiting for it to return, setState is called to empty out currentNotifications and numNotifications
*/
handleReadAllNotifications() {
const idList = this.state.currentNotifications.map((notification) => notification.id);
this.ws.publish({ destination: "/app/read", body: JSON.stringify(idList) });
}
renderNotifications() {
return this.state.currentNotifications.slice(0, 5).map((notification) => (React__default.default.createElement("li", { key: notification.id, "data-testid": "header-notification" },
React__default.default.createElement(PlatformNotification.default, { readNotification: this.handleReadNotification.bind(this), data: notification }))));
}
render() {
const { numNotifications, currentNotifications } = this.state;
const { baseEnvUrl } = this.props;
return (React__default.default.createElement("div", { "aria-labelledby": this.props["aria-labelledby"], className: cx__default.default(`${settings.prefix}--bmrg-notifications`, {
"--is-active": this.props.isOpen,
}), "data-testid": "header-notifications", id: this.props.id, role: "dialog" },
React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-notifications-header` },
React__default.default.createElement("h1", { className: `${settings.prefix}--bmrg-notifications-header__newNotifications` }, `${numNotifications} new notification${numNotifications !== 1 ? "s" : ""}`),
React__default.default.createElement("button", { className: `${settings.prefix}--bmrg-notifications-header__clear`, "data-testid": "header-notifications-all-read", disabled: !currentNotifications.length, onClick: this.handleReadAllNotifications.bind(this), "aria-label": "Mark all read" }, "Mark All Read")),
React__default.default.createElement("ul", { className: `${settings.prefix}--bmrg-notifications__collection` }, currentNotifications.length ? (this.renderNotifications()) : (React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-notifications-empty` },
React__default.default.createElement("h1", { className: `${settings.prefix}--bmrg-notifications-empty__no-news` }, "No news is good news, right?")))),
React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-notifications__notifications-footer` },
React__default.default.createElement("a", { "aria-label": "Link for notification center", href: `${baseEnvUrl}/launchpad/notifications`, className: `${settings.prefix}--bmrg-notifications__notifications-redirect-link`, "data-testid": "header-notifications-center-link" }, "Open Notification Center"))));
}
}
exports.default = PlatformNotificationsContainer;