UNPKG

@boomerang-io/carbon-addons-boomerang-react

Version:
155 lines (148 loc) 7.97 kB
'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;