@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,4 +1,7 @@
1
+ import { userRequestAnalytics } from '../util/analytics';
2
+ import { getPageTime } from '../util/performance';
1
3
  import CachingClient from './CachingClient';
4
+ import { getErrorAttributes } from './errorUtils';
2
5
  import { graphqlQuery } from './graphqlUtils';
3
6
  /**
4
7
  * Transform response from GraphQL
@@ -21,7 +24,6 @@ export const modifyResponse = response => {
21
24
  return {
22
25
  isBot: data.isBot,
23
26
  isCurrentUser: data.isCurrentUser,
24
- isNotMentionable: data.isNotMentionable,
25
27
  status: data.status,
26
28
  statusModifiedDate: data.statusModifiedDate || undefined,
27
29
  avatarUrl: data.avatarUrl || undefined,
@@ -83,7 +85,7 @@ export default class UserProfileCardClient extends CachingClient {
83
85
  return modifyResponse(response);
84
86
  }
85
87
 
86
- getProfile(cloudId, userId) {
88
+ getProfile(cloudId, userId, analytics) {
87
89
  if (!userId) {
88
90
  return Promise.reject(new Error('userId missing'));
89
91
  }
@@ -96,13 +98,32 @@ export default class UserProfileCardClient extends CachingClient {
96
98
  }
97
99
 
98
100
  return new Promise((resolve, reject) => {
101
+ const startTime = getPageTime();
102
+
103
+ if (analytics) {
104
+ analytics(userRequestAnalytics('triggered'));
105
+ }
106
+
99
107
  this.makeRequest(cloudId, userId).then(data => {
100
108
  if (this.cache) {
101
109
  this.setCachedProfile(cacheIdentifier, data);
102
110
  }
103
111
 
112
+ if (analytics) {
113
+ analytics(userRequestAnalytics('succeeded', {
114
+ duration: getPageTime() - startTime
115
+ }));
116
+ }
117
+
104
118
  resolve(data);
105
119
  }).catch(error => {
120
+ if (analytics) {
121
+ analytics(userRequestAnalytics('failed', {
122
+ duration: getPageTime() - startTime,
123
+ ...getErrorAttributes(error)
124
+ }));
125
+ }
126
+
106
127
  reject(error);
107
128
  });
108
129
  });
@@ -0,0 +1,17 @@
1
+ const IGNORED_ERRORS = ['NotPermitted', 'Gone'];
2
+
3
+ function isIgnoredError(error) {
4
+ return !!error && IGNORED_ERRORS.includes(error.reason);
5
+ }
6
+
7
+ export const getErrorAttributes = error => {
8
+ var _error$response, _error$response$heade;
9
+
10
+ const traceId = !!error ? (_error$response = error.response) === null || _error$response === void 0 ? void 0 : (_error$response$heade = _error$response.headers) === null || _error$response$heade === void 0 ? void 0 : _error$response$heade.get('atl-traceid') : undefined;
11
+ return {
12
+ errorStatus: error === null || error === void 0 ? void 0 : error.code,
13
+ errorReason: error === null || error === void 0 ? void 0 : error.reason,
14
+ isSLOFailure: !isIgnoredError(error),
15
+ traceId: traceId !== null && traceId !== void 0 ? traceId : undefined
16
+ };
17
+ };
@@ -1,47 +1,43 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import React from 'react';
3
- import AkButton from '@atlaskit/button/custom-theme-button';
1
+ import React, { useEffect } from 'react';
2
+ import Button from '@atlaskit/button/standard-button';
4
3
  import IconError from '@atlaskit/icon/glyph/cross-circle';
5
4
  import { ErrorText, ErrorTitle, ErrorWrapper } from '../../styled/Error';
6
- export default class ErrorMessage extends React.PureComponent {
7
- constructor(...args) {
8
- super(...args);
5
+ import { profileCardRendered } from '../../util/analytics';
9
6
 
10
- _defineProperty(this, "renderNotFound", () => /*#__PURE__*/React.createElement(ErrorTitle, null, "The user is no longer available for the site"));
11
-
12
- _defineProperty(this, "renderDefault", () => /*#__PURE__*/React.createElement(ErrorTitle, null, "Oops, looks like we\u2019re having issues", /*#__PURE__*/React.createElement("br", null), this.props.reload ? /*#__PURE__*/React.createElement(ErrorText, null, "Try again and we\u2019ll give it another shot") : null));
13
-
14
- _defineProperty(this, "renderRetryButton", () => this.props.reload ? /*#__PURE__*/React.createElement(AkButton, {
15
- appearance: "link",
16
- onClick: this.props.reload
17
- }, "Try again") : null);
18
- }
19
-
20
- renderErrorContent() {
21
- const errorType = this.props.errorType || {
22
- reason: 'default'
23
- };
24
-
25
- switch (errorType.reason) {
26
- case 'NotFound':
27
- return this.renderNotFound();
28
-
29
- default:
30
- return this.renderDefault();
7
+ const ErrorMessage = props => {
8
+ const errorType = props.errorType || {
9
+ reason: 'default'
10
+ };
11
+ const errorReason = errorType.reason;
12
+ const {
13
+ fireAnalytics,
14
+ reload
15
+ } = props;
16
+ const hasRetry = !!reload;
17
+ useEffect(() => {
18
+ fireAnalytics(profileCardRendered('user', 'error', {
19
+ hasRetry,
20
+ errorType: errorReason
21
+ }));
22
+ }, [errorReason, fireAnalytics, hasRetry]);
23
+
24
+ const errorContent = () => {
25
+ if (errorReason === 'NotFound') {
26
+ return /*#__PURE__*/React.createElement(ErrorTitle, null, "The user is no longer available for the site");
31
27
  }
32
- }
33
-
34
- render() {
35
- return /*#__PURE__*/React.createElement(ErrorWrapper, null, /*#__PURE__*/React.createElement(IconError, {
36
- label: "icon error",
37
- size: "xlarge"
38
- }), this.renderErrorContent(), this.renderRetryButton());
39
- }
40
28
 
41
- }
42
-
43
- _defineProperty(ErrorMessage, "defaultProps", {
44
- errorType: {
45
- reason: 'default'
46
- }
47
- });
29
+ return /*#__PURE__*/React.createElement(ErrorTitle, null, "Oops, looks like we\u2019re having issues", /*#__PURE__*/React.createElement("br", null), reload && /*#__PURE__*/React.createElement(ErrorText, null, "Try again and we\u2019ll give it another shot"));
30
+ };
31
+
32
+ return /*#__PURE__*/React.createElement(ErrorWrapper, {
33
+ "data-testid": "profilecard-error"
34
+ }, /*#__PURE__*/React.createElement(IconError, {
35
+ label: "icon error",
36
+ size: "xlarge"
37
+ }), errorContent(), reload && /*#__PURE__*/React.createElement(Button, {
38
+ appearance: "link",
39
+ onClick: reload
40
+ }, "Try again"));
41
+ };
42
+
43
+ export default ErrorMessage;
@@ -1,13 +1,13 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import Spinner from '@atlaskit/spinner';
3
3
  import { CardContent, CardHeader, CardWrapper, LoadingWrapper } from '../../styled/TeamCard';
4
- import { teamProfileCardRendered } from '../../util/analytics';
4
+ import { profileCardRendered } from '../../util/analytics';
5
5
  export default (props => {
6
6
  const {
7
7
  analytics
8
8
  } = props;
9
9
  useEffect(() => {
10
- analytics(duration => teamProfileCardRendered('spinner', {
10
+ analytics(duration => profileCardRendered('team', 'spinner', {
11
11
  duration
12
12
  }));
13
13
  }, [analytics]);
@@ -13,7 +13,7 @@ import messages from '../../messages';
13
13
  import { AnimatedKudosButton, KudosBlobAnimation } from '../../styled/Card';
14
14
  import { ErrorWrapper, TeamErrorText, TeamErrorTitle } from '../../styled/Error';
15
15
  import { ActionButtons, AvatarSection, CardContent, CardHeader, CardWrapper, Description, DescriptionWrapper, MemberCount, MoreButton, TeamName, WrappedButton } from '../../styled/TeamCard';
16
- import { errorRetryClicked, moreActionsClicked, moreMembersClicked, teamActionClicked, teamAvatarClicked, teamProfileCardRendered } from '../../util/analytics';
16
+ import { actionClicked, errorRetryClicked, moreActionsClicked, moreMembersClicked, profileCardRendered, teamAvatarClicked } from '../../util/analytics';
17
17
  import { isBasicClick } from '../../util/click';
18
18
  import { ErrorIllustration } from '../Error';
19
19
  import TeamLoadingState from './TeamLoadingState';
@@ -88,7 +88,7 @@ const TeamMembers = ({
88
88
 
89
89
  function onActionClick(action, analytics, index) {
90
90
  return (event, ...args) => {
91
- analytics(duration => teamActionClicked({
91
+ analytics(duration => actionClicked('team', {
92
92
  duration,
93
93
  hasHref: !!action.link,
94
94
  hasOnClick: !!action.callback,
@@ -132,7 +132,7 @@ const ExtraActions = ({
132
132
  const onMoreClick = useCallback(shouldBeOpen => {
133
133
  if (shouldBeOpen) {
134
134
  // Only fire this event when OPENING the dropdown
135
- analytics(duration => moreActionsClicked({
135
+ analytics(duration => moreActionsClicked('team', {
136
136
  duration,
137
137
  numActions: count + 2
138
138
  }));
@@ -209,7 +209,7 @@ const TeamProfilecardContent = ({
209
209
  analytics(duration => {
210
210
  var _team$members;
211
211
 
212
- return teamProfileCardRendered('content', {
212
+ return profileCardRendered('team', 'content', {
213
213
  duration,
214
214
  numActions: allActions.length,
215
215
  memberCount: (_team$members = team.members) === null || _team$members === void 0 ? void 0 : _team$members.length,
@@ -242,7 +242,7 @@ const ErrorMessage = ({
242
242
  }) => {
243
243
  const hasRetry = !!clientFetchProfile;
244
244
  useEffect(() => {
245
- analytics(duration => teamProfileCardRendered('error', {
245
+ analytics(duration => profileCardRendered('team', 'error', {
246
246
  duration,
247
247
  hasRetry
248
248
  }));
@@ -8,7 +8,7 @@ import Popup from '@atlaskit/popup';
8
8
  import { layers } from '@atlaskit/theme/constants';
9
9
  import filterActions from '../../internal/filterActions';
10
10
  import messages from '../../messages';
11
- import { fireEvent, teamCardTriggered, teamProfileCardRendered } from '../../util/analytics';
11
+ import { cardTriggered, fireEvent, profileCardRendered } from '../../util/analytics';
12
12
  import { isBasicClick } from '../../util/click';
13
13
  import { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
14
14
  import { getPageTime } from '../../util/performance';
@@ -89,7 +89,7 @@ export class TeamProfileCardTriggerInternal extends React.PureComponent {
89
89
  this.showProfilecard(0);
90
90
 
91
91
  if (!this.state.visible) {
92
- this.fireAnalytics(teamCardTriggered('click'));
92
+ this.fireAnalytics(cardTriggered('team', 'click'));
93
93
  }
94
94
  }
95
95
  });
@@ -101,7 +101,7 @@ export class TeamProfileCardTriggerInternal extends React.PureComponent {
101
101
 
102
102
  if (!this.state.visible) {
103
103
  this.openedByHover = true;
104
- this.fireAnalytics(teamCardTriggered('hover'));
104
+ this.fireAnalytics(cardTriggered('team', 'hover'));
105
105
  }
106
106
 
107
107
  this.showProfilecard(DELAY_MS_SHOW);
@@ -197,7 +197,7 @@ export class TeamProfileCardTriggerInternal extends React.PureComponent {
197
197
  });
198
198
 
199
199
  _defineProperty(this, "onErrorBoundary", () => {
200
- this.fireAnalytics(teamProfileCardRendered('errorBoundary', {
200
+ this.fireAnalytics(profileCardRendered('team', 'errorBoundary', {
201
201
  duration: 0
202
202
  }));
203
203
  this.setState({
@@ -1,14 +1,40 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React from 'react';
2
+ import React, { useCallback, useState } from 'react';
3
3
  import { useIntl } from 'react-intl-next';
4
4
  import Button from '@atlaskit/button/custom-theme-button';
5
5
  import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdown-menu';
6
6
  import MoreIcon from '@atlaskit/icon/glyph/more';
7
7
  import messages from '../../messages';
8
8
  import { OverflowActionButtonsWrapper } from '../../styled/Card';
9
+ import { moreActionsClicked } from '../../util/analytics';
10
+ export const ACTION_OVERFLOW_THRESHOLD = 2;
9
11
  export const OverflowProfileCardButtons = props => {
10
12
  const intl = useIntl();
11
- return /*#__PURE__*/React.createElement(OverflowActionButtonsWrapper, null, /*#__PURE__*/React.createElement(DropdownMenu, {
13
+ const [, setOpen] = useState(false);
14
+ const {
15
+ actions,
16
+ onItemClick,
17
+ fireAnalyticsWithDuration
18
+ } = props;
19
+ const numActions = actions.length + ACTION_OVERFLOW_THRESHOLD;
20
+ const onOpenChange = useCallback(({
21
+ isOpen: nextOpen
22
+ }) => {
23
+ setOpen(prevOpen => {
24
+ if (nextOpen && !prevOpen) {
25
+ fireAnalyticsWithDuration(duration => moreActionsClicked('user', {
26
+ duration,
27
+ numActions
28
+ }));
29
+ }
30
+
31
+ return nextOpen;
32
+ });
33
+ }, [numActions, fireAnalyticsWithDuration]);
34
+ return /*#__PURE__*/React.createElement(OverflowActionButtonsWrapper, {
35
+ "data-testid": "profilecard-actions-overflow"
36
+ }, /*#__PURE__*/React.createElement(DropdownMenu, {
37
+ onOpenChange: onOpenChange,
12
38
  placement: 'bottom-end',
13
39
  trigger: ({
14
40
  triggerRef,
@@ -23,10 +49,10 @@ export const OverflowProfileCardButtons = props => {
23
49
  label: intl.formatMessage(messages.profileCardMoreIconLabel)
24
50
  })
25
51
  }))
26
- }, /*#__PURE__*/React.createElement(DropdownItemGroup, null, props.actions.map(action => /*#__PURE__*/React.createElement(DropdownItem, {
52
+ }, /*#__PURE__*/React.createElement(DropdownItemGroup, null, actions.map((action, index) => /*#__PURE__*/React.createElement(DropdownItem, {
27
53
  key: action.id,
28
54
  onClick: (event, ...args) => {
29
- props.onItemClick(action, args, event);
55
+ onItemClick(action, args, event, index);
30
56
  },
31
57
  href: action.link
32
58
  }, action.label)))));