@atlaskit/profilecard 16.11.0 → 17.0.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 (74) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/client/ProfileCardClient.js +2 -2
  3. package/dist/cjs/client/TeamProfileCardClient.js +13 -12
  4. package/dist/cjs/client/UserProfileCardClient.js +25 -2
  5. package/dist/cjs/client/errorUtils.js +25 -0
  6. package/dist/cjs/components/Error/ErrorMessage.js +40 -77
  7. package/dist/cjs/components/Team/TeamLoadingState.js +1 -1
  8. package/dist/cjs/components/Team/TeamProfileCard.js +4 -4
  9. package/dist/cjs/components/Team/TeamProfileCardTrigger.js +3 -3
  10. package/dist/cjs/components/User/OverflowProfileCardButtons.js +44 -10
  11. package/dist/cjs/components/User/ProfileCard.js +195 -362
  12. package/dist/cjs/components/User/ProfileCardDetails.js +142 -0
  13. package/dist/cjs/components/User/ProfileCardResourced.js +25 -20
  14. package/dist/cjs/components/User/ProfileCardTrigger.js +35 -7
  15. package/dist/cjs/components/User/ReportingLinesDetails.js +13 -13
  16. package/dist/cjs/components/User/UserLoadingState.js +14 -2
  17. package/dist/cjs/util/analytics.js +31 -16
  18. package/dist/cjs/version.json +1 -1
  19. package/dist/es2019/client/ProfileCardClient.js +2 -2
  20. package/dist/es2019/client/TeamProfileCardClient.js +3 -9
  21. package/dist/es2019/client/UserProfileCardClient.js +23 -2
  22. package/dist/es2019/client/errorUtils.js +17 -0
  23. package/dist/es2019/components/Error/ErrorMessage.js +38 -42
  24. package/dist/es2019/components/Team/TeamLoadingState.js +2 -2
  25. package/dist/es2019/components/Team/TeamProfileCard.js +5 -5
  26. package/dist/es2019/components/Team/TeamProfileCardTrigger.js +4 -4
  27. package/dist/es2019/components/User/OverflowProfileCardButtons.js +30 -4
  28. package/dist/es2019/components/User/ProfileCard.js +161 -292
  29. package/dist/es2019/components/User/ProfileCardDetails.js +118 -0
  30. package/dist/es2019/components/User/ProfileCardResourced.js +21 -21
  31. package/dist/es2019/components/User/ProfileCardTrigger.js +32 -6
  32. package/dist/es2019/components/User/ReportingLinesDetails.js +10 -11
  33. package/dist/es2019/components/User/UserLoadingState.js +10 -2
  34. package/dist/es2019/util/analytics.js +13 -8
  35. package/dist/es2019/version.json +1 -1
  36. package/dist/esm/client/ProfileCardClient.js +2 -2
  37. package/dist/esm/client/TeamProfileCardClient.js +11 -12
  38. package/dist/esm/client/UserProfileCardClient.js +22 -2
  39. package/dist/esm/client/errorUtils.js +17 -0
  40. package/dist/esm/components/Error/ErrorMessage.js +35 -80
  41. package/dist/esm/components/Team/TeamLoadingState.js +2 -2
  42. package/dist/esm/components/Team/TeamProfileCard.js +5 -5
  43. package/dist/esm/components/Team/TeamProfileCardTrigger.js +4 -4
  44. package/dist/esm/components/User/OverflowProfileCardButtons.js +39 -9
  45. package/dist/esm/components/User/ProfileCard.js +180 -362
  46. package/dist/esm/components/User/ProfileCardDetails.js +120 -0
  47. package/dist/esm/components/User/ProfileCardResourced.js +17 -17
  48. package/dist/esm/components/User/ProfileCardTrigger.js +33 -7
  49. package/dist/esm/components/User/ReportingLinesDetails.js +12 -12
  50. package/dist/esm/components/User/UserLoadingState.js +7 -2
  51. package/dist/esm/util/analytics.js +21 -12
  52. package/dist/esm/version.json +1 -1
  53. package/dist/types/client/ProfileCardClient.d.ts +3 -2
  54. package/dist/types/client/TeamProfileCardClient.d.ts +2 -1
  55. package/dist/types/client/UserProfileCardClient.d.ts +2 -1
  56. package/dist/types/client/errorUtils.d.ts +6 -0
  57. package/dist/types/components/Error/ErrorMessage.d.ts +6 -15
  58. package/dist/types/components/Team/TeamProfileCardTrigger.d.ts +5 -11
  59. package/dist/types/components/User/OverflowProfileCardButtons.d.ts +4 -3
  60. package/dist/types/components/User/ProfileCard.d.ts +5 -29
  61. package/dist/types/components/User/ProfileCardDetails.d.ts +3 -0
  62. package/dist/types/components/User/ProfileCardResourced.d.ts +7 -3
  63. package/dist/types/components/User/ProfileCardTrigger.d.ts +3 -40
  64. package/dist/types/components/User/ReportingLinesDetails.d.ts +2 -4
  65. package/dist/types/components/User/UserLoadingState.d.ts +5 -1
  66. package/dist/types/components/User/lazyProfileCard.d.ts +1 -1
  67. package/dist/types/types.d.ts +11 -10
  68. package/dist/types/util/analytics.d.ts +22 -13
  69. package/package.json +9 -9
  70. package/report.api.md +71 -124
  71. package/dist/cjs/internal/analytics.js +0 -15
  72. package/dist/es2019/internal/analytics.js +0 -8
  73. package/dist/esm/internal/analytics.js +0 -8
  74. package/dist/types/internal/analytics.d.ts +0 -8
@@ -1,325 +1,194 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import React from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
3
  import { FormattedMessage } from 'react-intl-next';
4
+ import { withAnalyticsEvents } from '@atlaskit/analytics-next';
5
5
  import Avatar from '@atlaskit/avatar';
6
6
  import Button from '@atlaskit/button/custom-theme-button';
7
- import Lozenge from '@atlaskit/lozenge';
8
7
  import Spinner from '@atlaskit/spinner';
9
8
  import { N0 } from '@atlaskit/theme/colors';
10
9
  import { token } from '@atlaskit/tokens';
11
- import { AnalyticsName } from '../../internal/analytics';
12
- import relativeDate from '../../internal/relative-date';
13
10
  import messages from '../../messages';
14
- import { ActionButtonGroup, ActionsFlexSpacer, AnimatedKudosButton, AppTitleLabel, CardContainer, CardContent, CardWrapper, CustomLozengeContainer, DetailsGroup, DisabledInfo, FullNameLabel, JobTitleLabel, KudosBlobAnimation, LozengeWrapper, ProfileImage, SpinnerContainer } from '../../styled/Card';
11
+ import { ActionButtonGroup, ActionsFlexSpacer, AnimatedKudosButton, CardContainer, CardContent, CardWrapper, KudosBlobAnimation, ProfileImage, SpinnerContainer } from '../../styled/Card';
12
+ import { actionClicked, fireEvent, profileCardRendered } from '../../util/analytics';
15
13
  import { isBasicClick } from '../../util/click';
14
+ import { getPageTime } from '../../util/performance';
16
15
  import { ErrorMessage } from '../Error';
17
- import { IconLabel } from '../Icon';
18
- import { OverflowProfileCardButtons } from './OverflowProfileCardButtons';
19
- import ReportingLinesDetails from './ReportingLinesDetails';
20
- export default class Profilecard extends React.PureComponent {
21
- constructor(props) {
22
- super(props);
23
-
24
- _defineProperty(this, "GIVE_KUDOS_ACTION_ID", 'give-kudos');
25
-
26
- _defineProperty(this, "durationSince", from => {
27
- const fromParsed = from || 0;
28
- return fromParsed > 0 ? Date.now() - fromParsed : null;
29
- });
30
-
31
- _defineProperty(this, "callClientFetchProfile", (...args) => {
32
- if (this.props.clientFetchProfile) {
33
- this.props.clientFetchProfile(...args);
34
- }
35
- });
36
-
37
- _defineProperty(this, "callAnalytics", (id, options) => {
38
- if (this.props.analytics) {
39
- this.props.analytics(id, options);
40
- }
41
- });
42
-
43
- _defineProperty(this, "kudosUrl", () => {
44
- const recipientId = this.props.userId && `&recipientId=${this.props.userId}` || '';
45
- const cloudId = this.props.cloudId && `&cloudId=${this.props.cloudId}` || '';
46
- return `${this.props.teamCentralBaseUrl}/kudos/give?type=individual${recipientId}${cloudId}`;
47
- });
48
-
49
- _defineProperty(this, "kudosButtonCallback", () => {
50
- if (this.props.openKudosDrawer) {
51
- this.props.openKudosDrawer();
52
- } else {
53
- window.open(this.kudosUrl());
54
- }
55
- });
56
-
57
- _defineProperty(this, "renderButton", (action, idx) => {
58
- const isGiveKudosActionButton = action.id === this.GIVE_KUDOS_ACTION_ID;
59
- const actionButton = /*#__PURE__*/React.createElement(Button, {
60
- appearance: "default",
61
- key: action.id || idx,
62
- onClick: (event, ...args) => this.onActionClick(action, args, event),
63
- href: action.link
64
- }, action.label, isGiveKudosActionButton && /*#__PURE__*/React.createElement(KudosBlobAnimation, null));
65
-
66
- if (isGiveKudosActionButton) {
67
- return /*#__PURE__*/React.createElement(AnimatedKudosButton, null, actionButton);
68
- }
69
-
70
- return actionButton;
71
- });
72
-
73
- this.timeOpen = null;
74
-
75
- this.clientFetchProfile = (...args) => {
76
- this.callAnalytics(AnalyticsName.PROFILE_CARD_RELOAD, {});
77
- this.callClientFetchProfile(...args);
16
+ import { ACTION_OVERFLOW_THRESHOLD, OverflowProfileCardButtons } from './OverflowProfileCardButtons';
17
+ import { ProfileCardDetails } from './ProfileCardDetails';
18
+ const GIVE_KUDOS_ACTION_ID = 'give-kudos';
19
+
20
+ const useKudos = (cloudId, userId, teamCentralBaseUrl, openKudosDrawer) => {
21
+ const kudosUrl = useMemo(() => {
22
+ const recipientId = userId ? `&recipientId=${userId}` : '';
23
+ const cloudIdParam = cloudId ? `&cloudId=${cloudId}` : '';
24
+ return `${teamCentralBaseUrl || ''}/kudos/give?type=individual${recipientId}${cloudIdParam}`;
25
+ }, [cloudId, teamCentralBaseUrl, userId]);
26
+ const kudosButtonCallback = useCallback(() => {
27
+ if (openKudosDrawer) {
28
+ openKudosDrawer();
29
+ } else {
30
+ window.open(kudosUrl);
31
+ }
32
+ }, [kudosUrl, openKudosDrawer]);
33
+ const kudosAction = useMemo(() => {
34
+ return {
35
+ label: /*#__PURE__*/React.createElement(FormattedMessage, messages.giveKudosButton),
36
+ id: GIVE_KUDOS_ACTION_ID,
37
+ callback: kudosButtonCallback,
38
+ link: kudosUrl
78
39
  };
79
- }
80
-
81
- componentDidMount() {
82
- this.timeOpen = Date.now();
83
- this.callAnalytics(AnalyticsName.PROFILE_CARD_VIEW, {});
84
- }
85
-
86
- renderErrorMessage() {
87
- return /*#__PURE__*/React.createElement(ErrorMessage, {
88
- reload: this.props.clientFetchProfile && this.clientFetchProfile,
89
- errorType: this.props.errorType
90
- });
91
- }
92
-
93
- getActions() {
94
- const actions = this.props.actions || [];
95
-
96
- if (!this.props.isCurrentUser && this.props.isKudosEnabled) {
97
- const kudosAction = {
98
- label: /*#__PURE__*/React.createElement(FormattedMessage, messages.giveKudosButton),
99
- id: this.GIVE_KUDOS_ACTION_ID,
100
- callback: () => {
101
- this.kudosButtonCallback();
102
- },
103
- link: this.kudosUrl()
104
- };
105
- return actions.concat([kudosAction]);
40
+ }, [kudosButtonCallback, kudosUrl]);
41
+ return {
42
+ kudosAction,
43
+ kudosButtonCallback,
44
+ kudosUrl
45
+ };
46
+ };
47
+
48
+ const Wrapper = props => /*#__PURE__*/React.createElement(CardWrapper, {
49
+ "data-testid": "profilecard"
50
+ }, props.children);
51
+
52
+ export const ProfilecardInternal = props => {
53
+ const [openTime] = useState(getPageTime());
54
+ const {
55
+ createAnalyticsEvent
56
+ } = props;
57
+ const fireAnalytics = useCallback(payload => {
58
+ if (createAnalyticsEvent) {
59
+ fireEvent(createAnalyticsEvent, payload);
106
60
  }
107
-
108
- return actions;
109
- }
110
-
111
- renderActionsButtons() {
112
- if (this.props.actions && this.props.actions.length === 0) {
113
- return null;
61
+ }, [createAnalyticsEvent]);
62
+ const fireAnalyticsWithDuration = useCallback(generator => {
63
+ const elapsed = getPageTime() - openTime;
64
+ const event = generator(elapsed);
65
+ fireAnalytics(event);
66
+ }, [fireAnalytics, openTime]);
67
+ const {
68
+ kudosAction
69
+ } = useKudos(props.cloudId, props.userId, props.teamCentralBaseUrl, props.openKudosDrawer);
70
+ const {
71
+ actions = [],
72
+ isCurrentUser,
73
+ isKudosEnabled,
74
+ status = 'active'
75
+ } = props;
76
+ const realActions = useMemo(() => {
77
+ if (isCurrentUser || !isKudosEnabled || status !== 'active') {
78
+ return actions;
114
79
  }
115
80
 
116
- const actions = this.getActions();
117
- const firstTwoActions = actions.slice(0, 2);
118
- const restOfActions = actions && actions.length > 2 ? actions.slice(2) : undefined;
119
- return /*#__PURE__*/React.createElement(ActionButtonGroup, null, firstTwoActions.map((action, idx) => this.renderButton(action, idx)), restOfActions && /*#__PURE__*/React.createElement(OverflowProfileCardButtons, {
120
- actions: restOfActions,
121
- onItemClick: (action, args, event) => this.onActionClick(action, args, event)
122
- }));
123
- }
124
-
125
- onActionClick(action, args, event) {
126
- this.callAnalytics(AnalyticsName.PROFILE_CARD_CLICK, {
127
- id: action.id || null,
128
- duration: this.durationSince(this.timeOpen)
129
- });
130
-
131
- if (action.callback && isBasicClick(event)) {
132
- event.preventDefault();
133
- action.callback(event, ...args);
81
+ return actions.concat([kudosAction]);
82
+ }, [actions, isCurrentUser, isKudosEnabled, kudosAction, status]);
83
+ const {
84
+ isLoading,
85
+ fullName,
86
+ hasError
87
+ } = props;
88
+ const canRender = !hasError && !isLoading && !!(fullName || status === 'closed');
89
+ useEffect(() => {
90
+ if (canRender) {
91
+ fireAnalyticsWithDuration(duration => profileCardRendered('user', 'content', {
92
+ duration,
93
+ numActions: realActions.length
94
+ }));
134
95
  }
135
- }
96
+ }, [canRender, fireAnalyticsWithDuration, realActions]);
136
97
 
137
- renderCardDetailsDefault() {
138
- const {
139
- meta,
140
- location,
141
- email,
142
- timestring,
143
- companyName,
144
- customLozenges
145
- } = this.props;
146
- return /*#__PURE__*/React.createElement(DetailsGroup, null, this.renderFullNameAndPublicName(meta), meta && /*#__PURE__*/React.createElement(JobTitleLabel, null, meta), customLozenges && this.renderCustomLozenges(customLozenges), /*#__PURE__*/React.createElement(IconLabel, {
147
- icon: "email"
148
- }, email), /*#__PURE__*/React.createElement(IconLabel, {
149
- icon: "time"
150
- }, timestring), /*#__PURE__*/React.createElement(IconLabel, {
151
- icon: "companyName"
152
- }, companyName), /*#__PURE__*/React.createElement(IconLabel, {
153
- icon: "location"
154
- }, location), /*#__PURE__*/React.createElement(ReportingLinesDetails, {
155
- reportingLines: this.props.reportingLines,
156
- reportingLinesProfileUrl: this.props.reportingLinesProfileUrl,
157
- onReportingLinesClick: this.props.onReportingLinesClick,
158
- analytics: this.props.analytics,
159
- getDuration: () => this.durationSince(this.timeOpen)
98
+ if (hasError) {
99
+ return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(ErrorMessage, {
100
+ reload: props.clientFetchProfile,
101
+ errorType: props.errorType || null,
102
+ fireAnalytics: fireAnalytics
160
103
  }));
161
104
  }
162
105
 
163
- renderCardDetailsForDisabledAccount() {
164
- const {
165
- status,
166
- companyName,
167
- hasDisabledAccountLozenge
168
- } = this.props;
169
- return /*#__PURE__*/React.createElement(DetailsGroup, null, /*#__PURE__*/React.createElement(FullNameLabel, {
170
- noMeta: true,
171
- isDisabledAccount: true
172
- }, this.getDisabledAccountName()), hasDisabledAccountLozenge && /*#__PURE__*/React.createElement(LozengeWrapper, null, /*#__PURE__*/React.createElement(Lozenge, {
173
- appearance: "default",
174
- isBold: true
175
- }, status === 'inactive' && /*#__PURE__*/React.createElement(FormattedMessage, messages.inactiveAccountMsg), status === 'closed' && /*#__PURE__*/React.createElement(FormattedMessage, messages.closedAccountMsg))), /*#__PURE__*/React.createElement(DisabledInfo, null, this.getDisabledAccountDesc()), status === 'inactive' && /*#__PURE__*/React.createElement(IconLabel, {
176
- icon: "companyName"
177
- }, companyName));
106
+ if (isLoading) {
107
+ return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(LoadingView, {
108
+ fireAnalyticsWithDuration: fireAnalyticsWithDuration
109
+ }));
178
110
  }
179
111
 
180
- getDisabledAccountName() {
181
- const {
182
- nickname,
183
- fullName,
184
- status
185
- } = this.props;
186
-
187
- if (status === 'inactive') {
188
- return fullName || nickname;
189
- } else if (status === 'closed') {
190
- return nickname || /*#__PURE__*/React.createElement(FormattedMessage, messages.disabledAccountDefaultName);
191
- }
192
-
112
+ if (!canRender) {
193
113
  return null;
194
114
  }
195
115
 
196
- getDisabledAccountDesc() {
197
- const {
198
- status = 'closed',
199
- statusModifiedDate,
200
- disabledAccountMessage
201
- } = this.props;
202
- const date = statusModifiedDate ? new Date(statusModifiedDate * 1000) : null;
203
- const relativeDateKey = relativeDate(date); // consumer does not want to use built-in message
204
-
205
- if (disabledAccountMessage) {
206
- return disabledAccountMessage;
207
- }
208
-
209
- let secondSentence = null;
210
-
211
- if (relativeDateKey) {
212
- secondSentence = /*#__PURE__*/React.createElement(FormattedMessage // @ts-ignore
213
- , messages[`${status}AccountDescMsgHasDate${relativeDateKey}`]);
214
- } else {
215
- secondSentence =
216
- /*#__PURE__*/
217
- // @ts-ignore
218
- React.createElement(FormattedMessage, messages[`${status}AccountDescMsgNoDate`]);
219
- }
220
-
221
- return /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.generalDescMsgForDisabledUser), ' ', secondSentence);
222
- }
223
-
224
- renderFullNameAndPublicName(meta) {
225
- const {
226
- nickname,
227
- fullName
228
- } = this.props;
229
-
230
- if (!fullName && !nickname) {
231
- return null;
232
- }
233
-
234
- const displayName = fullName === nickname ? fullName : `${fullName}${nickname ? ` (${nickname}) ` : ''}`;
235
- return /*#__PURE__*/React.createElement(FullNameLabel, {
236
- noMeta: !meta
237
- }, displayName);
238
- } // Pass lozenges as an array rather taking it from the props. This will allow us combine the
239
- // other lozenges (like the "deactivated" lozenge) if we need to.
240
-
241
-
242
- renderCustomLozenges(lozenges) {
243
- return lozenges.length > 0 ? /*#__PURE__*/React.createElement(CustomLozengeContainer, null, lozenges.map(({
244
- text,
245
- ...otherProps
246
- }, index) => /*#__PURE__*/React.createElement(Lozenge, _extends({}, otherProps, {
247
- key: index
248
- }), text))) : null;
249
- }
250
-
251
- renderCardDetailsApp() {
252
- return /*#__PURE__*/React.createElement(DetailsGroup, null, this.renderFullNameAndPublicName(), /*#__PURE__*/React.createElement(AppTitleLabel, null, "App"));
253
- }
254
-
255
- renderCardDetails() {
256
- const {
257
- isBot,
258
- status
259
- } = this.props;
260
-
261
- if (isBot) {
262
- return this.renderCardDetailsApp();
263
- }
116
+ const isDisabledUser = status === 'inactive' || status === 'closed';
117
+ return /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(CardContainer, {
118
+ isDisabledUser: isDisabledUser,
119
+ withoutElevation: props.withoutElevation
120
+ }, /*#__PURE__*/React.createElement(ProfileImage, null, /*#__PURE__*/React.createElement(Avatar, {
121
+ size: "xlarge",
122
+ src: status !== 'closed' ? props.avatarUrl : undefined,
123
+ borderColor: token('elevation.shadow.overlay', N0)
124
+ })), /*#__PURE__*/React.createElement(CardContent, null, /*#__PURE__*/React.createElement(ProfileCardDetails, _extends({}, props, {
125
+ status: status,
126
+ fireAnalyticsWithDuration: fireAnalyticsWithDuration
127
+ })), realActions && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionsFlexSpacer, null), /*#__PURE__*/React.createElement(Actions, {
128
+ actions: realActions,
129
+ fireAnalyticsWithDuration: fireAnalyticsWithDuration
130
+ })))));
131
+ };
132
+
133
+ const Actions = ({
134
+ actions,
135
+ fireAnalyticsWithDuration
136
+ }) => {
137
+ const onActionClick = useCallback((action, args, event, index) => {
138
+ fireAnalyticsWithDuration(duration => actionClicked('user', {
139
+ duration,
140
+ hasHref: !!action.link,
141
+ hasOnClick: !!action.callback,
142
+ index,
143
+ actionId: action.id || 'no-id-specified'
144
+ }));
264
145
 
265
- if (status === 'inactive' || status === 'closed') {
266
- return this.renderCardDetailsForDisabledAccount();
146
+ if (action.callback && isBasicClick(event)) {
147
+ event.preventDefault();
148
+ action.callback(event, ...args);
267
149
  }
150
+ }, [fireAnalyticsWithDuration]);
268
151
 
269
- return this.renderCardDetailsDefault();
152
+ if (!actions || actions.length === 0) {
153
+ return null;
270
154
  }
271
155
 
272
- render() {
273
- const {
274
- fullName,
275
- status,
276
- withoutElevation,
277
- reportingLines
278
- } = this.props;
279
- let cardContent = null; // @FIXME do closed users have empty fullName field?
280
-
281
- const canRender = fullName || status === 'closed';
282
-
283
- if (this.props.hasError) {
284
- this.callAnalytics(AnalyticsName.PROFILE_CARD_ERROR, {});
285
- cardContent = this.renderErrorMessage();
286
- } else if (this.props.isLoading) {
287
- cardContent = /*#__PURE__*/React.createElement(SpinnerContainer, null, /*#__PURE__*/React.createElement(Spinner, null));
288
- } else if (canRender) {
289
- var _reportingLines$manag, _reportingLines$repor;
156
+ const regularActions = actions.slice(0, ACTION_OVERFLOW_THRESHOLD);
157
+ const overflowActions = actions.length > ACTION_OVERFLOW_THRESHOLD ? actions.slice(ACTION_OVERFLOW_THRESHOLD) : undefined;
158
+ return /*#__PURE__*/React.createElement(ActionButtonGroup, {
159
+ "data-testid": "profilecard-actions"
160
+ }, regularActions.map((action, index) => {
161
+ const isKudos = action.id === GIVE_KUDOS_ACTION_ID;
162
+ const button = /*#__PURE__*/React.createElement(Button, {
163
+ appearance: "default",
164
+ key: action.id || index,
165
+ onClick: (event, ...args) => onActionClick(action, args, event, index),
166
+ href: action.link
167
+ }, action.label, isKudos && /*#__PURE__*/React.createElement(KudosBlobAnimation, null));
290
168
 
291
- const isDisabledUser = status === 'inactive' || status === 'closed';
292
- const actions = this.renderActionsButtons();
293
- this.callAnalytics(AnalyticsName.PROFILE_CARD_LOADED, {
294
- duration: this.durationSince(this.timeOpen),
295
- managersCount: (reportingLines === null || reportingLines === void 0 ? void 0 : (_reportingLines$manag = reportingLines.managers) === null || _reportingLines$manag === void 0 ? void 0 : _reportingLines$manag.length) || 0,
296
- directReportsCount: (reportingLines === null || reportingLines === void 0 ? void 0 : (_reportingLines$repor = reportingLines.reports) === null || _reportingLines$repor === void 0 ? void 0 : _reportingLines$repor.length) || 0
297
- });
298
- cardContent = /*#__PURE__*/React.createElement(CardContainer, {
299
- isDisabledUser: isDisabledUser,
300
- withoutElevation: withoutElevation
301
- }, /*#__PURE__*/React.createElement(ProfileImage, null, /*#__PURE__*/React.createElement(Avatar, {
302
- size: "xlarge",
303
- src: this.props.status !== 'closed' ? this.props.avatarUrl : undefined,
304
- borderColor: token('elevation.surface.overlay', N0)
305
- })), /*#__PURE__*/React.createElement(CardContent, null, this.renderCardDetails(), actions ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionsFlexSpacer, null), actions) : null));
169
+ if (isKudos) {
170
+ return /*#__PURE__*/React.createElement(AnimatedKudosButton, null, button);
306
171
  }
307
172
 
308
- return /*#__PURE__*/React.createElement(CardWrapper, null, cardContent);
309
- }
310
-
311
- }
173
+ return button;
174
+ }), overflowActions && /*#__PURE__*/React.createElement(OverflowProfileCardButtons, {
175
+ actions: overflowActions,
176
+ fireAnalyticsWithDuration: fireAnalyticsWithDuration,
177
+ onItemClick: (action, args, event, index) => onActionClick(action, args, event, index + ACTION_OVERFLOW_THRESHOLD)
178
+ }));
179
+ };
180
+
181
+ const LoadingView = ({
182
+ fireAnalyticsWithDuration
183
+ }) => {
184
+ useEffect(() => {
185
+ fireAnalyticsWithDuration(duration => profileCardRendered('user', 'spinner', {
186
+ duration
187
+ }));
188
+ }, [fireAnalyticsWithDuration]);
189
+ return /*#__PURE__*/React.createElement(SpinnerContainer, {
190
+ "data-testid": "profilecard-spinner-container"
191
+ }, /*#__PURE__*/React.createElement(Spinner, null));
192
+ };
312
193
 
313
- _defineProperty(Profilecard, "defaultProps", {
314
- isLoading: false,
315
- hasError: false,
316
- errorType: null,
317
- status: 'active',
318
- isBot: false,
319
- isNotMentionable: false,
320
- actions: [],
321
- hasDisabledAccountLozenge: true,
322
- customLozenges: [],
323
- analytics: () => null,
324
- clientFetchProfile: () => null
325
- });
194
+ export default withAnalyticsEvents()(ProfilecardInternal);
@@ -0,0 +1,118 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import { FormattedMessage } from 'react-intl-next';
4
+ import Lozenge from '@atlaskit/lozenge';
5
+ import relativeDate from '../../internal/relative-date';
6
+ import messages from '../../messages';
7
+ import { AppTitleLabel, CustomLozengeContainer, DetailsGroup, DisabledInfo, FullNameLabel, JobTitleLabel, LozengeWrapper } from '../../styled/Card';
8
+ import { IconLabel } from '../Icon';
9
+ import ReportingLinesDetails from './ReportingLinesDetails';
10
+
11
+ const renderName = (nickname, fullName, meta) => {
12
+ if (!fullName && !nickname) {
13
+ return null;
14
+ }
15
+
16
+ const isNicknameRedundant = !nickname || nickname === fullName;
17
+ const shownNickname = ` (${nickname}) `;
18
+ const displayName = isNicknameRedundant ? fullName : `${fullName}${shownNickname}`;
19
+ return /*#__PURE__*/React.createElement(FullNameLabel, {
20
+ noMeta: !meta,
21
+ "data-testid": "profilecard-name"
22
+ }, displayName);
23
+ };
24
+
25
+ const disabledAccountDesc = (statusModifiedDate, disabledAccountMessage, status = 'closed') => {
26
+ // consumer does not want to use built-in message
27
+ if (disabledAccountMessage) {
28
+ return disabledAccountMessage;
29
+ }
30
+
31
+ const date = statusModifiedDate ? new Date(statusModifiedDate * 1000) : null;
32
+ const relativeDateKey = relativeDate(date);
33
+ const msgKey = relativeDateKey ? `${status}AccountDescMsgHasDate${relativeDateKey}` : `${status}AccountDescMsgNoDate`;
34
+ const secondSentence = /*#__PURE__*/React.createElement(FormattedMessage, messages[msgKey]);
35
+ return /*#__PURE__*/React.createElement("p", {
36
+ "data-testid": "profilecard-disabled-account"
37
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.generalDescMsgForDisabledUser), ' ', secondSentence);
38
+ };
39
+
40
+ const CustomLozenges = ({
41
+ lozenges = []
42
+ }) => {
43
+ if (lozenges.length === 0) {
44
+ return null;
45
+ }
46
+
47
+ return /*#__PURE__*/React.createElement(CustomLozengeContainer, null, lozenges.map(({
48
+ text,
49
+ ...otherProps
50
+ }, index) => /*#__PURE__*/React.createElement(Lozenge, _extends({}, otherProps, {
51
+ key: index
52
+ }), text)));
53
+ };
54
+
55
+ const BotProfileCardDetails = props => {
56
+ const {
57
+ fullName,
58
+ nickname
59
+ } = props;
60
+ return /*#__PURE__*/React.createElement(DetailsGroup, null, renderName(nickname, fullName), /*#__PURE__*/React.createElement(AppTitleLabel, null, "App"));
61
+ };
62
+
63
+ const DisabledProfileCardDetails = props => {
64
+ const {
65
+ companyName,
66
+ disabledAccountMessage,
67
+ fullName,
68
+ hasDisabledAccountLozenge = true,
69
+ nickname,
70
+ status,
71
+ statusModifiedDate
72
+ } = props;
73
+ const name = status === 'inactive' ? fullName || nickname : nickname || /*#__PURE__*/React.createElement(FormattedMessage, messages.disabledAccountDefaultName);
74
+ return /*#__PURE__*/React.createElement(DetailsGroup, null, /*#__PURE__*/React.createElement(FullNameLabel, {
75
+ noMeta: true,
76
+ isDisabledAccount: true,
77
+ "data-testid": "profilecard-name"
78
+ }, name), hasDisabledAccountLozenge && /*#__PURE__*/React.createElement(LozengeWrapper, null, /*#__PURE__*/React.createElement(Lozenge, {
79
+ appearance: "default",
80
+ isBold: true
81
+ }, status === 'inactive' ? /*#__PURE__*/React.createElement(FormattedMessage, messages.inactiveAccountMsg) : /*#__PURE__*/React.createElement(FormattedMessage, messages.closedAccountMsg))), /*#__PURE__*/React.createElement(DisabledInfo, null, disabledAccountDesc(statusModifiedDate, disabledAccountMessage, status)), status === 'inactive' && /*#__PURE__*/React.createElement(IconLabel, {
82
+ icon: "companyName"
83
+ }, companyName));
84
+ };
85
+
86
+ export const ProfileCardDetails = props => {
87
+ const {
88
+ meta,
89
+ status
90
+ } = props;
91
+
92
+ if (props.isBot) {
93
+ return /*#__PURE__*/React.createElement(BotProfileCardDetails, props);
94
+ }
95
+
96
+ if (status === 'inactive' || status === 'closed') {
97
+ return /*#__PURE__*/React.createElement(DisabledProfileCardDetails, _extends({}, props, {
98
+ status: status
99
+ }));
100
+ }
101
+
102
+ return /*#__PURE__*/React.createElement(DetailsGroup, null, renderName(props.nickname, props.fullName, meta), meta && /*#__PURE__*/React.createElement(JobTitleLabel, null, meta), /*#__PURE__*/React.createElement(CustomLozenges, {
103
+ lozenges: props.customLozenges
104
+ }), /*#__PURE__*/React.createElement(IconLabel, {
105
+ icon: "email"
106
+ }, props.email), /*#__PURE__*/React.createElement(IconLabel, {
107
+ icon: "time"
108
+ }, props.timestring), /*#__PURE__*/React.createElement(IconLabel, {
109
+ icon: "companyName"
110
+ }, props.companyName), /*#__PURE__*/React.createElement(IconLabel, {
111
+ icon: "location"
112
+ }, props.location), /*#__PURE__*/React.createElement(ReportingLinesDetails, {
113
+ reportingLines: props.reportingLines,
114
+ reportingLinesProfileUrl: props.reportingLinesProfileUrl,
115
+ onReportingLinesClick: props.onReportingLinesClick,
116
+ fireAnalyticsWithDuration: props.fireAnalyticsWithDuration
117
+ }));
118
+ };