@atlaskit/smart-user-picker 6.0.3 → 6.0.5

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 (129) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/analytics.js +12 -37
  3. package/dist/cjs/components/MessagesIntlProvider.js +4 -22
  4. package/dist/cjs/components/SmartUserPicker.js +22 -123
  5. package/dist/cjs/components/index.js +0 -7
  6. package/dist/cjs/i18n/cs.js +0 -1
  7. package/dist/cjs/i18n/da.js +0 -1
  8. package/dist/cjs/i18n/de.js +0 -1
  9. package/dist/cjs/i18n/en_ZZ.js +0 -1
  10. package/dist/cjs/i18n/es.js +0 -1
  11. package/dist/cjs/i18n/et.js +0 -1
  12. package/dist/cjs/i18n/fi.js +0 -1
  13. package/dist/cjs/i18n/fr.js +0 -1
  14. package/dist/cjs/i18n/hu.js +0 -1
  15. package/dist/cjs/i18n/index.js +0 -31
  16. package/dist/cjs/i18n/it.js +0 -1
  17. package/dist/cjs/i18n/ja.js +0 -1
  18. package/dist/cjs/i18n/ko.js +0 -1
  19. package/dist/cjs/i18n/nb.js +0 -1
  20. package/dist/cjs/i18n/nl.js +0 -1
  21. package/dist/cjs/i18n/pl.js +0 -1
  22. package/dist/cjs/i18n/pt_BR.js +0 -1
  23. package/dist/cjs/i18n/pt_PT.js +0 -1
  24. package/dist/cjs/i18n/ru.js +0 -1
  25. package/dist/cjs/i18n/sk.js +0 -1
  26. package/dist/cjs/i18n/sv.js +0 -1
  27. package/dist/cjs/i18n/th.js +0 -1
  28. package/dist/cjs/i18n/tr.js +0 -1
  29. package/dist/cjs/i18n/uk.js +0 -1
  30. package/dist/cjs/i18n/vi.js +0 -1
  31. package/dist/cjs/i18n/zh.js +0 -1
  32. package/dist/cjs/i18n/zh_TW.js +0 -1
  33. package/dist/cjs/i18n.js +0 -2
  34. package/dist/cjs/index.js +0 -4
  35. package/dist/cjs/service/default-value-hydration-client.js +0 -49
  36. package/dist/cjs/service/graphqlUtils.js +0 -5
  37. package/dist/cjs/service/index.js +0 -3
  38. package/dist/cjs/service/recommendation-client.js +0 -11
  39. package/dist/cjs/service/teams-client.js +0 -10
  40. package/dist/cjs/service/users-client.js +2 -20
  41. package/dist/cjs/service/users-transformer.js +0 -17
  42. package/dist/cjs/types.js +0 -1
  43. package/dist/cjs/ufoExperiences.js +8 -26
  44. package/dist/cjs/util/i18n-util.js +0 -43
  45. package/dist/cjs/version.json +1 -1
  46. package/dist/es2019/analytics.js +12 -10
  47. package/dist/es2019/components/MessagesIntlProvider.js +2 -4
  48. package/dist/es2019/components/SmartUserPicker.js +23 -55
  49. package/dist/es2019/components/index.js +0 -2
  50. package/dist/es2019/config/index.js +0 -4
  51. package/dist/es2019/index.js +4 -2
  52. package/dist/es2019/service/default-value-hydration-client.js +4 -22
  53. package/dist/es2019/service/graphqlUtils.js +0 -4
  54. package/dist/es2019/service/recommendation-client.js +0 -4
  55. package/dist/es2019/service/teams-client.js +2 -5
  56. package/dist/es2019/service/users-client.js +2 -6
  57. package/dist/es2019/service/users-transformer.js +0 -11
  58. package/dist/es2019/types.js +0 -1
  59. package/dist/es2019/ufoExperiences.js +8 -7
  60. package/dist/es2019/util/i18n-util.js +30 -120
  61. package/dist/es2019/version.json +1 -1
  62. package/dist/esm/analytics.js +12 -19
  63. package/dist/esm/components/MessagesIntlProvider.js +4 -11
  64. package/dist/esm/components/SmartUserPicker.js +24 -115
  65. package/dist/esm/components/index.js +0 -2
  66. package/dist/esm/index.js +4 -2
  67. package/dist/esm/service/default-value-hydration-client.js +0 -40
  68. package/dist/esm/service/graphqlUtils.js +0 -4
  69. package/dist/esm/service/recommendation-client.js +0 -7
  70. package/dist/esm/service/teams-client.js +0 -7
  71. package/dist/esm/service/users-client.js +2 -13
  72. package/dist/esm/service/users-transformer.js +0 -13
  73. package/dist/esm/types.js +0 -1
  74. package/dist/esm/ufoExperiences.js +8 -13
  75. package/dist/esm/util/i18n-util.js +30 -126
  76. package/dist/esm/version.json +1 -1
  77. package/package.json +7 -14
  78. package/report.api.md +26 -5
  79. package/tmp/api-report-tmp.d.ts +268 -0
  80. package/dist/types-ts4.0/analytics.d.ts +0 -21
  81. package/dist/types-ts4.0/components/MessagesIntlProvider.d.ts +0 -9
  82. package/dist/types-ts4.0/components/SmartUserPicker.d.ts +0 -34
  83. package/dist/types-ts4.0/components/index.d.ts +0 -4
  84. package/dist/types-ts4.0/config/index.d.ts +0 -6
  85. package/dist/types-ts4.0/i18n/cs.d.ts +0 -18
  86. package/dist/types-ts4.0/i18n/da.d.ts +0 -18
  87. package/dist/types-ts4.0/i18n/de.d.ts +0 -18
  88. package/dist/types-ts4.0/i18n/en.d.ts +0 -7
  89. package/dist/types-ts4.0/i18n/en_GB.d.ts +0 -7
  90. package/dist/types-ts4.0/i18n/en_ZZ.d.ts +0 -18
  91. package/dist/types-ts4.0/i18n/es.d.ts +0 -18
  92. package/dist/types-ts4.0/i18n/et.d.ts +0 -8
  93. package/dist/types-ts4.0/i18n/fi.d.ts +0 -18
  94. package/dist/types-ts4.0/i18n/fr.d.ts +0 -18
  95. package/dist/types-ts4.0/i18n/hu.d.ts +0 -18
  96. package/dist/types-ts4.0/i18n/index.d.ts +0 -36
  97. package/dist/types-ts4.0/i18n/is.d.ts +0 -7
  98. package/dist/types-ts4.0/i18n/it.d.ts +0 -18
  99. package/dist/types-ts4.0/i18n/ja.d.ts +0 -18
  100. package/dist/types-ts4.0/i18n/ko.d.ts +0 -18
  101. package/dist/types-ts4.0/i18n/languages.d.ts +0 -27
  102. package/dist/types-ts4.0/i18n/nb.d.ts +0 -18
  103. package/dist/types-ts4.0/i18n/nl.d.ts +0 -18
  104. package/dist/types-ts4.0/i18n/pl.d.ts +0 -18
  105. package/dist/types-ts4.0/i18n/pt_BR.d.ts +0 -18
  106. package/dist/types-ts4.0/i18n/pt_PT.d.ts +0 -8
  107. package/dist/types-ts4.0/i18n/ro.d.ts +0 -7
  108. package/dist/types-ts4.0/i18n/ru.d.ts +0 -18
  109. package/dist/types-ts4.0/i18n/sk.d.ts +0 -8
  110. package/dist/types-ts4.0/i18n/sv.d.ts +0 -18
  111. package/dist/types-ts4.0/i18n/th.d.ts +0 -18
  112. package/dist/types-ts4.0/i18n/tr.d.ts +0 -18
  113. package/dist/types-ts4.0/i18n/uk.d.ts +0 -18
  114. package/dist/types-ts4.0/i18n/vi.d.ts +0 -18
  115. package/dist/types-ts4.0/i18n/zh.d.ts +0 -18
  116. package/dist/types-ts4.0/i18n/zh_TW.d.ts +0 -18
  117. package/dist/types-ts4.0/i18n.d.ts +0 -47
  118. package/dist/types-ts4.0/index.d.ts +0 -5
  119. package/dist/types-ts4.0/service/constants.d.ts +0 -4
  120. package/dist/types-ts4.0/service/default-value-hydration-client.d.ts +0 -8
  121. package/dist/types-ts4.0/service/graphqlUtils.d.ts +0 -14
  122. package/dist/types-ts4.0/service/index.d.ts +0 -2
  123. package/dist/types-ts4.0/service/recommendation-client.d.ts +0 -5
  124. package/dist/types-ts4.0/service/teams-client.d.ts +0 -12
  125. package/dist/types-ts4.0/service/users-client.d.ts +0 -11
  126. package/dist/types-ts4.0/service/users-transformer.d.ts +0 -22
  127. package/dist/types-ts4.0/types.d.ts +0 -207
  128. package/dist/types-ts4.0/ufoExperiences.d.ts +0 -11
  129. package/dist/types-ts4.0/util/i18n-util.d.ts +0 -11
@@ -13,21 +13,23 @@ import MessagesIntlProvider from './MessagesIntlProvider';
13
13
  import { getUserRecommendations, hydrateDefaultValues } from '../service';
14
14
  import { smartUserPickerOptionsShownUfoExperience } from '../ufoExperiences';
15
15
  const DEFAULT_DEBOUNCE_TIME_MS = 150;
16
-
16
+ const ufoEndStateConfig = fieldId => {
17
+ return {
18
+ metadata: {
19
+ contextType: fieldId
20
+ }
21
+ };
22
+ };
17
23
  const hasContextChanged = (oldContext, newContext) => oldContext.siteId !== newContext.siteId || oldContext.orgId !== newContext.orgId || oldContext.productKey !== newContext.productKey || oldContext.principalId !== newContext.principalId || oldContext.containerId !== newContext.containerId || oldContext.objectId !== newContext.objectId || oldContext.childObjectId !== newContext.childObjectId;
18
-
19
24
  const stringContains = (str, substr) => {
20
25
  if (str === null || str === undefined) {
21
26
  return false;
22
27
  }
23
-
24
28
  if (substr === null || substr === '' || substr === undefined) {
25
29
  return true;
26
30
  }
27
-
28
31
  return str.toLowerCase().includes(substr.toLowerCase());
29
32
  };
30
-
31
33
  const getUsersForAnalytics = users => (users || []).map(({
32
34
  id,
33
35
  type
@@ -35,13 +37,10 @@ const getUsersForAnalytics = users => (users || []).map(({
35
37
  id,
36
38
  type
37
39
  }));
38
-
39
40
  export class SmartUserPickerWithoutAnalytics extends React.Component {
40
41
  constructor(props) {
41
42
  var _this$props$debounceT;
42
-
43
43
  super(props);
44
-
45
44
  _defineProperty(this, "state", {
46
45
  users: [],
47
46
  loading: false,
@@ -50,7 +49,6 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
50
49
  defaultValue: [],
51
50
  bootstrapOptions: []
52
51
  });
53
-
54
52
  _defineProperty(this, "abortOptionsShownUfoExperience", () => {
55
53
  if (this.optionsShownUfoExperienceInstance.state.id === UFOExperienceState.STARTED.id) {
56
54
  // There may be an existing UFO timing running from previous key entry or focus,
@@ -58,26 +56,20 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
58
56
  this.optionsShownUfoExperienceInstance.abort();
59
57
  }
60
58
  });
61
-
62
59
  _defineProperty(this, "startOptionsShownUfoExperience", () => {
63
60
  this.abortOptionsShownUfoExperience();
64
61
  this.optionsShownUfoExperienceInstance.start();
65
62
  });
66
-
67
63
  _defineProperty(this, "fireEvent", (eventCreator, ...args) => {
68
64
  const {
69
65
  createAnalyticsEvent
70
66
  } = this.props;
71
-
72
67
  if (createAnalyticsEvent) {
73
68
  createAndFireEventInElementsChannel(eventCreator(this.props, this.state, ...args))(createAnalyticsEvent);
74
69
  }
75
70
  });
76
-
77
71
  _defineProperty(this, "filterOptions", (users, query, propFilterOptions) => propFilterOptions ? propFilterOptions(users, query) : users);
78
-
79
72
  _defineProperty(this, "memoizedFilterOptions", memoizeOne(this.filterOptions));
80
-
81
73
  _defineProperty(this, "getUsers", debounce(async () => {
82
74
  const {
83
75
  query,
@@ -127,10 +119,8 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
127
119
  query,
128
120
  searchQueryFilter
129
121
  };
130
-
131
122
  try {
132
123
  var _await$onEmpty;
133
-
134
124
  this.fireEvent(requestUsersEvent);
135
125
  const recommendedUsers = await getUserRecommendations(recommendationsRequest, intl);
136
126
  const elapsedTimeMilli = window.performance.now() - startTime;
@@ -155,26 +145,22 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
155
145
  if (!closed && !onError) {
156
146
  // If the user lookup fails while the menu is open, and the consumer is not providing a
157
147
  // fallback data source via the onError prop, then send UFO failure
158
- this.optionsShownUfoExperienceInstance.failure();
148
+ this.optionsShownUfoExperienceInstance.failure(ufoEndStateConfig(this.props.fieldId));
159
149
  }
160
-
161
150
  this.setState({
162
151
  users: []
163
152
  });
164
153
  let onErrorProducedError = false;
165
154
  let defaultUsers = [];
166
-
167
155
  try {
168
156
  defaultUsers = onError ? (await onError(e, recommendationsRequest)) || [] : [];
169
157
  } catch (error) {
170
158
  onErrorProducedError = true;
171
159
  }
172
-
173
160
  if (onErrorProducedError) {
174
161
  // Log error from fallback data source `onError` to UFO
175
- this.optionsShownUfoExperienceInstance.failure();
162
+ this.optionsShownUfoExperienceInstance.failure(ufoEndStateConfig(this.props.fieldId));
176
163
  }
177
-
178
164
  this.setState({
179
165
  users: defaultUsers,
180
166
  loading: false
@@ -186,17 +172,14 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
186
172
  });
187
173
  }
188
174
  }, (_this$props$debounceT = this.props.debounceTime) !== null && _this$props$debounceT !== void 0 ? _this$props$debounceT : 0));
189
-
190
175
  _defineProperty(this, "onInputChange", (newQuery, sessionId) => {
191
176
  const query = newQuery || '';
192
177
  const {
193
178
  closed
194
179
  } = this.state;
195
-
196
180
  if (query === this.state.query) {
197
181
  return;
198
182
  }
199
-
200
183
  if (!closed) {
201
184
  // If the input has been typed into and the dropdown has not been closed
202
185
  // (i.e. input blurred) then start the UFO timer.
@@ -208,21 +191,19 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
208
191
  query,
209
192
  sessionId
210
193
  });
211
-
212
194
  if (this.props.onInputChange) {
213
195
  this.props.onInputChange(query, sessionId);
214
196
  }
215
197
  }
216
198
  });
217
-
218
199
  _defineProperty(this, "filterUsers", () => {
219
200
  const {
220
201
  loading,
221
202
  users,
222
203
  query
223
204
  } = this.state;
224
- const filteredUsers = this.memoizedFilterOptions(users, query, this.props.filterOptions); //If bootstrapOptions have been passed in and it is bootstrap
225
-
205
+ const filteredUsers = this.memoizedFilterOptions(users, query, this.props.filterOptions);
206
+ //If bootstrapOptions have been passed in and it is bootstrap
226
207
  if (this.props.bootstrapOptions && this.props.bootstrapOptions.length !== 0 && query === '') {
227
208
  const bootstrapFilteredUsers = this.memoizedFilterOptions(this.props.bootstrapOptions, query, this.props.filterOptions);
228
209
  this.fireEvent(filterUsersEvent, {
@@ -230,29 +211,26 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
230
211
  all: getUsersForAnalytics(this.props.bootstrapOptions)
231
212
  });
232
213
  return bootstrapFilteredUsers;
233
- } // while when not loading just return already filtered result from server.
234
-
235
-
214
+ }
215
+ // while when not loading just return already filtered result from server.
236
216
  if (!loading) {
237
217
  return filteredUsers;
238
218
  }
239
-
240
219
  const queryFilteredUsers = filteredUsers.filter(user => stringContains(user.name, query));
241
220
  this.fireEvent(filterUsersEvent, {
242
221
  filtered: getUsersForAnalytics(queryFilteredUsers),
243
222
  all: getUsersForAnalytics(users)
244
- }); // when loading filter previous result.
223
+ });
245
224
 
225
+ // when loading filter previous result.
246
226
  return filteredUsers;
247
227
  });
248
-
249
228
  _defineProperty(this, "onFocus", sessionId => {
250
229
  const state = {
251
230
  query: '',
252
231
  closed: false
253
232
  };
254
233
  this.startOptionsShownUfoExperience();
255
-
256
234
  if (this.state.users.length === 0) {
257
235
  state.sessionId = sessionId;
258
236
  state.loading = true;
@@ -263,36 +241,32 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
263
241
  sessionId
264
242
  });
265
243
  }
266
-
267
- this.setState(currentState => ({ ...currentState,
244
+ this.setState(currentState => ({
245
+ ...currentState,
268
246
  ...state
269
247
  }));
270
-
271
248
  if (this.props.onFocus) {
272
249
  this.props.onFocus(sessionId);
273
250
  }
274
251
  });
275
-
276
252
  _defineProperty(this, "onBlur", sessionId => {
277
253
  this.getUsers.cancel();
278
- this.abortOptionsShownUfoExperience(); // clear old users if query is populated so that on refocus,
279
- // the old list is not shown
254
+ this.abortOptionsShownUfoExperience();
280
255
 
256
+ // clear old users if query is populated so that on refocus,
257
+ // the old list is not shown
281
258
  const users = this.state.query.length === 0 ? this.state.users : [];
282
259
  this.setState({
283
260
  loading: false,
284
261
  closed: true,
285
262
  users
286
263
  });
287
-
288
264
  if (this.props.onBlur) {
289
265
  this.props.onBlur(sessionId);
290
266
  }
291
267
  });
292
-
293
268
  this.optionsShownUfoExperienceInstance = smartUserPickerOptionsShownUfoExperience.getInstance(props.inputId || props.fieldId);
294
269
  }
295
-
296
270
  async componentDidMount() {
297
271
  try {
298
272
  const value = await hydrateDefaultValues(this.props.baseUrl, this.props.defaultValue, this.props.productKey);
@@ -305,11 +279,9 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
305
279
  defaultValue: defaultValue
306
280
  });
307
281
  }
308
-
309
282
  const {
310
283
  prefetch
311
284
  } = this.props;
312
-
313
285
  if (prefetch) {
314
286
  const sessionId = uuidV4();
315
287
  this.fireEvent(mountedWithPrefetchEvent, {
@@ -320,25 +292,22 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
320
292
  });
321
293
  }
322
294
  }
323
-
324
295
  componentDidUpdate(prevProps, prevState) {
325
296
  if (hasContextChanged(prevProps, this.props) || this.props.fieldId !== prevProps.fieldId) {
326
297
  this.setState({
327
298
  users: []
328
299
  });
329
300
  }
330
-
331
301
  if ((this.state.sessionId !== prevState.sessionId || this.state.query !== prevState.query) && (this.state.query !== '' || !this.props.bootstrapOptions)) {
332
302
  this.getUsers();
333
303
  } else if (!this.state.closed && !this.state.loading) {
334
304
  // If the component has rendered (including its dropdown list) and it
335
305
  // is not loading anything further, send the success UFO event
336
306
  if (![UFOExperienceState.FAILED.id, UFOExperienceState.SUCCEEDED.id].includes(this.optionsShownUfoExperienceInstance.state.id)) {
337
- this.optionsShownUfoExperienceInstance.success();
307
+ this.optionsShownUfoExperienceInstance.success(ufoEndStateConfig(this.props.fieldId));
338
308
  }
339
309
  }
340
310
  }
341
-
342
311
  render() {
343
312
  return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(UserPicker, _extends({}, this.props, {
344
313
  onInputChange: this.onInputChange,
@@ -349,9 +318,9 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
349
318
  options: this.filterUsers()
350
319
  })));
351
320
  }
321
+ }
352
322
 
353
- } // TODO: Smart User picker team will have to add a type annotation here
354
-
323
+ // TODO: Smart User picker team will have to add a type annotation here
355
324
  _defineProperty(SmartUserPickerWithoutAnalytics, "defaultProps", {
356
325
  baseUrl: '',
357
326
  includeUsers: true,
@@ -361,5 +330,4 @@ _defineProperty(SmartUserPickerWithoutAnalytics, "defaultProps", {
361
330
  principalId: 'Context',
362
331
  debounceTime: DEFAULT_DEBOUNCE_TIME_MS
363
332
  });
364
-
365
333
  export const SmartUserPicker = withAnalyticsEvents()(injectIntl(SmartUserPickerWithoutAnalytics));
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import { SmartUserPicker } from './SmartUserPicker';
3
3
  import MessagesIntlProvider from './MessagesIntlProvider';
4
4
  import { useUFOConcurrentExperience, smartUserPickerRenderedUfoExperience, UfoErrorBoundary } from '../ufoExperiences';
5
-
6
5
  const SmartUserPickerWithIntlProvider = props => {
7
6
  const ufoId = props.inputId || props.fieldId;
8
7
  useUFOConcurrentExperience(smartUserPickerRenderedUfoExperience, ufoId);
@@ -10,5 +9,4 @@ const SmartUserPickerWithIntlProvider = props => {
10
9
  id: ufoId
11
10
  }, /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(SmartUserPicker, props)));
12
11
  };
13
-
14
12
  export default SmartUserPickerWithIntlProvider;
@@ -2,17 +2,13 @@ export const config = {
2
2
  getRecommendationServiceUrl(baseUrl) {
3
3
  return baseUrl ? `${baseUrl}/gateway/api/v1/recommendations` : '/gateway/api/v1/recommendations';
4
4
  },
5
-
6
5
  getUsersServiceUrl(productKey, baseUrl = '') {
7
6
  return productKey === 'jira' ? `${baseUrl}/rest/api/3/user/bulk` : `${baseUrl}/wiki/rest/api/user/bulk`;
8
7
  },
9
-
10
8
  getGraphQLUrl(baseUrl) {
11
9
  return baseUrl ? `${baseUrl}/gateway/api/graphql` : `/gateway/api/graphql`;
12
10
  },
13
-
14
11
  getTeamsUrl(baseUrl) {
15
12
  return baseUrl ? `${baseUrl}/gateway/api/v3/teams` : `/gateway/api/v3/teams`;
16
13
  }
17
-
18
14
  };
@@ -1,5 +1,7 @@
1
1
  export { default } from './components';
2
2
  export { getUserRecommendations, hydrateDefaultValues } from './service';
3
- export { //Utils
4
- isEmail, isTeam, isUser, isValidEmail, // Constants
3
+ export {
4
+ //Utils
5
+ isEmail, isTeam, isUser, isValidEmail,
6
+ // Constants
5
7
  EmailType, GroupType, TeamType, UserType } from '@atlaskit/user-picker';
@@ -3,7 +3,6 @@ import { config } from '../config';
3
3
  import getHydratedUsersFromPrs from './users-client';
4
4
  import hydrateTeamFromLegion from './teams-client';
5
5
  import { UNKNOWN } from './constants';
6
-
7
6
  const getHydratedUsersFromProducts = request => {
8
7
  const url = `${config.getUsersServiceUrl(request.productKey, request.baseUrl)}`;
9
8
  let params = new URLSearchParams();
@@ -19,20 +18,16 @@ const getHydratedUsersFromProducts = request => {
19
18
  if (response.status === 200) {
20
19
  return response.json();
21
20
  }
22
-
23
21
  return Promise.reject({
24
22
  message: `error calling users service, statusCode=${response.status}, statusText=${response.statusText}`
25
23
  });
26
24
  }).then(request.productKey === 'jira' ? transformJiraUsers : transformConfluenceUsers);
27
25
  };
28
-
29
26
  const transformJiraUsers = userResponse => userResponse.values.map(transformJiraUser).filter(user => !!user).map(user => user);
30
-
31
27
  const transformJiraUser = item => {
32
28
  if (!item) {
33
29
  return null;
34
30
  }
35
-
36
31
  return {
37
32
  id: item.accountId,
38
33
  type: UserType,
@@ -41,14 +36,11 @@ const transformJiraUser = item => {
41
36
  email: item.emailAddress
42
37
  };
43
38
  };
44
-
45
39
  const transformConfluenceUsers = userResponse => userResponse.results.map(transformConfluenceUser).filter(user => !!user).map(user => user);
46
-
47
40
  const transformConfluenceUser = item => {
48
41
  if (!item) {
49
42
  return null;
50
43
  }
51
-
52
44
  return {
53
45
  id: item.accountId,
54
46
  type: UserType,
@@ -57,16 +49,13 @@ const transformConfluenceUser = item => {
57
49
  email: item.email
58
50
  };
59
51
  };
60
-
61
52
  const sortResults = (options, sortIds) => {
62
53
  const resultsMap = new Map(options.map(option => [option && option.id, option]));
63
54
  return sortIds.map(option => {
64
55
  const user = resultsMap.get(option.id);
65
-
66
56
  if (user) {
67
57
  return user;
68
58
  }
69
-
70
59
  return {
71
60
  id: option.id,
72
61
  type: option.type,
@@ -74,52 +63,45 @@ const sortResults = (options, sortIds) => {
74
63
  };
75
64
  });
76
65
  };
77
-
78
66
  const isOptionData = option => {
79
67
  return option.name !== undefined;
80
68
  };
81
-
82
69
  const hydrateTeamIds = async (baseUrl, values) => {
83
70
  if (values.length === 0) {
84
71
  return [];
85
72
  }
86
-
87
73
  const legionPromises = values.map(value => hydrateTeamFromLegion({
88
74
  baseUrl,
89
75
  id: value.id
90
76
  }));
91
77
  return await Promise.all(legionPromises);
92
78
  };
93
-
94
79
  const hydrateAccountIds = async (baseUrl, productKey, values) => {
95
80
  if (values.length === 0) {
96
81
  return [];
97
82
  }
83
+ const accountIds = values.map(val => val.id);
98
84
 
99
- const accountIds = values.map(val => val.id); //if we are not jira or confluence then use PRS platform hydration
100
-
85
+ //if we are not jira or confluence then use PRS platform hydration
101
86
  return productKey === 'jira' || productKey === 'confluence' ? await getHydratedUsersFromProducts({
102
87
  baseUrl,
103
88
  productKey,
104
89
  accountIds
105
90
  }) : await getHydratedUsersFromPrs(baseUrl, accountIds);
106
91
  };
107
-
108
92
  async function hydrateDefaultValues(baseUrl, value, productKey) {
109
93
  //return if no value
110
94
  if (!value || Array.isArray(value) && value.length === 0) {
111
95
  return [];
112
96
  }
97
+ const values = Array.isArray(value) ? value : [value];
113
98
 
114
- const values = Array.isArray(value) ? value : [value]; // return if all hydrated
115
-
99
+ // return if all hydrated
116
100
  if (!values.some(val => !isOptionData(val))) {
117
101
  return value;
118
102
  }
119
-
120
103
  const [hydratedUsers, hydratedTeams] = await Promise.all([hydrateAccountIds(baseUrl, productKey, values.filter(val => !isOptionData(val) && val.type === 'user')), hydrateTeamIds(baseUrl, values.filter(val => !isOptionData(val) && val.type === 'team'))]);
121
104
  const hydratedOptions = values.filter(val => isOptionData(val)).map(val => val).concat(hydratedUsers).concat(hydratedTeams);
122
105
  return sortResults(hydratedOptions, values);
123
106
  }
124
-
125
107
  export default hydrateDefaultValues;
@@ -3,7 +3,6 @@ const buildHeaders = () => {
3
3
  headers.append('Content-Type', 'application/json');
4
4
  return headers;
5
5
  };
6
-
7
6
  /**
8
7
  * @param {string} serviceUrl - GraphQL service endpoint
9
8
  * @param {Query} query - GraphQL query
@@ -23,17 +22,14 @@ export function graphqlQuery(serviceUrl, query) {
23
22
  reason: response.statusText
24
23
  });
25
24
  }
26
-
27
25
  return response;
28
26
  }).then(response => response.json()).then(json => {
29
27
  if (json.errors) {
30
28
  var _json$errors$;
31
-
32
29
  return Promise.reject({
33
30
  reason: ((_json$errors$ = json.errors[0]) === null || _json$errors$ === void 0 ? void 0 : _json$errors$.category) || 'default'
34
31
  });
35
32
  }
36
-
37
33
  return json.data;
38
34
  });
39
35
  }
@@ -1,9 +1,7 @@
1
1
  import { transformUsers } from './users-transformer';
2
2
  import { config } from '../config';
3
-
4
3
  const getUserRecommendations = (request, intl) => {
5
4
  var _request$context, _request$context$prod;
6
-
7
5
  const url = config.getRecommendationServiceUrl(request.baseUrl || '');
8
6
  return fetch(url, {
9
7
  method: 'POST',
@@ -42,11 +40,9 @@ const getUserRecommendations = (request, intl) => {
42
40
  if (response.status === 200) {
43
41
  return response.json();
44
42
  }
45
-
46
43
  return Promise.reject({
47
44
  message: `error calling smart service, statusCode=${response.status}, statusText=${response.statusText}`
48
45
  });
49
46
  }).then(response => transformUsers(response, intl));
50
47
  };
51
-
52
48
  export default getUserRecommendations;
@@ -1,6 +1,5 @@
1
1
  import { config } from '../config';
2
2
  import { UNKNOWN_TEAM } from './constants';
3
-
4
3
  const transformTeam = (team, id) => {
5
4
  return {
6
5
  id,
@@ -9,7 +8,6 @@ const transformTeam = (team, id) => {
9
8
  avatarUrl: team.smallAvatarImageUrl
10
9
  };
11
10
  };
12
-
13
11
  const hydrateTeamFromLegion = request => {
14
12
  const url = `${config.getTeamsUrl(request.baseUrl)}/${request.id}`;
15
13
  return fetch(url, {
@@ -22,16 +20,15 @@ const hydrateTeamFromLegion = request => {
22
20
  if (response.status === 200) {
23
21
  return response.json();
24
22
  }
25
-
26
23
  return Promise.reject({
27
24
  message: `error calling Legion, statusCode=${response.status}, statusText=${response.statusText}`
28
25
  });
29
26
  }).then(response => {
30
27
  return transformTeam(response, request.id);
31
- }).catch(() => ({ ...UNKNOWN_TEAM,
28
+ }).catch(() => ({
29
+ ...UNKNOWN_TEAM,
32
30
  // on network error, return original team with label 'Unknown'
33
31
  id: request.id
34
32
  }));
35
33
  };
36
-
37
34
  export default hydrateTeamFromLegion;
@@ -1,7 +1,6 @@
1
1
  import { UNKNOWN_USER } from './constants';
2
2
  import { graphqlQuery } from './graphqlUtils';
3
3
  import { config } from '../config';
4
-
5
4
  /**
6
5
  * @param {string} accountIds ids to hydrate
7
6
  * @return GraphQL Query
@@ -18,12 +17,10 @@ const buildUsersQuery = accountIds => ({
18
17
  accountIds
19
18
  }
20
19
  });
21
-
22
20
  const makeRequest = async (url, accountIds) => {
23
21
  const query = buildUsersQuery(accountIds);
24
22
  return await graphqlQuery(url, query);
25
23
  };
26
-
27
24
  const modifyResponse = users => users.map(({
28
25
  accountId,
29
26
  name,
@@ -34,7 +31,6 @@ const modifyResponse = users => users.map(({
34
31
  name,
35
32
  type: 'user'
36
33
  }));
37
-
38
34
  const getHydratedUsers = (baseUrl, userIds) => {
39
35
  const url = config.getGraphQLUrl(baseUrl);
40
36
  return new Promise(resolve => {
@@ -42,11 +38,11 @@ const getHydratedUsers = (baseUrl, userIds) => {
42
38
  resolve(modifyResponse(data.users));
43
39
  }).catch(() => {
44
40
  // on network error, return original list with label 'Unknown'
45
- resolve(userIds.map(id => ({ ...UNKNOWN_USER,
41
+ resolve(userIds.map(id => ({
42
+ ...UNKNOWN_USER,
46
43
  id
47
44
  })));
48
45
  });
49
46
  });
50
47
  };
51
-
52
48
  export default getHydratedUsers;
@@ -1,20 +1,16 @@
1
1
  import { TeamType, UserType, GroupType } from '@atlaskit/user-picker';
2
2
  import { messages } from '../i18n';
3
3
  var EntityType;
4
-
5
4
  (function (EntityType) {
6
5
  EntityType["USER"] = "USER";
7
6
  EntityType["TEAM"] = "TEAM";
8
7
  EntityType["GROUP"] = "GROUP";
9
8
  })(EntityType || (EntityType = {}));
10
-
11
9
  const getLozenzeProperties = (entity, intl) => {
12
10
  var _entity$attributes, _entity$attributes2;
13
-
14
11
  if ((_entity$attributes = entity.attributes) !== null && _entity$attributes !== void 0 && _entity$attributes.workspaceMember) {
15
12
  return intl.formatMessage(messages.memberLozengeText);
16
13
  }
17
-
18
14
  if ((_entity$attributes2 = entity.attributes) !== null && _entity$attributes2 !== void 0 && _entity$attributes2.isConfluenceExternalCollaborator) {
19
15
  const lozengeTooltipMessage = entity.entityType === EntityType.GROUP ? messages.guestGroupLozengeTooltip : messages.guestUserLozengeTooltip;
20
16
  return {
@@ -23,13 +19,10 @@ const getLozenzeProperties = (entity, intl) => {
23
19
  appearance: 'new'
24
20
  };
25
21
  }
26
-
27
22
  return undefined;
28
23
  };
29
-
30
24
  const transformUser = (item, intl) => {
31
25
  const type = item.entityType;
32
-
33
26
  if (type === EntityType.USER) {
34
27
  const user = item;
35
28
  const lozenge = getLozenzeProperties(user, intl);
@@ -42,7 +35,6 @@ const transformUser = (item, intl) => {
42
35
  lozenge: lozenge
43
36
  };
44
37
  }
45
-
46
38
  if (type === EntityType.TEAM) {
47
39
  const team = item;
48
40
  return {
@@ -56,7 +48,6 @@ const transformUser = (item, intl) => {
56
48
  avatarUrl: team.largeAvatarImageUrl || team.smallAvatarImageUrl
57
49
  };
58
50
  }
59
-
60
51
  if (type === EntityType.GROUP) {
61
52
  const group = item;
62
53
  const lozenge = getLozenzeProperties(group, intl);
@@ -67,8 +58,6 @@ const transformUser = (item, intl) => {
67
58
  lozenge: lozenge
68
59
  };
69
60
  }
70
-
71
61
  return;
72
62
  };
73
-
74
63
  export const transformUsers = (serverResponse, intl) => (serverResponse.recommendedUsers || []).map(item => transformUser(item, intl)).filter(user => !!user).map(user => user);
@@ -1,5 +1,4 @@
1
1
  export let EntityType;
2
-
3
2
  (function (EntityType) {
4
3
  EntityType["USER"] = "USER";
5
4
  EntityType["TEAM"] = "TEAM";
@@ -17,23 +17,26 @@ export const smartUserPickerOptionsShownUfoExperience = new ConcurrentExperience
17
17
  performanceType: ExperiencePerformanceTypes.InlineResult
18
18
  });
19
19
  export const useUFOConcurrentExperience = (experience, id) => {
20
- const experienceForId = experience.getInstance(id); // Equivalent to componentWillMount - replace with @atlaskit/ufo's
21
- // useUFOComponentExperience when it supports ConcurrentExperience.
20
+ const experienceForId = experience.getInstance(id);
22
21
 
22
+ // Equivalent to componentWillMount - replace with @atlaskit/ufo's
23
+ // useUFOComponentExperience when it supports ConcurrentExperience.
23
24
  useState(() => {
24
25
  experienceForId.start();
25
- }); // Replace with @atlaskit/ufo's <ExperienceSuccess> when it supports ConcurrentExperience
26
+ });
26
27
 
28
+ // Replace with @atlaskit/ufo's <ExperienceSuccess> when it supports ConcurrentExperience
27
29
  useEffect(() => {
28
30
  if (experienceForId.state !== UFOExperienceState['FAILED']) {
29
31
  experienceForId.success();
30
32
  }
31
-
32
33
  return () => {
33
34
  if ([UFOExperienceState['STARTED'], UFOExperienceState['IN_PROGRESS']].includes(experienceForId.state)) {
34
35
  experienceForId.abort();
35
36
  }
36
- }; // We only want this useEffect to run once after component mount, so no deps are needed.
37
+ };
38
+
39
+ // We only want this useEffect to run once after component mount, so no deps are needed.
37
40
  // eslint-disable-next-line react-hooks/exhaustive-deps
38
41
  }, []);
39
42
  };
@@ -41,9 +44,7 @@ export class UfoErrorBoundary extends React.Component {
41
44
  componentDidCatch() {
42
45
  smartUserPickerRenderedUfoExperience.getInstance(this.props.id).failure();
43
46
  }
44
-
45
47
  render() {
46
48
  return this.props.children;
47
49
  }
48
-
49
50
  }