@carbon/ibm-security
Version:
Carbon for Cloud & Cognitive IBM Security UI components
467 lines (458 loc) • 24.2 kB
JavaScript
"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)));
}
}));