@atlaskit/editor-plugin-mentions 14.6.6 → 14.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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlaskit/editor-plugin-mentions
2
2
 
3
+ ## 14.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`d6596dc895420`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d6596dc895420) -
8
+ Show a loading shimmer in the mention typeahead Agents section while the (slower) agent source
9
+ resolves. The Rovo chat mention provider now emits a non-selectable loading placeholder in the
10
+ agents slot until agents arrive (gated by rovo_chat_agent_selection); @atlaskit/mention renders it
11
+ as a skeleton row, and the editor mention plugin guards it from selection/analytics.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
17
+ ## 14.7.0
18
+
19
+ ### Minor Changes
20
+
21
+ - [`f4cf0276c2938`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f4cf0276c2938) -
22
+ Add metric attributes for tracking agent inclusion and selection from the mention picker
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies
27
+
3
28
  ## 14.6.6
4
29
 
5
30
  ### Patch Changes
@@ -66,7 +66,7 @@ var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
66
66
  var AGENT_MENTION_INACTIVITY_MS = 3000;
67
67
  var MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
68
68
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
69
- var PACKAGE_VERSION = "14.6.5";
69
+ var PACKAGE_VERSION = "14.7.0";
70
70
  var setProvider = function setProvider(provider) {
71
71
  return function (state, dispatch) {
72
72
  if (dispatch) {
@@ -105,7 +105,7 @@ var buildTypeAheadInviteItemClickedPayload = exports.buildTypeAheadInviteItemCli
105
105
  }, additionalAttributes)
106
106
  };
107
107
  };
108
- var buildTypeAheadInsertedPayload = exports.buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent) {
108
+ var buildTypeAheadInsertedPayload = exports.buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent, agentSectioningEnabled) {
109
109
  var _extractAttributesFro3 = extractAttributesFromQuery(query),
110
110
  queryLength = _extractAttributesFro3.queryLength,
111
111
  spaceInQuery = _extractAttributesFro3.spaceInQuery;
@@ -141,7 +141,8 @@ var buildTypeAheadInsertedPayload = exports.buildTypeAheadInsertedPayload = func
141
141
  memberCount: (0, _utils.isTeamType)(mention.userType) && mention.context ? mention.context.memberCount : null,
142
142
  includesYou: (0, _utils.isTeamType)(mention.userType) && mention.context ? mention.context.includesYou : null
143
143
  }, isAgent ? {
144
- isAgent: isAgent
144
+ isAgent: isAgent,
145
+ agentSectioningEnabled: agentSectioningEnabled
145
146
  } : {}), {}, {
146
147
  taskListId: taskListId,
147
148
  taskItemId: taskItemId,
@@ -152,16 +153,21 @@ var buildTypeAheadInsertedPayload = exports.buildTypeAheadInsertedPayload = func
152
153
  })
153
154
  };
154
155
  };
155
- var buildTypeAheadRenderedPayload = exports.buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength) {
156
+ var buildTypeAheadRenderedPayload = exports.buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength, agentAnalytics) {
156
157
  var _extractAttributesFro4 = extractAttributesFromQuery(query),
157
158
  queryLength = _extractAttributesFro4.queryLength,
158
159
  spaceInQuery = _extractAttributesFro4.spaceInQuery;
159
160
  var actionSubject = userIds ? _analytics.ACTION_SUBJECT.MENTION_TYPEAHEAD : _analytics.ACTION_SUBJECT.TEAM_MENTION_TYPEAHEAD;
161
+ var agentAnalyticsAttributes = agentAnalytics ? {
162
+ agentCount: agentAnalytics.agentCount,
163
+ agentsShown: agentAnalytics.agentCount > 0,
164
+ agentSectioningEnabled: agentAnalytics.agentSectioningEnabled
165
+ } : {};
160
166
  return {
161
167
  action: _analytics.ACTION.RENDERED,
162
168
  actionSubject: actionSubject,
163
169
  eventType: _analytics.EVENT_TYPE.OPERATIONAL,
164
- attributes: {
170
+ attributes: _objectSpread({
165
171
  componentName: componentName,
166
172
  duration: duration,
167
173
  userIds: userIds,
@@ -169,6 +175,6 @@ var buildTypeAheadRenderedPayload = exports.buildTypeAheadRenderedPayload = func
169
175
  queryLength: queryLength,
170
176
  spaceInQuery: spaceInQuery,
171
177
  xProductMentionsLength: xProductMentionsLength
172
- }
178
+ }, agentAnalyticsAttributes)
173
179
  };
174
180
  };
@@ -46,6 +46,14 @@ var isAgentMention = function isAgentMention(mention) {
46
46
  var isAgentTypeAheadItem = function isAgentTypeAheadItem(item) {
47
47
  return item.mention ? isAgentMention(item.mention) : false;
48
48
  };
49
+
50
+ // A non-selectable loading placeholder injected by the provider (e.g.
51
+ // `RovoChatMentionResource`) while the slower agent source resolves. It
52
+ // renders as a skeleton row via `@atlaskit/mention`'s `MentionItem` and
53
+ // must never be inserted or counted in rendered-mention analytics.
54
+ var isLoadingPlaceholder = function isLoadingPlaceholder(mention) {
55
+ return !!(mention !== null && mention !== void 0 && mention.isPlaceholder);
56
+ };
49
57
  var createInviteItem = function createInviteItem(_ref) {
50
58
  var mentionProvider = _ref.mentionProvider,
51
59
  onInviteItemMount = _ref.onInviteItemMount,
@@ -158,7 +166,8 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
158
166
  return function (_ref5) {
159
167
  var query = _ref5.query,
160
168
  mentions = _ref5.mentions,
161
- stats = _ref5.stats;
169
+ stats = _ref5.stats,
170
+ agentAnalytics = _ref5.agentAnalytics;
162
171
  var duration = 0;
163
172
  var userOrTeamIds = null;
164
173
  var teams = null;
@@ -191,7 +200,7 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
191
200
  return !!m;
192
201
  });
193
202
  }
194
- var payload = (0, _analytics.buildTypeAheadRenderedPayload)(duration, userOrTeamIds, query, teams, xProductMentionsLength);
203
+ var payload = (0, _analytics.buildTypeAheadRenderedPayload)(duration, userOrTeamIds, query, teams, xProductMentionsLength, agentAnalytics);
195
204
  fireEvent(payload, 'fabric-elements');
196
205
  };
197
206
  };
@@ -264,7 +273,8 @@ var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToType
264
273
  var fireEvent = _ref6.fireEvent,
265
274
  getFirstQueryWithoutResults = _ref6.getFirstQueryWithoutResults,
266
275
  setFirstQueryWithoutResults = _ref6.setFirstQueryWithoutResults,
267
- toItem = _ref6.toItem;
276
+ toItem = _ref6.toItem,
277
+ enableAgentSectioning = _ref6.enableAgentSectioning;
268
278
  return function (_ref7) {
269
279
  var mentions = _ref7.mentions,
270
280
  query = _ref7.query,
@@ -275,12 +285,29 @@ var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToType
275
285
  var mentionItems = mentions.map(function (mention) {
276
286
  return toItem(mention);
277
287
  });
288
+ var agentCount = mentions.filter(isAgentMention).length;
289
+ var agentAnalytics = {
290
+ agentCount: agentCount,
291
+ agentSectioningEnabled: enableAgentSectioning
292
+ };
293
+
294
+ // The loading placeholder is a rendered-only row — keep it in
295
+ // `mentionItems` so the shimmer shows, but exclude it from analytics
296
+ // and no-results bookkeeping so it isn't counted as a real result.
297
+ var realMentions = mentions.filter(function (mention) {
298
+ return !isLoadingPlaceholder(mention);
299
+ });
278
300
  buildAndSendElementsTypeAheadAnalytics(fireEvent)({
279
301
  query: query,
280
- mentions: mentions,
281
- stats: stats
302
+ mentions: realMentions,
303
+ stats: stats,
304
+ agentAnalytics: agentAnalytics
282
305
  });
283
- if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
306
+
307
+ // While a loading placeholder is present the result set isn't settled yet
308
+ // (e.g. agents still resolving) — don't record this query as "no results",
309
+ // or a later emission that arrives with results would be ignored.
310
+ if (realMentions.length === 0 && !mentions.some(isLoadingPlaceholder) && getFirstQueryWithoutResults() === null) {
284
311
  setFirstQueryWithoutResults(query);
285
312
  }
286
313
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
@@ -315,6 +342,7 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
315
342
  var firstQueryWithoutResults = null;
316
343
  var subscriptionKeys = new Set();
317
344
  var transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
345
+ enableAgentSectioning: enableAgentSectioning,
318
346
  fireEvent: fireEvent,
319
347
  getFirstQueryWithoutResults: function getFirstQueryWithoutResults() {
320
348
  return firstQueryWithoutResults;
@@ -424,6 +452,12 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
424
452
  query = _ref10.query,
425
453
  sourceListItem = _ref10.sourceListItem;
426
454
  var schema = state.schema;
455
+
456
+ // Placeholder isn't selectable. Return `false` (not a transaction) so
457
+ // the runtime keeps the dropdown open; a transaction would close it.
458
+ if (isLoadingPlaceholder(item.mention)) {
459
+ return false;
460
+ }
427
461
  var pluginState = (0, _utils2.getMentionPluginState)(state);
428
462
  var mentionProvider = pluginState.mentionProvider;
429
463
  var _item$mention = item.mention,
@@ -438,8 +472,8 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
438
472
  var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
439
473
  sessionId: sessionId
440
474
  });
441
- var isAgentMentionsExperimentEnabled = (0, _expVal.expVal)('platform_editor_agent_mentions', 'isEnabled', false);
442
- var isAgentMentionInsertion = isAgentMentionsExperimentEnabled && isAgentMention(item.mention);
475
+ var isAgentMentionSelection = isAgentMention(item.mention);
476
+ var isAgentMentionInsertion = isAgentMentionSelection && (0, _expVal.expVal)('platform_editor_agent_mentions', 'isEnabled', false);
443
477
  // userType can be missing for provider-only agent mentions. Copy/paste cannot
444
478
  // see appType, so persist APP only when there is no explicit userType.
445
479
  var persistedUserType = isAgentMentionInsertion && userType == null ? 'APP' : userType;
@@ -512,7 +546,7 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
512
546
  }
513
547
  fireEvent((0, _analytics.buildTypeAheadInsertedPayload)(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(function (x) {
514
548
  return x.mention;
515
- }), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionInsertion));
549
+ }), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionSelection, enableAgentSectioning));
516
550
 
517
551
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
518
552
  sessionId = (0, _uuid.default)();
@@ -50,7 +50,7 @@ const AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
50
50
  const AGENT_MENTION_INACTIVITY_MS = 3000;
51
51
  const MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
52
52
  const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
53
- const PACKAGE_VERSION = "14.6.5";
53
+ const PACKAGE_VERSION = "14.7.0";
54
54
  const setProvider = provider => (state, dispatch) => {
55
55
  if (dispatch) {
56
56
  dispatch(state.tr.setMeta(mentionPluginKey, {
@@ -97,7 +97,7 @@ export const buildTypeAheadInviteItemClickedPayload = (duration, upKeyCount, dow
97
97
  }
98
98
  };
99
99
  };
100
- export const buildTypeAheadInsertedPayload = (duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent) => {
100
+ export const buildTypeAheadInsertedPayload = (duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent, agentSectioningEnabled) => {
101
101
  const {
102
102
  queryLength,
103
103
  spaceInQuery
@@ -134,7 +134,8 @@ export const buildTypeAheadInsertedPayload = (duration, upKeyCount, downKeyCount
134
134
  memberCount: isTeamType(mention.userType) && mention.context ? mention.context.memberCount : null,
135
135
  includesYou: isTeamType(mention.userType) && mention.context ? mention.context.includesYou : null,
136
136
  ...(isAgent ? {
137
- isAgent
137
+ isAgent,
138
+ agentSectioningEnabled
138
139
  } : {}),
139
140
  taskListId,
140
141
  taskItemId,
@@ -145,12 +146,17 @@ export const buildTypeAheadInsertedPayload = (duration, upKeyCount, downKeyCount
145
146
  }
146
147
  };
147
148
  };
148
- export const buildTypeAheadRenderedPayload = (duration, userIds, query, teams, xProductMentionsLength) => {
149
+ export const buildTypeAheadRenderedPayload = (duration, userIds, query, teams, xProductMentionsLength, agentAnalytics) => {
149
150
  const {
150
151
  queryLength,
151
152
  spaceInQuery
152
153
  } = extractAttributesFromQuery(query);
153
154
  const actionSubject = userIds ? ACTION_SUBJECT.MENTION_TYPEAHEAD : ACTION_SUBJECT.TEAM_MENTION_TYPEAHEAD;
155
+ const agentAnalyticsAttributes = agentAnalytics ? {
156
+ agentCount: agentAnalytics.agentCount,
157
+ agentsShown: agentAnalytics.agentCount > 0,
158
+ agentSectioningEnabled: agentAnalytics.agentSectioningEnabled
159
+ } : {};
154
160
  return {
155
161
  action: ACTION.RENDERED,
156
162
  actionSubject,
@@ -162,7 +168,8 @@ export const buildTypeAheadRenderedPayload = (duration, userIds, query, teams, x
162
168
  teams,
163
169
  queryLength,
164
170
  spaceInQuery,
165
- xProductMentionsLength
171
+ xProductMentionsLength,
172
+ ...agentAnalyticsAttributes
166
173
  }
167
174
  };
168
175
  };
@@ -24,6 +24,12 @@ import { isInviteItem, isTeamStats, isTeamType, shouldKeepInviteItem } from './u
24
24
  const isAgentUserType = userType => userType === 'APP' || userType === 'AGENT';
25
25
  const isAgentMention = mention => isAgentUserType(mention.userType) || mention.appType === 'agent';
26
26
  const isAgentTypeAheadItem = item => item.mention ? isAgentMention(item.mention) : false;
27
+
28
+ // A non-selectable loading placeholder injected by the provider (e.g.
29
+ // `RovoChatMentionResource`) while the slower agent source resolves. It
30
+ // renders as a skeleton row via `@atlaskit/mention`'s `MentionItem` and
31
+ // must never be inserted or counted in rendered-mention analytics.
32
+ const isLoadingPlaceholder = mention => !!(mention !== null && mention !== void 0 && mention.isPlaceholder);
27
33
  const createInviteItem = ({
28
34
  mentionProvider,
29
35
  onInviteItemMount,
@@ -129,7 +135,8 @@ export function memoize(fn
129
135
  const buildAndSendElementsTypeAheadAnalytics = fireEvent => ({
130
136
  query,
131
137
  mentions,
132
- stats
138
+ stats,
139
+ agentAnalytics
133
140
  }) => {
134
141
  let duration = 0;
135
142
  let userOrTeamIds = null;
@@ -155,7 +162,7 @@ const buildAndSendElementsTypeAheadAnalytics = fireEvent => ({
155
162
  memberCount: mention.context.memberCount
156
163
  } : null).filter(m => !!m);
157
164
  }
158
- const payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength);
165
+ const payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, agentAnalytics);
159
166
  fireEvent(payload, 'fabric-elements');
160
167
  };
161
168
 
@@ -233,7 +240,8 @@ const makeTransformMentionsToTypeAheadItems = ({
233
240
  fireEvent,
234
241
  getFirstQueryWithoutResults,
235
242
  setFirstQueryWithoutResults,
236
- toItem
243
+ toItem,
244
+ enableAgentSectioning
237
245
  }) => {
238
246
  return ({
239
247
  mentions,
@@ -244,12 +252,27 @@ const makeTransformMentionsToTypeAheadItems = ({
244
252
  sessionId
245
253
  }) => {
246
254
  const mentionItems = mentions.map(mention => toItem(mention));
255
+ const agentCount = mentions.filter(isAgentMention).length;
256
+ const agentAnalytics = {
257
+ agentCount,
258
+ agentSectioningEnabled: enableAgentSectioning
259
+ };
260
+
261
+ // The loading placeholder is a rendered-only row — keep it in
262
+ // `mentionItems` so the shimmer shows, but exclude it from analytics
263
+ // and no-results bookkeeping so it isn't counted as a real result.
264
+ const realMentions = mentions.filter(mention => !isLoadingPlaceholder(mention));
247
265
  buildAndSendElementsTypeAheadAnalytics(fireEvent)({
248
266
  query,
249
- mentions,
250
- stats
267
+ mentions: realMentions,
268
+ stats,
269
+ agentAnalytics
251
270
  });
252
- if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
271
+
272
+ // While a loading placeholder is present the result set isn't settled yet
273
+ // (e.g. agents still resolving) — don't record this query as "no results",
274
+ // or a later emission that arrives with results would be ignored.
275
+ if (realMentions.length === 0 && !mentions.some(isLoadingPlaceholder) && getFirstQueryWithoutResults() === null) {
253
276
  setFirstQueryWithoutResults(query);
254
277
  }
255
278
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
@@ -284,6 +307,7 @@ export const createTypeAheadConfig = ({
284
307
  let firstQueryWithoutResults = null;
285
308
  const subscriptionKeys = new Set();
286
309
  const transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
310
+ enableAgentSectioning,
287
311
  fireEvent,
288
312
  getFirstQueryWithoutResults: () => firstQueryWithoutResults,
289
313
  setFirstQueryWithoutResults: query => {
@@ -394,6 +418,12 @@ export const createTypeAheadConfig = ({
394
418
  const {
395
419
  schema
396
420
  } = state;
421
+
422
+ // Placeholder isn't selectable. Return `false` (not a transaction) so
423
+ // the runtime keeps the dropdown open; a transaction would close it.
424
+ if (isLoadingPlaceholder(item.mention)) {
425
+ return false;
426
+ }
397
427
  const pluginState = getMentionPluginState(state);
398
428
  const {
399
429
  mentionProvider
@@ -413,8 +443,8 @@ export const createTypeAheadConfig = ({
413
443
  ...contextIdentifierProvider,
414
444
  sessionId
415
445
  };
416
- const isAgentMentionsExperimentEnabled = expVal('platform_editor_agent_mentions', 'isEnabled', false);
417
- const isAgentMentionInsertion = isAgentMentionsExperimentEnabled && isAgentMention(item.mention);
446
+ const isAgentMentionSelection = isAgentMention(item.mention);
447
+ const isAgentMentionInsertion = isAgentMentionSelection && expVal('platform_editor_agent_mentions', 'isEnabled', false);
418
448
  // userType can be missing for provider-only agent mentions. Copy/paste cannot
419
449
  // see appType, so persist APP only when there is no explicit userType.
420
450
  const persistedUserType = isAgentMentionInsertion && userType == null ? 'APP' : userType;
@@ -489,7 +519,7 @@ export const createTypeAheadConfig = ({
489
519
  handleMentionsChanged([mentionChange]);
490
520
  }
491
521
  }
492
- fireEvent(buildTypeAheadInsertedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(x => x.mention), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionInsertion));
522
+ fireEvent(buildTypeAheadInsertedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(x => x.mention), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionSelection, enableAgentSectioning));
493
523
 
494
524
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
495
525
  sessionId = uuid();
@@ -57,7 +57,7 @@ var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
57
57
  var AGENT_MENTION_INACTIVITY_MS = 3000;
58
58
  var MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
59
59
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
60
- var PACKAGE_VERSION = "14.6.5";
60
+ var PACKAGE_VERSION = "14.7.0";
61
61
  var setProvider = function setProvider(provider) {
62
62
  return function (state, dispatch) {
63
63
  if (dispatch) {
@@ -98,7 +98,7 @@ export var buildTypeAheadInviteItemClickedPayload = function buildTypeAheadInvit
98
98
  }, additionalAttributes)
99
99
  };
100
100
  };
101
- export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent) {
101
+ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent, agentSectioningEnabled) {
102
102
  var _extractAttributesFro3 = extractAttributesFromQuery(query),
103
103
  queryLength = _extractAttributesFro3.queryLength,
104
104
  spaceInQuery = _extractAttributesFro3.spaceInQuery;
@@ -134,7 +134,8 @@ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayloa
134
134
  memberCount: isTeamType(mention.userType) && mention.context ? mention.context.memberCount : null,
135
135
  includesYou: isTeamType(mention.userType) && mention.context ? mention.context.includesYou : null
136
136
  }, isAgent ? {
137
- isAgent: isAgent
137
+ isAgent: isAgent,
138
+ agentSectioningEnabled: agentSectioningEnabled
138
139
  } : {}), {}, {
139
140
  taskListId: taskListId,
140
141
  taskItemId: taskItemId,
@@ -145,16 +146,21 @@ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayloa
145
146
  })
146
147
  };
147
148
  };
148
- export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength) {
149
+ export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength, agentAnalytics) {
149
150
  var _extractAttributesFro4 = extractAttributesFromQuery(query),
150
151
  queryLength = _extractAttributesFro4.queryLength,
151
152
  spaceInQuery = _extractAttributesFro4.spaceInQuery;
152
153
  var actionSubject = userIds ? ACTION_SUBJECT.MENTION_TYPEAHEAD : ACTION_SUBJECT.TEAM_MENTION_TYPEAHEAD;
154
+ var agentAnalyticsAttributes = agentAnalytics ? {
155
+ agentCount: agentAnalytics.agentCount,
156
+ agentsShown: agentAnalytics.agentCount > 0,
157
+ agentSectioningEnabled: agentAnalytics.agentSectioningEnabled
158
+ } : {};
153
159
  return {
154
160
  action: ACTION.RENDERED,
155
161
  actionSubject: actionSubject,
156
162
  eventType: EVENT_TYPE.OPERATIONAL,
157
- attributes: {
163
+ attributes: _objectSpread({
158
164
  componentName: componentName,
159
165
  duration: duration,
160
166
  userIds: userIds,
@@ -162,6 +168,6 @@ export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayloa
162
168
  queryLength: queryLength,
163
169
  spaceInQuery: spaceInQuery,
164
170
  xProductMentionsLength: xProductMentionsLength
165
- }
171
+ }, agentAnalyticsAttributes)
166
172
  };
167
173
  };
@@ -37,6 +37,14 @@ var isAgentMention = function isAgentMention(mention) {
37
37
  var isAgentTypeAheadItem = function isAgentTypeAheadItem(item) {
38
38
  return item.mention ? isAgentMention(item.mention) : false;
39
39
  };
40
+
41
+ // A non-selectable loading placeholder injected by the provider (e.g.
42
+ // `RovoChatMentionResource`) while the slower agent source resolves. It
43
+ // renders as a skeleton row via `@atlaskit/mention`'s `MentionItem` and
44
+ // must never be inserted or counted in rendered-mention analytics.
45
+ var isLoadingPlaceholder = function isLoadingPlaceholder(mention) {
46
+ return !!(mention !== null && mention !== void 0 && mention.isPlaceholder);
47
+ };
40
48
  var createInviteItem = function createInviteItem(_ref) {
41
49
  var mentionProvider = _ref.mentionProvider,
42
50
  onInviteItemMount = _ref.onInviteItemMount,
@@ -149,7 +157,8 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
149
157
  return function (_ref5) {
150
158
  var query = _ref5.query,
151
159
  mentions = _ref5.mentions,
152
- stats = _ref5.stats;
160
+ stats = _ref5.stats,
161
+ agentAnalytics = _ref5.agentAnalytics;
153
162
  var duration = 0;
154
163
  var userOrTeamIds = null;
155
164
  var teams = null;
@@ -182,7 +191,7 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
182
191
  return !!m;
183
192
  });
184
193
  }
185
- var payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength);
194
+ var payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, agentAnalytics);
186
195
  fireEvent(payload, 'fabric-elements');
187
196
  };
188
197
  };
@@ -255,7 +264,8 @@ var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToType
255
264
  var fireEvent = _ref6.fireEvent,
256
265
  getFirstQueryWithoutResults = _ref6.getFirstQueryWithoutResults,
257
266
  setFirstQueryWithoutResults = _ref6.setFirstQueryWithoutResults,
258
- toItem = _ref6.toItem;
267
+ toItem = _ref6.toItem,
268
+ enableAgentSectioning = _ref6.enableAgentSectioning;
259
269
  return function (_ref7) {
260
270
  var mentions = _ref7.mentions,
261
271
  query = _ref7.query,
@@ -266,12 +276,29 @@ var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToType
266
276
  var mentionItems = mentions.map(function (mention) {
267
277
  return toItem(mention);
268
278
  });
279
+ var agentCount = mentions.filter(isAgentMention).length;
280
+ var agentAnalytics = {
281
+ agentCount: agentCount,
282
+ agentSectioningEnabled: enableAgentSectioning
283
+ };
284
+
285
+ // The loading placeholder is a rendered-only row — keep it in
286
+ // `mentionItems` so the shimmer shows, but exclude it from analytics
287
+ // and no-results bookkeeping so it isn't counted as a real result.
288
+ var realMentions = mentions.filter(function (mention) {
289
+ return !isLoadingPlaceholder(mention);
290
+ });
269
291
  buildAndSendElementsTypeAheadAnalytics(fireEvent)({
270
292
  query: query,
271
- mentions: mentions,
272
- stats: stats
293
+ mentions: realMentions,
294
+ stats: stats,
295
+ agentAnalytics: agentAnalytics
273
296
  });
274
- if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
297
+
298
+ // While a loading placeholder is present the result set isn't settled yet
299
+ // (e.g. agents still resolving) — don't record this query as "no results",
300
+ // or a later emission that arrives with results would be ignored.
301
+ if (realMentions.length === 0 && !mentions.some(isLoadingPlaceholder) && getFirstQueryWithoutResults() === null) {
275
302
  setFirstQueryWithoutResults(query);
276
303
  }
277
304
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
@@ -306,6 +333,7 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
306
333
  var firstQueryWithoutResults = null;
307
334
  var subscriptionKeys = new Set();
308
335
  var transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
336
+ enableAgentSectioning: enableAgentSectioning,
309
337
  fireEvent: fireEvent,
310
338
  getFirstQueryWithoutResults: function getFirstQueryWithoutResults() {
311
339
  return firstQueryWithoutResults;
@@ -415,6 +443,12 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
415
443
  query = _ref10.query,
416
444
  sourceListItem = _ref10.sourceListItem;
417
445
  var schema = state.schema;
446
+
447
+ // Placeholder isn't selectable. Return `false` (not a transaction) so
448
+ // the runtime keeps the dropdown open; a transaction would close it.
449
+ if (isLoadingPlaceholder(item.mention)) {
450
+ return false;
451
+ }
418
452
  var pluginState = getMentionPluginState(state);
419
453
  var mentionProvider = pluginState.mentionProvider;
420
454
  var _item$mention = item.mention,
@@ -429,8 +463,8 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
429
463
  var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
430
464
  sessionId: sessionId
431
465
  });
432
- var isAgentMentionsExperimentEnabled = expVal('platform_editor_agent_mentions', 'isEnabled', false);
433
- var isAgentMentionInsertion = isAgentMentionsExperimentEnabled && isAgentMention(item.mention);
466
+ var isAgentMentionSelection = isAgentMention(item.mention);
467
+ var isAgentMentionInsertion = isAgentMentionSelection && expVal('platform_editor_agent_mentions', 'isEnabled', false);
434
468
  // userType can be missing for provider-only agent mentions. Copy/paste cannot
435
469
  // see appType, so persist APP only when there is no explicit userType.
436
470
  var persistedUserType = isAgentMentionInsertion && userType == null ? 'APP' : userType;
@@ -503,7 +537,7 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
503
537
  }
504
538
  fireEvent(buildTypeAheadInsertedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(function (x) {
505
539
  return x.mention;
506
- }), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionInsertion));
540
+ }), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionSelection, enableAgentSectioning));
507
541
 
508
542
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
509
543
  sessionId = uuid();
@@ -8,5 +8,8 @@ export declare const MENTION_SOURCE = "mentionInEditor";
8
8
  export declare const buildTypeAheadCancelPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, query?: string) => AnalyticsEventPayload;
9
9
  export declare const buildTypeAheadInviteItemViewedPayload: (sessionId: string, contextIdentifierProvider?: ContextIdentifierProvider, userRole?: UserRole, additionalAttributes?: Record<string, unknown>) => AnalyticsEventPayload;
10
10
  export declare const buildTypeAheadInviteItemClickedPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, insertType: SelectItemMode, query?: string, contextIdentifierProvider?: ContextIdentifierProvider, userRole?: UserRole, additionalAttributes?: Record<string, unknown>) => AnalyticsEventPayload;
11
- export declare const buildTypeAheadInsertedPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, insertType: SelectItemMode, mention: MentionDescription, mentionLocalId: string, mentionList?: MentionDescription[], query?: string, contextIdentifierProvider?: ContextIdentifierProvider, taskListId?: string, taskItemId?: string, isAgent?: boolean) => AnalyticsEventPayload;
12
- export declare const buildTypeAheadRenderedPayload: (duration: number, userIds: Array<string> | null, query: string, teams: TeamInfoAttrAnalytics[] | null, xProductMentionsLength: number) => AnalyticsEventPayload;
11
+ export declare const buildTypeAheadInsertedPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, insertType: SelectItemMode, mention: MentionDescription, mentionLocalId: string, mentionList?: MentionDescription[], query?: string, contextIdentifierProvider?: ContextIdentifierProvider, taskListId?: string, taskItemId?: string, isAgent?: boolean, agentSectioningEnabled?: boolean) => AnalyticsEventPayload;
12
+ export declare const buildTypeAheadRenderedPayload: (duration: number, userIds: Array<string> | null, query: string, teams: TeamInfoAttrAnalytics[] | null, xProductMentionsLength: number, agentAnalytics?: {
13
+ agentCount: number;
14
+ agentSectioningEnabled: boolean;
15
+ }) => AnalyticsEventPayload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-mentions",
3
- "version": "14.6.6",
3
+ "version": "14.8.0",
4
4
  "description": "Mentions plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,7 @@
33
33
  "@atlaskit/insm": "^1.0.0",
34
34
  "@atlaskit/link": "^4.3.0",
35
35
  "@atlaskit/lozenge": "^14.1.0",
36
- "@atlaskit/mention": "^27.5.0",
36
+ "@atlaskit/mention": "^27.7.0",
37
37
  "@atlaskit/platform-feature-flags": "^2.0.0",
38
38
  "@atlaskit/popper": "^8.3.0",
39
39
  "@atlaskit/portal": "^6.1.0",
@@ -41,7 +41,7 @@
41
41
  "@atlaskit/profilecard": "^26.9.0",
42
42
  "@atlaskit/teams-app-config": "^2.1.0",
43
43
  "@atlaskit/theme": "^26.1.0",
44
- "@atlaskit/tmp-editor-statsig": "^126.0.0",
44
+ "@atlaskit/tmp-editor-statsig": "^126.1.0",
45
45
  "@atlaskit/tokens": "^15.8.0",
46
46
  "@atlaskit/tooltip": "^23.1.0",
47
47
  "@atlaskit/user-picker": "^13.4.0",
@@ -53,7 +53,7 @@
53
53
  "uuid": "^3.1.0"
54
54
  },
55
55
  "peerDependencies": {
56
- "@atlaskit/editor-common": "^116.30.0",
56
+ "@atlaskit/editor-common": "^116.32.0",
57
57
  "react": "^18.2.0",
58
58
  "react-dom": "^18.2.0",
59
59
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"