UNPKG

@atlaskit/profilecard

Version:

A React component to display a card with user information.

406 lines (404 loc) 19.6 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 _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _reactIntlNext = require("react-intl-next"); var _avatar = _interopRequireDefault(require("@atlaskit/avatar")); var _avatarGroup = _interopRequireDefault(require("@atlaskit/avatar-group")); var _loadingButton = _interopRequireDefault(require("@atlaskit/button/loading-button")); var _new = _interopRequireWildcard(require("@atlaskit/button/new")); var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button")); var _focusRing = _interopRequireDefault(require("@atlaskit/focus-ring")); var _showMoreHorizontalMore = _interopRequireDefault(require("@atlaskit/icon/core/migration/show-more-horizontal--more")); var _menu = require("@atlaskit/menu"); var _verifiedTeamIcon = require("@atlaskit/people-teams-ui-public/verified-team-icon"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _popup = _interopRequireDefault(require("@atlaskit/popup")); var _compiled = require("@atlaskit/primitives/compiled"); var _constants = require("@atlaskit/theme/constants"); var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip")); var _messages = _interopRequireDefault(require("../../messages")); var _Card = require("../../styled/Card"); var _Error = require("../../styled/Error"); var _TeamCard = require("../../styled/TeamCard"); var _analytics = require("../../util/analytics"); var _click = require("../../util/click"); var _Error2 = require("../Error"); var _TeamForbiddenErrorState = _interopRequireDefault(require("./TeamForbiddenErrorState")); var _TeamLoadingState = _interopRequireDefault(require("./TeamLoadingState")); 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; } var LARGE_MEMBER_COUNT = 50; var GIVE_KUDOS_ACTION_ID = 'give-kudos'; var avatarGroupMaxCount = 9; function onMemberClick(callback, userId, analytics, index, hasHref) { return function (event) { analytics(function (duration) { return (0, _analytics.teamAvatarClicked)({ duration: duration, hasHref: hasHref, hasOnClick: !!callback, index: index }); }); if (callback) { callback(userId, event); } }; } var TeamMembers = function TeamMembers(_ref) { var analytics = _ref.analytics, generateUserLink = _ref.generateUserLink, members = _ref.members, onUserClick = _ref.onUserClick, includingYou = _ref.includingYou, isTriggeredByKeyboard = _ref.isTriggeredByKeyboard; var _useIntl = (0, _reactIntlNext.useIntl)(), formatMessage = _useIntl.formatMessage; var count = members ? members.length : 0; var message = includingYou ? count >= LARGE_MEMBER_COUNT ? _messages.default.membersMoreThan50IncludingYou : _messages.default.memberCountIncludingYou : count >= LARGE_MEMBER_COUNT ? _messages.default.membersMoreThan50 : _messages.default.memberCount; // Use a ref to track whether this is currently open, so we can fire events // iff the more section is being opened (not closed). var isMoreMembersOpen = (0, _react.useRef)(false); var avatarRef = (0, _react.useRef)(null); var ref = function ref(element) { if (isTriggeredByKeyboard) { var _avatarRef$current; avatarRef.current = element; (_avatarRef$current = avatarRef.current) === null || _avatarRef$current === void 0 || _avatarRef$current.focus(); } }; var onMoreClick = (0, _react.useCallback)(function () { var isOpen = isMoreMembersOpen.current; if (!isOpen) { analytics(function (duration) { return (0, _analytics.moreMembersClicked)({ duration: duration, memberCount: count }); }); } isMoreMembersOpen.current = !isOpen; }, [analytics, count]); var showMoreButtonProps = _objectSpread({ onClick: onMoreClick }, (0, _platformFeatureFlags.fg)('platform_profilecard-enable_reporting_lines_label') ? { 'aria-label': formatMessage(_messages.default.profileCardMoreMembersLabel, { count: count - avatarGroupMaxCount + 1 }) } : {}); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_TeamCard.MemberCount, null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, message, { values: { count: count } }))), members && members.length > 0 && /*#__PURE__*/_react.default.createElement(_TeamCard.AvatarSection, null, (0, _platformFeatureFlags.fg)('enable_team_profilecard_toggletip_a11y_fix') ? /*#__PURE__*/_react.default.createElement(_avatarGroup.default, { appearance: "stack", data: members.map(function (member, index) { var href = generateUserLink === null || generateUserLink === void 0 ? void 0 : generateUserLink(member.id); var onClick = onMemberClick(onUserClick, member.id, analytics, index, !!generateUserLink); return { key: member.id, name: member.fullName, src: member.avatarUrl, href: href, onClick: onClick }; }), maxCount: avatarGroupMaxCount, showMoreButtonProps: showMoreButtonProps, testId: "profilecard-avatar-group", overrides: { Avatar: { render: function render(Component, props, index) { return index === 0 ? /*#__PURE__*/_react.default.createElement(_avatar.default, (0, _extends2.default)({ ref: ref }, props, { testId: "first-member" })) : /*#__PURE__*/_react.default.createElement(Component, props); } } } }) : /*#__PURE__*/_react.default.createElement(_avatarGroup.default, { appearance: "stack", data: members.map(function (member, index) { var href = generateUserLink === null || generateUserLink === void 0 ? void 0 : generateUserLink(member.id); var onClick = onMemberClick(onUserClick, member.id, analytics, index, !!generateUserLink); return { key: member.id, name: member.fullName, src: member.avatarUrl, href: href, onClick: onClick }; }), maxCount: avatarGroupMaxCount, showMoreButtonProps: showMoreButtonProps, testId: "profilecard-avatar-group" }))); }; function onActionClick(action, analytics, index) { return function (event) { analytics(function (duration) { return (0, _analytics.actionClicked)('team', { duration: duration, hasHref: !!action.link, hasOnClick: !!action.callback, index: index, actionId: action.id || '' }); }); if (action.callback && (0, _click.isBasicClick)(event)) { event.preventDefault(); for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } action.callback.apply(action, [event].concat(args)); } }; } var ActionButton = function ActionButton(_ref2) { var action = _ref2.action, analytics = _ref2.analytics, index = _ref2.index; var isGiveKudosActionButton = action.id === GIVE_KUDOS_ACTION_ID; var actionButton = /*#__PURE__*/_react.default.createElement(_focusRing.default, { isInset: true }, (0, _platformFeatureFlags.fg)('ptc_migrate_buttons') ? /*#__PURE__*/_react.default.createElement(_new.LinkButton, { key: action.id || index, onClick: onActionClick(action, analytics, index), href: action.link || '', shouldFitContainer: true }, action.label, isGiveKudosActionButton && /*#__PURE__*/_react.default.createElement(_Card.AnimationWrapper, null, /*#__PURE__*/_react.default.createElement(_Card.KudosBlobAnimation, null))) : /*#__PURE__*/_react.default.createElement(_standardButton.default, { key: action.id || index, onClick: onActionClick(action, analytics, index), href: action.link, shouldFitContainer: true }, action.label, isGiveKudosActionButton && /*#__PURE__*/_react.default.createElement(_Card.AnimationWrapper, null, /*#__PURE__*/_react.default.createElement(_Card.KudosBlobAnimation, null)))); if (isGiveKudosActionButton) { return /*#__PURE__*/_react.default.createElement(_Card.AnimatedKudosButton, null, actionButton); } return /*#__PURE__*/_react.default.createElement(_TeamCard.WrappedButton, null, actionButton); }; var ExtraActions = function ExtraActions(_ref3) { var actions = _ref3.actions, analytics = _ref3.analytics; var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2.default)(_useState, 2), isOpen = _useState2[0], setOpen = _useState2[1]; var count = actions.length; var onMoreClick = (0, _react.useCallback)(function (shouldBeOpen) { if (shouldBeOpen) { // Only fire this event when OPENING the dropdown analytics(function (duration) { return (0, _analytics.moreActionsClicked)('team', { duration: duration, numActions: count + 2 }); }); } setOpen(shouldBeOpen); }, [analytics, count]); if (!count) { return null; } return /*#__PURE__*/_react.default.createElement(_TeamCard.MoreButton, null, /*#__PURE__*/_react.default.createElement(_popup.default, { isOpen: isOpen, onClose: function onClose() { return setOpen(false); }, placement: "bottom-start", content: function content() { return /*#__PURE__*/_react.default.createElement(_menu.MenuGroup, null, actions.map(function (action, index) { return /*#__PURE__*/_react.default.createElement(_menu.LinkItem, { onClick: onActionClick(action, analytics, index + 2), key: action.id || index, href: action.link }, action.label); })); }, trigger: function trigger(triggerProps) { return (0, _platformFeatureFlags.fg)('ptc_migrate_buttons') ? /*#__PURE__*/_react.default.createElement(_new.IconButton, (0, _extends2.default)({ testId: "more-actions-button" }, triggerProps, { isSelected: isOpen, onClick: function onClick() { return onMoreClick(!isOpen); }, icon: _showMoreHorizontalMore.default, label: "actions" })) : /*#__PURE__*/_react.default.createElement(_standardButton.default, (0, _extends2.default)({ testId: "more-actions-button" }, triggerProps, { isSelected: isOpen, onClick: function onClick() { return onMoreClick(!isOpen); }, iconAfter: /*#__PURE__*/_react.default.createElement(_showMoreHorizontalMore.default, { spacing: "spacious", label: "actions", color: "currentColor" }) })); }, zIndex: _constants.layers.modal(), shouldRenderToParent: (0, _platformFeatureFlags.fg)('enable_appropriate_reading_order_in_profile_card') })); }; var ButtonSection = function ButtonSection(_ref4) { var actions = _ref4.actions, analytics = _ref4.analytics; if (!actions) { return null; } var extraActions = actions.slice(2); var initialActions = actions.slice(0, 2); return /*#__PURE__*/_react.default.createElement(_TeamCard.ActionButtons, null, initialActions.map(function (action, index) { return /*#__PURE__*/_react.default.createElement(ActionButton, { action: action, analytics: analytics, index: index, key: index }); }), extraActions && /*#__PURE__*/_react.default.createElement(ExtraActions, { actions: extraActions, analytics: analytics })); }; var TeamProfilecardContent = function TeamProfilecardContent(_ref5) { var actions = _ref5.actions, analytics = _ref5.analytics, team = _ref5.team, viewingUserId = _ref5.viewingUserId, generateUserLink = _ref5.generateUserLink, onUserClick = _ref5.onUserClick, viewProfileLink = _ref5.viewProfileLink, viewProfileOnClick = _ref5.viewProfileOnClick, isTriggeredByKeyboard = _ref5.isTriggeredByKeyboard; var allActions = [{ label: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.teamViewProfile), link: viewProfileLink, callback: viewProfileOnClick, id: 'view-profile' }].concat((0, _toConsumableArray2.default)(actions || [])); var includingYou = team.members && team.members.some(function (member) { return member.id === viewingUserId; }); (0, _react.useEffect)(function () { analytics(function (duration) { var _team$members; return (0, _analytics.profileCardRendered)('team', 'content', { duration: duration, numActions: allActions.length, memberCount: (_team$members = team.members) === null || _team$members === void 0 ? void 0 : _team$members.length, includingYou: includingYou, descriptionLength: team.description.length, titleLength: team.displayName.length }); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [analytics]); return /*#__PURE__*/_react.default.createElement(_TeamCard.CardWrapper, { testId: "team-profilecard" }, /*#__PURE__*/_react.default.createElement(_TeamCard.CardHeader, { image: team.largeHeaderImageUrl || team.smallHeaderImageUrl, label: team.displayName }), /*#__PURE__*/_react.default.createElement(_TeamCard.CardContent, null, /*#__PURE__*/_react.default.createElement(_tooltip.default, { content: team.displayName }, /*#__PURE__*/_react.default.createElement(_compiled.Inline, null, /*#__PURE__*/_react.default.createElement(_TeamCard.TeamName, null, team.displayName), team.isVerified && /*#__PURE__*/_react.default.createElement(_verifiedTeamIcon.VerifiedTeamIcon, null))), /*#__PURE__*/_react.default.createElement(TeamMembers, { analytics: analytics, members: team.members, generateUserLink: generateUserLink, includingYou: includingYou, onUserClick: onUserClick, isTriggeredByKeyboard: isTriggeredByKeyboard }), team.description.trim() && /*#__PURE__*/_react.default.createElement(_TeamCard.DescriptionWrapper, null, /*#__PURE__*/_react.default.createElement(_TeamCard.Description, null, team.description)), /*#__PURE__*/_react.default.createElement(ButtonSection, { actions: allActions, analytics: analytics }))); }; var ErrorMessage = function ErrorMessage(_ref6) { var analytics = _ref6.analytics, clientFetchProfile = _ref6.clientFetchProfile, isLoading = _ref6.isLoading; var hasRetry = !!clientFetchProfile; (0, _react.useEffect)(function () { analytics(function (duration) { return (0, _analytics.profileCardRendered)('team', 'error', { duration: duration, hasRetry: hasRetry }); }); }, [analytics, hasRetry]); var retry = (0, _react.useCallback)(function () { analytics(function (duration) { return (0, _analytics.errorRetryClicked)({ duration: duration }); }); if (clientFetchProfile) { clientFetchProfile(); } }, [analytics, clientFetchProfile]); return /*#__PURE__*/_react.default.createElement(_Error.ErrorWrapper, { testId: "team-profilecard-error" }, /*#__PURE__*/_react.default.createElement(_Error2.ErrorIllustration, null), /*#__PURE__*/_react.default.createElement(_compiled.Text, { as: "p", weight: "semibold" }, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.teamErrorTitle)), /*#__PURE__*/_react.default.createElement(_Error.TeamErrorText, null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.teamErrorText)), clientFetchProfile && /*#__PURE__*/_react.default.createElement(_TeamCard.ActionButtons, null, /*#__PURE__*/_react.default.createElement(_TeamCard.WrappedButton, null, (0, _platformFeatureFlags.fg)('ptc_migrate_buttons') ? /*#__PURE__*/_react.default.createElement(_new.default, { testId: "client-fetch-profile-button", shouldFitContainer: true, onClick: retry, isLoading: isLoading }, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.teamErrorButton)) : /*#__PURE__*/_react.default.createElement(_loadingButton.default, { testId: "client-fetch-profile-button", shouldFitContainer: true, onClick: retry, isLoading: isLoading }, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.teamErrorButton))))); }; var TeamProfileCard = function TeamProfileCard(props) { var analytics = props.analytics, clientFetchProfile = props.clientFetchProfile, hasError = props.hasError, isLoading = props.isLoading, team = props.team, errorType = props.errorType; if (hasError) { if ((errorType === null || errorType === void 0 ? void 0 : errorType.reason) === 'TEAMS_FORBIDDEN') { return /*#__PURE__*/_react.default.createElement(_TeamForbiddenErrorState.default, { analytics: analytics }); } else { return /*#__PURE__*/_react.default.createElement(_TeamCard.CardWrapper, { testId: "team-profilecard" }, /*#__PURE__*/_react.default.createElement(ErrorMessage, { analytics: analytics, clientFetchProfile: clientFetchProfile, isLoading: isLoading })); } } if (isLoading) { return /*#__PURE__*/_react.default.createElement(_TeamLoadingState.default, { analytics: analytics }); } if (team) { return /*#__PURE__*/_react.default.createElement(TeamProfilecardContent, _objectSpread(_objectSpread({}, props), {}, { team: team })); } return null; }; var _default = exports.default = TeamProfileCard;