@atlaskit/user-picker 8.8.1 → 8.8.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/user-picker
2
2
 
3
+ ## 8.8.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d9b9077397d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d9b9077397d) - [ux] Updated the default copy for the byline when selecting email options in UserPicker.
8
+
9
+ ## 8.8.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [`3553b21ec20`](https://bitbucket.org/atlassian/atlassian-frontend/commits/3553b21ec20) - Render time of user picker list is now tracked with UFO
14
+
15
+ ## 8.8.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [`cc773aa7ecc`](https://bitbucket.org/atlassian/atlassian-frontend/commits/cc773aa7ecc) - [ux] show error message in tooltip when there is no user source
20
+
3
21
  ## 8.8.1
4
22
 
5
23
  ### Patch Changes
@@ -25,12 +25,16 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
25
25
 
26
26
  var _analyticsNext = require("@atlaskit/analytics-next");
27
27
 
28
+ var _ufo = require("@atlaskit/ufo");
29
+
28
30
  var _debounce = _interopRequireDefault(require("lodash/debounce"));
29
31
 
30
32
  var _react = _interopRequireDefault(require("react"));
31
33
 
32
34
  var _reactIntlNext = require("react-intl-next");
33
35
 
36
+ var _uuid = require("uuid");
37
+
34
38
  var _analytics = require("../analytics");
35
39
 
36
40
  var _batch = require("./batch");
@@ -39,6 +43,8 @@ var _i18n = require("./i18n");
39
43
 
40
44
  var _utils = require("./utils");
41
45
 
46
+ var _ufoExperiences = require("../util/ufoExperiences");
47
+
42
48
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
43
49
 
44
50
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -233,6 +239,18 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
233
239
  });
234
240
  }
235
241
  }, 200));
242
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "abortOptionsShownUfoExperience", function () {
243
+ if (_this.optionsShownUfoExperienceInstance.state.id === _ufo.UFOExperienceState.STARTED.id) {
244
+ // There may be an existing UFO timing running from previous key entry or focus,
245
+ // so abort it and restart it just in case.
246
+ _this.optionsShownUfoExperienceInstance.abort();
247
+ }
248
+ });
249
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "startOptionsShownUfoExperience", function () {
250
+ _this.abortOptionsShownUfoExperience();
251
+
252
+ _this.optionsShownUfoExperienceInstance.start();
253
+ });
236
254
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "executeLoadOptions", function (search) {
237
255
  var loadOptions = _this.props.loadOptions;
238
256
 
@@ -253,6 +271,8 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
253
271
  _this.startSession();
254
272
  }
255
273
 
274
+ _this.startOptionsShownUfoExperience();
275
+
256
276
  (0, _utils.callCallback)(_this.props.onFocus, _this.getSessionId());
257
277
 
258
278
  _this.setState({
@@ -288,6 +308,8 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
288
308
 
289
309
  _this.resetInputState();
290
310
 
311
+ _this.abortOptionsShownUfoExperience();
312
+
291
313
  _this.setState({
292
314
  menuIsOpen: false,
293
315
  options: []
@@ -313,6 +335,8 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
313
335
  inputValue: search
314
336
  });
315
337
 
338
+ _this.startOptionsShownUfoExperience();
339
+
316
340
  _this.executeLoadOptions(search);
317
341
  }
318
342
  });
@@ -411,6 +435,7 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
411
435
  inputValue: props.search || '',
412
436
  resolving: false
413
437
  };
438
+ _this.optionsShownUfoExperienceInstance = _ufoExperiences.userPickerOptionsShownUfoExperience.getInstance((0, _uuid.v4)());
414
439
  return _this;
415
440
  }
416
441
 
@@ -434,7 +459,9 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
434
459
  value: function componentDidUpdate(_, prevState) {
435
460
  var _this$state2 = this.state,
436
461
  menuIsOpen = _this$state2.menuIsOpen,
437
- options = _this$state2.options; // load options when the picker open
462
+ options = _this$state2.options,
463
+ resolving = _this$state2.resolving,
464
+ count = _this$state2.count; // load options when the picker open
438
465
 
439
466
  if (menuIsOpen && !prevState.menuIsOpen) {
440
467
  if (!this.session) {
@@ -459,6 +486,10 @@ var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Component) {
459
486
  this.session.inputChangeTime = Date.now();
460
487
  }
461
488
  }
489
+
490
+ if (menuIsOpen && (!_.loadOptions || prevState.menuIsOpen) && count === 0 && !resolving && [_ufo.UFOExperienceState.STARTED.id, _ufo.UFOExperienceState.IN_PROGRESS.id].includes(this.optionsShownUfoExperienceInstance.state.id)) {
491
+ this.optionsShownUfoExperienceInstance.success();
492
+ }
462
493
  }
463
494
  }, {
464
495
  key: "render",
@@ -78,8 +78,7 @@ var SUPPORTED_SOURCES = [{
78
78
 
79
79
  var SourcesTooltipContent = function SourcesTooltipContent(_ref) {
80
80
  var sources = _ref.sources,
81
- sourcesLoading = _ref.sourcesLoading,
82
- sourcesError = _ref.sourcesError;
81
+ sourcesLoading = _ref.sourcesLoading;
83
82
 
84
83
  var sourcesToRender = _react.default.useMemo(function () {
85
84
  return SUPPORTED_SOURCES.filter(function (supportedSource) {
@@ -87,7 +86,7 @@ var SourcesTooltipContent = function SourcesTooltipContent(_ref) {
87
86
  });
88
87
  }, [sources]);
89
88
 
90
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesError)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesHeading)), /*#__PURE__*/_react.default.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/_react.default.createElement(_spinner.default, {
89
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, !sourcesLoading && sources.length === 0 ? /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesError)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _i18n.messages.externalUserSourcesHeading)), /*#__PURE__*/_react.default.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/_react.default.createElement(_spinner.default, {
91
90
  size: "small",
92
91
  appearance: "invert"
93
92
  }), !sourcesLoading && sourcesToRender.map(function (_ref2) {
@@ -19,22 +19,19 @@ var ExternalUserSourcesContainer = function ExternalUserSourcesContainer(_ref) {
19
19
 
20
20
  var _useUserSource = (0, _UserSourceProvider.useUserSource)(accountId, shouldFetchSources, initialSources),
21
21
  sources = _useUserSource.sources,
22
- sourcesLoading = _useUserSource.loading,
23
- sourcesError = _useUserSource.error;
22
+ sourcesLoading = _useUserSource.loading;
24
23
 
25
24
  if (typeof children === 'function') {
26
25
  return children({
27
26
  sources: sources,
28
- sourcesLoading: sourcesLoading,
29
- sourcesError: sourcesError
27
+ sourcesLoading: sourcesLoading
30
28
  });
31
29
  }
32
30
 
33
31
  return _react.default.Children.map(children, function (child) {
34
32
  return /*#__PURE__*/_react.default.cloneElement(child, {
35
33
  sources: sources,
36
- sourcesLoading: sourcesLoading,
37
- sourcesError: sourcesError
34
+ sourcesLoading: sourcesLoading
38
35
  });
39
36
  });
40
37
  };
@@ -55,7 +55,7 @@ var messages = (0, _reactIntlNext.defineMessages)({
55
55
  },
56
56
  selectToAddEmail: {
57
57
  id: 'fabric.elements.user-picker.email.select.to.add',
58
- defaultMessage: 'Select then Invite',
58
+ defaultMessage: 'Select an email address',
59
59
  description: 'Byline for valid email option.'
60
60
  },
61
61
  continueToAddEmail: {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.userPickerRenderedUfoExperience = exports.UfoErrorBoundary = void 0;
8
+ exports.userPickerRenderedUfoExperience = exports.userPickerOptionsShownUfoExperience = exports.UfoErrorBoundary = void 0;
9
9
 
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
 
@@ -33,6 +33,14 @@ var userPickerRenderedUfoExperience = new _ufo.ConcurrentExperience('user-picker
33
33
  performanceType: _ufo.ExperiencePerformanceTypes.PageSegmentLoad
34
34
  });
35
35
  exports.userPickerRenderedUfoExperience = userPickerRenderedUfoExperience;
36
+ var userPickerOptionsShownUfoExperience = new _ufo.ConcurrentExperience('user-picker-options-shown', {
37
+ platform: {
38
+ component: 'user-picker'
39
+ },
40
+ type: _ufo.ExperienceTypes.Operation,
41
+ performanceType: _ufo.ExperiencePerformanceTypes.InlineResult
42
+ });
43
+ exports.userPickerOptionsShownUfoExperience = userPickerOptionsShownUfoExperience;
36
44
 
37
45
  var UfoErrorBoundary = /*#__PURE__*/function (_React$Component) {
38
46
  (0, _inherits2.default)(UfoErrorBoundary, _React$Component);
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/user-picker",
3
- "version": "8.8.1",
3
+ "version": "8.8.4",
4
4
  "sideEffects": false
5
5
  }
@@ -1,13 +1,16 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
4
+ import { UFOExperienceState } from '@atlaskit/ufo';
4
5
  import debounce from 'lodash/debounce';
5
6
  import React from 'react';
6
7
  import { FormattedMessage } from 'react-intl-next';
8
+ import { v4 as uuidv4 } from 'uuid';
7
9
  import { cancelEvent, clearEvent, createAndFireEventInElementsChannel, deleteEvent, failedEvent, focusEvent, searchedEvent, selectEvent, startSession } from '../analytics';
8
10
  import { batchByKey } from './batch';
9
11
  import { messages } from './i18n';
10
12
  import { callCallback, extractOptionValue, getOptions, isIterable, isPopupUserPickerByComponent, isDefaultValuePopulated, isSingleValue, optionToSelectableOptions } from './utils';
13
+ import { userPickerOptionsShownUfoExperience } from '../util/ufoExperiences';
11
14
 
12
15
  const loadingMessage = () => null;
13
16
 
@@ -198,6 +201,19 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
198
201
  }
199
202
  }, 200));
200
203
 
204
+ _defineProperty(this, "abortOptionsShownUfoExperience", () => {
205
+ if (this.optionsShownUfoExperienceInstance.state.id === UFOExperienceState.STARTED.id) {
206
+ // There may be an existing UFO timing running from previous key entry or focus,
207
+ // so abort it and restart it just in case.
208
+ this.optionsShownUfoExperienceInstance.abort();
209
+ }
210
+ });
211
+
212
+ _defineProperty(this, "startOptionsShownUfoExperience", () => {
213
+ this.abortOptionsShownUfoExperience();
214
+ this.optionsShownUfoExperienceInstance.start();
215
+ });
216
+
201
217
  _defineProperty(this, "executeLoadOptions", search => {
202
218
  const {
203
219
  loadOptions
@@ -220,6 +236,7 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
220
236
  this.startSession();
221
237
  }
222
238
 
239
+ this.startOptionsShownUfoExperience();
223
240
  callCallback(this.props.onFocus, this.getSessionId());
224
241
  this.setState({
225
242
  menuIsOpen: true
@@ -253,6 +270,7 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
253
270
  }
254
271
 
255
272
  this.resetInputState();
273
+ this.abortOptionsShownUfoExperience();
256
274
  this.setState({
257
275
  menuIsOpen: false,
258
276
  options: []
@@ -276,6 +294,7 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
276
294
  this.setState({
277
295
  inputValue: search
278
296
  });
297
+ this.startOptionsShownUfoExperience();
279
298
  this.executeLoadOptions(search);
280
299
  }
281
300
  });
@@ -373,6 +392,7 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
373
392
  inputValue: props.search || '',
374
393
  resolving: false
375
394
  };
395
+ this.optionsShownUfoExperienceInstance = userPickerOptionsShownUfoExperience.getInstance(uuidv4());
376
396
  }
377
397
 
378
398
  componentDidMount() {
@@ -393,7 +413,9 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
393
413
  componentDidUpdate(_, prevState) {
394
414
  const {
395
415
  menuIsOpen,
396
- options
416
+ options,
417
+ resolving,
418
+ count
397
419
  } = this.state; // load options when the picker open
398
420
 
399
421
  if (menuIsOpen && !prevState.menuIsOpen) {
@@ -419,6 +441,10 @@ export class BaseUserPickerWithoutAnalytics extends React.Component {
419
441
  this.session.inputChangeTime = Date.now();
420
442
  }
421
443
  }
444
+
445
+ if (menuIsOpen && (!_.loadOptions || prevState.menuIsOpen) && count === 0 && !resolving && [UFOExperienceState.STARTED.id, UFOExperienceState.IN_PROGRESS.id].includes(this.optionsShownUfoExperienceInstance.state.id)) {
446
+ this.optionsShownUfoExperienceInstance.success();
447
+ }
422
448
  }
423
449
 
424
450
  render() {
@@ -55,11 +55,10 @@ const SUPPORTED_SOURCES = [{
55
55
  }];
56
56
  export const SourcesTooltipContent = ({
57
57
  sources,
58
- sourcesLoading,
59
- sourcesError
58
+ sourcesLoading
60
59
  }) => {
61
60
  const sourcesToRender = React.useMemo(() => SUPPORTED_SOURCES.filter(supportedSource => sources.includes(supportedSource.sourceType)), [sources]);
62
- return /*#__PURE__*/React.createElement(React.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
61
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !sourcesLoading && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
63
62
  size: "small",
64
63
  appearance: "invert"
65
64
  }), !sourcesLoading && sourcesToRender.map(({
@@ -8,21 +8,18 @@ export const ExternalUserSourcesContainer = ({
8
8
  }) => {
9
9
  const {
10
10
  sources,
11
- loading: sourcesLoading,
12
- error: sourcesError
11
+ loading: sourcesLoading
13
12
  } = useUserSource(accountId, shouldFetchSources, initialSources);
14
13
 
15
14
  if (typeof children === 'function') {
16
15
  return children({
17
16
  sources,
18
- sourcesLoading,
19
- sourcesError
17
+ sourcesLoading
20
18
  });
21
19
  }
22
20
 
23
21
  return React.Children.map(children, child => /*#__PURE__*/React.cloneElement(child, {
24
22
  sources,
25
- sourcesLoading,
26
- sourcesError
23
+ sourcesLoading
27
24
  }));
28
25
  };
@@ -47,7 +47,7 @@ export const messages = defineMessages({
47
47
  },
48
48
  selectToAddEmail: {
49
49
  id: 'fabric.elements.user-picker.email.select.to.add',
50
- defaultMessage: 'Select then Invite',
50
+ defaultMessage: 'Select an email address',
51
51
  description: 'Byline for valid email option.'
52
52
  },
53
53
  continueToAddEmail: {
@@ -7,6 +7,13 @@ export const userPickerRenderedUfoExperience = new ConcurrentExperience('user-pi
7
7
  type: ExperienceTypes.Load,
8
8
  performanceType: ExperiencePerformanceTypes.PageSegmentLoad
9
9
  });
10
+ export const userPickerOptionsShownUfoExperience = new ConcurrentExperience('user-picker-options-shown', {
11
+ platform: {
12
+ component: 'user-picker'
13
+ },
14
+ type: ExperienceTypes.Operation,
15
+ performanceType: ExperiencePerformanceTypes.InlineResult
16
+ });
10
17
  export class UfoErrorBoundary extends React.Component {
11
18
  componentDidCatch() {
12
19
  const instance = userPickerRenderedUfoExperience.getInstance(this.props.id);
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/user-picker",
3
- "version": "8.8.1",
3
+ "version": "8.8.4",
4
4
  "sideEffects": false
5
5
  }
@@ -18,13 +18,16 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
18
18
  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; } }
19
19
 
20
20
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
21
+ import { UFOExperienceState } from '@atlaskit/ufo';
21
22
  import debounce from 'lodash/debounce';
22
23
  import React from 'react';
23
24
  import { FormattedMessage } from 'react-intl-next';
25
+ import { v4 as uuidv4 } from 'uuid';
24
26
  import { cancelEvent, clearEvent, createAndFireEventInElementsChannel, deleteEvent, failedEvent, focusEvent, searchedEvent, selectEvent, startSession } from '../analytics';
25
27
  import { batchByKey } from './batch';
26
28
  import { messages } from './i18n';
27
29
  import { callCallback, extractOptionValue, getOptions, isIterable, isPopupUserPickerByComponent, isDefaultValuePopulated, isSingleValue, optionToSelectableOptions } from './utils';
30
+ import { userPickerOptionsShownUfoExperience } from '../util/ufoExperiences';
28
31
 
29
32
  var loadingMessage = function loadingMessage() {
30
33
  return null;
@@ -224,6 +227,20 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
224
227
  }
225
228
  }, 200));
226
229
 
230
+ _defineProperty(_assertThisInitialized(_this), "abortOptionsShownUfoExperience", function () {
231
+ if (_this.optionsShownUfoExperienceInstance.state.id === UFOExperienceState.STARTED.id) {
232
+ // There may be an existing UFO timing running from previous key entry or focus,
233
+ // so abort it and restart it just in case.
234
+ _this.optionsShownUfoExperienceInstance.abort();
235
+ }
236
+ });
237
+
238
+ _defineProperty(_assertThisInitialized(_this), "startOptionsShownUfoExperience", function () {
239
+ _this.abortOptionsShownUfoExperience();
240
+
241
+ _this.optionsShownUfoExperienceInstance.start();
242
+ });
243
+
227
244
  _defineProperty(_assertThisInitialized(_this), "executeLoadOptions", function (search) {
228
245
  var loadOptions = _this.props.loadOptions;
229
246
 
@@ -245,6 +262,8 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
245
262
  _this.startSession();
246
263
  }
247
264
 
265
+ _this.startOptionsShownUfoExperience();
266
+
248
267
  callCallback(_this.props.onFocus, _this.getSessionId());
249
268
 
250
269
  _this.setState({
@@ -282,6 +301,8 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
282
301
 
283
302
  _this.resetInputState();
284
303
 
304
+ _this.abortOptionsShownUfoExperience();
305
+
285
306
  _this.setState({
286
307
  menuIsOpen: false,
287
308
  options: []
@@ -309,6 +330,8 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
309
330
  inputValue: search
310
331
  });
311
332
 
333
+ _this.startOptionsShownUfoExperience();
334
+
312
335
  _this.executeLoadOptions(search);
313
336
  }
314
337
  });
@@ -414,6 +437,7 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
414
437
  inputValue: props.search || '',
415
438
  resolving: false
416
439
  };
440
+ _this.optionsShownUfoExperienceInstance = userPickerOptionsShownUfoExperience.getInstance(uuidv4());
417
441
  return _this;
418
442
  }
419
443
 
@@ -437,7 +461,9 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
437
461
  value: function componentDidUpdate(_, prevState) {
438
462
  var _this$state2 = this.state,
439
463
  menuIsOpen = _this$state2.menuIsOpen,
440
- options = _this$state2.options; // load options when the picker open
464
+ options = _this$state2.options,
465
+ resolving = _this$state2.resolving,
466
+ count = _this$state2.count; // load options when the picker open
441
467
 
442
468
  if (menuIsOpen && !prevState.menuIsOpen) {
443
469
  if (!this.session) {
@@ -462,6 +488,10 @@ export var BaseUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compon
462
488
  this.session.inputChangeTime = Date.now();
463
489
  }
464
490
  }
491
+
492
+ if (menuIsOpen && (!_.loadOptions || prevState.menuIsOpen) && count === 0 && !resolving && [UFOExperienceState.STARTED.id, UFOExperienceState.IN_PROGRESS.id].includes(this.optionsShownUfoExperienceInstance.state.id)) {
493
+ this.optionsShownUfoExperienceInstance.success();
494
+ }
465
495
  }
466
496
  }, {
467
497
  key: "render",
@@ -52,14 +52,13 @@ var SUPPORTED_SOURCES = [{
52
52
  }];
53
53
  export var SourcesTooltipContent = function SourcesTooltipContent(_ref) {
54
54
  var sources = _ref.sources,
55
- sourcesLoading = _ref.sourcesLoading,
56
- sourcesError = _ref.sourcesError;
55
+ sourcesLoading = _ref.sourcesLoading;
57
56
  var sourcesToRender = React.useMemo(function () {
58
57
  return SUPPORTED_SOURCES.filter(function (supportedSource) {
59
58
  return sources.includes(supportedSource.sourceType);
60
59
  });
61
60
  }, [sources]);
62
- return /*#__PURE__*/React.createElement(React.Fragment, null, sourcesError !== null && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
61
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !sourcesLoading && sources.length === 0 ? /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesError)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.externalUserSourcesHeading)), /*#__PURE__*/React.createElement(SourcesTooltipContainer, null, sourcesLoading && /*#__PURE__*/React.createElement(Spinner, {
63
62
  size: "small",
64
63
  appearance: "invert"
65
64
  }), !sourcesLoading && sourcesToRender.map(function (_ref2) {
@@ -8,22 +8,19 @@ export var ExternalUserSourcesContainer = function ExternalUserSourcesContainer(
8
8
 
9
9
  var _useUserSource = useUserSource(accountId, shouldFetchSources, initialSources),
10
10
  sources = _useUserSource.sources,
11
- sourcesLoading = _useUserSource.loading,
12
- sourcesError = _useUserSource.error;
11
+ sourcesLoading = _useUserSource.loading;
13
12
 
14
13
  if (typeof children === 'function') {
15
14
  return children({
16
15
  sources: sources,
17
- sourcesLoading: sourcesLoading,
18
- sourcesError: sourcesError
16
+ sourcesLoading: sourcesLoading
19
17
  });
20
18
  }
21
19
 
22
20
  return React.Children.map(children, function (child) {
23
21
  return /*#__PURE__*/React.cloneElement(child, {
24
22
  sources: sources,
25
- sourcesLoading: sourcesLoading,
26
- sourcesError: sourcesError
23
+ sourcesLoading: sourcesLoading
27
24
  });
28
25
  });
29
26
  };
@@ -47,7 +47,7 @@ export var messages = defineMessages({
47
47
  },
48
48
  selectToAddEmail: {
49
49
  id: 'fabric.elements.user-picker.email.select.to.add',
50
- defaultMessage: 'Select then Invite',
50
+ defaultMessage: 'Select an email address',
51
51
  description: 'Byline for valid email option.'
52
52
  },
53
53
  continueToAddEmail: {
@@ -17,6 +17,13 @@ export var userPickerRenderedUfoExperience = new ConcurrentExperience('user-pick
17
17
  type: ExperienceTypes.Load,
18
18
  performanceType: ExperiencePerformanceTypes.PageSegmentLoad
19
19
  });
20
+ export var userPickerOptionsShownUfoExperience = new ConcurrentExperience('user-picker-options-shown', {
21
+ platform: {
22
+ component: 'user-picker'
23
+ },
24
+ type: ExperienceTypes.Operation,
25
+ performanceType: ExperiencePerformanceTypes.InlineResult
26
+ });
20
27
  export var UfoErrorBoundary = /*#__PURE__*/function (_React$Component) {
21
28
  _inherits(UfoErrorBoundary, _React$Component);
22
29
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/user-picker",
3
- "version": "8.8.1",
3
+ "version": "8.8.4",
4
4
  "sideEffects": false
5
5
  }
@@ -19,6 +19,7 @@ export declare class BaseUserPickerWithoutAnalytics extends React.Component<Base
19
19
  private selectRef;
20
20
  private session?;
21
21
  private journeyId?;
22
+ private optionsShownUfoExperienceInstance;
22
23
  constructor(props: BaseUserPickerProps);
23
24
  private getSessionId;
24
25
  private withSelectRef;
@@ -32,6 +33,8 @@ export declare class BaseUserPickerWithoutAnalytics extends React.Component<Base
32
33
  private addOptions;
33
34
  private handleLoadOptionsError;
34
35
  private debouncedLoadOptions;
36
+ abortOptionsShownUfoExperience: () => void;
37
+ startOptionsShownUfoExperience: () => void;
35
38
  private executeLoadOptions;
36
39
  private handleFocus;
37
40
  private resetInputState;
@@ -3,7 +3,6 @@ import { UserSource } from '../types';
3
3
  export interface ExternalUserSourcesData {
4
4
  sources: UserSource[];
5
5
  sourcesLoading: boolean;
6
- sourcesError: string | null;
7
6
  }
8
7
  declare type SourcesChildrenFunc = (sourcesData: ExternalUserSourcesData) => ReactNode;
9
8
  interface SourcesContainerProps {
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { ConcurrentExperience } from '@atlaskit/ufo';
3
3
  export declare const userPickerRenderedUfoExperience: ConcurrentExperience;
4
+ export declare const userPickerOptionsShownUfoExperience: ConcurrentExperience;
4
5
  export declare class UfoErrorBoundary extends React.Component<{
5
6
  id: string;
6
7
  }> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/user-picker",
3
- "version": "8.8.1",
3
+ "version": "8.8.4",
4
4
  "description": "Fabric component for display a dropdown to select a user from",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"