@atlaskit/profilecard 16.0.1 → 16.2.1

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 (69) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/client/CachingClient.js +2 -2
  3. package/dist/cjs/client/ProfileCardClient.js +33 -0
  4. package/dist/cjs/client/TeamCentralCardClient.js +162 -0
  5. package/dist/cjs/client/UserProfileCardClient.js +2 -2
  6. package/dist/cjs/components/Team/TeamProfileCard.js +2 -2
  7. package/dist/cjs/components/Team/lazyTeamProfileCard.js +3 -5
  8. package/dist/cjs/components/User/ProfileCard.js +23 -4
  9. package/dist/cjs/components/User/ProfileCardResourced.js +18 -10
  10. package/dist/cjs/components/User/ProfileCardTrigger.js +30 -14
  11. package/dist/cjs/components/User/ReportingLinesDetails.js +90 -0
  12. package/dist/cjs/components/User/index.js +3 -17
  13. package/dist/cjs/components/User/lazyProfileCard.js +23 -0
  14. package/dist/cjs/index.js +0 -1
  15. package/dist/cjs/messages.js +10 -0
  16. package/dist/cjs/mocks/mock-profile-client.js +45 -6
  17. package/dist/cjs/mocks/reporting-lines-data.js +28 -0
  18. package/dist/cjs/mocks/simple-mock-clients.js +2 -2
  19. package/dist/cjs/styled/ReportingLines.js +38 -0
  20. package/dist/cjs/util/analytics.js +3 -3
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/client/ProfileCardClient.js +25 -0
  23. package/dist/es2019/client/TeamCentralCardClient.js +109 -0
  24. package/dist/es2019/components/Team/lazyTeamProfileCard.js +2 -3
  25. package/dist/es2019/components/User/ProfileCard.js +15 -3
  26. package/dist/es2019/components/User/ProfileCardResourced.js +13 -6
  27. package/dist/es2019/components/User/ProfileCardTrigger.js +16 -9
  28. package/dist/es2019/components/User/ReportingLinesDetails.js +71 -0
  29. package/dist/es2019/components/User/index.js +2 -4
  30. package/dist/es2019/components/User/lazyProfileCard.js +4 -0
  31. package/dist/es2019/index.js +1 -2
  32. package/dist/es2019/messages.js +10 -0
  33. package/dist/es2019/mocks/mock-profile-client.js +25 -0
  34. package/dist/es2019/mocks/reporting-lines-data.js +14 -0
  35. package/dist/es2019/styled/ReportingLines.js +28 -0
  36. package/dist/es2019/util/analytics.js +1 -1
  37. package/dist/es2019/version.json +1 -1
  38. package/dist/esm/client/CachingClient.js +2 -2
  39. package/dist/esm/client/ProfileCardClient.js +32 -0
  40. package/dist/esm/client/TeamCentralCardClient.js +147 -0
  41. package/dist/esm/client/UserProfileCardClient.js +2 -2
  42. package/dist/esm/components/Team/TeamProfileCard.js +2 -2
  43. package/dist/esm/components/Team/lazyTeamProfileCard.js +3 -5
  44. package/dist/esm/components/User/ProfileCard.js +21 -4
  45. package/dist/esm/components/User/ProfileCardResourced.js +18 -10
  46. package/dist/esm/components/User/ProfileCardTrigger.js +23 -14
  47. package/dist/esm/components/User/ReportingLinesDetails.js +73 -0
  48. package/dist/esm/components/User/index.js +2 -4
  49. package/dist/esm/components/User/lazyProfileCard.js +6 -0
  50. package/dist/esm/index.js +1 -2
  51. package/dist/esm/messages.js +10 -0
  52. package/dist/esm/mocks/mock-profile-client.js +45 -6
  53. package/dist/esm/mocks/reporting-lines-data.js +16 -0
  54. package/dist/esm/mocks/simple-mock-clients.js +2 -2
  55. package/dist/esm/styled/ReportingLines.js +12 -0
  56. package/dist/esm/util/analytics.js +3 -3
  57. package/dist/esm/version.json +1 -1
  58. package/dist/types/client/ProfileCardClient.d.ts +4 -1
  59. package/dist/types/client/TeamCentralCardClient.d.ts +22 -0
  60. package/dist/types/components/User/ProfileCardResourced.d.ts +2 -2
  61. package/dist/types/components/User/ProfileCardTrigger.d.ts +2 -2
  62. package/dist/types/components/User/ReportingLinesDetails.d.ts +7 -0
  63. package/dist/types/components/User/index.d.ts +2 -4
  64. package/dist/types/components/User/lazyProfileCard.d.ts +2 -0
  65. package/dist/types/messages.d.ts +10 -0
  66. package/dist/types/mocks/reporting-lines-data.d.ts +2 -0
  67. package/dist/types/styled/ReportingLines.d.ts +6 -0
  68. package/dist/types/types.d.ts +30 -0
  69. package/package.json +7 -7
@@ -1,12 +1,12 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import React from 'react';
3
+ import React, { Suspense } from 'react';
4
4
  import Popup from '@atlaskit/popup';
5
5
  import { layers } from '@atlaskit/theme/constants';
6
6
  import filterActions from '../../internal/filterActions';
7
7
  import { CardWrapper } from '../../styled/Card';
8
8
  import { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
9
- import Profilecard from './ProfileCard';
9
+ import { ProfileCardLazy } from './lazyProfileCard';
10
10
  import UserLoadingState from './UserLoadingState';
11
11
 
12
12
  class ProfilecardTrigger extends React.PureComponent {
@@ -63,7 +63,8 @@ class ProfilecardTrigger extends React.PureComponent {
63
63
  isLoading: undefined,
64
64
  hasError: false,
65
65
  error: null,
66
- data: null
66
+ data: null,
67
+ reportingLinesData: undefined
67
68
  });
68
69
 
69
70
  _defineProperty(this, "clientFetchProfile", () => {
@@ -85,7 +86,8 @@ class ProfilecardTrigger extends React.PureComponent {
85
86
  hasError: false,
86
87
  data: null
87
88
  }, () => {
88
- this.props.resourceClient.getProfile(cloudId || '', userId).then(res => this.handleClientSuccess(res), err => this.handleClientError(err)).catch(err => this.handleClientError(err));
89
+ const requests = Promise.all([this.props.resourceClient.getProfile(cloudId || '', userId), this.props.resourceClient.getReportingLines(userId)]);
90
+ requests.then(res => this.handleClientSuccess(res[0], res[1]), err => this.handleClientError(err)).catch(err => this.handleClientError(err));
89
91
  });
90
92
  });
91
93
 
@@ -129,7 +131,7 @@ class ProfilecardTrigger extends React.PureComponent {
129
131
  clearTimeout(this.hideTimer);
130
132
  }
131
133
 
132
- handleClientSuccess(res) {
134
+ handleClientSuccess(profileData, reportingLinesData) {
133
135
  if (!this._isMounted) {
134
136
  return;
135
137
  }
@@ -137,7 +139,8 @@ class ProfilecardTrigger extends React.PureComponent {
137
139
  this.setState({
138
140
  isLoading: false,
139
141
  hasError: false,
140
- data: res
142
+ data: profileData,
143
+ reportingLinesData
141
144
  });
142
145
  }
143
146
 
@@ -161,18 +164,22 @@ class ProfilecardTrigger extends React.PureComponent {
161
164
  const newProps = {
162
165
  clientFetchProfile: this.clientFetchProfile,
163
166
  analytics: this.props.analytics,
164
- ...this.state.data
167
+ ...this.state.data,
168
+ reportingLines: this.state.reportingLinesData,
169
+ onReportingLinesClick: this.props.onReportingLinesClick
165
170
  };
166
171
  const wrapperProps = this.props.trigger === 'hover' ? {
167
172
  onMouseEnter: this.showProfilecard,
168
173
  onMouseLeave: this.hideProfilecard
169
174
  } : {};
170
- return /*#__PURE__*/React.createElement("div", wrapperProps, /*#__PURE__*/React.createElement(Profilecard, _extends({}, newProps, {
175
+ return /*#__PURE__*/React.createElement("div", wrapperProps, this.state.visible && /*#__PURE__*/React.createElement(Suspense, {
176
+ fallback: null
177
+ }, /*#__PURE__*/React.createElement(ProfileCardLazy, _extends({}, newProps, {
171
178
  actions: this.filterActions(),
172
179
  hasError: this.state.hasError,
173
180
  errorType: this.state.error,
174
181
  withoutElevation: true
175
- })));
182
+ }))));
176
183
  }
177
184
 
178
185
  renderWithTrigger() {
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { FormattedMessage } from 'react-intl-next';
3
+ import Avatar from '@atlaskit/avatar';
4
+ import AvatarGroup from '@atlaskit/avatar-group';
5
+ import Button from '@atlaskit/button/custom-theme-button';
6
+ import { AnalyticsName } from '../../internal/analytics';
7
+ import messages from '../../messages';
8
+ import { ManagerName, ManagerSection, OffsetWrapper, ReportingLinesHeading, ReportingLinesSection } from '../../styled/ReportingLines';
9
+
10
+ function getProfileHref(userId, profileUrl) {
11
+ return profileUrl ? profileUrl + userId : undefined;
12
+ }
13
+
14
+ const ReportingLinesDetails = props => {
15
+ var _manager$pii, _manager$pii2;
16
+
17
+ const {
18
+ reportingLines = {},
19
+ reportingLinesProfileUrl,
20
+ onReportingLinesClick,
21
+ analytics = () => {},
22
+ getDuration
23
+ } = props;
24
+ const {
25
+ managers = [],
26
+ reports = []
27
+ } = reportingLines;
28
+ const manager = managers.length >= 1 ? managers[0] : undefined;
29
+ const hasReports = reports.length > 0;
30
+
31
+ const getReportingLinesOnClick = (user, analyticsId) => onReportingLinesClick ? () => {
32
+ analytics(AnalyticsName.PROFILE_CARD_CLICK, {
33
+ id: analyticsId,
34
+ duration: getDuration()
35
+ });
36
+ onReportingLinesClick(user);
37
+ } : undefined;
38
+
39
+ return /*#__PURE__*/React.createElement(React.Fragment, null, manager && /*#__PURE__*/React.createElement(ReportingLinesSection, null, /*#__PURE__*/React.createElement(ReportingLinesHeading, {
40
+ style: {
41
+ marginBottom: 0
42
+ }
43
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.managerSectionHeading)), /*#__PURE__*/React.createElement(OffsetWrapper, null, /*#__PURE__*/React.createElement(Button, {
44
+ appearance: "subtle",
45
+ spacing: "none",
46
+ href: getProfileHref(manager.accountIdentifier, reportingLinesProfileUrl),
47
+ onClick: getReportingLinesOnClick(manager, 'reporting-lines-manager'),
48
+ isDisabled: !onReportingLinesClick
49
+ }, /*#__PURE__*/React.createElement(ManagerSection, null, /*#__PURE__*/React.createElement(Avatar, {
50
+ size: "xsmall",
51
+ src: (_manager$pii = manager.pii) === null || _manager$pii === void 0 ? void 0 : _manager$pii.picture
52
+ }), /*#__PURE__*/React.createElement(ManagerName, null, (_manager$pii2 = manager.pii) === null || _manager$pii2 === void 0 ? void 0 : _manager$pii2.name))))), hasReports && /*#__PURE__*/React.createElement(ReportingLinesSection, null, /*#__PURE__*/React.createElement(ReportingLinesHeading, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.directReportsSectionHeading)), /*#__PURE__*/React.createElement(AvatarGroup, {
53
+ appearance: "stack",
54
+ size: "small",
55
+ data: reports.map((member, index) => {
56
+ var _member$pii, _member$pii2;
57
+
58
+ return {
59
+ key: member.accountIdentifier,
60
+ name: ((_member$pii = member.pii) === null || _member$pii === void 0 ? void 0 : _member$pii.name) || '',
61
+ src: (_member$pii2 = member.pii) === null || _member$pii2 === void 0 ? void 0 : _member$pii2.picture,
62
+ href: getProfileHref(member.accountIdentifier, reportingLinesProfileUrl),
63
+ onClick: getReportingLinesOnClick(member, 'reporting-lines-direct-report')
64
+ };
65
+ }),
66
+ maxCount: 5,
67
+ testId: "profilecard-reports-avatar-group"
68
+ })));
69
+ };
70
+
71
+ export default ReportingLinesDetails;
@@ -1,6 +1,4 @@
1
- import { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
2
- import ProfileCard from './ProfileCard';
1
+ export { DELAY_MS_HIDE, DELAY_MS_SHOW } from '../../util/config';
2
+ export { ProfileCardLazy } from './lazyProfileCard';
3
3
  import ProfileCardTrigger from './ProfileCardTrigger';
4
- export { DELAY_MS_HIDE, DELAY_MS_SHOW, ProfileCard, ProfileCardTrigger };
5
- export { default as ProfileCardResourced } from './ProfileCardResourced';
6
4
  export default ProfileCardTrigger;
@@ -0,0 +1,4 @@
1
+ import { lazy } from 'react';
2
+ export const ProfileCardLazy = /*#__PURE__*/lazy(() => import(
3
+ /* webpackChunkName: "@atlaskit-internal_lazy-profilecard" */
4
+ './ProfileCard'));
@@ -8,8 +8,7 @@ import UserProfileClient, { modifyResponse } from './client/UserProfileCardClien
8
8
  import TeamProfileCardTrigger from './components/Team/TeamProfileCardTrigger';
9
9
  import ProfileCard from './components/User/ProfileCard';
10
10
  import ProfileCardResourced from './components/User/ProfileCardResourced';
11
- import ProfileCardTrigger from './components/User/ProfileCardTrigger'; // Do not export TeamProfileCard here as it will break lazy-loading for the team trigger.
12
-
11
+ import ProfileCardTrigger from './components/User/ProfileCardTrigger';
13
12
  import { DELAY_MS_HIDE, DELAY_MS_SHOW } from './util/config'; // Legacy Profile Card in Jira still needs to use `withOuterListeners`
14
13
 
15
14
  export { default as withOuterListeners } from './util/withOuterListeners';
@@ -129,6 +129,16 @@ const messages = defineMessages({
129
129
  id: 'pt.team-profile-card.error.refresh-button',
130
130
  defaultMessage: 'Try again',
131
131
  description: 'Text on a button that will try to get the data again when clicked'
132
+ },
133
+ managerSectionHeading: {
134
+ id: 'pt.team-profile-card.manager.heading',
135
+ defaultMessage: 'Manager',
136
+ description: "Title for a section on the profile card that show the user's direct manager"
137
+ },
138
+ directReportsSectionHeading: {
139
+ id: 'pt.team-profile-card.directReports.heading',
140
+ defaultMessage: 'Direct reports',
141
+ description: "Title for a section on the profile card that show the user's direct reports"
132
142
  }
133
143
  });
134
144
  export default messages;
@@ -1,5 +1,7 @@
1
+ import TeamCentralCardClient from '../client/TeamCentralCardClient';
1
2
  import UserProfileCardClient from '../client/UserProfileCardClient';
2
3
  import profiles from './profile-data';
4
+ import { reportingLinesData } from './reporting-lines-data';
3
5
  import { getTimeString, getWeekday, random } from './util';
4
6
  export default function getMockProfileClient(BaseProfileClient, modifyResponse) {
5
7
  class MockUserClient extends UserProfileCardClient {
@@ -37,10 +39,33 @@ export default function getMockProfileClient(BaseProfileClient, modifyResponse)
37
39
 
38
40
  }
39
41
 
42
+ class MockTeamCentralClient extends TeamCentralCardClient {
43
+ makeRequest(userId) {
44
+ const timeout = random(1500) + 500;
45
+ const matchError = userId.match(/^error:([0-9a-zA-Z\-]+)$/);
46
+ const error = matchError && matchError[1];
47
+ return new Promise((resolve, reject) => {
48
+ setTimeout(() => {
49
+ if (error) {
50
+ return reject({
51
+ reason: error
52
+ });
53
+ }
54
+
55
+ return resolve(reportingLinesData);
56
+ }, timeout);
57
+ });
58
+ }
59
+
60
+ }
61
+
40
62
  return class MockProfileClient extends BaseProfileClient {
41
63
  constructor(options, clients = {}) {
42
64
  super(options, {
43
65
  userClient: new MockUserClient(options),
66
+ teamCentralClient: new MockTeamCentralClient({ ...options,
67
+ teamCentralUrl: 'defaultTeamCentralUrl'
68
+ }),
44
69
  ...clients
45
70
  });
46
71
  }
@@ -0,0 +1,14 @@
1
+ import profiles from './profile-data';
2
+ const mappedProfileToReportingLines = profiles.map((profile, index) => ({
3
+ accountIdentifier: '123456:12345-67890-' + index,
4
+ identifierType: 'ATLASSIAN_ID',
5
+ pii: {
6
+ name: profile.User.fullName,
7
+ picture: profile.User.avatarUrl
8
+ }
9
+ }));
10
+ const halfCount = Math.ceil(mappedProfileToReportingLines.length / 2);
11
+ export const reportingLinesData = {
12
+ managers: mappedProfileToReportingLines.slice(0, halfCount),
13
+ reports: mappedProfileToReportingLines.slice(-halfCount)
14
+ };
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components';
2
+ import { gridSize } from '@atlaskit/theme/constants';
3
+ import { appLabelTextColor } from '../styled/constants';
4
+ export const ReportingLinesSection = styled.div`
5
+ // Minor left margin to align better with existing icon fields
6
+ margin-left: ${gridSize() / 2}px;
7
+ margin-top: ${gridSize()}px;
8
+ `;
9
+ export const ReportingLinesHeading = styled.h5`
10
+ color: ${appLabelTextColor};
11
+ font-size: ${gridSize() * 1.5}px;
12
+ font-weight: 600;
13
+ margin-bottom: ${gridSize()}px;
14
+ `;
15
+ export const ManagerSection = styled.div`
16
+ display: flex;
17
+ align-items: center;
18
+ margin: ${gridSize() / 2}px ${gridSize() / 2}px;
19
+ `;
20
+ export const ManagerName = styled.span`
21
+ font-size: ${gridSize() * 1.5}px;
22
+ margin-left: ${gridSize()}px;
23
+ `;
24
+ export const OffsetWrapper = styled.div`
25
+ margin-top: ${gridSize() / 2}px;
26
+ // Offset left margin so the avatar aligns with the heading
27
+ margin-left: -${gridSize() / 2}px;
28
+ `;
@@ -11,7 +11,7 @@ const createEvent = (eventType, action, actionSubject, actionSubjectId, attribut
11
11
  actionSubjectId,
12
12
  attributes: {
13
13
  packageName: "@atlaskit/profilecard",
14
- packageVersion: "16.0.1",
14
+ packageVersion: "16.2.1",
15
15
  ...attributes,
16
16
  firedAt: getPageTime()
17
17
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/profilecard",
3
- "version": "16.0.1"
3
+ "version": "16.2.1"
4
4
  }
@@ -2,9 +2,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
4
 
5
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
5
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
6
6
 
7
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
7
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
8
8
 
9
9
  import { LRUCache } from 'lru-fast';
10
10
 
@@ -1,5 +1,12 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
+
5
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
6
+
7
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
8
+
9
+ import TeamCentralCardClient from './TeamCentralCardClient';
3
10
  import TeamProfileCardClient from './TeamProfileCardClient';
4
11
  import UserProfileCardClient from './UserProfileCardClient';
5
12
 
@@ -9,13 +16,17 @@ var ProfileCardClient = /*#__PURE__*/function () {
9
16
 
10
17
  this.userClient = (clients === null || clients === void 0 ? void 0 : clients.userClient) || new UserProfileCardClient(config);
11
18
  this.teamClient = (clients === null || clients === void 0 ? void 0 : clients.teamClient) || new TeamProfileCardClient(config);
19
+ this.tcClient = maybeCreateTeamCentralClient(config, clients);
12
20
  }
13
21
 
14
22
  _createClass(ProfileCardClient, [{
15
23
  key: "flushCache",
16
24
  value: function flushCache() {
25
+ var _this$tcClient;
26
+
17
27
  this.userClient.flushCache();
18
28
  this.teamClient.flushCache();
29
+ (_this$tcClient = this.tcClient) === null || _this$tcClient === void 0 ? void 0 : _this$tcClient.flushCache();
19
30
  }
20
31
  }, {
21
32
  key: "getProfile",
@@ -27,9 +38,30 @@ var ProfileCardClient = /*#__PURE__*/function () {
27
38
  value: function getTeamProfile(teamId, orgId, analytics) {
28
39
  return this.teamClient.getProfile(teamId, orgId, analytics);
29
40
  }
41
+ }, {
42
+ key: "getReportingLines",
43
+ value: function getReportingLines(userId) {
44
+ var _this$tcClient2;
45
+
46
+ return ((_this$tcClient2 = this.tcClient) === null || _this$tcClient2 === void 0 ? void 0 : _this$tcClient2.getReportingLines(userId)) || Promise.resolve({
47
+ managers: [],
48
+ reports: []
49
+ });
50
+ }
30
51
  }]);
31
52
 
32
53
  return ProfileCardClient;
33
54
  }();
34
55
 
56
+ function maybeCreateTeamCentralClient(config, clients) {
57
+ if (clients !== null && clients !== void 0 && clients.teamCentralClient) {
58
+ return clients.teamCentralClient;
59
+ }
60
+
61
+ var teamCentralUrl = config.teamCentralUrl;
62
+ return teamCentralUrl ? new TeamCentralCardClient(_objectSpread(_objectSpread({}, config), {}, {
63
+ teamCentralUrl: teamCentralUrl
64
+ })) : undefined;
65
+ }
66
+
35
67
  export default ProfileCardClient;
@@ -0,0 +1,147 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
+ import _createClass from "@babel/runtime/helpers/createClass";
5
+ import _inherits from "@babel/runtime/helpers/inherits";
6
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
7
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
8
+
9
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
10
+
11
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
+
13
+ import CachingClient from './CachingClient';
14
+ import { graphqlQuery } from './graphqlUtils';
15
+
16
+ var buildReportingLinesQuery = function buildReportingLinesQuery(aaid) {
17
+ return {
18
+ query: "\n fragment ReportingLinesUserPII on UserPII {\n name\n picture\n }\n\n fragment ReportingLinesUserFragment on ReportingLinesUser {\n accountIdentifier\n identifierType\n pii {\n ...ReportingLinesUserPII\n }\n }\n\n query ReportingLines($aaid: String) {\n reportingLines(aaidOrHash: $aaid) {\n managers {\n ...ReportingLinesUserFragment\n }\n reports {\n ...ReportingLinesUserFragment\n }\n }\n }\n ",
19
+ variables: {
20
+ aaid: aaid
21
+ }
22
+ };
23
+ };
24
+
25
+ var TeamCentralCardClient = /*#__PURE__*/function (_CachingClient) {
26
+ _inherits(TeamCentralCardClient, _CachingClient);
27
+
28
+ var _super = _createSuper(TeamCentralCardClient);
29
+
30
+ /**
31
+ * Simple circuit breaker to avoid making unnecessary calls to Team Central on auth failures
32
+ * This is to handle the case where products may have provided teamCentralUrl, but the site itself
33
+ * doesn't actually have any TC product.
34
+ *
35
+ * There's currently no way to reset this circuit breaker, but that's fine. This is meant to
36
+ * catch a pretty specific edge case.
37
+ */
38
+ function TeamCentralCardClient(options) {
39
+ var _this;
40
+
41
+ _classCallCheck(this, TeamCentralCardClient);
42
+
43
+ _this = _super.call(this, options);
44
+ _this.options = options;
45
+ _this.bypassOnFailure = false;
46
+ return _this;
47
+ }
48
+
49
+ _createClass(TeamCentralCardClient, [{
50
+ key: "makeRequest",
51
+ value: function () {
52
+ var _makeRequest = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(userId) {
53
+ var query, response;
54
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
55
+ while (1) {
56
+ switch (_context.prev = _context.next) {
57
+ case 0:
58
+ if (this.options.teamCentralUrl) {
59
+ _context.next = 2;
60
+ break;
61
+ }
62
+
63
+ throw new Error('options.teamCentralUrl is a required parameter for retrieving Team Central data');
64
+
65
+ case 2:
66
+ query = buildReportingLinesQuery(userId);
67
+ _context.next = 5;
68
+ return graphqlQuery(this.options.teamCentralUrl, query);
69
+
70
+ case 5:
71
+ response = _context.sent;
72
+ return _context.abrupt("return", response.reportingLines);
73
+
74
+ case 7:
75
+ case "end":
76
+ return _context.stop();
77
+ }
78
+ }
79
+ }, _callee, this);
80
+ }));
81
+
82
+ function makeRequest(_x) {
83
+ return _makeRequest.apply(this, arguments);
84
+ }
85
+
86
+ return makeRequest;
87
+ }()
88
+ }, {
89
+ key: "getReportingLines",
90
+ value: function getReportingLines(userId) {
91
+ var _this2 = this;
92
+
93
+ if (!userId) {
94
+ return Promise.reject(new Error('userId missing'));
95
+ }
96
+
97
+ var cache = this.getCachedProfile(userId);
98
+
99
+ if (cache) {
100
+ return Promise.resolve(cache);
101
+ }
102
+
103
+ if (this.bypassOnFailure) {
104
+ return Promise.resolve({});
105
+ }
106
+
107
+ return new Promise(function (resolve) {
108
+ _this2.makeRequest(userId).then(function (data) {
109
+ var enhancedData = {
110
+ managers: _this2.filterReportingLinesUser(data === null || data === void 0 ? void 0 : data.managers),
111
+ reports: _this2.filterReportingLinesUser(data === null || data === void 0 ? void 0 : data.reports)
112
+ };
113
+
114
+ if (_this2.cache) {
115
+ _this2.setCachedProfile(userId, enhancedData);
116
+ }
117
+
118
+ resolve(enhancedData);
119
+ }).catch(function (error) {
120
+ if ((error === null || error === void 0 ? void 0 : error.status) === 401 || (error === null || error === void 0 ? void 0 : error.status) === 403) {
121
+ // Trigger circuit breaker
122
+ _this2.bypassOnFailure = true;
123
+ }
124
+ /**
125
+ * Reporting lines aren't part of the critical path of profile card.
126
+ * Just resolve with empty values instead of bubbling up the error.
127
+ */
128
+
129
+
130
+ resolve({});
131
+ });
132
+ });
133
+ }
134
+ }, {
135
+ key: "filterReportingLinesUser",
136
+ value: function filterReportingLinesUser() {
137
+ var users = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
138
+ return users.filter(function (user) {
139
+ return user.identifierType === 'ATLASSIAN_ID';
140
+ });
141
+ }
142
+ }]);
143
+
144
+ return TeamCentralCardClient;
145
+ }(CachingClient);
146
+
147
+ export default TeamCentralCardClient;
@@ -11,9 +11,9 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
11
11
 
12
12
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
13
13
 
14
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
14
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
15
15
 
16
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
16
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
17
17
 
18
18
  import CachingClient from './CachingClient';
19
19
  import { graphqlQuery } from './graphqlUtils';
@@ -3,9 +3,9 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
4
  import _extends from "@babel/runtime/helpers/extends";
5
5
 
6
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
6
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
7
7
 
8
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
8
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
9
9
 
10
10
  import React, { useCallback, useEffect, useRef, useState } from 'react';
11
11
  import { FormattedMessage } from 'react-intl-next';
@@ -1,8 +1,6 @@
1
1
  import { lazy } from 'react';
2
2
  export var TeamProfileCardLazy = /*#__PURE__*/lazy(function () {
3
- return (// eslint-disable-next-line import/dynamic-import-chunkname
4
- import(
5
- /* webpackChunkName:"lazy-team-profilecard" */
6
- './TeamProfileCard')
7
- );
3
+ return import(
4
+ /* webpackChunkName: "@atlaskit-internal_lazy-team-profilecard" */
5
+ './TeamProfileCard');
8
6
  });
@@ -7,6 +7,7 @@ import _inherits from "@babel/runtime/helpers/inherits";
7
7
  import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
8
8
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
9
9
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
10
+ var _excluded = ["text"];
10
11
 
11
12
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
12
13
 
@@ -27,6 +28,7 @@ import { ActionButtonGroup, ActionsFlexSpacer, AppTitleLabel, CardContainer, Car
27
28
  import { isBasicClick } from '../../util/click';
28
29
  import { ErrorMessage } from '../Error';
29
30
  import { IconLabel } from '../Icon';
31
+ import ReportingLinesDetails from './ReportingLinesDetails';
30
32
 
31
33
  var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
32
34
  _inherits(Profilecard, _React$PureComponent);
@@ -122,6 +124,8 @@ var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
122
124
  }, {
123
125
  key: "renderCardDetailsDefault",
124
126
  value: function renderCardDetailsDefault() {
127
+ var _this4 = this;
128
+
125
129
  var _this$props2 = this.props,
126
130
  meta = _this$props2.meta,
127
131
  location = _this$props2.location,
@@ -137,7 +141,15 @@ var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
137
141
  icon: "companyName"
138
142
  }, companyName), /*#__PURE__*/React.createElement(IconLabel, {
139
143
  icon: "location"
140
- }, location));
144
+ }, location), /*#__PURE__*/React.createElement(ReportingLinesDetails, {
145
+ reportingLines: this.props.reportingLines,
146
+ reportingLinesProfileUrl: this.props.reportingLinesProfileUrl,
147
+ onReportingLinesClick: this.props.onReportingLinesClick,
148
+ analytics: this.props.analytics,
149
+ getDuration: function getDuration() {
150
+ return _this4.durationSince(_this4.timeOpen);
151
+ }
152
+ }));
141
153
  }
142
154
  }, {
143
155
  key: "renderCardDetailsForDisabledAccount",
@@ -224,7 +236,7 @@ var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
224
236
  value: function renderCustomLozenges(lozenges) {
225
237
  return lozenges.length > 0 ? /*#__PURE__*/React.createElement(CustomLozengeContainer, null, lozenges.map(function (_ref, index) {
226
238
  var text = _ref.text,
227
- otherProps = _objectWithoutProperties(_ref, ["text"]);
239
+ otherProps = _objectWithoutProperties(_ref, _excluded);
228
240
 
229
241
  return /*#__PURE__*/React.createElement(Lozenge, _extends({}, otherProps, {
230
242
  key: index
@@ -259,7 +271,8 @@ var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
259
271
  var _this$props8 = this.props,
260
272
  fullName = _this$props8.fullName,
261
273
  status = _this$props8.status,
262
- withoutElevation = _this$props8.withoutElevation;
274
+ withoutElevation = _this$props8.withoutElevation,
275
+ reportingLines = _this$props8.reportingLines;
263
276
  var cardContent = null; // @FIXME do closed users have empty fullName field?
264
277
 
265
278
  var canRender = fullName || status === 'closed';
@@ -270,10 +283,14 @@ var Profilecard = /*#__PURE__*/function (_React$PureComponent) {
270
283
  } else if (this.props.isLoading) {
271
284
  cardContent = /*#__PURE__*/React.createElement(SpinnerContainer, null, /*#__PURE__*/React.createElement(Spinner, null));
272
285
  } else if (canRender) {
286
+ var _reportingLines$manag, _reportingLines$repor;
287
+
273
288
  var isDisabledUser = status === 'inactive' || status === 'closed';
274
289
  var actions = this.renderActionsButtons();
275
290
  this.callAnalytics(AnalyticsName.PROFILE_CARD_LOADED, {
276
- duration: this.durationSince(this.timeOpen)
291
+ duration: this.durationSince(this.timeOpen),
292
+ managersCount: (reportingLines === null || reportingLines === void 0 ? void 0 : (_reportingLines$manag = reportingLines.managers) === null || _reportingLines$manag === void 0 ? void 0 : _reportingLines$manag.length) || 0,
293
+ directReportsCount: (reportingLines === null || reportingLines === void 0 ? void 0 : (_reportingLines$repor = reportingLines.reports) === null || _reportingLines$repor === void 0 ? void 0 : _reportingLines$repor.length) || 0
277
294
  });
278
295
  cardContent = /*#__PURE__*/React.createElement(CardContainer, {
279
296
  isDisabledUser: isDisabledUser,