@atlaskit/profilecard 19.7.15 → 19.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/dist/cjs/client/getTeamFromAGG.js +1 -1
  4. package/dist/cjs/components/User/ProfileCard.js +17 -5
  5. package/dist/cjs/components/User/ProfileCardTrigger.js +7 -2
  6. package/dist/cjs/components/User/ProfileCardTriggerNext.js +347 -0
  7. package/dist/cjs/i18n/en.js +1 -0
  8. package/dist/cjs/i18n/en_GB.js +1 -0
  9. package/dist/cjs/i18n/en_ZZ.js +1 -0
  10. package/dist/cjs/util/analytics.js +1 -1
  11. package/dist/es2019/client/getTeamFromAGG.js +1 -1
  12. package/dist/es2019/components/User/ProfileCard.js +18 -6
  13. package/dist/es2019/components/User/ProfileCardTrigger.js +6 -1
  14. package/dist/es2019/components/User/ProfileCardTriggerNext.js +266 -0
  15. package/dist/es2019/i18n/en.js +1 -0
  16. package/dist/es2019/i18n/en_GB.js +1 -0
  17. package/dist/es2019/i18n/en_ZZ.js +1 -0
  18. package/dist/es2019/util/analytics.js +1 -1
  19. package/dist/esm/client/getTeamFromAGG.js +1 -1
  20. package/dist/esm/components/User/ProfileCard.js +18 -6
  21. package/dist/esm/components/User/ProfileCardTrigger.js +6 -1
  22. package/dist/esm/components/User/ProfileCardTriggerNext.js +337 -0
  23. package/dist/esm/i18n/en.js +1 -0
  24. package/dist/esm/i18n/en_GB.js +1 -0
  25. package/dist/esm/i18n/en_ZZ.js +1 -0
  26. package/dist/esm/util/analytics.js +1 -1
  27. package/dist/types/components/User/ProfileCardTrigger.d.ts +3 -4
  28. package/dist/types/components/User/ProfileCardTriggerNext.d.ts +3 -0
  29. package/dist/types/i18n/en.d.ts +1 -0
  30. package/dist/types/i18n/en_GB.d.ts +1 -0
  31. package/dist/types/i18n/en_ZZ.d.ts +1 -0
  32. package/dist/types/types.d.ts +4 -1
  33. package/dist/types-ts4.5/components/User/ProfileCardTrigger.d.ts +3 -4
  34. package/dist/types-ts4.5/components/User/ProfileCardTriggerNext.d.ts +3 -0
  35. package/dist/types-ts4.5/i18n/en.d.ts +1 -0
  36. package/dist/types-ts4.5/i18n/en_GB.d.ts +1 -0
  37. package/dist/types-ts4.5/i18n/en_ZZ.d.ts +1 -0
  38. package/dist/types-ts4.5/types.d.ts +4 -1
  39. package/package.json +12 -6
@@ -0,0 +1,266 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
4
+ import { GiveKudosLauncherLazy, KudosType } from '@atlaskit/give-kudos';
5
+ import Popup from '@atlaskit/popup';
6
+ import { layers } from '@atlaskit/theme/constants';
7
+ import filterActionsInner from '../../internal/filterActions';
8
+ import { CardWrapper } from '../../styled/Card';
9
+ import { cardTriggered, fireEvent } from '../../util/analytics';
10
+ import { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
11
+ import { ProfileCardLazy } from './lazyProfileCard';
12
+ import UserLoadingState from './UserLoadingState';
13
+ export default function ProfilecardTriggerNext({
14
+ trigger = 'hover',
15
+ userId,
16
+ cloudId,
17
+ resourceClient,
18
+ actions = [],
19
+ position = 'bottom-start',
20
+ children,
21
+ testId,
22
+ addFlag,
23
+ onReportingLinesClick,
24
+ ariaLabel,
25
+ ariaLabelledBy
26
+ }) {
27
+ const {
28
+ createAnalyticsEvent
29
+ } = useAnalyticsEvents();
30
+ const [isMounted, setIsMounted] = useState(false);
31
+ const showDelay = trigger === 'click' ? 0 : DELAY_MS_SHOW;
32
+ const hideDelay = trigger === 'click' ? 0 : DELAY_MS_HIDE;
33
+ const [showTimer, setShowTimer] = useState(0);
34
+ const [hideTimer, setHideTimer] = useState(0);
35
+ const [visible, setVisible] = useState(false);
36
+ const [isLoading, setIsLoading] = useState(undefined);
37
+ const [hasError, setHasError] = useState(false);
38
+ const [error, setError] = useState(null);
39
+ const [data, setData] = useState(null);
40
+ const [reportingLinesData, setReportingLinesData] = useState(undefined);
41
+ const [shouldShowGiveKudos, setShouldShowGiveKudos] = useState(false);
42
+ const [teamCentralBaseUrl, setTeamCentralBaseUrl] = useState(undefined);
43
+ const [kudosDrawerOpen, setKudosDrawerOpen] = useState(false);
44
+ const [isTriggeredUsingKeyboard, setTriggeredUsingKeyboard] = useState(false);
45
+ const triggerRef = useRef(null);
46
+ useEffect(() => {
47
+ setIsMounted(true);
48
+ return () => {
49
+ setIsMounted(false);
50
+ clearTimeout(showTimer);
51
+ clearTimeout(hideTimer);
52
+ };
53
+ // eslint-disable-next-line react-hooks/exhaustive-deps
54
+ }, []);
55
+ useEffect(() => {
56
+ // Reset state when the userId changes
57
+ setIsLoading(undefined);
58
+ setHasError(false);
59
+ setError(null);
60
+ setData(null);
61
+ setReportingLinesData(undefined);
62
+ setShouldShowGiveKudos(false);
63
+ setTeamCentralBaseUrl(undefined);
64
+ }, [userId]);
65
+ const fireAnalytics = useCallback(payload => {
66
+ // Don't fire any analytics if the component is unmounted
67
+ if (!isMounted) {
68
+ return;
69
+ }
70
+ fireEvent(createAnalyticsEvent, payload);
71
+ }, [createAnalyticsEvent, isMounted]);
72
+ const hideProfilecard = useCallback(() => {
73
+ clearTimeout(showTimer);
74
+ clearTimeout(hideTimer);
75
+ if (!isTriggeredUsingKeyboard) {
76
+ setHideTimer(window.setTimeout(() => {
77
+ setVisible(false);
78
+ }, hideDelay));
79
+ }
80
+ setTriggeredUsingKeyboard(false);
81
+ }, [hideDelay, hideTimer, showTimer, isTriggeredUsingKeyboard]);
82
+ const handleKeyboardClose = useCallback(event => {
83
+ if (event.key !== 'Escape') {
84
+ return;
85
+ }
86
+ if (triggerRef.current) {
87
+ triggerRef.current.focus();
88
+ }
89
+ setTriggeredUsingKeyboard(false);
90
+ setVisible(false);
91
+ }, [setTriggeredUsingKeyboard, setVisible]);
92
+ const handleClientSuccess = useCallback((profileData, reportingLinesData, shouldShowGiveKudos) => {
93
+ if (!isMounted) {
94
+ return;
95
+ }
96
+ setIsLoading(false);
97
+ setHasError(false);
98
+ setData(profileData);
99
+ setReportingLinesData(reportingLinesData);
100
+ setShouldShowGiveKudos(shouldShowGiveKudos);
101
+ }, [isMounted, setHasError, setIsLoading, setData, setReportingLinesData, setShouldShowGiveKudos]);
102
+ const handleClientError = useCallback(err => {
103
+ if (!isMounted) {
104
+ return;
105
+ }
106
+ setIsLoading(false);
107
+ setHasError(true);
108
+ setError(err);
109
+ }, [isMounted, setHasError, setIsLoading, setError]);
110
+ const clientFetchProfile = useCallback(async () => {
111
+ if (isLoading === true) {
112
+ // don't fetch data when fetching is in process
113
+ return;
114
+ }
115
+ setTeamCentralBaseUrl(resourceClient.getTeamCentralBaseUrl());
116
+ setIsLoading(true);
117
+ setHasError(false);
118
+ setError(null);
119
+ setData(null);
120
+ try {
121
+ const requests = Promise.all([resourceClient.getProfile(cloudId || '', userId, fireAnalytics), resourceClient.getReportingLines(userId), resourceClient.shouldShowGiveKudos()]);
122
+ const responses = await requests;
123
+ handleClientSuccess(...responses);
124
+ } catch (err) {
125
+ handleClientError(err);
126
+ }
127
+ }, [cloudId, fireAnalytics, isLoading, resourceClient, userId, handleClientSuccess, handleClientError]);
128
+ const showProfilecard = useCallback(() => {
129
+ clearTimeout(hideTimer);
130
+ clearTimeout(showTimer);
131
+ setShowTimer(window.setTimeout(() => {
132
+ if (!visible) {
133
+ void clientFetchProfile();
134
+ setVisible(true);
135
+ }
136
+ }, showDelay));
137
+ }, [hideTimer, showDelay, showTimer, visible, clientFetchProfile]);
138
+ const onClick = useCallback(event => {
139
+ // If the user clicks on the trigger then we don't want that click event to
140
+ // propagate out to parent containers. For example when clicking a mention
141
+ // lozenge in an inline-edit.
142
+ event.stopPropagation();
143
+ showProfilecard();
144
+ if (!visible) {
145
+ fireAnalytics(cardTriggered('user', 'click'));
146
+ }
147
+ }, [fireAnalytics, showProfilecard, visible]);
148
+ const onMouseEnter = useCallback(() => {
149
+ showProfilecard();
150
+ if (!visible) {
151
+ fireAnalytics(cardTriggered('user', 'hover'));
152
+ }
153
+ }, [fireAnalytics, showProfilecard, visible]);
154
+ const onKeyPress = useCallback(event => {
155
+ if (event.key === 'Enter' || event.key === ' ') {
156
+ event.preventDefault();
157
+ setTriggeredUsingKeyboard(true);
158
+ showProfilecard();
159
+ if (!visible) {
160
+ fireAnalytics(cardTriggered('user', 'click'));
161
+ }
162
+ }
163
+ }, [fireAnalytics, showProfilecard, visible]);
164
+ const onFocus = useCallback(() => {
165
+ showProfilecard();
166
+ }, [showProfilecard]);
167
+ const containerListeners = useMemo(() => trigger === 'hover' ? {
168
+ onMouseEnter: onMouseEnter,
169
+ onMouseLeave: hideProfilecard,
170
+ onBlur: hideProfilecard,
171
+ onKeyPress: onKeyPress
172
+ } : {
173
+ onClick: onClick,
174
+ onKeyPress: onKeyPress
175
+ }, [hideProfilecard, onClick, onKeyPress, onMouseEnter, trigger]);
176
+ const filterActions = useCallback(() => {
177
+ return filterActionsInner(actions, data);
178
+ }, [actions, data]);
179
+ const openKudosDrawer = () => {
180
+ hideProfilecard();
181
+ setKudosDrawerOpen(true);
182
+ };
183
+ const closeKudosDrawer = () => {
184
+ setKudosDrawerOpen(false);
185
+ };
186
+ const showLoading = isLoading === true || isLoading === undefined;
187
+ const wrapperProps = useMemo(() => trigger === 'hover' ? {
188
+ onMouseEnter: onMouseEnter,
189
+ onMouseLeave: hideProfilecard,
190
+ onFocus: onFocus
191
+ } : {}, [hideProfilecard, onFocus, onMouseEnter, trigger]);
192
+ const profilecardProps = {
193
+ userId: userId,
194
+ isCurrentUser: data === null || data === void 0 ? void 0 : data.isCurrentUser,
195
+ clientFetchProfile: clientFetchProfile,
196
+ ...data,
197
+ reportingLines: reportingLinesData,
198
+ onReportingLinesClick: onReportingLinesClick,
199
+ isKudosEnabled: shouldShowGiveKudos,
200
+ teamCentralBaseUrl: teamCentralBaseUrl,
201
+ cloudId: cloudId,
202
+ openKudosDrawer: openKudosDrawer,
203
+ isTriggeredUsingKeyboard: isTriggeredUsingKeyboard
204
+ };
205
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Popup, {
206
+ isOpen: !!visible,
207
+ onClose: event => {
208
+ hideProfilecard();
209
+ handleKeyboardClose(event);
210
+ },
211
+ placement: position,
212
+ content: () => showLoading ? /*#__PURE__*/React.createElement(LoadingView, {
213
+ fireAnalytics: fireAnalytics
214
+ }) : /*#__PURE__*/React.createElement("div", wrapperProps, visible && /*#__PURE__*/React.createElement(Suspense, {
215
+ fallback: null
216
+ }, /*#__PURE__*/React.createElement(ProfileCardLazy, _extends({}, profilecardProps, {
217
+ actions: filterActions(),
218
+ hasError: hasError,
219
+ errorType: error,
220
+ withoutElevation: true
221
+ })))),
222
+ trigger: triggerProps => {
223
+ const {
224
+ ref: callbackRef,
225
+ ...innerProps
226
+ } = triggerProps;
227
+ const ref = element => {
228
+ triggerRef.current = element;
229
+ if (typeof callbackRef === 'function') {
230
+ callbackRef(element);
231
+ }
232
+ };
233
+ return /*#__PURE__*/React.createElement("span", _extends({}, innerProps, containerListeners, {
234
+ ref: ref,
235
+ "data-testid": testId,
236
+ role: "button",
237
+ tabIndex: 0,
238
+ "aria-label": ariaLabel,
239
+ "aria-labelledby": ariaLabelledBy
240
+ }), children);
241
+ },
242
+ zIndex: layers.modal(),
243
+ shouldUseCaptureOnOutsideClick: true,
244
+ autoFocus: trigger === 'click'
245
+ }), shouldShowGiveKudos && /*#__PURE__*/React.createElement(Suspense, {
246
+ fallback: null
247
+ }, /*#__PURE__*/React.createElement(GiveKudosLauncherLazy, {
248
+ isOpen: kudosDrawerOpen,
249
+ recipient: {
250
+ type: KudosType.INDIVIDUAL,
251
+ recipientId: userId
252
+ },
253
+ analyticsSource: "profile-card",
254
+ teamCentralBaseUrl: teamCentralBaseUrl,
255
+ cloudId: cloudId,
256
+ addFlag: addFlag,
257
+ onClose: closeKudosDrawer
258
+ })));
259
+ }
260
+ const LoadingView = ({
261
+ fireAnalytics
262
+ }) => /*#__PURE__*/React.createElement(CardWrapper, {
263
+ "data-testId": "profilecard.profilecardtrigger.loading"
264
+ }, /*#__PURE__*/React.createElement(UserLoadingState, {
265
+ fireAnalytics: fireAnalytics
266
+ }));
@@ -7,6 +7,7 @@
7
7
  */
8
8
  //
9
9
  export default {
10
+ 'profilecard.user.trigger.aria-label': 'More information about {fullName}',
10
11
  'pt.profile-card.closed.account': 'Account deleted',
11
12
  'pt.profile-card.closed.account.has.date.a.few.months': 'Their account has been deleted for a few months.',
12
13
  'pt.profile-card.closed.account.has.date.last.month': 'Their account was deleted last month.',
@@ -7,6 +7,7 @@
7
7
  */
8
8
  //English (United Kingdom)
9
9
  export default {
10
+ 'profilecard.user.trigger.aria-label': 'More information about {fullName}',
10
11
  'pt.profile-card.closed.account': 'Account deleted',
11
12
  'pt.profile-card.closed.account.has.date.a.few.months': 'Their account has been deleted for a few months.',
12
13
  'pt.profile-card.closed.account.has.date.last.month': 'Their account was deleted last month.',
@@ -7,6 +7,7 @@
7
7
  */
8
8
  //
9
9
  export default {
10
+ 'profilecard.user.trigger.aria-label': '⁣⁢More information about {fullName}⁠‍⁡؜‍‌‌⁡‌؜⁡‌⁣⁤',
10
11
  'pt.profile-card.closed.account': '⁣⁢Account deleted⁠؜⁡‌؜⁠‍⁡⁠؜؜⁣⁤',
11
12
  'pt.profile-card.closed.account.has.date.a.few.months': '⁣⁢Their account has been deleted for a few months.⁠⁡⁠‍‌⁠⁡‍؜‌⁡‌‌؜⁣⁤',
12
13
  'pt.profile-card.closed.account.has.date.last.month': '⁣⁢Their account was deleted last month.⁡‍⁠‌⁡؜‍؜⁠‍⁠؜⁣⁤',
@@ -31,7 +31,7 @@ const createEvent = (eventType, action, actionSubject, actionSubjectId, attribut
31
31
  actionSubjectId,
32
32
  attributes: {
33
33
  packageName: "@atlaskit/profilecard",
34
- packageVersion: "19.7.15",
34
+ packageVersion: "19.9.0",
35
35
  ...attributes,
36
36
  firedAt: Math.round(getPageTime())
37
37
  }
@@ -48,7 +48,7 @@ export var addHeaders = function addHeaders(headers) {
48
48
  headers.append('X-ExperimentalApi', 'teams-beta');
49
49
  headers.append('X-ExperimentalApi', 'team-members-beta');
50
50
  headers.append('atl-client-name', "@atlaskit/profilecard");
51
- headers.append('atl-client-version', "19.7.15");
51
+ headers.append('atl-client-version', "19.9.0");
52
52
  return headers;
53
53
  };
54
54
  export function getTeamFromAGG(_x, _x2, _x3) {
@@ -1,7 +1,7 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import _extends from "@babel/runtime/helpers/extends";
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { FormattedMessage } from 'react-intl-next';
6
6
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
7
7
  import Avatar from '@atlaskit/avatar';
@@ -121,12 +121,14 @@ export var ProfilecardInternal = function ProfilecardInternal(props) {
121
121
  fireAnalyticsWithDuration: fireAnalyticsWithDuration
122
122
  })), realActions && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionsFlexSpacer, null), /*#__PURE__*/React.createElement(Actions, {
123
123
  actions: realActions,
124
- fireAnalyticsWithDuration: fireAnalyticsWithDuration
124
+ fireAnalyticsWithDuration: fireAnalyticsWithDuration,
125
+ isTriggeredUsingKeyboard: props.isTriggeredUsingKeyboard
125
126
  })))));
126
127
  };
127
128
  var Actions = function Actions(_ref) {
128
129
  var actions = _ref.actions,
129
- fireAnalyticsWithDuration = _ref.fireAnalyticsWithDuration;
130
+ fireAnalyticsWithDuration = _ref.fireAnalyticsWithDuration,
131
+ isTriggeredUsingKeyboard = _ref.isTriggeredUsingKeyboard;
130
132
  var onActionClick = useCallback(function (action, args, event, index) {
131
133
  fireAnalyticsWithDuration(function (duration) {
132
134
  return actionClicked('user', {
@@ -142,6 +144,12 @@ var Actions = function Actions(_ref) {
142
144
  action.callback.apply(action, [event].concat(_toConsumableArray(args)));
143
145
  }
144
146
  }, [fireAnalyticsWithDuration]);
147
+ var buttonRef = useRef(null);
148
+ useEffect(function () {
149
+ if (actions.length > 0 && buttonRef.current && isTriggeredUsingKeyboard) {
150
+ buttonRef.current.focus();
151
+ }
152
+ }, [isTriggeredUsingKeyboard, actions.length]);
145
153
  if (!actions || actions.length === 0) {
146
154
  return null;
147
155
  }
@@ -152,7 +160,8 @@ var Actions = function Actions(_ref) {
152
160
  }, regularActions.map(function (action, index) {
153
161
  var isKudos = action.id === GIVE_KUDOS_ACTION_ID;
154
162
  var button = /*#__PURE__*/React.createElement(FocusRing, {
155
- isInset: true
163
+ isInset: true,
164
+ key: "profile-card-action-focus-ring_".concat(action.id || index)
156
165
  }, /*#__PURE__*/React.createElement(Button, {
157
166
  appearance: "default",
158
167
  key: action.id || index,
@@ -162,10 +171,13 @@ var Actions = function Actions(_ref) {
162
171
  }
163
172
  return onActionClick(action, args, event, index);
164
173
  },
165
- href: action.link
174
+ href: action.link,
175
+ ref: index === 0 ? buttonRef : undefined
166
176
  }, action.label, isKudos && /*#__PURE__*/React.createElement(AnimationWrapper, null, /*#__PURE__*/React.createElement(KudosBlobAnimation, null))));
167
177
  if (isKudos) {
168
- return /*#__PURE__*/React.createElement(AnimatedKudosButton, null, button);
178
+ return /*#__PURE__*/React.createElement(AnimatedKudosButton, {
179
+ key: "profile-card-action-kudos_".concat(action.id || index)
180
+ }, button);
169
181
  }
170
182
  return button;
171
183
  }), overflowActions && /*#__PURE__*/React.createElement(OverflowProfileCardButtons, {
@@ -16,6 +16,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
16
16
  import React, { Suspense } from 'react';
17
17
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
18
18
  import { GiveKudosLauncherLazy, KudosType } from '@atlaskit/give-kudos';
19
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
19
20
  import Popup from '@atlaskit/popup';
20
21
  import { layers } from '@atlaskit/theme/constants';
21
22
  import _filterActions from '../../internal/filterActions';
@@ -23,6 +24,7 @@ import { CardWrapper } from '../../styled/Card';
23
24
  import { cardTriggered, fireEvent } from '../../util/analytics';
24
25
  import { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
25
26
  import { ProfileCardLazy } from './lazyProfileCard';
27
+ import ProfilecardTriggerNext from './ProfileCardTriggerNext';
26
28
  import UserLoadingState from './UserLoadingState';
27
29
  var ProfilecardTrigger = /*#__PURE__*/function (_React$PureComponent) {
28
30
  _inherits(ProfilecardTrigger, _React$PureComponent);
@@ -315,4 +317,7 @@ _defineProperty(ProfilecardTrigger, "defaultProps", {
315
317
  trigger: 'hover',
316
318
  position: 'bottom-start'
317
319
  });
318
- export default withAnalyticsEvents()(ProfilecardTrigger);
320
+ var ProfilecardTriggerLegacy = withAnalyticsEvents()(ProfilecardTrigger);
321
+ export default function ProfilecardTriggerSwitch(props) {
322
+ return getBooleanFF('platform.profile-card-trigger-next') ? /*#__PURE__*/React.createElement(ProfilecardTriggerNext, props) : /*#__PURE__*/React.createElement(ProfilecardTriggerLegacy, props);
323
+ }