UNPKG

@carbon/ibm-security

Version:

Carbon for Cloud & Cognitive IBM Security UI components

467 lines (458 loc) 24.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _iconsReact = require("@carbon/icons-react"); var _classnames4 = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _theme = _interopRequireDefault(require("../../globals/theme")); var _Component2 = _interopRequireDefault(require("../Component")); var _Accordion = require("../Accordion"); var _Button = _interopRequireDefault(require("../Button")); var _Icon = _interopRequireDefault(require("../Icon")); var _IconButton = _interopRequireDefault(require("../IconButton")); var _IconButton2 = require("../IconButton/IconButton"); var _Link = _interopRequireDefault(require("../Link")); var _ProfileImage = _interopRequireDefault(require("../ProfileImage")); var _ScrollGradient = _interopRequireDefault(require("../ScrollGradient")); var _Transition = _interopRequireDefault(require("../Transition")); var _HeaderListItem = _interopRequireDefault(require("./HeaderListItem")); var _constants = require("./HeaderListItem/constants"); var _HeaderNotification = _interopRequireDefault(require("./HeaderNotification")); var _HeaderPopoverHeader = _interopRequireDefault(require("./HeaderPopoverHeader")); var _HeaderPopoverLinkSecondary = _interopRequireDefault(require("./HeaderPopoverLinkSecondary")); var _constants2 = require("./constants"); var _namespace = require("../../globals/namespace"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /** * @file Header. * @copyright IBM Security 2019, 2021 */ var headerButtonNamespace = "".concat(_constants2.namespace, "__button"); var assistiveTextClass = "".concat(_namespace.carbonPrefix, "--assistive-text"); var profileButtonAssistiveTextId = "".concat(_constants2.namespace, "__profile__button--assistive-text"); var getPopoverLabelId = function getPopoverLabelId(string) { return "".concat(_constants2.namespace, "__popover__label--").concat(string); }; /** * Renders the popover. * @param {HTMLElement} children The containing elements of the popover. * @param {boolean} state Whether the popover is toggled or not. * @returns {HTMLElement} The rendered popover. */ var renderPopover = function renderPopover(children, state) { return /*#__PURE__*/_react.default.createElement(_Transition.default, { className: _constants2.namespace, component: "span" }, state && /*#__PURE__*/_react.default.createElement("div", { className: "".concat(_constants2.namespace, "__popover") }, children)); }; var Header = exports.default = /*#__PURE__*/function (_Component) { function Header() { var _this; (0, _classCallCheck2.default)(this, Header); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, Header, [].concat(args)); (0, _defineProperty2.default)(_this, "state", { isActive: { notifications: false, profile: false }, isUserActive: Header.getIsUserActive(_this.props.profile), accountList: Header.getAccountList({ accounts: _this.props.accounts, profile: _this.props.profile }) }); (0, _defineProperty2.default)(_this, "toggle", _Component2.default.bind(_this)); return _this; } (0, _inherits2.default)(Header, _Component); return (0, _createClass2.default)(Header, [{ key: "clearNotification", value: /** * Clears a notification. * @param {string} id The ID of the notification to clear. */ function clearNotification(id) { this.props.onNotificationClear(id); } /** * Clears all notifications. */ }, { key: "clearAllNotifications", value: function clearAllNotifications() { var _this2 = this; if (!this.props.clearAllNotifications) { this.props.notifications.forEach(function (notification) { return _this2.props.onNotificationClear(notification.id); }); } else { this.props.clearAllNotifications(this.props.notifications.map(function (notification) { return notification.id; })); } } /** * Closes the popover when loses focus. */ }, { key: "closePopover", value: function closePopover(target) { var _this3 = this; setTimeout(function () { var activeElement = target.getRootNode().activeElement || document.activeElement; var value = target.getAttribute('value'); var label = activeElement ? activeElement.getAttribute('aria-label') || '' : ''; if (!target.contains(activeElement) && label.indexOf(value) === -1) { _this3.toggle(value); } }, 0); } /** * Renders the profile. * @returns {Function} The rendered profile element. */ }, { key: "renderProfile", value: function renderProfile() { var _this4 = this; var _this$props = this.props, labels = _this$props.labels, links = _this$props.links, profile = _this$props.profile, onAccountClick = _this$props.onAccountClick; var _this$state = this.state, accountList = _this$state.accountList, isActive = _this$state.isActive; if (isActive.profile) { setTimeout(function () { _this4.userProfile.focus(); }, 0); } var hasAccount = profile.account; var accountElement = hasAccount && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement("div", { className: "".concat(_constants2.namespace, "__popover__profile__body__label") }, labels.profile.account, ":", ' ', /*#__PURE__*/_react.default.createElement("span", { className: "selectable-text" }, profile.account.id)), /*#__PURE__*/_react.default.createElement("div", { className: "".concat(_constants2.namespace, "__popover__profile__body__name") }, /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__popover__profile__body__name__text") }, hasAccount.name))); var hasAccountList = accountList.length > 0; var popoverLabelId = getPopoverLabelId('profile'); return renderPopover(/*#__PURE__*/_react.default.createElement("div", { ref: function ref(userProfile) { _this4.userProfile = userProfile; }, className: "".concat(_constants2.namespace, "__popover--focus"), "aria-labelledby": popoverLabelId, onBlur: function onBlur() { return _this4.closePopover(_this4.userProfile); }, role: "tabpanel", tabIndex: "0", value: "profile" }, /*#__PURE__*/_react.default.createElement(_HeaderPopoverHeader.default, { className: "".concat(_constants2.namespace, "__popover__profile__header") }, /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_ProfileImage.default, { className: "".concat(_constants2.namespace, "__popover__profile__header__icon"), profile: profile, large: true }), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", { id: popoverLabelId, className: "".concat(_constants2.namespace, "__popover__profile__header__title") }, profile.name.first_name, " ", profile.name.surname), /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__popover__profile__header__email") }, profile.email)))), profile.description && /*#__PURE__*/_react.default.createElement("section", { className: "".concat(_constants2.namespace, "__popover__profile__description") }, profile.description), hasAccount && /*#__PURE__*/_react.default.createElement("section", { className: (0, _classnames4.default)("".concat(_constants2.namespace, "__popover__profile__body"), (0, _defineProperty2.default)({}, "".concat(_constants2.namespace, "__popover__profile__body--account"), !hasAccountList)) }, !hasAccountList ? accountElement : /*#__PURE__*/_react.default.createElement(_Accordion.Accordion, { className: "".concat(_constants2.namespace, "__popover__profile__body__accordion") }, /*#__PURE__*/_react.default.createElement(_Accordion.AccordionItem, { className: "".concat(_constants2.namespace, "__popover__profile__body__accordion__item"), title: accountElement }, /*#__PURE__*/_react.default.createElement("ul", { className: "".concat(_constants2.namespace, "__popover__profile__body__list") }, accountList.map(function (_ref) { var id = _ref.id, name = _ref.name; return /*#__PURE__*/_react.default.createElement("li", { key: id, className: "".concat(_constants2.namespace, "__popover__profile__body__account") }, /*#__PURE__*/_react.default.createElement("button", { value: id, onClick: onAccountClick, className: "".concat(_constants2.namespace, "__popover__profile__body__account__button"), type: "button" }, name)); }))))), /*#__PURE__*/_react.default.createElement("section", { className: "".concat(_constants2.namespace, "__popover__footer") }, this.props.showEditProfile && /*#__PURE__*/_react.default.createElement(_HeaderPopoverLinkSecondary.default, { className: "".concat(_constants2.namespace, "__popover__profile__footer__edit"), href: links.edit_profile }, labels.profile.edit_profile), /*#__PURE__*/_react.default.createElement(_HeaderPopoverLinkSecondary.default, { className: "".concat(_constants2.namespace, "__popover__profile__footer__logout"), href: links.sign_out }, labels.profile.sign_out))), isActive.profile); } /** * Renders notifications. * @returns {Function} The rendered notifications element. */ }, { key: "renderNotifications", value: function renderNotifications() { var _this5 = this; var _this$props2 = this.props, labels = _this$props2.labels, links = _this$props2.links, notifications = _this$props2.notifications, totalNotifications = _this$props2.totalNotifications; var isActive = this.state.isActive; var length = notifications.length; if (isActive.notifications) { setTimeout(function () { _this5.notifications.focus(); }, 0); } var popoverLabelId = getPopoverLabelId('notifications'); return renderPopover(/*#__PURE__*/_react.default.createElement("div", { ref: function ref(notifications) { _this5.notifications = notifications; }, className: "".concat(_constants2.namespace, "__popover--focus"), "aria-labelledby": popoverLabelId, onBlur: function onBlur() { return _this5.closePopover(_this5.notifications); }, role: "tabpanel", tabIndex: "0", value: "notifications" }, /*#__PURE__*/_react.default.createElement(_HeaderPopoverHeader.default, { id: popoverLabelId, title: labels.notifications.title }), length > 0 && /*#__PURE__*/_react.default.createElement("div", { className: "".concat(_constants2.namespace, "__popover__content") }, /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__popover__label") }, labels.notifications.today), /*#__PURE__*/_react.default.createElement("button", { className: "".concat(_constants2.namespace, "__popover__button"), "aria-label": labels.notifications.clear_all, onClick: function onClick() { return _this5.clearAllNotifications(); }, type: "button" }, /*#__PURE__*/_react.default.createElement(_Icon.default, { renderIcon: _iconsReact.Close20 }))), /*#__PURE__*/_react.default.createElement(_ScrollGradient.default, { color: _theme.default.inverse02 }, /*#__PURE__*/_react.default.createElement("ul", { className: "".concat(_constants2.namespace, "__popover__list") }, /*#__PURE__*/_react.default.createElement(_Transition.default, { className: "".concat(_constants2.namespace, "__notification"), component: "span" }, notifications.sort(function (a, b) { return new Date(b.datetime).getTime() - new Date(a.datetime).getTime(); }).map(function (_ref2, index) { var datetime = _ref2.datetime, description = _ref2.description, href = _ref2.href, id = _ref2.id, label = _ref2.label, product = _ref2.product; return /*#__PURE__*/_react.default.createElement("li", { key: id, className: "".concat(_constants2.namespace, "__popover__list-item") }, /*#__PURE__*/_react.default.createElement(_HeaderNotification.default, { clearButtonLabel: "".concat(labels.notifications.clear, " '").concat(description, "'"), dateTime: datetime, description: description, href: href, onClearButtonClick: function onClearButtonClick() { return _this5.clearNotification(id); }, product: product, timeLabel: label, viaLabel: labels.notifications.via, tabIndex: "0", tooltipDirection: index === 0 ? 'bottom' : 'top' })); })))), !length && /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__popover__container") }, labels.notifications.success), /*#__PURE__*/_react.default.createElement("div", { className: "".concat(_constants2.namespace, "__popover__footer") }, links.notifications_view_all && /*#__PURE__*/_react.default.createElement(_HeaderPopoverLinkSecondary.default, { href: links.notifications_view_all }, labels.notifications.link, ' ', totalNotifications > 0 && "(".concat(totalNotifications, ")")), links.notifications_preferences && /*#__PURE__*/_react.default.createElement(_Icon.default, { className: "".concat(_constants2.namespace, "__popover__icon"), renderIcon: _iconsReact.Settings20, title: labels.notifications.preferences || '' }))), isActive.notifications); } /** * Renders whether the user is active or not. * @returns {Fragment} The correctly rendered profile element. */ }, { key: "renderIsUserActive", value: function renderIsUserActive() { var _this6 = this; var _this$props3 = this.props, labels = _this$props3.labels, links = _this$props3.links, profile = _this$props3.profile; var _this$state2 = this.state, isActive = _this$state2.isActive, isUserActive = _this$state2.isUserActive; var notifications = isActive.notifications; var activeClass = '--active'; var headerListItemClass = "".concat(_constants.namespace).concat(activeClass); var buttonActiveClass = "".concat(headerButtonNamespace).concat(activeClass); var notificationsButtonClasses = (0, _classnames4.default)(headerButtonNamespace, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, buttonActiveClass, notifications), "".concat(headerButtonNamespace, "--notifications"), this.props.notifications.filter(function (n) { return !n.acknowledged; }).length > 0)); var profileButtonClasses = (0, _classnames4.default)(_IconButton2.namespace, headerButtonNamespace, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, buttonActiveClass, isActive.profile), "".concat(_IconButton2.namespace).concat(activeClass), isActive.profile)); return isUserActive ? /*#__PURE__*/_react.default.createElement(_react.Fragment, null, this.props.showNotifications && /*#__PURE__*/_react.default.createElement(_HeaderListItem.default, { className: headerListItemClass }, /*#__PURE__*/_react.default.createElement(_IconButton.default, { "aria-expanded": isActive.notifications, "aria-haspopup": isUserActive, "aria-label": labels.notifications.button, className: notificationsButtonClasses, onClick: function onClick() { return _this6.toggle('notifications'); }, renderIcon: _iconsReact.Notification20, state: notifications, tooltip: false }, /*#__PURE__*/_react.default.createElement(_Icon.default, { name: "notification" })), this.renderNotifications()), /*#__PURE__*/_react.default.createElement(_HeaderListItem.default, { className: headerListItemClass }, /*#__PURE__*/_react.default.createElement("button", { "aria-expanded": isActive.profile, "aria-haspopup": isUserActive, "aria-describedby": profileButtonAssistiveTextId, className: profileButtonClasses, onClick: function onClick() { return _this6.toggle('profile'); }, type: "button" }, /*#__PURE__*/_react.default.createElement("span", { id: profileButtonAssistiveTextId, className: assistiveTextClass }, labels.profile.button), /*#__PURE__*/_react.default.createElement(_ProfileImage.default, { profile: profile })), this.renderProfile())) : this.props.renderLoginAndSignup(links, labels.profile); } }, { key: "render", value: function render() { var _this$props4 = this.props, className = _this$props4.className, labels = _this$props4.labels, links = _this$props4.links; var brand = labels.brand; var link = links.product; var company = brand.company, domain = brand.domain, product = brand.product; var isUserActive = this.state.isUserActive; var classes = (0, _classnames4.default)("".concat(_constants2.namespace, "__container"), className); var domainElement = function domainElement(title) { return /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__link__title--domain") }, title); }; return /*#__PURE__*/_react.default.createElement("div", { className: classes }, /*#__PURE__*/_react.default.createElement("header", { className: _constants2.namespace, role: "banner" }, /*#__PURE__*/_react.default.createElement(_Link.default, { className: "".concat(_constants2.namespace, "__link"), href: link }, "".concat(company, " "), domain ? /*#__PURE__*/_react.default.createElement(_react.Fragment, null, domainElement("".concat(domain, " ")), /*#__PURE__*/_react.default.createElement("span", { className: "".concat(_constants2.namespace, "__link__title--product") }, product)) : domainElement(product)), /*#__PURE__*/_react.default.createElement("ul", { className: "".concat(_constants2.namespace, "__group ").concat(isUserActive && "".concat(_constants2.namespace, "__group--active")) }, this.renderIsUserActive()))); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps) { return { isUserActive: Header.getIsUserActive(nextProps.profile), accountList: Header.getAccountList({ accounts: nextProps.accounts, profile: nextProps.profile }) }; } /** * Returns whether a user is active or not. * @param {Record<string, any>} profile An object list of profile information. * @returns {boolean} Whether the user is active or not. * @static */ }, { key: "getIsUserActive", value: function getIsUserActive(profile) { return profile !== null; } /** * Returns a list of valid user accounts not including their current one. * @param {Record<Array, any>} userAccounts An object list of account information. * @returns {Array} A list of valid accounts. * @static */ }, { key: "getAccountList", value: function getAccountList(userAccounts) { if (userAccounts.profile && userAccounts.profile.account) { return userAccounts.accounts && userAccounts.accounts.filter(function (account) { return account.id !== userAccounts.profile.account.id; }) || []; } return []; } }]); }(_react.Component); (0, _defineProperty2.default)(Header, "propTypes", _objectSpread(_objectSpread({}, _constants2.propTypes), {}, { /** * @type {function(links: Object, labels: Object): React.Element} render custom login and sign up section */ renderLoginAndSignup: _propTypes.default.func })); (0, _defineProperty2.default)(Header, "defaultProps", _objectSpread(_objectSpread({}, _constants2.defaultProps), {}, { renderLoginAndSignup: function renderLoginAndSignup(links, labels) { return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_HeaderListItem.default, null, /*#__PURE__*/_react.default.createElement(_Button.default, { href: links.registration }, labels.registration)), /*#__PURE__*/_react.default.createElement(_HeaderListItem.default, null, /*#__PURE__*/_react.default.createElement(_Button.default, { href: links.sign_in, kind: "secondary" }, labels.sign_in))); } }));