@atlaskit/smart-user-picker 8.6.0 → 8.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cjs/components/SmartUserPicker.js +62 -46
- package/dist/cjs/service/recommendation-client.js +1 -1
- package/dist/es2019/components/SmartUserPicker.js +23 -4
- package/dist/es2019/service/recommendation-client.js +1 -1
- package/dist/esm/components/SmartUserPicker.js +62 -46
- package/dist/esm/service/recommendation-client.js +1 -1
- package/dist/types/components/SmartUserPicker.d.ts +1 -0
- package/dist/types/types.d.ts +16 -0
- package/dist/types-ts4.5/components/SmartUserPicker.d.ts +1 -0
- package/dist/types-ts4.5/types.d.ts +16 -0
- package/package.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlassian/smart-user-picker
|
|
2
2
|
|
|
3
|
+
## 8.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`386987f274ff5`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/386987f274ff5) -
|
|
8
|
+
Add support for `restrictTo` prop to filter recommendations by user IDs and group IDs. This allows
|
|
9
|
+
filtering down results based on specific groups or users in a site.
|
|
10
|
+
|
|
11
|
+
**New prop:** `restrictTo?: { userIds?: string[], groupIds?: string[] }`
|
|
12
|
+
|
|
13
|
+
This prop is passed directly to the URS recommendations endpoint's `searchQuery.restrictTo` field,
|
|
14
|
+
enabling you to constrain recommendations to a specific set of users and/or groups.
|
|
15
|
+
|
|
16
|
+
**Feature gate:** `smart-user-picker-restrict-to-gate` - The prop is only forwarded to the backend
|
|
17
|
+
when this feature gate is enabled.
|
|
18
|
+
|
|
19
|
+
## 8.7.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- [`ae3f597598ae8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ae3f597598ae8) -
|
|
24
|
+
Added prop to toggle the ability to return only verified teams. Only applies when includeTeams is
|
|
25
|
+
true.
|
|
26
|
+
|
|
3
27
|
## 8.6.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -32,13 +32,13 @@ var _MessagesIntlProvider = _interopRequireDefault(require("./MessagesIntlProvid
|
|
|
32
32
|
var _types = require("../types");
|
|
33
33
|
var _service = require("../service");
|
|
34
34
|
var _ufoExperiences = require("../ufoExperiences");
|
|
35
|
-
var _excluded = ["allowEmail", "enableEmailSearch", "allowEmailSelectionWhenEmailMatched"
|
|
35
|
+
var _excluded = ["allowEmail", "enableEmailSearch", "allowEmailSelectionWhenEmailMatched"];
|
|
36
36
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
37
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
38
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
39
37
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
40
38
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
41
39
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
40
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
41
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
42
42
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
43
43
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
44
44
|
var DEFAULT_DEBOUNCE_TIME_MS = 150;
|
|
@@ -118,16 +118,16 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
118
118
|
});
|
|
119
119
|
(0, _defineProperty2.default)(_this, "memoizedFilterOptions", (0, _memoizeOne.default)(_this.filterOptions));
|
|
120
120
|
(0, _defineProperty2.default)(_this, "getUsers", (0, _debounce.default)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
121
|
-
var _this$state, query, sessionId, closed, _this$props, baseUrl, childObjectId, containerId, fieldId, includeGroups, includeTeams, includeTeamsUpdates, includeUsers, includeNonLicensedUsers, intl, fetchOptions, maxOptions, objectId, onEmpty, onError, overrideByline, displayEmailInByline, orgId, principalId, productAttributes, productKey, searchQueryFilter, siteId, transformOptions, userResolvers, enableEmailSearch, maxNumberOfResults, startTime, isEmail, recommendationsRequest, _yield$onEmpty, _query, recommendedUsers, userRecommendationsPromise, userResolversPromises, _yield$Promise$all, _yield$Promise$all2, mainRecommendations, userResolverResults, _iterator, _step, option, _iterator2, _step2, _option, _iterator3, _step3, _option2, elapsedTimeMilli, transformedOptions, displayedUsers, is5xxEvent, onErrorProducedError, defaultUsers, _elapsedTimeMilli;
|
|
121
|
+
var _this$state, query, sessionId, closed, _this$props, baseUrl, childObjectId, containerId, fieldId, includeGroups, includeTeams, includeTeamsUpdates, includeUsers, includeNonLicensedUsers, intl, fetchOptions, maxOptions, objectId, onEmpty, onError, overrideByline, displayEmailInByline, verifiedTeams, orgId, principalId, productAttributes, productKey, restrictTo, searchQueryFilter, siteId, transformOptions, userResolvers, enableEmailSearch, maxNumberOfResults, startTime, isEmail, recommendationsRequest, _yield$onEmpty, _query, recommendedUsers, userRecommendationsPromise, userResolversPromises, _yield$Promise$all, _yield$Promise$all2, mainRecommendations, userResolverResults, _iterator, _step, option, _iterator2, _step2, _option, _iterator3, _step3, _option2, elapsedTimeMilli, transformedOptions, displayedUsers, is5xxEvent, onErrorProducedError, defaultUsers, _elapsedTimeMilli;
|
|
122
122
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
123
123
|
while (1) switch (_context.prev = _context.next) {
|
|
124
124
|
case 0:
|
|
125
125
|
_this$state = _this.state, query = _this$state.query, sessionId = _this$state.sessionId, closed = _this$state.closed;
|
|
126
|
-
_this$props = _this.props, baseUrl = _this$props.baseUrl, childObjectId = _this$props.childObjectId, containerId = _this$props.containerId, fieldId = _this$props.fieldId, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, includeTeamsUpdates = _this$props.includeTeamsUpdates, includeUsers = _this$props.includeUsers, includeNonLicensedUsers = _this$props.includeNonLicensedUsers, intl = _this$props.intl, fetchOptions = _this$props.fetchOptions, maxOptions = _this$props.maxOptions, objectId = _this$props.objectId, onEmpty = _this$props.onEmpty, onError = _this$props.onError, overrideByline = _this$props.overrideByline, displayEmailInByline = _this$props.displayEmailInByline, orgId = _this$props.orgId, principalId = _this$props.principalId, productAttributes = _this$props.productAttributes, productKey = _this$props.productKey, searchQueryFilter = _this$props.searchQueryFilter, siteId = _this$props.siteId, transformOptions = _this$props.transformOptions, userResolvers = _this$props.userResolvers, enableEmailSearch = _this$props.enableEmailSearch;
|
|
126
|
+
_this$props = _this.props, baseUrl = _this$props.baseUrl, childObjectId = _this$props.childObjectId, containerId = _this$props.containerId, fieldId = _this$props.fieldId, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, includeTeamsUpdates = _this$props.includeTeamsUpdates, includeUsers = _this$props.includeUsers, includeNonLicensedUsers = _this$props.includeNonLicensedUsers, intl = _this$props.intl, fetchOptions = _this$props.fetchOptions, maxOptions = _this$props.maxOptions, objectId = _this$props.objectId, onEmpty = _this$props.onEmpty, onError = _this$props.onError, overrideByline = _this$props.overrideByline, displayEmailInByline = _this$props.displayEmailInByline, verifiedTeams = _this$props.verifiedTeams, orgId = _this$props.orgId, principalId = _this$props.principalId, productAttributes = _this$props.productAttributes, productKey = _this$props.productKey, restrictTo = _this$props.restrictTo, searchQueryFilter = _this$props.searchQueryFilter, siteId = _this$props.siteId, transformOptions = _this$props.transformOptions, userResolvers = _this$props.userResolvers, enableEmailSearch = _this$props.enableEmailSearch;
|
|
127
127
|
maxNumberOfResults = maxOptions || 100;
|
|
128
128
|
startTime = window.performance.now(); // Check if this is an email search
|
|
129
129
|
isEmail = enableEmailSearch && isEmailQuery(query);
|
|
130
|
-
recommendationsRequest = {
|
|
130
|
+
recommendationsRequest = _objectSpread({
|
|
131
131
|
baseUrl: baseUrl,
|
|
132
132
|
context: {
|
|
133
133
|
containerId: containerId,
|
|
@@ -149,6 +149,7 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
149
149
|
maxNumberOfResults: maxNumberOfResults,
|
|
150
150
|
query: query,
|
|
151
151
|
searchEmail: isEmail,
|
|
152
|
+
verifiedTeams: verifiedTeams,
|
|
152
153
|
/*
|
|
153
154
|
For email-based searches, we have decided to filter out apps.
|
|
154
155
|
Also - because the other 2 filters ((NOT not_mentionable:true) AND (account_status:active)) are included
|
|
@@ -156,7 +157,9 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
156
157
|
Further ref: https://developer.atlassian.com/platform/user-recommendations/guides/frequently-asked-questions/#filter-behavior
|
|
157
158
|
*/
|
|
158
159
|
searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter
|
|
159
|
-
}
|
|
160
|
+
}, restrictTo && (0, _platformFeatureFlags.fg)('smart-user-picker-restrict-to-gate') && {
|
|
161
|
+
restrictTo: restrictTo
|
|
162
|
+
});
|
|
160
163
|
_context.prev = 6;
|
|
161
164
|
_query = _this.state.query;
|
|
162
165
|
_this.fireEvent(_analytics.requestUsersEvent);
|
|
@@ -252,6 +255,19 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
|
|
258
|
+
// Filter to only verified teams when verifiedTeams is true and feature flag is enabled
|
|
259
|
+
if (verifiedTeams && includeTeams && (0, _platformFeatureFlags.fg)('smart-user-picker-managed-teams-gate')) {
|
|
260
|
+
recommendedUsers = recommendedUsers.filter(function (option) {
|
|
261
|
+
if ((0, _userPicker.isTeam)(option)) {
|
|
262
|
+
// Only include teams that are verified
|
|
263
|
+
// The verified property is set by the transformer from the server response
|
|
264
|
+
var team = option;
|
|
265
|
+
return team.verified === true;
|
|
266
|
+
}
|
|
267
|
+
return true; // Keep non-team options
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
255
271
|
// Track if email search found matches for conditional allowEmail logic
|
|
256
272
|
if (isEmail) {
|
|
257
273
|
_this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
|
|
@@ -260,50 +276,50 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
260
276
|
}
|
|
261
277
|
elapsedTimeMilli = window.performance.now() - startTime;
|
|
262
278
|
if (!transformOptions) {
|
|
263
|
-
_context.next =
|
|
279
|
+
_context.next = 42;
|
|
264
280
|
break;
|
|
265
281
|
}
|
|
266
|
-
_context.next =
|
|
282
|
+
_context.next = 39;
|
|
267
283
|
return transformOptions(recommendedUsers, _query);
|
|
268
|
-
case
|
|
284
|
+
case 39:
|
|
269
285
|
_context.t0 = _context.sent;
|
|
270
|
-
_context.next =
|
|
286
|
+
_context.next = 43;
|
|
271
287
|
break;
|
|
272
|
-
case 41:
|
|
273
|
-
_context.t0 = recommendedUsers;
|
|
274
288
|
case 42:
|
|
289
|
+
_context.t0 = recommendedUsers;
|
|
290
|
+
case 43:
|
|
275
291
|
transformedOptions = _context.t0;
|
|
276
292
|
if (!(transformedOptions.length === 0 && onEmpty)) {
|
|
277
|
-
_context.next =
|
|
293
|
+
_context.next = 59;
|
|
278
294
|
break;
|
|
279
295
|
}
|
|
280
|
-
_context.next =
|
|
296
|
+
_context.next = 47;
|
|
281
297
|
return onEmpty(_query);
|
|
282
|
-
case
|
|
298
|
+
case 47:
|
|
283
299
|
_context.t3 = _yield$onEmpty = _context.sent;
|
|
284
300
|
_context.t2 = _context.t3 !== null;
|
|
285
301
|
if (!_context.t2) {
|
|
286
|
-
_context.next =
|
|
302
|
+
_context.next = 51;
|
|
287
303
|
break;
|
|
288
304
|
}
|
|
289
305
|
_context.t2 = _yield$onEmpty !== void 0;
|
|
290
|
-
case
|
|
306
|
+
case 51:
|
|
291
307
|
if (!_context.t2) {
|
|
292
|
-
_context.next =
|
|
308
|
+
_context.next = 55;
|
|
293
309
|
break;
|
|
294
310
|
}
|
|
295
311
|
_context.t4 = _yield$onEmpty;
|
|
296
|
-
_context.next =
|
|
312
|
+
_context.next = 56;
|
|
297
313
|
break;
|
|
298
|
-
case 54:
|
|
299
|
-
_context.t4 = [];
|
|
300
314
|
case 55:
|
|
315
|
+
_context.t4 = [];
|
|
316
|
+
case 56:
|
|
301
317
|
_context.t1 = _context.t4;
|
|
302
|
-
_context.next =
|
|
318
|
+
_context.next = 60;
|
|
303
319
|
break;
|
|
304
|
-
case 58:
|
|
305
|
-
_context.t1 = transformedOptions;
|
|
306
320
|
case 59:
|
|
321
|
+
_context.t1 = transformedOptions;
|
|
322
|
+
case 60:
|
|
307
323
|
displayedUsers = _context.t1;
|
|
308
324
|
_this.setState(function (state) {
|
|
309
325
|
var applicable = state.query === _query;
|
|
@@ -325,10 +341,10 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
325
341
|
loading: loading
|
|
326
342
|
};
|
|
327
343
|
});
|
|
328
|
-
_context.next =
|
|
344
|
+
_context.next = 93;
|
|
329
345
|
break;
|
|
330
|
-
case
|
|
331
|
-
_context.prev =
|
|
346
|
+
case 64:
|
|
347
|
+
_context.prev = 64;
|
|
332
348
|
_context.t5 = _context["catch"](6);
|
|
333
349
|
is5xxEvent = checkIf500Event(_context.t5.statusCode);
|
|
334
350
|
if (!closed && !onError && is5xxEvent) {
|
|
@@ -341,35 +357,35 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
341
357
|
});
|
|
342
358
|
onErrorProducedError = false;
|
|
343
359
|
defaultUsers = [];
|
|
344
|
-
_context.prev =
|
|
360
|
+
_context.prev = 71;
|
|
345
361
|
if (!onError) {
|
|
346
|
-
_context.next =
|
|
362
|
+
_context.next = 81;
|
|
347
363
|
break;
|
|
348
364
|
}
|
|
349
|
-
_context.next =
|
|
365
|
+
_context.next = 75;
|
|
350
366
|
return onError(_context.t5, recommendationsRequest);
|
|
351
|
-
case
|
|
367
|
+
case 75:
|
|
352
368
|
_context.t7 = _context.sent;
|
|
353
369
|
if (_context.t7) {
|
|
354
|
-
_context.next =
|
|
370
|
+
_context.next = 78;
|
|
355
371
|
break;
|
|
356
372
|
}
|
|
357
373
|
_context.t7 = [];
|
|
358
|
-
case
|
|
374
|
+
case 78:
|
|
359
375
|
_context.t6 = _context.t7;
|
|
360
|
-
_context.next =
|
|
376
|
+
_context.next = 82;
|
|
361
377
|
break;
|
|
362
|
-
case 80:
|
|
363
|
-
_context.t6 = [];
|
|
364
378
|
case 81:
|
|
379
|
+
_context.t6 = [];
|
|
380
|
+
case 82:
|
|
365
381
|
defaultUsers = _context.t6;
|
|
366
|
-
_context.next =
|
|
382
|
+
_context.next = 88;
|
|
367
383
|
break;
|
|
368
|
-
case
|
|
369
|
-
_context.prev =
|
|
370
|
-
_context.t8 = _context["catch"](
|
|
384
|
+
case 85:
|
|
385
|
+
_context.prev = 85;
|
|
386
|
+
_context.t8 = _context["catch"](71);
|
|
371
387
|
onErrorProducedError = true;
|
|
372
|
-
case
|
|
388
|
+
case 88:
|
|
373
389
|
if (onErrorProducedError && is5xxEvent) {
|
|
374
390
|
// Log error from fallback data source `onError` to UFO
|
|
375
391
|
_this.optionsShownUfoExperienceInstance.failure(ufoEndStateConfig(_this.props.fieldId));
|
|
@@ -386,11 +402,11 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
386
402
|
elapsedTimeMilli: _elapsedTimeMilli,
|
|
387
403
|
productAttributes: productAttributes
|
|
388
404
|
});
|
|
389
|
-
case
|
|
405
|
+
case 93:
|
|
390
406
|
case "end":
|
|
391
407
|
return _context.stop();
|
|
392
408
|
}
|
|
393
|
-
}, _callee, null, [[6,
|
|
409
|
+
}, _callee, null, [[6, 64], [71, 85]]);
|
|
394
410
|
})), (_this$props$debounceT = _this.props.debounceTime) !== null && _this$props$debounceT !== void 0 ? _this$props$debounceT : 0));
|
|
395
411
|
(0, _defineProperty2.default)(_this, "onInputChange", function (newQuery, sessionId) {
|
|
396
412
|
var query = newQuery || '';
|
|
@@ -562,7 +578,6 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
562
578
|
allowEmail = _this$props2.allowEmail,
|
|
563
579
|
enableEmailSearch = _this$props2.enableEmailSearch,
|
|
564
580
|
allowEmailSelectionWhenEmailMatched = _this$props2.allowEmailSelectionWhenEmailMatched,
|
|
565
|
-
fetchOptions = _this$props2.fetchOptions,
|
|
566
581
|
restProps = (0, _objectWithoutProperties2.default)(_this$props2, _excluded);
|
|
567
582
|
|
|
568
583
|
// Determine whether to allow email selection based on allowEmailSelectionWhenEmailMatched, if needed
|
|
@@ -598,6 +613,7 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
|
|
|
598
613
|
debounceTime: DEFAULT_DEBOUNCE_TIME_MS,
|
|
599
614
|
userResolvers: [],
|
|
600
615
|
enableEmailSearch: false,
|
|
601
|
-
allowEmailSelectionWhenEmailMatched: true
|
|
616
|
+
allowEmailSelectionWhenEmailMatched: true,
|
|
617
|
+
verifiedTeams: false
|
|
602
618
|
});
|
|
603
619
|
var SmartUserPicker = exports.SmartUserPicker = (0, _analyticsNext.withAnalyticsEvents)()((0, _reactIntlNext.injectIntl)(SmartUserPickerWithoutAnalytics));
|
|
@@ -40,7 +40,7 @@ var getUserRecommendations = function getUserRecommendations(request, intl) {
|
|
|
40
40
|
filter: request.searchQueryFilter || '',
|
|
41
41
|
minimumAccessLevel: 'APPLICATION',
|
|
42
42
|
queryString: request.query,
|
|
43
|
-
restrictTo: {
|
|
43
|
+
restrictTo: request.restrictTo || {
|
|
44
44
|
userIds: [],
|
|
45
45
|
groupIds: []
|
|
46
46
|
},
|
|
@@ -103,10 +103,12 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
|
|
|
103
103
|
onError,
|
|
104
104
|
overrideByline,
|
|
105
105
|
displayEmailInByline,
|
|
106
|
+
verifiedTeams,
|
|
106
107
|
orgId,
|
|
107
108
|
principalId,
|
|
108
109
|
productAttributes,
|
|
109
110
|
productKey,
|
|
111
|
+
restrictTo,
|
|
110
112
|
searchQueryFilter,
|
|
111
113
|
siteId,
|
|
112
114
|
transformOptions,
|
|
@@ -140,13 +142,17 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
|
|
|
140
142
|
maxNumberOfResults,
|
|
141
143
|
query,
|
|
142
144
|
searchEmail: isEmail,
|
|
145
|
+
verifiedTeams,
|
|
143
146
|
/*
|
|
144
147
|
For email-based searches, we have decided to filter out apps.
|
|
145
148
|
Also - because the other 2 filters ((NOT not_mentionable:true) AND (account_status:active)) are included
|
|
146
149
|
when filter is empty, they have been added here to maintain consistency.
|
|
147
150
|
Further ref: https://developer.atlassian.com/platform/user-recommendations/guides/frequently-asked-questions/#filter-behavior
|
|
148
151
|
*/
|
|
149
|
-
searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter
|
|
152
|
+
searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter,
|
|
153
|
+
...(restrictTo && fg('smart-user-picker-restrict-to-gate') && {
|
|
154
|
+
restrictTo
|
|
155
|
+
})
|
|
150
156
|
};
|
|
151
157
|
try {
|
|
152
158
|
var _await$onEmpty;
|
|
@@ -198,6 +204,19 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
|
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
206
|
|
|
207
|
+
// Filter to only verified teams when verifiedTeams is true and feature flag is enabled
|
|
208
|
+
if (verifiedTeams && includeTeams && fg('smart-user-picker-managed-teams-gate')) {
|
|
209
|
+
recommendedUsers = recommendedUsers.filter(option => {
|
|
210
|
+
if (isTeam(option)) {
|
|
211
|
+
// Only include teams that are verified
|
|
212
|
+
// The verified property is set by the transformer from the server response
|
|
213
|
+
const team = option;
|
|
214
|
+
return team.verified === true;
|
|
215
|
+
}
|
|
216
|
+
return true; // Keep non-team options
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
201
220
|
// Track if email search found matches for conditional allowEmail logic
|
|
202
221
|
if (isEmail) {
|
|
203
222
|
this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
|
|
@@ -240,7 +259,7 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
|
|
|
240
259
|
let defaultUsers = [];
|
|
241
260
|
try {
|
|
242
261
|
defaultUsers = onError ? (await onError(e, recommendationsRequest)) || [] : [];
|
|
243
|
-
} catch
|
|
262
|
+
} catch {
|
|
244
263
|
onErrorProducedError = true;
|
|
245
264
|
}
|
|
246
265
|
if (onErrorProducedError && is5xxEvent) {
|
|
@@ -402,7 +421,6 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
|
|
|
402
421
|
allowEmail,
|
|
403
422
|
enableEmailSearch,
|
|
404
423
|
allowEmailSelectionWhenEmailMatched,
|
|
405
|
-
fetchOptions,
|
|
406
424
|
...restProps
|
|
407
425
|
} = this.props;
|
|
408
426
|
|
|
@@ -440,6 +458,7 @@ _defineProperty(SmartUserPickerWithoutAnalytics, "defaultProps", {
|
|
|
440
458
|
debounceTime: DEFAULT_DEBOUNCE_TIME_MS,
|
|
441
459
|
userResolvers: [],
|
|
442
460
|
enableEmailSearch: false,
|
|
443
|
-
allowEmailSelectionWhenEmailMatched: true
|
|
461
|
+
allowEmailSelectionWhenEmailMatched: true,
|
|
462
|
+
verifiedTeams: false
|
|
444
463
|
});
|
|
445
464
|
export const SmartUserPicker = withAnalyticsEvents()(injectIntl(SmartUserPickerWithoutAnalytics));
|
|
@@ -9,13 +9,13 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
9
9
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
10
10
|
import _inherits from "@babel/runtime/helpers/inherits";
|
|
11
11
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
12
|
-
var _excluded = ["allowEmail", "enableEmailSearch", "allowEmailSelectionWhenEmailMatched"
|
|
12
|
+
var _excluded = ["allowEmail", "enableEmailSearch", "allowEmailSelectionWhenEmailMatched"];
|
|
13
13
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
14
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
15
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
16
14
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
17
15
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
18
16
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
17
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
19
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
20
20
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
21
21
|
import React from 'react';
|
|
@@ -110,16 +110,16 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
110
110
|
});
|
|
111
111
|
_defineProperty(_this, "memoizedFilterOptions", memoizeOne(_this.filterOptions));
|
|
112
112
|
_defineProperty(_this, "getUsers", debounce( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
113
|
-
var _this$state, query, sessionId, closed, _this$props, baseUrl, childObjectId, containerId, fieldId, includeGroups, includeTeams, includeTeamsUpdates, includeUsers, includeNonLicensedUsers, intl, fetchOptions, maxOptions, objectId, onEmpty, onError, overrideByline, displayEmailInByline, orgId, principalId, productAttributes, productKey, searchQueryFilter, siteId, transformOptions, userResolvers, enableEmailSearch, maxNumberOfResults, startTime, isEmail, recommendationsRequest, _yield$onEmpty, _query, recommendedUsers, userRecommendationsPromise, userResolversPromises, _yield$Promise$all, _yield$Promise$all2, mainRecommendations, userResolverResults, _iterator, _step, option, _iterator2, _step2, _option, _iterator3, _step3, _option2, elapsedTimeMilli, transformedOptions, displayedUsers, is5xxEvent, onErrorProducedError, defaultUsers, _elapsedTimeMilli;
|
|
113
|
+
var _this$state, query, sessionId, closed, _this$props, baseUrl, childObjectId, containerId, fieldId, includeGroups, includeTeams, includeTeamsUpdates, includeUsers, includeNonLicensedUsers, intl, fetchOptions, maxOptions, objectId, onEmpty, onError, overrideByline, displayEmailInByline, verifiedTeams, orgId, principalId, productAttributes, productKey, restrictTo, searchQueryFilter, siteId, transformOptions, userResolvers, enableEmailSearch, maxNumberOfResults, startTime, isEmail, recommendationsRequest, _yield$onEmpty, _query, recommendedUsers, userRecommendationsPromise, userResolversPromises, _yield$Promise$all, _yield$Promise$all2, mainRecommendations, userResolverResults, _iterator, _step, option, _iterator2, _step2, _option, _iterator3, _step3, _option2, elapsedTimeMilli, transformedOptions, displayedUsers, is5xxEvent, onErrorProducedError, defaultUsers, _elapsedTimeMilli;
|
|
114
114
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
115
115
|
while (1) switch (_context.prev = _context.next) {
|
|
116
116
|
case 0:
|
|
117
117
|
_this$state = _this.state, query = _this$state.query, sessionId = _this$state.sessionId, closed = _this$state.closed;
|
|
118
|
-
_this$props = _this.props, baseUrl = _this$props.baseUrl, childObjectId = _this$props.childObjectId, containerId = _this$props.containerId, fieldId = _this$props.fieldId, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, includeTeamsUpdates = _this$props.includeTeamsUpdates, includeUsers = _this$props.includeUsers, includeNonLicensedUsers = _this$props.includeNonLicensedUsers, intl = _this$props.intl, fetchOptions = _this$props.fetchOptions, maxOptions = _this$props.maxOptions, objectId = _this$props.objectId, onEmpty = _this$props.onEmpty, onError = _this$props.onError, overrideByline = _this$props.overrideByline, displayEmailInByline = _this$props.displayEmailInByline, orgId = _this$props.orgId, principalId = _this$props.principalId, productAttributes = _this$props.productAttributes, productKey = _this$props.productKey, searchQueryFilter = _this$props.searchQueryFilter, siteId = _this$props.siteId, transformOptions = _this$props.transformOptions, userResolvers = _this$props.userResolvers, enableEmailSearch = _this$props.enableEmailSearch;
|
|
118
|
+
_this$props = _this.props, baseUrl = _this$props.baseUrl, childObjectId = _this$props.childObjectId, containerId = _this$props.containerId, fieldId = _this$props.fieldId, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, includeTeamsUpdates = _this$props.includeTeamsUpdates, includeUsers = _this$props.includeUsers, includeNonLicensedUsers = _this$props.includeNonLicensedUsers, intl = _this$props.intl, fetchOptions = _this$props.fetchOptions, maxOptions = _this$props.maxOptions, objectId = _this$props.objectId, onEmpty = _this$props.onEmpty, onError = _this$props.onError, overrideByline = _this$props.overrideByline, displayEmailInByline = _this$props.displayEmailInByline, verifiedTeams = _this$props.verifiedTeams, orgId = _this$props.orgId, principalId = _this$props.principalId, productAttributes = _this$props.productAttributes, productKey = _this$props.productKey, restrictTo = _this$props.restrictTo, searchQueryFilter = _this$props.searchQueryFilter, siteId = _this$props.siteId, transformOptions = _this$props.transformOptions, userResolvers = _this$props.userResolvers, enableEmailSearch = _this$props.enableEmailSearch;
|
|
119
119
|
maxNumberOfResults = maxOptions || 100;
|
|
120
120
|
startTime = window.performance.now(); // Check if this is an email search
|
|
121
121
|
isEmail = enableEmailSearch && isEmailQuery(query);
|
|
122
|
-
recommendationsRequest = {
|
|
122
|
+
recommendationsRequest = _objectSpread({
|
|
123
123
|
baseUrl: baseUrl,
|
|
124
124
|
context: {
|
|
125
125
|
containerId: containerId,
|
|
@@ -141,6 +141,7 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
141
141
|
maxNumberOfResults: maxNumberOfResults,
|
|
142
142
|
query: query,
|
|
143
143
|
searchEmail: isEmail,
|
|
144
|
+
verifiedTeams: verifiedTeams,
|
|
144
145
|
/*
|
|
145
146
|
For email-based searches, we have decided to filter out apps.
|
|
146
147
|
Also - because the other 2 filters ((NOT not_mentionable:true) AND (account_status:active)) are included
|
|
@@ -148,7 +149,9 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
148
149
|
Further ref: https://developer.atlassian.com/platform/user-recommendations/guides/frequently-asked-questions/#filter-behavior
|
|
149
150
|
*/
|
|
150
151
|
searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter
|
|
151
|
-
}
|
|
152
|
+
}, restrictTo && fg('smart-user-picker-restrict-to-gate') && {
|
|
153
|
+
restrictTo: restrictTo
|
|
154
|
+
});
|
|
152
155
|
_context.prev = 6;
|
|
153
156
|
_query = _this.state.query;
|
|
154
157
|
_this.fireEvent(requestUsersEvent);
|
|
@@ -244,6 +247,19 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
|
|
250
|
+
// Filter to only verified teams when verifiedTeams is true and feature flag is enabled
|
|
251
|
+
if (verifiedTeams && includeTeams && fg('smart-user-picker-managed-teams-gate')) {
|
|
252
|
+
recommendedUsers = recommendedUsers.filter(function (option) {
|
|
253
|
+
if (isTeam(option)) {
|
|
254
|
+
// Only include teams that are verified
|
|
255
|
+
// The verified property is set by the transformer from the server response
|
|
256
|
+
var team = option;
|
|
257
|
+
return team.verified === true;
|
|
258
|
+
}
|
|
259
|
+
return true; // Keep non-team options
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
247
263
|
// Track if email search found matches for conditional allowEmail logic
|
|
248
264
|
if (isEmail) {
|
|
249
265
|
_this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
|
|
@@ -252,50 +268,50 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
252
268
|
}
|
|
253
269
|
elapsedTimeMilli = window.performance.now() - startTime;
|
|
254
270
|
if (!transformOptions) {
|
|
255
|
-
_context.next =
|
|
271
|
+
_context.next = 42;
|
|
256
272
|
break;
|
|
257
273
|
}
|
|
258
|
-
_context.next =
|
|
274
|
+
_context.next = 39;
|
|
259
275
|
return transformOptions(recommendedUsers, _query);
|
|
260
|
-
case
|
|
276
|
+
case 39:
|
|
261
277
|
_context.t0 = _context.sent;
|
|
262
|
-
_context.next =
|
|
278
|
+
_context.next = 43;
|
|
263
279
|
break;
|
|
264
|
-
case 41:
|
|
265
|
-
_context.t0 = recommendedUsers;
|
|
266
280
|
case 42:
|
|
281
|
+
_context.t0 = recommendedUsers;
|
|
282
|
+
case 43:
|
|
267
283
|
transformedOptions = _context.t0;
|
|
268
284
|
if (!(transformedOptions.length === 0 && onEmpty)) {
|
|
269
|
-
_context.next =
|
|
285
|
+
_context.next = 59;
|
|
270
286
|
break;
|
|
271
287
|
}
|
|
272
|
-
_context.next =
|
|
288
|
+
_context.next = 47;
|
|
273
289
|
return onEmpty(_query);
|
|
274
|
-
case
|
|
290
|
+
case 47:
|
|
275
291
|
_context.t3 = _yield$onEmpty = _context.sent;
|
|
276
292
|
_context.t2 = _context.t3 !== null;
|
|
277
293
|
if (!_context.t2) {
|
|
278
|
-
_context.next =
|
|
294
|
+
_context.next = 51;
|
|
279
295
|
break;
|
|
280
296
|
}
|
|
281
297
|
_context.t2 = _yield$onEmpty !== void 0;
|
|
282
|
-
case
|
|
298
|
+
case 51:
|
|
283
299
|
if (!_context.t2) {
|
|
284
|
-
_context.next =
|
|
300
|
+
_context.next = 55;
|
|
285
301
|
break;
|
|
286
302
|
}
|
|
287
303
|
_context.t4 = _yield$onEmpty;
|
|
288
|
-
_context.next =
|
|
304
|
+
_context.next = 56;
|
|
289
305
|
break;
|
|
290
|
-
case 54:
|
|
291
|
-
_context.t4 = [];
|
|
292
306
|
case 55:
|
|
307
|
+
_context.t4 = [];
|
|
308
|
+
case 56:
|
|
293
309
|
_context.t1 = _context.t4;
|
|
294
|
-
_context.next =
|
|
310
|
+
_context.next = 60;
|
|
295
311
|
break;
|
|
296
|
-
case 58:
|
|
297
|
-
_context.t1 = transformedOptions;
|
|
298
312
|
case 59:
|
|
313
|
+
_context.t1 = transformedOptions;
|
|
314
|
+
case 60:
|
|
299
315
|
displayedUsers = _context.t1;
|
|
300
316
|
_this.setState(function (state) {
|
|
301
317
|
var applicable = state.query === _query;
|
|
@@ -317,10 +333,10 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
317
333
|
loading: loading
|
|
318
334
|
};
|
|
319
335
|
});
|
|
320
|
-
_context.next =
|
|
336
|
+
_context.next = 93;
|
|
321
337
|
break;
|
|
322
|
-
case
|
|
323
|
-
_context.prev =
|
|
338
|
+
case 64:
|
|
339
|
+
_context.prev = 64;
|
|
324
340
|
_context.t5 = _context["catch"](6);
|
|
325
341
|
is5xxEvent = checkIf500Event(_context.t5.statusCode);
|
|
326
342
|
if (!closed && !onError && is5xxEvent) {
|
|
@@ -333,35 +349,35 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
333
349
|
});
|
|
334
350
|
onErrorProducedError = false;
|
|
335
351
|
defaultUsers = [];
|
|
336
|
-
_context.prev =
|
|
352
|
+
_context.prev = 71;
|
|
337
353
|
if (!onError) {
|
|
338
|
-
_context.next =
|
|
354
|
+
_context.next = 81;
|
|
339
355
|
break;
|
|
340
356
|
}
|
|
341
|
-
_context.next =
|
|
357
|
+
_context.next = 75;
|
|
342
358
|
return onError(_context.t5, recommendationsRequest);
|
|
343
|
-
case
|
|
359
|
+
case 75:
|
|
344
360
|
_context.t7 = _context.sent;
|
|
345
361
|
if (_context.t7) {
|
|
346
|
-
_context.next =
|
|
362
|
+
_context.next = 78;
|
|
347
363
|
break;
|
|
348
364
|
}
|
|
349
365
|
_context.t7 = [];
|
|
350
|
-
case
|
|
366
|
+
case 78:
|
|
351
367
|
_context.t6 = _context.t7;
|
|
352
|
-
_context.next =
|
|
368
|
+
_context.next = 82;
|
|
353
369
|
break;
|
|
354
|
-
case 80:
|
|
355
|
-
_context.t6 = [];
|
|
356
370
|
case 81:
|
|
371
|
+
_context.t6 = [];
|
|
372
|
+
case 82:
|
|
357
373
|
defaultUsers = _context.t6;
|
|
358
|
-
_context.next =
|
|
374
|
+
_context.next = 88;
|
|
359
375
|
break;
|
|
360
|
-
case
|
|
361
|
-
_context.prev =
|
|
362
|
-
_context.t8 = _context["catch"](
|
|
376
|
+
case 85:
|
|
377
|
+
_context.prev = 85;
|
|
378
|
+
_context.t8 = _context["catch"](71);
|
|
363
379
|
onErrorProducedError = true;
|
|
364
|
-
case
|
|
380
|
+
case 88:
|
|
365
381
|
if (onErrorProducedError && is5xxEvent) {
|
|
366
382
|
// Log error from fallback data source `onError` to UFO
|
|
367
383
|
_this.optionsShownUfoExperienceInstance.failure(ufoEndStateConfig(_this.props.fieldId));
|
|
@@ -378,11 +394,11 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
378
394
|
elapsedTimeMilli: _elapsedTimeMilli,
|
|
379
395
|
productAttributes: productAttributes
|
|
380
396
|
});
|
|
381
|
-
case
|
|
397
|
+
case 93:
|
|
382
398
|
case "end":
|
|
383
399
|
return _context.stop();
|
|
384
400
|
}
|
|
385
|
-
}, _callee, null, [[6,
|
|
401
|
+
}, _callee, null, [[6, 64], [71, 85]]);
|
|
386
402
|
})), (_this$props$debounceT = _this.props.debounceTime) !== null && _this$props$debounceT !== void 0 ? _this$props$debounceT : 0));
|
|
387
403
|
_defineProperty(_this, "onInputChange", function (newQuery, sessionId) {
|
|
388
404
|
var query = newQuery || '';
|
|
@@ -554,7 +570,6 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
|
|
|
554
570
|
allowEmail = _this$props2.allowEmail,
|
|
555
571
|
enableEmailSearch = _this$props2.enableEmailSearch,
|
|
556
572
|
allowEmailSelectionWhenEmailMatched = _this$props2.allowEmailSelectionWhenEmailMatched,
|
|
557
|
-
fetchOptions = _this$props2.fetchOptions,
|
|
558
573
|
restProps = _objectWithoutProperties(_this$props2, _excluded);
|
|
559
574
|
|
|
560
575
|
// Determine whether to allow email selection based on allowEmailSelectionWhenEmailMatched, if needed
|
|
@@ -592,6 +607,7 @@ _defineProperty(SmartUserPickerWithoutAnalytics, "defaultProps", {
|
|
|
592
607
|
debounceTime: DEFAULT_DEBOUNCE_TIME_MS,
|
|
593
608
|
userResolvers: [],
|
|
594
609
|
enableEmailSearch: false,
|
|
595
|
-
allowEmailSelectionWhenEmailMatched: true
|
|
610
|
+
allowEmailSelectionWhenEmailMatched: true,
|
|
611
|
+
verifiedTeams: false
|
|
596
612
|
});
|
|
597
613
|
export var SmartUserPicker = withAnalyticsEvents()(injectIntl(SmartUserPickerWithoutAnalytics));
|
|
@@ -33,7 +33,7 @@ var getUserRecommendations = function getUserRecommendations(request, intl) {
|
|
|
33
33
|
filter: request.searchQueryFilter || '',
|
|
34
34
|
minimumAccessLevel: 'APPLICATION',
|
|
35
35
|
queryString: request.query,
|
|
36
|
-
restrictTo: {
|
|
36
|
+
restrictTo: request.restrictTo || {
|
|
37
37
|
userIds: [],
|
|
38
38
|
groupIds: []
|
|
39
39
|
},
|
|
@@ -21,6 +21,7 @@ export declare class SmartUserPickerWithoutAnalytics extends React.Component<Pro
|
|
|
21
21
|
userResolvers: never[];
|
|
22
22
|
enableEmailSearch: boolean;
|
|
23
23
|
allowEmailSelectionWhenEmailMatched: boolean;
|
|
24
|
+
verifiedTeams: boolean;
|
|
24
25
|
};
|
|
25
26
|
constructor(props: Props & WrappedComponentProps);
|
|
26
27
|
componentDidMount(): Promise<void>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ export interface Context {
|
|
|
12
12
|
organizationId?: string;
|
|
13
13
|
productAttributes?: ProductAttributes;
|
|
14
14
|
}
|
|
15
|
+
export interface RestrictionFilter {
|
|
16
|
+
userIds?: string[];
|
|
17
|
+
groupIds?: string[];
|
|
18
|
+
}
|
|
15
19
|
export interface RecommendationRequest {
|
|
16
20
|
baseUrl?: string;
|
|
17
21
|
context: Context;
|
|
@@ -23,6 +27,8 @@ export interface RecommendationRequest {
|
|
|
23
27
|
includeTeams?: boolean;
|
|
24
28
|
includeNonLicensedUsers?: boolean;
|
|
25
29
|
searchEmail?: boolean;
|
|
30
|
+
verifiedTeams?: boolean;
|
|
31
|
+
restrictTo?: RestrictionFilter;
|
|
26
32
|
}
|
|
27
33
|
type OnError = (error: any, request: RecommendationRequest) => Promise<OptionData[]> | void;
|
|
28
34
|
type OnValueError = (error: any, defaultValue: DefaultValue) => Promise<OptionData[]> | void;
|
|
@@ -126,6 +132,10 @@ export interface SmartProps {
|
|
|
126
132
|
* Whether to include teams in the resultset. @default false
|
|
127
133
|
*/
|
|
128
134
|
includeTeams?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* When set to true, only returns verified teams. Only applies when includeTeams is true. @default false
|
|
137
|
+
*/
|
|
138
|
+
verifiedTeams?: boolean;
|
|
129
139
|
/**
|
|
130
140
|
* Whether to include users in the resultset. @default true
|
|
131
141
|
*/
|
|
@@ -242,6 +252,12 @@ export interface SmartProps {
|
|
|
242
252
|
isFooterFocused?: boolean;
|
|
243
253
|
/** Sets if the footer is focused or not. This is needed to keep the menu open when the footer is focused */
|
|
244
254
|
setIsFooterFocused?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
255
|
+
/**
|
|
256
|
+
* Restricts the recommendations to specific users and/or groups.
|
|
257
|
+
* If provided, only users matching the provided user IDs and/or groups matching the provided group IDs will be included in the results.
|
|
258
|
+
* @example { userIds: ["123", "456"], groupIds: ["789"] }
|
|
259
|
+
*/
|
|
260
|
+
restrictTo?: RestrictionFilter;
|
|
245
261
|
}
|
|
246
262
|
export interface Props extends SmartProps, UserPickerProps, WithAnalyticsEventsProps {
|
|
247
263
|
/**
|
|
@@ -21,6 +21,7 @@ export declare class SmartUserPickerWithoutAnalytics extends React.Component<Pro
|
|
|
21
21
|
userResolvers: never[];
|
|
22
22
|
enableEmailSearch: boolean;
|
|
23
23
|
allowEmailSelectionWhenEmailMatched: boolean;
|
|
24
|
+
verifiedTeams: boolean;
|
|
24
25
|
};
|
|
25
26
|
constructor(props: Props & WrappedComponentProps);
|
|
26
27
|
componentDidMount(): Promise<void>;
|
|
@@ -12,6 +12,10 @@ export interface Context {
|
|
|
12
12
|
organizationId?: string;
|
|
13
13
|
productAttributes?: ProductAttributes;
|
|
14
14
|
}
|
|
15
|
+
export interface RestrictionFilter {
|
|
16
|
+
userIds?: string[];
|
|
17
|
+
groupIds?: string[];
|
|
18
|
+
}
|
|
15
19
|
export interface RecommendationRequest {
|
|
16
20
|
baseUrl?: string;
|
|
17
21
|
context: Context;
|
|
@@ -23,6 +27,8 @@ export interface RecommendationRequest {
|
|
|
23
27
|
includeTeams?: boolean;
|
|
24
28
|
includeNonLicensedUsers?: boolean;
|
|
25
29
|
searchEmail?: boolean;
|
|
30
|
+
verifiedTeams?: boolean;
|
|
31
|
+
restrictTo?: RestrictionFilter;
|
|
26
32
|
}
|
|
27
33
|
type OnError = (error: any, request: RecommendationRequest) => Promise<OptionData[]> | void;
|
|
28
34
|
type OnValueError = (error: any, defaultValue: DefaultValue) => Promise<OptionData[]> | void;
|
|
@@ -126,6 +132,10 @@ export interface SmartProps {
|
|
|
126
132
|
* Whether to include teams in the resultset. @default false
|
|
127
133
|
*/
|
|
128
134
|
includeTeams?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* When set to true, only returns verified teams. Only applies when includeTeams is true. @default false
|
|
137
|
+
*/
|
|
138
|
+
verifiedTeams?: boolean;
|
|
129
139
|
/**
|
|
130
140
|
* Whether to include users in the resultset. @default true
|
|
131
141
|
*/
|
|
@@ -242,6 +252,12 @@ export interface SmartProps {
|
|
|
242
252
|
isFooterFocused?: boolean;
|
|
243
253
|
/** Sets if the footer is focused or not. This is needed to keep the menu open when the footer is focused */
|
|
244
254
|
setIsFooterFocused?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
255
|
+
/**
|
|
256
|
+
* Restricts the recommendations to specific users and/or groups.
|
|
257
|
+
* If provided, only users matching the provided user IDs and/or groups matching the provided group IDs will be included in the results.
|
|
258
|
+
* @example { userIds: ["123", "456"], groupIds: ["789"] }
|
|
259
|
+
*/
|
|
260
|
+
restrictTo?: RestrictionFilter;
|
|
245
261
|
}
|
|
246
262
|
export interface Props extends SmartProps, UserPickerProps, WithAnalyticsEventsProps {
|
|
247
263
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/smart-user-picker",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.8.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -66,6 +66,12 @@
|
|
|
66
66
|
},
|
|
67
67
|
"smart-user-picker-load-options-gate": {
|
|
68
68
|
"type": "boolean"
|
|
69
|
+
},
|
|
70
|
+
"smart-user-picker-managed-teams-gate": {
|
|
71
|
+
"type": "boolean"
|
|
72
|
+
},
|
|
73
|
+
"smart-user-picker-restrict-to-gate": {
|
|
74
|
+
"type": "boolean"
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
}
|