@atlaskit/smart-user-picker 8.9.3 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/analytics.js +1 -1
  3. package/dist/cjs/components/SmartUserPicker.js +28 -8
  4. package/dist/cjs/service/atl-attribution.js +39 -0
  5. package/dist/cjs/service/default-value-hydration-client.js +11 -6
  6. package/dist/cjs/service/graphqlUtils.js +10 -3
  7. package/dist/cjs/service/recommendation-client.js +3 -1
  8. package/dist/cjs/service/users-client.js +5 -5
  9. package/dist/cjs/service/users-transformer.js +3 -1
  10. package/dist/es2019/analytics.js +1 -1
  11. package/dist/es2019/components/SmartUserPicker.js +25 -5
  12. package/dist/es2019/service/atl-attribution.js +27 -0
  13. package/dist/es2019/service/default-value-hydration-client.js +7 -4
  14. package/dist/es2019/service/graphqlUtils.js +10 -3
  15. package/dist/es2019/service/recommendation-client.js +3 -0
  16. package/dist/es2019/service/users-client.js +4 -4
  17. package/dist/es2019/service/users-transformer.js +3 -1
  18. package/dist/esm/analytics.js +1 -1
  19. package/dist/esm/components/SmartUserPicker.js +28 -8
  20. package/dist/esm/service/atl-attribution.js +32 -0
  21. package/dist/esm/service/default-value-hydration-client.js +11 -6
  22. package/dist/esm/service/graphqlUtils.js +10 -3
  23. package/dist/esm/service/recommendation-client.js +3 -1
  24. package/dist/esm/service/users-client.js +5 -5
  25. package/dist/esm/service/users-transformer.js +3 -1
  26. package/dist/types/service/atl-attribution.d.ts +20 -0
  27. package/dist/types/service/default-value-hydration-client.d.ts +4 -1
  28. package/dist/types/service/graphqlUtils.d.ts +4 -2
  29. package/dist/types/service/users-client.d.ts +2 -1
  30. package/dist/types/types.d.ts +19 -1
  31. package/dist/types-ts4.5/service/atl-attribution.d.ts +20 -0
  32. package/dist/types-ts4.5/service/default-value-hydration-client.d.ts +4 -1
  33. package/dist/types-ts4.5/service/graphqlUtils.d.ts +4 -2
  34. package/dist/types-ts4.5/service/users-client.d.ts +2 -1
  35. package/dist/types-ts4.5/types.d.ts +19 -1
  36. package/package.json +9 -6
  37. package/tsconfig.json +1 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlassian/smart-user-picker
2
2
 
3
+ ## 9.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`94aa45d957856`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/94aa45d957856) -
8
+ Add atl-attribution header to network requests for metrics attribution in AGG
9
+
10
+ ## 9.0.0
11
+
12
+ ### Major Changes
13
+
14
+ - [`fe65ecbc97c01`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fe65ecbc97c01) -
15
+ Filter team results to directory-synced teams only, so only supported teams can be selected and
16
+ unsynced teams do not cause errors.
17
+
3
18
  ## 8.9.3
4
19
 
5
20
  ### Patch Changes
@@ -11,7 +11,7 @@ var _uuid = require("uuid");
11
11
  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; }
12
12
  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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
13
13
  var packageName = "@atlaskit/smart-user-picker";
14
- var packageVersion = "8.9.2";
14
+ var packageVersion = "0.0.0-development";
15
15
  var startSession = exports.startSession = function startSession() {
16
16
  return {
17
17
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -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, 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;
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, isTeamSyncedToGroupDirectoryFilter, 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, userMatches, 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, 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;
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, isTeamSyncedToGroupDirectoryFilter = _this$props.isTeamSyncedToGroupDirectoryFilter, 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 = _objectSpread(_objectSpread({
130
+ recommendationsRequest = _objectSpread(_objectSpread(_objectSpread({
131
131
  baseUrl: baseUrl,
132
132
  context: {
133
133
  containerId: containerId,
@@ -149,7 +149,7 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
149
149
  maxNumberOfResults: maxNumberOfResults,
150
150
  query: query,
151
151
  searchEmail: isEmail
152
- }, verifiedTeams === true && (0, _platformFeatureFlags.fg)('smart-user-picker-managed-teams-gate') && {
152
+ }, verifiedTeams === true && {
153
153
  verifiedTeams: true
154
154
  }), {}, {
155
155
  /*
@@ -161,6 +161,8 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
161
161
  searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter
162
162
  }, restrictTo && (0, _platformFeatureFlags.fg)('smart-user-picker-restrict-to-gate') && {
163
163
  restrictTo: restrictTo
164
+ }), isTeamSyncedToGroupDirectoryFilter === true && {
165
+ isTeamSyncedToGroupDirectoryFilter: true
164
166
  });
165
167
  _context.prev = 6;
166
168
  _query = _this.state.query;
@@ -259,7 +261,15 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
259
261
 
260
262
  // Track if email search found matches for conditional allowEmail logic
261
263
  if (isEmail) {
262
- _this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
264
+ if ((0, _platformFeatureFlags.fg)('smart_user_picker_allow_email_if_team_is_found')) {
265
+ // Only count user/external user matches, not teams or groups
266
+ userMatches = recommendedUsers.filter(function (user) {
267
+ return (0, _userPicker.isUser)(user) || (0, _userPicker.isExternalUser)(user);
268
+ });
269
+ _this.lastEmailSearchFoundMatches = userMatches.length > 0;
270
+ } else {
271
+ _this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
272
+ }
263
273
  } else {
264
274
  _this.lastEmailSearchFoundMatches = false;
265
275
  }
@@ -501,7 +511,10 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
501
511
  case 0:
502
512
  _context2.prev = 0;
503
513
  _context2.next = 3;
504
- return (0, _service.hydrateDefaultValues)(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId);
514
+ return (0, _service.hydrateDefaultValues)(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId, {
515
+ tenantId: this.props.siteId,
516
+ activationId: this.props.activationId
517
+ });
505
518
  case 3:
506
519
  value = _context2.sent;
507
520
  this.setState({
@@ -572,9 +585,16 @@ var SmartUserPickerWithoutAnalytics = exports.SmartUserPickerWithoutAnalytics =
572
585
  // Determine whether to allow email selection based on allowEmailSelectionWhenEmailMatched, if needed
573
586
  var shouldAllowEmail = allowEmail;
574
587
  if (allowEmail && enableEmailSearch && !allowEmailSelectionWhenEmailMatched) {
575
- // Only allow email selection if we're in an email search that found no matches
576
588
  var isCurrentQueryEmail = isEmailQuery(this.state.query);
577
- shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
589
+ if ((0, _platformFeatureFlags.fg)('smart_user_picker_allow_email_if_team_is_found')) {
590
+ // Only allow email selection when:
591
+ // 1. The query matches email format (validated by regex)
592
+ // 2. No user/external user matches were found (only teams/groups suggested)
593
+ shouldAllowEmail = isCurrentQueryEmail && !this.lastEmailSearchFoundMatches;
594
+ } else {
595
+ // Only allow email selection if we're in an email search that found no matches
596
+ shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
597
+ }
578
598
  }
579
599
  return /*#__PURE__*/_react.default.createElement(_MessagesIntlProvider.default, null, /*#__PURE__*/_react.default.createElement(_userPicker.default, (0, _extends2.default)({}, restProps, {
580
600
  allowEmail: shouldAllowEmail,
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createAtlAttributionHeader = createAtlAttributionHeader;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
+ var _excluded = ["product", "activationId"];
11
+ 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; }
12
+ 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; }
13
+ /**
14
+ * Utility for creating the atl-attribution header for AGG requests
15
+ * Reference: https://hello.atlassian.net/wiki/spaces/AGG/pages/5954141702/Metrics+Attribution+Onboarding+Doc+for+AGG+Clients
16
+ */
17
+
18
+ /**
19
+ * Creates the atl-attribution header value for network requests.
20
+ * This header is used for metrics attribution in AGG (Analytics & Insights Graph).
21
+ *
22
+ * @param data Optional attribution data including tenantId, atlWorkspaceId, and product
23
+ * @returns Object with atl-attribution header
24
+ */
25
+ function createAtlAttributionHeader() {
26
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
27
+ var _ref$product = _ref.product,
28
+ product = _ref$product === void 0 ? 'platform' : _ref$product,
29
+ activationId = _ref.activationId,
30
+ props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
31
+ var headerData = _objectSpread({
32
+ service: 'smart-experiences/smart-user-picker',
33
+ product: product,
34
+ atlWorkspaceId: activationId && props.tenantId ? "ari:cloud:".concat(product, ":").concat(props.tenantId, ":workspace/").concat(activationId) : undefined
35
+ }, props);
36
+ return {
37
+ 'atl-attribution': JSON.stringify(headerData)
38
+ };
39
+ }
@@ -7,12 +7,15 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
11
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
12
  var _userPicker = require("@atlaskit/user-picker");
12
13
  var _config = require("../config");
13
14
  var _usersClient = _interopRequireDefault(require("./users-client"));
14
15
  var _teamsClient = _interopRequireDefault(require("./teams-client"));
15
16
  var _constants = require("./constants");
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) { (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; }
16
19
  var getHydratedUsersFromProducts = function getHydratedUsersFromProducts(request) {
17
20
  var url = "".concat(_config.config.getUsersServiceUrl(request.productKey, request.baseUrl));
18
21
  var params = new URLSearchParams();
@@ -126,7 +129,7 @@ var hydrateTeamIds = /*#__PURE__*/function () {
126
129
  };
127
130
  }();
128
131
  var hydrateAccountIds = /*#__PURE__*/function () {
129
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(baseUrl, productKey, values) {
132
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(baseUrl, productKey, values, atlAttributes) {
130
133
  var accountIds;
131
134
  return _regenerator.default.wrap(function _callee2$(_context2) {
132
135
  while (1) switch (_context2.prev = _context2.next) {
@@ -156,7 +159,9 @@ var hydrateAccountIds = /*#__PURE__*/function () {
156
159
  break;
157
160
  case 9:
158
161
  _context2.next = 11;
159
- return (0, _usersClient.default)(baseUrl, accountIds);
162
+ return (0, _usersClient.default)(baseUrl, accountIds, _objectSpread({
163
+ product: productKey
164
+ }, atlAttributes));
160
165
  case 11:
161
166
  _context2.t0 = _context2.sent;
162
167
  case 12:
@@ -167,15 +172,15 @@ var hydrateAccountIds = /*#__PURE__*/function () {
167
172
  }
168
173
  }, _callee2);
169
174
  }));
170
- return function hydrateAccountIds(_x4, _x5, _x6) {
175
+ return function hydrateAccountIds(_x4, _x5, _x6, _x7) {
171
176
  return _ref2.apply(this, arguments);
172
177
  };
173
178
  }();
174
- function hydrateDefaultValues(_x7, _x8, _x9, _x0) {
179
+ function hydrateDefaultValues(_x8, _x9, _x0, _x1, _x10) {
175
180
  return _hydrateDefaultValues.apply(this, arguments);
176
181
  }
177
182
  function _hydrateDefaultValues() {
178
- _hydrateDefaultValues = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(baseUrl, value, productKey, siteId) {
183
+ _hydrateDefaultValues = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(baseUrl, value, productKey, siteId, atlAttributes) {
179
184
  var values, _yield$Promise$all, _yield$Promise$all2, hydratedUsers, hydratedTeams, hydratedOptions;
180
185
  return _regenerator.default.wrap(function _callee3$(_context3) {
181
186
  while (1) switch (_context3.prev = _context3.next) {
@@ -198,7 +203,7 @@ function _hydrateDefaultValues() {
198
203
  _context3.next = 7;
199
204
  return Promise.all([hydrateAccountIds(baseUrl, productKey, values.filter(function (val) {
200
205
  return !isOptionData(val) && val.type === 'user';
201
- })), hydrateTeamIds(baseUrl, values.filter(function (val) {
206
+ }), atlAttributes), hydrateTeamIds(baseUrl, values.filter(function (val) {
202
207
  return !isOptionData(val) && val.type === 'team';
203
208
  }), siteId)]);
204
209
  case 7:
@@ -4,17 +4,24 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.graphqlQuery = graphqlQuery;
7
- var buildHeaders = function buildHeaders() {
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
+ var _atlAttribution = require("./atl-attribution");
9
+ var buildHeaders = function buildHeaders(attributionData) {
8
10
  var headers = new Headers();
9
11
  headers.append('Content-Type', 'application/json');
12
+ if ((0, _platformFeatureFlags.fg)('smart-user-picker-attribution-header')) {
13
+ var atlAttributionHeader = (0, _atlAttribution.createAtlAttributionHeader)(attributionData);
14
+ headers.append('atl-attribution', atlAttributionHeader['atl-attribution']);
15
+ }
10
16
  return headers;
11
17
  };
12
18
  /**
13
19
  * @param {string} serviceUrl - GraphQL service endpoint
14
20
  * @param {Query} query - GraphQL query
21
+ * @param {Partial<AtlAttributionHeaderData>} attributionData - Optional attribution data for the atl-attribution header
15
22
  */
16
- function graphqlQuery(serviceUrl, query) {
17
- var headers = buildHeaders();
23
+ function graphqlQuery(serviceUrl, query, attributionData) {
24
+ var headers = buildHeaders(attributionData);
18
25
  return fetch(new Request("".concat(serviceUrl), {
19
26
  method: 'POST',
20
27
  credentials: 'include',
@@ -27,8 +27,10 @@ var getUserRecommendations = function getUserRecommendations(request, intl) {
27
27
  includeNonLicensedUsers: request.includeNonLicensedUsers,
28
28
  maxNumberOfResults: request.maxNumberOfResults,
29
29
  performSearchQueryOnly: false,
30
- searchQuery: _objectSpread(_objectSpread(_objectSpread({}, request.verifiedTeams === true && {
30
+ searchQuery: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, request.verifiedTeams === true && {
31
31
  isVerifiedTeamFilter: true
32
+ }), request.isTeamSyncedToGroupDirectoryFilter === true && {
33
+ isTeamSyncedToGroupDirectoryFilter: true
32
34
  }), {}, {
33
35
  cpusQueryHighlights: {
34
36
  query: '',
@@ -26,14 +26,14 @@ var buildUsersQuery = function buildUsersQuery(accountIds) {
26
26
  };
27
27
  };
28
28
  var makeRequest = /*#__PURE__*/function () {
29
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url, accountIds) {
29
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url, accountIds, attributionData) {
30
30
  var query;
31
31
  return _regenerator.default.wrap(function _callee$(_context) {
32
32
  while (1) switch (_context.prev = _context.next) {
33
33
  case 0:
34
34
  query = buildUsersQuery(accountIds);
35
35
  _context.next = 3;
36
- return (0, _graphqlUtils.graphqlQuery)(url, query);
36
+ return (0, _graphqlUtils.graphqlQuery)(url, query, attributionData);
37
37
  case 3:
38
38
  return _context.abrupt("return", _context.sent);
39
39
  case 4:
@@ -42,7 +42,7 @@ var makeRequest = /*#__PURE__*/function () {
42
42
  }
43
43
  }, _callee);
44
44
  }));
45
- return function makeRequest(_x, _x2) {
45
+ return function makeRequest(_x, _x2, _x3) {
46
46
  return _ref.apply(this, arguments);
47
47
  };
48
48
  }();
@@ -59,10 +59,10 @@ var modifyResponse = function modifyResponse(users) {
59
59
  };
60
60
  });
61
61
  };
62
- var getHydratedUsers = function getHydratedUsers(baseUrl, userIds) {
62
+ var getHydratedUsers = function getHydratedUsers(baseUrl, userIds, attributionData) {
63
63
  var url = _config.config.getGraphQLUrl(baseUrl);
64
64
  return new Promise(function (resolve) {
65
- makeRequest(url, userIds).then(function (data) {
65
+ makeRequest(url, userIds, attributionData).then(function (data) {
66
66
  resolve(modifyResponse(data.users));
67
67
  }).catch(function () {
68
68
  // on network error, return original list with label 'Unknown'
@@ -42,6 +42,7 @@ var transformUser = function transformUser(item, intl) {
42
42
  };
43
43
  }
44
44
  if (type === _types.EntityType.TEAM) {
45
+ var _team$type;
45
46
  var team = item;
46
47
  return {
47
48
  id: team.id,
@@ -53,7 +54,8 @@ var transformUser = function transformUser(item, intl) {
53
54
  includesYou: team.includesYou,
54
55
  avatarUrl: team.largeAvatarImageUrl || team.smallAvatarImageUrl,
55
56
  tooltip: team.displayName,
56
- verified: team.verified
57
+ verified: team.verified,
58
+ teamTypeName: (_team$type = team.type) === null || _team$type === void 0 ? void 0 : _team$type.name
57
59
  };
58
60
  }
59
61
  if (type === _types.EntityType.GROUP) {
@@ -2,7 +2,7 @@ import { createAndFireEvent } from '@atlaskit/analytics-next';
2
2
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
3
3
  import { v4 as uuid } from 'uuid';
4
4
  const packageName = "@atlaskit/smart-user-picker";
5
- const packageVersion = "8.9.2";
5
+ const packageVersion = "0.0.0-development";
6
6
  export const startSession = () => ({
7
7
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
8
8
  id: uuid(),
@@ -111,6 +111,7 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
111
111
  restrictTo,
112
112
  searchQueryFilter,
113
113
  siteId,
114
+ isTeamSyncedToGroupDirectoryFilter,
114
115
  transformOptions,
115
116
  userResolvers,
116
117
  enableEmailSearch
@@ -142,7 +143,7 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
142
143
  maxNumberOfResults,
143
144
  query,
144
145
  searchEmail: isEmail,
145
- ...(verifiedTeams === true && fg('smart-user-picker-managed-teams-gate') && {
146
+ ...(verifiedTeams === true && {
146
147
  verifiedTeams: true
147
148
  }),
148
149
  /*
@@ -154,6 +155,9 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
154
155
  searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter,
155
156
  ...(restrictTo && fg('smart-user-picker-restrict-to-gate') && {
156
157
  restrictTo
158
+ }),
159
+ ...(isTeamSyncedToGroupDirectoryFilter === true && {
160
+ isTeamSyncedToGroupDirectoryFilter: true
157
161
  })
158
162
  };
159
163
  try {
@@ -208,7 +212,13 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
208
212
 
209
213
  // Track if email search found matches for conditional allowEmail logic
210
214
  if (isEmail) {
211
- this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
215
+ if (fg('smart_user_picker_allow_email_if_team_is_found')) {
216
+ // Only count user/external user matches, not teams or groups
217
+ const userMatches = recommendedUsers.filter(user => isUser(user) || isExternalUser(user));
218
+ this.lastEmailSearchFoundMatches = userMatches.length > 0;
219
+ } else {
220
+ this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
221
+ }
212
222
  } else {
213
223
  this.lastEmailSearchFoundMatches = false;
214
224
  }
@@ -365,7 +375,10 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
365
375
  }
366
376
  async componentDidMount() {
367
377
  try {
368
- const value = await hydrateDefaultValues(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId);
378
+ const value = await hydrateDefaultValues(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId, {
379
+ tenantId: this.props.siteId,
380
+ activationId: this.props.activationId
381
+ });
369
382
  this.setState({
370
383
  defaultValue: value
371
384
  });
@@ -416,9 +429,16 @@ export class SmartUserPickerWithoutAnalytics extends React.Component {
416
429
  // Determine whether to allow email selection based on allowEmailSelectionWhenEmailMatched, if needed
417
430
  let shouldAllowEmail = allowEmail;
418
431
  if (allowEmail && enableEmailSearch && !allowEmailSelectionWhenEmailMatched) {
419
- // Only allow email selection if we're in an email search that found no matches
420
432
  const isCurrentQueryEmail = isEmailQuery(this.state.query);
421
- shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
433
+ if (fg('smart_user_picker_allow_email_if_team_is_found')) {
434
+ // Only allow email selection when:
435
+ // 1. The query matches email format (validated by regex)
436
+ // 2. No user/external user matches were found (only teams/groups suggested)
437
+ shouldAllowEmail = isCurrentQueryEmail && !this.lastEmailSearchFoundMatches;
438
+ } else {
439
+ // Only allow email selection if we're in an email search that found no matches
440
+ shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
441
+ }
422
442
  }
423
443
  return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(UserPicker, _extends({}, restProps, {
424
444
  allowEmail: shouldAllowEmail,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Utility for creating the atl-attribution header for AGG requests
3
+ * Reference: https://hello.atlassian.net/wiki/spaces/AGG/pages/5954141702/Metrics+Attribution+Onboarding+Doc+for+AGG+Clients
4
+ */
5
+
6
+ /**
7
+ * Creates the atl-attribution header value for network requests.
8
+ * This header is used for metrics attribution in AGG (Analytics & Insights Graph).
9
+ *
10
+ * @param data Optional attribution data including tenantId, atlWorkspaceId, and product
11
+ * @returns Object with atl-attribution header
12
+ */
13
+ export function createAtlAttributionHeader({
14
+ product = 'platform',
15
+ activationId,
16
+ ...props
17
+ } = {}) {
18
+ const headerData = {
19
+ service: 'smart-experiences/smart-user-picker',
20
+ product,
21
+ atlWorkspaceId: activationId && props.tenantId ? `ari:cloud:${product}:${props.tenantId}:workspace/${activationId}` : undefined,
22
+ ...props
23
+ };
24
+ return {
25
+ 'atl-attribution': JSON.stringify(headerData)
26
+ };
27
+ }
@@ -77,7 +77,7 @@ const hydrateTeamIds = async (baseUrl, values, siteId) => {
77
77
  }));
78
78
  return await Promise.all(legionPromises);
79
79
  };
80
- const hydrateAccountIds = async (baseUrl, productKey, values) => {
80
+ const hydrateAccountIds = async (baseUrl, productKey, values, atlAttributes) => {
81
81
  if (values.length === 0) {
82
82
  return [];
83
83
  }
@@ -88,9 +88,12 @@ const hydrateAccountIds = async (baseUrl, productKey, values) => {
88
88
  baseUrl,
89
89
  productKey,
90
90
  accountIds
91
- }) : await getHydratedUsersFromPrs(baseUrl, accountIds);
91
+ }) : await getHydratedUsersFromPrs(baseUrl, accountIds, {
92
+ product: productKey,
93
+ ...atlAttributes
94
+ });
92
95
  };
93
- async function hydrateDefaultValues(baseUrl, value, productKey, siteId) {
96
+ async function hydrateDefaultValues(baseUrl, value, productKey, siteId, atlAttributes) {
94
97
  //return if no value
95
98
  if (!value || Array.isArray(value) && value.length === 0) {
96
99
  return [];
@@ -101,7 +104,7 @@ async function hydrateDefaultValues(baseUrl, value, productKey, siteId) {
101
104
  if (!values.some(val => !isOptionData(val))) {
102
105
  return value;
103
106
  }
104
- 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'), siteId)]);
107
+ const [hydratedUsers, hydratedTeams] = await Promise.all([hydrateAccountIds(baseUrl, productKey, values.filter(val => !isOptionData(val) && val.type === 'user'), atlAttributes), hydrateTeamIds(baseUrl, values.filter(val => !isOptionData(val) && val.type === 'team'), siteId)]);
105
108
  const hydratedOptions = values.filter(val => isOptionData(val)).map(val => val).concat(hydratedUsers).concat(hydratedTeams);
106
109
  return sortResults(hydratedOptions, values);
107
110
  }
@@ -1,14 +1,21 @@
1
- const buildHeaders = () => {
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { createAtlAttributionHeader } from './atl-attribution';
3
+ const buildHeaders = attributionData => {
2
4
  const headers = new Headers();
3
5
  headers.append('Content-Type', 'application/json');
6
+ if (fg('smart-user-picker-attribution-header')) {
7
+ const atlAttributionHeader = createAtlAttributionHeader(attributionData);
8
+ headers.append('atl-attribution', atlAttributionHeader['atl-attribution']);
9
+ }
4
10
  return headers;
5
11
  };
6
12
  /**
7
13
  * @param {string} serviceUrl - GraphQL service endpoint
8
14
  * @param {Query} query - GraphQL query
15
+ * @param {Partial<AtlAttributionHeaderData>} attributionData - Optional attribution data for the atl-attribution header
9
16
  */
10
- export function graphqlQuery(serviceUrl, query) {
11
- const headers = buildHeaders();
17
+ export function graphqlQuery(serviceUrl, query, attributionData) {
18
+ const headers = buildHeaders(attributionData);
12
19
  return fetch(new Request(`${serviceUrl}`, {
13
20
  method: 'POST',
14
21
  credentials: 'include',
@@ -21,6 +21,9 @@ const getUserRecommendations = (request, intl) => {
21
21
  ...(request.verifiedTeams === true && {
22
22
  isVerifiedTeamFilter: true
23
23
  }),
24
+ ...(request.isTeamSyncedToGroupDirectoryFilter === true && {
25
+ isTeamSyncedToGroupDirectoryFilter: true
26
+ }),
24
27
  cpusQueryHighlights: {
25
28
  query: '',
26
29
  field: ''
@@ -17,9 +17,9 @@ const buildUsersQuery = accountIds => ({
17
17
  accountIds
18
18
  }
19
19
  });
20
- const makeRequest = async (url, accountIds) => {
20
+ const makeRequest = async (url, accountIds, attributionData) => {
21
21
  const query = buildUsersQuery(accountIds);
22
- return await graphqlQuery(url, query);
22
+ return await graphqlQuery(url, query, attributionData);
23
23
  };
24
24
  const modifyResponse = users => users.map(({
25
25
  accountId,
@@ -31,10 +31,10 @@ const modifyResponse = users => users.map(({
31
31
  name,
32
32
  type: 'user'
33
33
  }));
34
- const getHydratedUsers = (baseUrl, userIds) => {
34
+ const getHydratedUsers = (baseUrl, userIds, attributionData) => {
35
35
  const url = config.getGraphQLUrl(baseUrl);
36
36
  return new Promise(resolve => {
37
- makeRequest(url, userIds).then(data => {
37
+ makeRequest(url, userIds, attributionData).then(data => {
38
38
  resolve(modifyResponse(data.users));
39
39
  }).catch(() => {
40
40
  // on network error, return original list with label 'Unknown'
@@ -36,6 +36,7 @@ const transformUser = (item, intl) => {
36
36
  };
37
37
  }
38
38
  if (type === EntityType.TEAM) {
39
+ var _team$type;
39
40
  const team = item;
40
41
  return {
41
42
  id: team.id,
@@ -47,7 +48,8 @@ const transformUser = (item, intl) => {
47
48
  includesYou: team.includesYou,
48
49
  avatarUrl: team.largeAvatarImageUrl || team.smallAvatarImageUrl,
49
50
  tooltip: team.displayName,
50
- verified: team.verified
51
+ verified: team.verified,
52
+ teamTypeName: (_team$type = team.type) === null || _team$type === void 0 ? void 0 : _team$type.name
51
53
  };
52
54
  }
53
55
  if (type === EntityType.GROUP) {
@@ -5,7 +5,7 @@ import { createAndFireEvent } from '@atlaskit/analytics-next';
5
5
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
6
6
  import { v4 as uuid } from 'uuid';
7
7
  var packageName = "@atlaskit/smart-user-picker";
8
- var packageVersion = "8.9.2";
8
+ var packageVersion = "0.0.0-development";
9
9
  export var startSession = function startSession() {
10
10
  return {
11
11
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -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, 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;
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, isTeamSyncedToGroupDirectoryFilter, 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, userMatches, 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, 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;
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, isTeamSyncedToGroupDirectoryFilter = _this$props.isTeamSyncedToGroupDirectoryFilter, 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 = _objectSpread(_objectSpread({
122
+ recommendationsRequest = _objectSpread(_objectSpread(_objectSpread({
123
123
  baseUrl: baseUrl,
124
124
  context: {
125
125
  containerId: containerId,
@@ -141,7 +141,7 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
141
141
  maxNumberOfResults: maxNumberOfResults,
142
142
  query: query,
143
143
  searchEmail: isEmail
144
- }, verifiedTeams === true && fg('smart-user-picker-managed-teams-gate') && {
144
+ }, verifiedTeams === true && {
145
145
  verifiedTeams: true
146
146
  }), {}, {
147
147
  /*
@@ -153,6 +153,8 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
153
153
  searchQueryFilter: isEmail && !searchQueryFilter ? '(NOT not_mentionable:true) AND (account_status:active) AND (NOT account_type:app)' : searchQueryFilter
154
154
  }, restrictTo && fg('smart-user-picker-restrict-to-gate') && {
155
155
  restrictTo: restrictTo
156
+ }), isTeamSyncedToGroupDirectoryFilter === true && {
157
+ isTeamSyncedToGroupDirectoryFilter: true
156
158
  });
157
159
  _context.prev = 6;
158
160
  _query = _this.state.query;
@@ -251,7 +253,15 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
251
253
 
252
254
  // Track if email search found matches for conditional allowEmail logic
253
255
  if (isEmail) {
254
- _this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
256
+ if (fg('smart_user_picker_allow_email_if_team_is_found')) {
257
+ // Only count user/external user matches, not teams or groups
258
+ userMatches = recommendedUsers.filter(function (user) {
259
+ return isUser(user) || isExternalUser(user);
260
+ });
261
+ _this.lastEmailSearchFoundMatches = userMatches.length > 0;
262
+ } else {
263
+ _this.lastEmailSearchFoundMatches = recommendedUsers.length > 0;
264
+ }
255
265
  } else {
256
266
  _this.lastEmailSearchFoundMatches = false;
257
267
  }
@@ -493,7 +503,10 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
493
503
  case 0:
494
504
  _context2.prev = 0;
495
505
  _context2.next = 3;
496
- return hydrateDefaultValues(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId);
506
+ return hydrateDefaultValues(this.props.baseUrl, this.props.defaultValue, this.props.productKey, this.props.siteId, {
507
+ tenantId: this.props.siteId,
508
+ activationId: this.props.activationId
509
+ });
497
510
  case 3:
498
511
  value = _context2.sent;
499
512
  this.setState({
@@ -564,9 +577,16 @@ export var SmartUserPickerWithoutAnalytics = /*#__PURE__*/function (_React$Compo
564
577
  // Determine whether to allow email selection based on allowEmailSelectionWhenEmailMatched, if needed
565
578
  var shouldAllowEmail = allowEmail;
566
579
  if (allowEmail && enableEmailSearch && !allowEmailSelectionWhenEmailMatched) {
567
- // Only allow email selection if we're in an email search that found no matches
568
580
  var isCurrentQueryEmail = isEmailQuery(this.state.query);
569
- shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
581
+ if (fg('smart_user_picker_allow_email_if_team_is_found')) {
582
+ // Only allow email selection when:
583
+ // 1. The query matches email format (validated by regex)
584
+ // 2. No user/external user matches were found (only teams/groups suggested)
585
+ shouldAllowEmail = isCurrentQueryEmail && !this.lastEmailSearchFoundMatches;
586
+ } else {
587
+ // Only allow email selection if we're in an email search that found no matches
588
+ shouldAllowEmail = !isCurrentQueryEmail || !this.lastEmailSearchFoundMatches;
589
+ }
570
590
  }
571
591
  return /*#__PURE__*/React.createElement(MessagesIntlProvider, null, /*#__PURE__*/React.createElement(UserPicker, _extends({}, restProps, {
572
592
  allowEmail: shouldAllowEmail,
@@ -0,0 +1,32 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
+ var _excluded = ["product", "activationId"];
4
+ 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; }
5
+ 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; }
6
+ /**
7
+ * Utility for creating the atl-attribution header for AGG requests
8
+ * Reference: https://hello.atlassian.net/wiki/spaces/AGG/pages/5954141702/Metrics+Attribution+Onboarding+Doc+for+AGG+Clients
9
+ */
10
+
11
+ /**
12
+ * Creates the atl-attribution header value for network requests.
13
+ * This header is used for metrics attribution in AGG (Analytics & Insights Graph).
14
+ *
15
+ * @param data Optional attribution data including tenantId, atlWorkspaceId, and product
16
+ * @returns Object with atl-attribution header
17
+ */
18
+ export function createAtlAttributionHeader() {
19
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20
+ var _ref$product = _ref.product,
21
+ product = _ref$product === void 0 ? 'platform' : _ref$product,
22
+ activationId = _ref.activationId,
23
+ props = _objectWithoutProperties(_ref, _excluded);
24
+ var headerData = _objectSpread({
25
+ service: 'smart-experiences/smart-user-picker',
26
+ product: product,
27
+ atlWorkspaceId: activationId && props.tenantId ? "ari:cloud:".concat(product, ":").concat(props.tenantId, ":workspace/").concat(activationId) : undefined
28
+ }, props);
29
+ return {
30
+ 'atl-attribution': JSON.stringify(headerData)
31
+ };
32
+ }
@@ -1,5 +1,8 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
+ 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; }
5
+ 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; }
3
6
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
7
  import { UserType } from '@atlaskit/user-picker';
5
8
  import { config } from '../config';
@@ -119,7 +122,7 @@ var hydrateTeamIds = /*#__PURE__*/function () {
119
122
  };
120
123
  }();
121
124
  var hydrateAccountIds = /*#__PURE__*/function () {
122
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(baseUrl, productKey, values) {
125
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(baseUrl, productKey, values, atlAttributes) {
123
126
  var accountIds;
124
127
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
125
128
  while (1) switch (_context2.prev = _context2.next) {
@@ -149,7 +152,9 @@ var hydrateAccountIds = /*#__PURE__*/function () {
149
152
  break;
150
153
  case 9:
151
154
  _context2.next = 11;
152
- return getHydratedUsersFromPrs(baseUrl, accountIds);
155
+ return getHydratedUsersFromPrs(baseUrl, accountIds, _objectSpread({
156
+ product: productKey
157
+ }, atlAttributes));
153
158
  case 11:
154
159
  _context2.t0 = _context2.sent;
155
160
  case 12:
@@ -160,15 +165,15 @@ var hydrateAccountIds = /*#__PURE__*/function () {
160
165
  }
161
166
  }, _callee2);
162
167
  }));
163
- return function hydrateAccountIds(_x4, _x5, _x6) {
168
+ return function hydrateAccountIds(_x4, _x5, _x6, _x7) {
164
169
  return _ref2.apply(this, arguments);
165
170
  };
166
171
  }();
167
- function hydrateDefaultValues(_x7, _x8, _x9, _x0) {
172
+ function hydrateDefaultValues(_x8, _x9, _x0, _x1, _x10) {
168
173
  return _hydrateDefaultValues.apply(this, arguments);
169
174
  }
170
175
  function _hydrateDefaultValues() {
171
- _hydrateDefaultValues = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(baseUrl, value, productKey, siteId) {
176
+ _hydrateDefaultValues = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(baseUrl, value, productKey, siteId, atlAttributes) {
172
177
  var values, _yield$Promise$all, _yield$Promise$all2, hydratedUsers, hydratedTeams, hydratedOptions;
173
178
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
174
179
  while (1) switch (_context3.prev = _context3.next) {
@@ -191,7 +196,7 @@ function _hydrateDefaultValues() {
191
196
  _context3.next = 7;
192
197
  return Promise.all([hydrateAccountIds(baseUrl, productKey, values.filter(function (val) {
193
198
  return !isOptionData(val) && val.type === 'user';
194
- })), hydrateTeamIds(baseUrl, values.filter(function (val) {
199
+ }), atlAttributes), hydrateTeamIds(baseUrl, values.filter(function (val) {
195
200
  return !isOptionData(val) && val.type === 'team';
196
201
  }), siteId)]);
197
202
  case 7:
@@ -1,14 +1,21 @@
1
- var buildHeaders = function buildHeaders() {
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { createAtlAttributionHeader } from './atl-attribution';
3
+ var buildHeaders = function buildHeaders(attributionData) {
2
4
  var headers = new Headers();
3
5
  headers.append('Content-Type', 'application/json');
6
+ if (fg('smart-user-picker-attribution-header')) {
7
+ var atlAttributionHeader = createAtlAttributionHeader(attributionData);
8
+ headers.append('atl-attribution', atlAttributionHeader['atl-attribution']);
9
+ }
4
10
  return headers;
5
11
  };
6
12
  /**
7
13
  * @param {string} serviceUrl - GraphQL service endpoint
8
14
  * @param {Query} query - GraphQL query
15
+ * @param {Partial<AtlAttributionHeaderData>} attributionData - Optional attribution data for the atl-attribution header
9
16
  */
10
- export function graphqlQuery(serviceUrl, query) {
11
- var headers = buildHeaders();
17
+ export function graphqlQuery(serviceUrl, query, attributionData) {
18
+ var headers = buildHeaders(attributionData);
12
19
  return fetch(new Request("".concat(serviceUrl), {
13
20
  method: 'POST',
14
21
  credentials: 'include',
@@ -20,8 +20,10 @@ var getUserRecommendations = function getUserRecommendations(request, intl) {
20
20
  includeNonLicensedUsers: request.includeNonLicensedUsers,
21
21
  maxNumberOfResults: request.maxNumberOfResults,
22
22
  performSearchQueryOnly: false,
23
- searchQuery: _objectSpread(_objectSpread(_objectSpread({}, request.verifiedTeams === true && {
23
+ searchQuery: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, request.verifiedTeams === true && {
24
24
  isVerifiedTeamFilter: true
25
+ }), request.isTeamSyncedToGroupDirectoryFilter === true && {
26
+ isTeamSyncedToGroupDirectoryFilter: true
25
27
  }), {}, {
26
28
  cpusQueryHighlights: {
27
29
  query: '',
@@ -19,14 +19,14 @@ var buildUsersQuery = function buildUsersQuery(accountIds) {
19
19
  };
20
20
  };
21
21
  var makeRequest = /*#__PURE__*/function () {
22
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url, accountIds) {
22
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url, accountIds, attributionData) {
23
23
  var query;
24
24
  return _regeneratorRuntime.wrap(function _callee$(_context) {
25
25
  while (1) switch (_context.prev = _context.next) {
26
26
  case 0:
27
27
  query = buildUsersQuery(accountIds);
28
28
  _context.next = 3;
29
- return graphqlQuery(url, query);
29
+ return graphqlQuery(url, query, attributionData);
30
30
  case 3:
31
31
  return _context.abrupt("return", _context.sent);
32
32
  case 4:
@@ -35,7 +35,7 @@ var makeRequest = /*#__PURE__*/function () {
35
35
  }
36
36
  }, _callee);
37
37
  }));
38
- return function makeRequest(_x, _x2) {
38
+ return function makeRequest(_x, _x2, _x3) {
39
39
  return _ref.apply(this, arguments);
40
40
  };
41
41
  }();
@@ -52,10 +52,10 @@ var modifyResponse = function modifyResponse(users) {
52
52
  };
53
53
  });
54
54
  };
55
- var getHydratedUsers = function getHydratedUsers(baseUrl, userIds) {
55
+ var getHydratedUsers = function getHydratedUsers(baseUrl, userIds, attributionData) {
56
56
  var url = config.getGraphQLUrl(baseUrl);
57
57
  return new Promise(function (resolve) {
58
- makeRequest(url, userIds).then(function (data) {
58
+ makeRequest(url, userIds, attributionData).then(function (data) {
59
59
  resolve(modifyResponse(data.users));
60
60
  }).catch(function () {
61
61
  // on network error, return original list with label 'Unknown'
@@ -36,6 +36,7 @@ var transformUser = function transformUser(item, intl) {
36
36
  };
37
37
  }
38
38
  if (type === EntityType.TEAM) {
39
+ var _team$type;
39
40
  var team = item;
40
41
  return {
41
42
  id: team.id,
@@ -47,7 +48,8 @@ var transformUser = function transformUser(item, intl) {
47
48
  includesYou: team.includesYou,
48
49
  avatarUrl: team.largeAvatarImageUrl || team.smallAvatarImageUrl,
49
50
  tooltip: team.displayName,
50
- verified: team.verified
51
+ verified: team.verified,
52
+ teamTypeName: (_team$type = team.type) === null || _team$type === void 0 ? void 0 : _team$type.name
51
53
  };
52
54
  }
53
55
  if (type === EntityType.GROUP) {
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utility for creating the atl-attribution header for AGG requests
3
+ * Reference: https://hello.atlassian.net/wiki/spaces/AGG/pages/5954141702/Metrics+Attribution+Onboarding+Doc+for+AGG+Clients
4
+ */
5
+ export interface AtlAttributionHeaderData {
6
+ service: string;
7
+ tenantId?: string;
8
+ activationId?: string;
9
+ product?: string;
10
+ }
11
+ /**
12
+ * Creates the atl-attribution header value for network requests.
13
+ * This header is used for metrics attribution in AGG (Analytics & Insights Graph).
14
+ *
15
+ * @param data Optional attribution data including tenantId, atlWorkspaceId, and product
16
+ * @returns Object with atl-attribution header
17
+ */
18
+ export declare function createAtlAttributionHeader({ product, activationId, ...props }?: Partial<AtlAttributionHeaderData>): {
19
+ 'atl-attribution': string;
20
+ };
@@ -4,5 +4,8 @@ export interface UsersRequest {
4
4
  accountIds: string[];
5
5
  productKey: 'jira' | 'confluence';
6
6
  }
7
- declare function hydrateDefaultValues(baseUrl: string | undefined, value: DefaultValue, productKey: string, siteId: string | undefined): Promise<DefaultValue>;
7
+ declare function hydrateDefaultValues(baseUrl: string | undefined, value: DefaultValue, productKey: string, siteId: string | undefined, atlAttributes?: {
8
+ tenantId?: string;
9
+ activationId?: string;
10
+ }): Promise<DefaultValue>;
8
11
  export default hydrateDefaultValues;
@@ -1,3 +1,5 @@
1
+ import { type AtlAttributionHeaderData } from './atl-attribution';
2
+ export type { AtlAttributionHeaderData } from './atl-attribution';
1
3
  interface Query {
2
4
  query: string;
3
5
  variables: Record<string, string> | Record<string, string[]>;
@@ -9,6 +11,6 @@ export interface GraphQLError {
9
11
  /**
10
12
  * @param {string} serviceUrl - GraphQL service endpoint
11
13
  * @param {Query} query - GraphQL query
14
+ * @param {Partial<AtlAttributionHeaderData>} attributionData - Optional attribution data for the atl-attribution header
12
15
  */
13
- export declare function graphqlQuery<D>(serviceUrl: string, query: Query): Promise<D>;
14
- export {};
16
+ export declare function graphqlQuery<D>(serviceUrl: string, query: Query, attributionData?: Partial<AtlAttributionHeaderData>): Promise<D>;
@@ -1,4 +1,5 @@
1
1
  import { type User } from '@atlaskit/user-picker';
2
+ import { type AtlAttributionHeaderData } from './graphqlUtils';
2
3
  interface UserData {
3
4
  accountId: string;
4
5
  name: string;
@@ -7,5 +8,5 @@ interface UserData {
7
8
  export interface ApiClientResponse {
8
9
  users: UserData[];
9
10
  }
10
- declare const getHydratedUsers: (baseUrl: string | undefined, userIds: string[]) => Promise<User[]>;
11
+ declare const getHydratedUsers: (baseUrl: string | undefined, userIds: string[], attributionData?: Partial<AtlAttributionHeaderData>) => Promise<User[]>;
11
12
  export default getHydratedUsers;
@@ -29,6 +29,12 @@ export interface RecommendationRequest {
29
29
  searchEmail?: boolean;
30
30
  verifiedTeams?: boolean;
31
31
  restrictTo?: RestrictionFilter;
32
+ /**
33
+ * When true, URS returns only userbase-aligned teams (teams synced to Identity).
34
+ * Confluence uses this for teams-as-principals to avoid errors when users select teams
35
+ * that are not yet mirrored to Identity (e.g. old org-scoped teams in NonVortex orgs).
36
+ */
37
+ isTeamSyncedToGroupDirectoryFilter?: boolean;
32
38
  }
33
39
  type OnError = (error: any, request: RecommendationRequest) => Promise<OptionData[]> | void;
34
40
  type OnValueError = (error: any, defaultValue: DefaultValue) => Promise<OptionData[]> | void;
@@ -211,7 +217,9 @@ export interface SmartProps {
211
217
  /**
212
218
  * When both allowEmail and enableEmailSearch are true, this controls whether both email entry
213
219
  * and matched user entries can be selected simultaneously.
214
- * If false, only allows email selection when no users are found.
220
+ * If false, only allows email selection when:
221
+ * 1. The query matches email format (validated by regex)
222
+ * 2. No user/external user matches are found (teams/groups don't suppress email entry)
215
223
  * @default true
216
224
  */
217
225
  allowEmailSelectionWhenEmailMatched?: boolean;
@@ -225,6 +233,10 @@ export interface SmartProps {
225
233
  * Identifier for the product's tenant, also known as tenantId or cloudId
226
234
  */
227
235
  siteId: string;
236
+ /**
237
+ * Identifier for the product activation.
238
+ */
239
+ activationId?: string;
228
240
  /**
229
241
  * Identifier for the organization in which to search for teams.
230
242
  */
@@ -258,6 +270,12 @@ export interface SmartProps {
258
270
  * @example { userIds: ["123", "456"], groupIds: ["789"] }
259
271
  */
260
272
  restrictTo?: RestrictionFilter;
273
+ /**
274
+ * When true, URS returns only userbase-aligned teams (teams synced to Identity).
275
+ * Confluence uses this for teams-as-principals to avoid errors when users select teams
276
+ * that are not yet mirrored to Identity (e.g. old org-scoped teams in NonVortex orgs).
277
+ */
278
+ isTeamSyncedToGroupDirectoryFilter?: boolean;
261
279
  }
262
280
  export interface Props extends SmartProps, UserPickerProps, WithAnalyticsEventsProps {
263
281
  /**
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utility for creating the atl-attribution header for AGG requests
3
+ * Reference: https://hello.atlassian.net/wiki/spaces/AGG/pages/5954141702/Metrics+Attribution+Onboarding+Doc+for+AGG+Clients
4
+ */
5
+ export interface AtlAttributionHeaderData {
6
+ service: string;
7
+ tenantId?: string;
8
+ activationId?: string;
9
+ product?: string;
10
+ }
11
+ /**
12
+ * Creates the atl-attribution header value for network requests.
13
+ * This header is used for metrics attribution in AGG (Analytics & Insights Graph).
14
+ *
15
+ * @param data Optional attribution data including tenantId, atlWorkspaceId, and product
16
+ * @returns Object with atl-attribution header
17
+ */
18
+ export declare function createAtlAttributionHeader({ product, activationId, ...props }?: Partial<AtlAttributionHeaderData>): {
19
+ 'atl-attribution': string;
20
+ };
@@ -4,5 +4,8 @@ export interface UsersRequest {
4
4
  accountIds: string[];
5
5
  productKey: 'jira' | 'confluence';
6
6
  }
7
- declare function hydrateDefaultValues(baseUrl: string | undefined, value: DefaultValue, productKey: string, siteId: string | undefined): Promise<DefaultValue>;
7
+ declare function hydrateDefaultValues(baseUrl: string | undefined, value: DefaultValue, productKey: string, siteId: string | undefined, atlAttributes?: {
8
+ tenantId?: string;
9
+ activationId?: string;
10
+ }): Promise<DefaultValue>;
8
11
  export default hydrateDefaultValues;
@@ -1,3 +1,5 @@
1
+ import { type AtlAttributionHeaderData } from './atl-attribution';
2
+ export type { AtlAttributionHeaderData } from './atl-attribution';
1
3
  interface Query {
2
4
  query: string;
3
5
  variables: Record<string, string> | Record<string, string[]>;
@@ -9,6 +11,6 @@ export interface GraphQLError {
9
11
  /**
10
12
  * @param {string} serviceUrl - GraphQL service endpoint
11
13
  * @param {Query} query - GraphQL query
14
+ * @param {Partial<AtlAttributionHeaderData>} attributionData - Optional attribution data for the atl-attribution header
12
15
  */
13
- export declare function graphqlQuery<D>(serviceUrl: string, query: Query): Promise<D>;
14
- export {};
16
+ export declare function graphqlQuery<D>(serviceUrl: string, query: Query, attributionData?: Partial<AtlAttributionHeaderData>): Promise<D>;
@@ -1,4 +1,5 @@
1
1
  import { type User } from '@atlaskit/user-picker';
2
+ import { type AtlAttributionHeaderData } from './graphqlUtils';
2
3
  interface UserData {
3
4
  accountId: string;
4
5
  name: string;
@@ -7,5 +8,5 @@ interface UserData {
7
8
  export interface ApiClientResponse {
8
9
  users: UserData[];
9
10
  }
10
- declare const getHydratedUsers: (baseUrl: string | undefined, userIds: string[]) => Promise<User[]>;
11
+ declare const getHydratedUsers: (baseUrl: string | undefined, userIds: string[], attributionData?: Partial<AtlAttributionHeaderData>) => Promise<User[]>;
11
12
  export default getHydratedUsers;
@@ -29,6 +29,12 @@ export interface RecommendationRequest {
29
29
  searchEmail?: boolean;
30
30
  verifiedTeams?: boolean;
31
31
  restrictTo?: RestrictionFilter;
32
+ /**
33
+ * When true, URS returns only userbase-aligned teams (teams synced to Identity).
34
+ * Confluence uses this for teams-as-principals to avoid errors when users select teams
35
+ * that are not yet mirrored to Identity (e.g. old org-scoped teams in NonVortex orgs).
36
+ */
37
+ isTeamSyncedToGroupDirectoryFilter?: boolean;
32
38
  }
33
39
  type OnError = (error: any, request: RecommendationRequest) => Promise<OptionData[]> | void;
34
40
  type OnValueError = (error: any, defaultValue: DefaultValue) => Promise<OptionData[]> | void;
@@ -211,7 +217,9 @@ export interface SmartProps {
211
217
  /**
212
218
  * When both allowEmail and enableEmailSearch are true, this controls whether both email entry
213
219
  * and matched user entries can be selected simultaneously.
214
- * If false, only allows email selection when no users are found.
220
+ * If false, only allows email selection when:
221
+ * 1. The query matches email format (validated by regex)
222
+ * 2. No user/external user matches are found (teams/groups don't suppress email entry)
215
223
  * @default true
216
224
  */
217
225
  allowEmailSelectionWhenEmailMatched?: boolean;
@@ -225,6 +233,10 @@ export interface SmartProps {
225
233
  * Identifier for the product's tenant, also known as tenantId or cloudId
226
234
  */
227
235
  siteId: string;
236
+ /**
237
+ * Identifier for the product activation.
238
+ */
239
+ activationId?: string;
228
240
  /**
229
241
  * Identifier for the organization in which to search for teams.
230
242
  */
@@ -258,6 +270,12 @@ export interface SmartProps {
258
270
  * @example { userIds: ["123", "456"], groupIds: ["789"] }
259
271
  */
260
272
  restrictTo?: RestrictionFilter;
273
+ /**
274
+ * When true, URS returns only userbase-aligned teams (teams synced to Identity).
275
+ * Confluence uses this for teams-as-principals to avoid errors when users select teams
276
+ * that are not yet mirrored to Identity (e.g. old org-scoped teams in NonVortex orgs).
277
+ */
278
+ isTeamSyncedToGroupDirectoryFilter?: boolean;
261
279
  }
262
280
  export interface Props extends SmartProps, UserPickerProps, WithAnalyticsEventsProps {
263
281
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-user-picker",
3
- "version": "8.9.3",
3
+ "version": "9.0.1",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -38,7 +38,7 @@
38
38
  "@atlaskit/analytics-next": "^11.1.0",
39
39
  "@atlaskit/platform-feature-flags": "^1.1.0",
40
40
  "@atlaskit/ufo": "^0.4.0",
41
- "@atlaskit/user-picker": "^11.20.0",
41
+ "@atlaskit/user-picker": "^11.23.0",
42
42
  "@babel/runtime": "^7.0.0",
43
43
  "lodash": "^4.17.21",
44
44
  "memoize-one": "^6.0.0",
@@ -51,8 +51,8 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@atlaskit/select": "^21.7.0",
54
- "@atlaskit/util-data-test": "^18.4.0",
55
- "@atlassian/a11y-jest-testing": "^0.8.0",
54
+ "@atlaskit/util-data-test": "^18.5.0",
55
+ "@atlassian/a11y-jest-testing": "^0.10.0",
56
56
  "@testing-library/dom": "^10.1.0",
57
57
  "@testing-library/react": "^16.3.0",
58
58
  "@testing-library/user-event": "^14.4.3",
@@ -68,10 +68,13 @@
68
68
  "smart-user-picker-load-options-gate": {
69
69
  "type": "boolean"
70
70
  },
71
- "smart-user-picker-managed-teams-gate": {
71
+ "smart-user-picker-restrict-to-gate": {
72
72
  "type": "boolean"
73
73
  },
74
- "smart-user-picker-restrict-to-gate": {
74
+ "smart_user_picker_allow_email_if_team_is_found": {
75
+ "type": "boolean"
76
+ },
77
+ "smart-user-picker-attribution-header": {
75
78
  "type": "boolean"
76
79
  }
77
80
  }
package/tsconfig.json CHANGED
@@ -15,6 +15,5 @@
15
15
  "**/stories/*.tsx",
16
16
  "**/stories/**/*.ts",
17
17
  "**/stories/**/*.tsx"
18
- ],
19
- "compilerOptions": {}
18
+ ]
20
19
  }