UNPKG

@atlaskit/profilecard

Version:

A React component to display a card with user information.

433 lines (432 loc) 19.9 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 = ProfilecardTriggerNext; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireWildcard(require("react")); var _reactIntlNext = require("react-intl-next"); var _analyticsNext = require("@atlaskit/analytics-next"); var _giveKudos = require("@atlaskit/give-kudos"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _popup = _interopRequireDefault(require("@atlaskit/popup")); var _constants = require("@atlaskit/theme/constants"); var _filterActions = _interopRequireDefault(require("../../internal/filterActions")); var _getLabelMessage = _interopRequireDefault(require("../../internal/getLabelMessage")); var _Card = require("../../styled/Card"); var _analytics = require("../../util/analytics"); var _config = require("../../util/config"); var _AgentProfileCardResourced = require("../Agent/AgentProfileCardResourced"); var _lazyProfileCard = require("./lazyProfileCard"); var _UserLoadingState = _interopRequireDefault(require("./UserLoadingState")); var _excluded = ["ref"], _excluded2 = ["aria-expanded", "aria-haspopup"]; 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 ProfileCardContent(_ref) { var profilecardProps = _ref.profilecardProps, userId = _ref.userId, cloudId = _ref.cloudId, resourceClient = _ref.resourceClient, viewingUserId = _ref.viewingUserId, trigger = _ref.trigger, product = _ref.product, isAgent = _ref.isAgent, profileCardAction = _ref.profileCardAction, hasError = _ref.hasError, errorType = _ref.errorType, agentActions = _ref.agentActions, addFlag = _ref.addFlag; if (isAgent) { return /*#__PURE__*/_react.default.createElement(_AgentProfileCardResourced.AgentProfileCardResourced, { accountId: userId, cloudId: cloudId, resourceClient: resourceClient, viewingUserId: viewingUserId, trigger: trigger, product: product, onChatClick: agentActions === null || agentActions === void 0 ? void 0 : agentActions.onChatClick, onConversationStartersClick: agentActions === null || agentActions === void 0 ? void 0 : agentActions.onConversationStartersClick, addFlag: addFlag }); } else { return /*#__PURE__*/_react.default.createElement(_react.Suspense, { fallback: null }, /*#__PURE__*/_react.default.createElement(_lazyProfileCard.ProfileCardLazy, (0, _extends2.default)({}, profilecardProps, { actions: profileCardAction, hasError: hasError, errorType: errorType, withoutElevation: true }))); } } function ProfilecardTriggerNext(_ref2) { var autoFocus = _ref2.autoFocus, _ref2$trigger = _ref2.trigger, trigger = _ref2$trigger === void 0 ? 'hover' : _ref2$trigger, userId = _ref2.userId, cloudId = _ref2.cloudId, resourceClient = _ref2.resourceClient, _ref2$actions = _ref2.actions, actions = _ref2$actions === void 0 ? [] : _ref2$actions, _ref2$position = _ref2.position, position = _ref2$position === void 0 ? 'bottom-start' : _ref2$position, children = _ref2.children, testId = _ref2.testId, addFlag = _ref2.addFlag, onReportingLinesClick = _ref2.onReportingLinesClick, ariaLabel = _ref2.ariaLabel, ariaLabelledBy = _ref2.ariaLabelledBy, prepopulatedData = _ref2.prepopulatedData, disabledAriaAttributes = _ref2.disabledAriaAttributes, onVisibilityChange = _ref2.onVisibilityChange, offset = _ref2.offset, viewingUserId = _ref2.viewingUserId, product = _ref2.product, agentActions = _ref2.agentActions, _ref2$ariaHideProfile = _ref2.ariaHideProfileTrigger, ariaHideProfileTrigger = _ref2$ariaHideProfile === void 0 ? false : _ref2$ariaHideProfile, propsIsVisible = _ref2.isVisible; var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(), createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent; var _useIntl = (0, _reactIntlNext.useIntl)(), formatMessage = _useIntl.formatMessage; var isMounted = (0, _react.useRef)(false); var showDelay = trigger === 'click' || propsIsVisible && (0, _platformFeatureFlags.fg)('fix_profilecard_trigger_isvisible') ? 0 : _config.DELAY_MS_SHOW; var hideDelay = trigger === 'click' || propsIsVisible && (0, _platformFeatureFlags.fg)('fix_profilecard_trigger_isvisible') ? 0 : _config.DELAY_MS_HIDE; var showTimer = (0, _react.useRef)(0); var hideTimer = (0, _react.useRef)(0); var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2.default)(_useState, 2), visible = _useState2[0], setVisible = _useState2[1]; var _useState3 = (0, _react.useState)(undefined), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), isLoading = _useState4[0], setIsLoading = _useState4[1]; var _useState5 = (0, _react.useState)(false), _useState6 = (0, _slicedToArray2.default)(_useState5, 2), hasError = _useState6[0], setHasError = _useState6[1]; var _useState7 = (0, _react.useState)(null), _useState8 = (0, _slicedToArray2.default)(_useState7, 2), error = _useState8[0], setError = _useState8[1]; var _useState9 = (0, _react.useState)(null), _useState10 = (0, _slicedToArray2.default)(_useState9, 2), data = _useState10[0], setData = _useState10[1]; var _useState11 = (0, _react.useState)(undefined), _useState12 = (0, _slicedToArray2.default)(_useState11, 2), reportingLinesData = _useState12[0], setReportingLinesData = _useState12[1]; var _useState13 = (0, _react.useState)(false), _useState14 = (0, _slicedToArray2.default)(_useState13, 2), shouldShowGiveKudos = _useState14[0], setShouldShowGiveKudos = _useState14[1]; var _useState15 = (0, _react.useState)(undefined), _useState16 = (0, _slicedToArray2.default)(_useState15, 2), teamCentralBaseUrl = _useState16[0], setTeamCentralBaseUrl = _useState16[1]; var _useState17 = (0, _react.useState)(false), _useState18 = (0, _slicedToArray2.default)(_useState17, 2), kudosDrawerOpen = _useState18[0], setKudosDrawerOpen = _useState18[1]; var _useState19 = (0, _react.useState)(false), _useState20 = (0, _slicedToArray2.default)(_useState19, 2), isTriggeredUsingKeyboard = _useState20[0], setTriggeredUsingKeyboard = _useState20[1]; var triggerRef = (0, _react.useRef)(null); (0, _react.useEffect)(function () { isMounted.current = true; return function () { isMounted.current = false; clearTimeout(showTimer.current); clearTimeout(hideTimer.current); }; }, []); (0, _react.useEffect)(function () { // Reset state when the userId changes setIsLoading(undefined); setHasError(false); setError(null); setData(null); setReportingLinesData(undefined); setShouldShowGiveKudos(false); setTeamCentralBaseUrl(undefined); }, [userId]); var fireAnalytics = (0, _react.useCallback)(function (payload) { // Don't fire any analytics if the component is unmounted if (!isMounted.current) { return; } (0, _analytics.fireEvent)(createAnalyticsEvent, payload); }, [createAnalyticsEvent]); var hideProfilecard = (0, _react.useCallback)(function () { clearTimeout(showTimer.current); clearTimeout(hideTimer.current); if (!isTriggeredUsingKeyboard) { hideTimer.current = window.setTimeout(function () { setVisible(false); onVisibilityChange && onVisibilityChange(false); }, hideDelay); } }, [hideDelay, isTriggeredUsingKeyboard, onVisibilityChange]); var handleKeyboardClose = (0, _react.useCallback)(function (event) { if (event.key && event.key !== 'Escape') { return; } if (triggerRef.current) { triggerRef.current.focus(); } setTriggeredUsingKeyboard(false); setVisible(false); onVisibilityChange && onVisibilityChange(false); }, [setTriggeredUsingKeyboard, setVisible, onVisibilityChange]); var handleClientSuccess = (0, _react.useCallback)(function (profileData, reportingLinesData, shouldShowGiveKudos, teamCentralBaseUrl) { if (!isMounted.current) { return; } setIsLoading(false); setHasError(false); setData(profileData); setReportingLinesData(reportingLinesData); setTeamCentralBaseUrl(teamCentralBaseUrl); setShouldShowGiveKudos(shouldShowGiveKudos); }, [setHasError, setIsLoading, setData, setReportingLinesData, setShouldShowGiveKudos]); var handleClientError = (0, _react.useCallback)(function (err) { if (!isMounted.current) { return; } setIsLoading(false); setHasError(true); setError(err); }, [setHasError, setIsLoading, setError]); var clientFetchProfile = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { var requests, responses; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (!(isLoading === true)) { _context.next = 2; break; } return _context.abrupt("return"); case 2: setIsLoading(true); setHasError(false); setError(null); setData(null); _context.prev = 6; requests = Promise.all([resourceClient.getProfile(cloudId || '', userId, fireAnalytics), resourceClient.getReportingLines(userId), resourceClient.shouldShowGiveKudos(), resourceClient.getTeamCentralBaseUrl({ withOrgContext: true, withSiteContext: true })]); _context.next = 10; return requests; case 10: responses = _context.sent; handleClientSuccess.apply(void 0, (0, _toConsumableArray2.default)(responses)); _context.next = 17; break; case 14: _context.prev = 14; _context.t0 = _context["catch"](6); handleClientError(_context.t0); case 17: case "end": return _context.stop(); } }, _callee, null, [[6, 14]]); })), [cloudId, fireAnalytics, isLoading, resourceClient, userId, handleClientSuccess, handleClientError]); var showProfilecard = (0, _react.useCallback)(function () { clearTimeout(hideTimer.current); clearTimeout(showTimer.current); showTimer.current = window.setTimeout(function () { if (!visible) { void clientFetchProfile(); setVisible(true); onVisibilityChange && onVisibilityChange(true); } }, showDelay); }, [showDelay, visible, clientFetchProfile, onVisibilityChange]); var onClick = (0, _react.useCallback)(function (event) { // If the user clicks on the trigger then we don't want that click event to // propagate out to parent containers. For example when clicking a mention // lozenge in an inline-edit. event.stopPropagation(); showProfilecard(); if (!visible) { fireAnalytics((0, _analytics.cardTriggered)('user', 'click')); } }, [fireAnalytics, showProfilecard, visible]); var onMouseEnter = (0, _react.useCallback)(function () { showProfilecard(); if (!visible) { fireAnalytics((0, _analytics.cardTriggered)('user', 'hover')); } }, [fireAnalytics, showProfilecard, visible]); var onKeyPress = (0, _react.useCallback)(function (event) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); setTriggeredUsingKeyboard(true); showProfilecard(); if (!visible) { fireAnalytics((0, _analytics.cardTriggered)('user', 'click')); } } }, [fireAnalytics, showProfilecard, visible]); var onFocus = (0, _react.useCallback)(function () { showProfilecard(); }, [showProfilecard]); (0, _react.useEffect)(function () { if (!(0, _platformFeatureFlags.fg)('fix_profilecard_trigger_isvisible')) { return; } // If the prop isVisible is not defined, we don't want to do anything if (propsIsVisible === undefined) { return; } // If the prop isVisible is defined, we want to show or hide the profile card based on the value if (propsIsVisible) { showProfilecard(); } else { hideProfilecard(); } }, [hideProfilecard, propsIsVisible, showProfilecard]); var containerListeners = (0, _react.useMemo)(function () { return trigger === 'hover' ? { onMouseEnter: onMouseEnter, onMouseLeave: hideProfilecard, onBlur: hideProfilecard, onKeyPress: onKeyPress } : { onClick: onClick, onKeyPress: onKeyPress }; }, [hideProfilecard, onClick, onKeyPress, onMouseEnter, trigger]); var filterActions = (0, _react.useCallback)(function () { return (0, _filterActions.default)(actions, data); }, [actions, data]); var openKudosDrawer = function openKudosDrawer() { hideProfilecard(); setKudosDrawerOpen(true); }; var closeKudosDrawer = function closeKudosDrawer() { setKudosDrawerOpen(false); }; var showLoading = isLoading === true || isLoading === undefined; var wrapperProps = (0, _react.useMemo)(function () { return trigger === 'hover' ? { onMouseEnter: onMouseEnter, onMouseLeave: hideProfilecard, onFocus: onFocus } : {}; }, [hideProfilecard, onFocus, onMouseEnter, trigger]); var profilecardProps = _objectSpread(_objectSpread({ userId: userId, fullName: prepopulatedData === null || prepopulatedData === void 0 ? void 0 : prepopulatedData.fullName, isCurrentUser: userId === viewingUserId, clientFetchProfile: clientFetchProfile }, data), {}, { reportingLines: reportingLinesData, onReportingLinesClick: onReportingLinesClick, isKudosEnabled: shouldShowGiveKudos, teamCentralBaseUrl: teamCentralBaseUrl, cloudId: cloudId, openKudosDrawer: openKudosDrawer, isTriggeredUsingKeyboard: isTriggeredUsingKeyboard, disabledAriaAttributes: disabledAriaAttributes }); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_popup.default, { isOpen: !!visible, onClose: function onClose(event) { hideProfilecard(); handleKeyboardClose(event); }, placement: position, offset: offset !== null && offset !== void 0 ? offset : [0, 8], content: function content() { return /*#__PURE__*/_react.default.createElement("div", wrapperProps, showLoading ? /*#__PURE__*/_react.default.createElement(LoadingView, { fireAnalytics: fireAnalytics }) : visible && /*#__PURE__*/_react.default.createElement(ProfileCardContent, { profilecardProps: profilecardProps, isAgent: !!(data !== null && data !== void 0 && data.isAgent), userId: userId, cloudId: cloudId, resourceClient: resourceClient, viewingUserId: viewingUserId, trigger: trigger, product: product, profileCardAction: filterActions(), errorType: error, hasError: hasError, agentActions: agentActions, addFlag: addFlag })); }, trigger: function trigger(triggerProps) { var callbackRef = triggerProps.ref, innerProps = (0, _objectWithoutProperties2.default)(triggerProps, _excluded); var ref = function ref(element) { triggerRef.current = element; if (typeof callbackRef === 'function') { callbackRef(element); } }; var _ = innerProps['aria-expanded'], __ = innerProps['aria-haspopup'], restInnerProps = (0, _objectWithoutProperties2.default)(innerProps, _excluded2); return /*#__PURE__*/_react.default.createElement("span", (0, _extends2.default)({}, disabledAriaAttributes ? restInnerProps : triggerProps, containerListeners, { ref: ref, "data-testid": testId }, !ariaHideProfileTrigger && { 'aria-labelledby': ariaLabelledBy }, disabledAriaAttributes ? {} : { role: 'button', // aria-hidden cannot contain focusable elements: https://dequeuniversity.com/rules/axe/3.5/aria-hidden-focus tabIndex: ariaHideProfileTrigger ? -1 : 0, 'aria-label': ariaHideProfileTrigger ? undefined : (0, _getLabelMessage.default)(ariaLabel, profilecardProps.fullName, formatMessage) }, ariaHideProfileTrigger && { 'aria-hidden': 'true' }), children); }, zIndex: _constants.layers.modal(), shouldUseCaptureOnOutsideClick: true, autoFocus: autoFocus !== null && autoFocus !== void 0 ? autoFocus : trigger === 'click' // This feature gate is currently enabled only for Jira_Web to avoid UI issues in Confluence_Web. , shouldRenderToParent: (0, _platformFeatureFlags.fg)('enable_appropriate_reading_order_in_profile_card') }), shouldShowGiveKudos && teamCentralBaseUrl && /*#__PURE__*/_react.default.createElement(_react.Suspense, { fallback: null }, /*#__PURE__*/_react.default.createElement(_giveKudos.GiveKudosLauncherLazy, { isOpen: kudosDrawerOpen, recipient: { type: _giveKudos.KudosType.INDIVIDUAL, recipientId: userId }, analyticsSource: "profile-card", teamCentralBaseUrl: teamCentralBaseUrl, cloudId: cloudId, addFlag: addFlag, onClose: closeKudosDrawer }))); } var LoadingView = function LoadingView(_ref4) { var fireAnalytics = _ref4.fireAnalytics; return /*#__PURE__*/_react.default.createElement(_Card.CardWrapper, { testId: "profilecard.profilecardtrigger.loading" }, /*#__PURE__*/_react.default.createElement(_UserLoadingState.default, { fireAnalytics: fireAnalytics })); };