@atlaskit/editor-plugin-mentions 14.2.3 → 14.4.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 +30 -0
- package/dist/cjs/pm-plugins/main.js +2 -3
- package/dist/cjs/ui/type-ahead/index.js +216 -54
- package/dist/es2019/pm-plugins/main.js +2 -3
- package/dist/es2019/ui/type-ahead/index.js +189 -25
- package/dist/esm/pm-plugins/main.js +2 -3
- package/dist/esm/ui/type-ahead/index.js +216 -54
- package/package.json +12 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-mentions
|
|
2
2
|
|
|
3
|
+
## 14.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`dbf22f118dd9e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dbf22f118dd9e) -
|
|
8
|
+
Rewrite Rovo Chat @-mention provider on a single Relay-native RovoChatMentionResource that fires
|
|
9
|
+
people + agents in parallel via Promise. People render as soon as URS resolves and agents pop in
|
|
10
|
+
below when ready. New aliased agentStudio_getAgents query consolidates 3 prefetch round trips into
|
|
11
|
+
1, drops over-fetched fields, and uses real abort plumbing. Adds opt-in subscribeToItemsUpdates
|
|
12
|
+
multi-emit contract to the editor mention typeahead so progressive emissions are no longer dropped
|
|
13
|
+
after the first frame.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`ddeae9a5f8bdf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ddeae9a5f8bdf) -
|
|
18
|
+
Prevent remote collaborative agent mention insertions from publishing local agent mention
|
|
19
|
+
insertion state.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
22
|
+
## 14.3.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- [`cf7797df5ff1e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf7797df5ff1e) -
|
|
27
|
+
[ux] Add a Labs lozenge to the agent mention typeahead section.
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
|
|
3
33
|
## 14.2.3
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
|
@@ -39,7 +39,7 @@ var isAgentUserType = function isAgentUserType(userType) {
|
|
|
39
39
|
var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
40
40
|
var AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
41
41
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
42
|
-
var PACKAGE_VERSION = "14.
|
|
42
|
+
var PACKAGE_VERSION = "14.3.0";
|
|
43
43
|
var setProvider = function setProvider(provider) {
|
|
44
44
|
return function (state, dispatch) {
|
|
45
45
|
if (dispatch) {
|
|
@@ -355,8 +355,7 @@ function createMentionPlugin(_ref2) {
|
|
|
355
355
|
}
|
|
356
356
|
(_insm$session2 = _insm.insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('mentionDeletionDetection');
|
|
357
357
|
}
|
|
358
|
-
|
|
359
|
-
if (tr.docChanged && !tr.getMeta('replaceDocument') && !isAIStreaming && isAgentMentionsExperimentEnabled) {
|
|
358
|
+
if (isAgentMentionsExperimentEnabled && isQualifyingLocalUserDocChange(tr)) {
|
|
360
359
|
var _mentionSchema = newState.schema.nodes.mention;
|
|
361
360
|
var newDocRanges = [];
|
|
362
361
|
var oldDocRanges = [];
|
|
@@ -16,6 +16,7 @@ var _messages = require("@atlaskit/editor-common/messages");
|
|
|
16
16
|
var _typeAhead = require("@atlaskit/editor-common/type-ahead");
|
|
17
17
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
18
18
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
19
|
+
var _lozenge = _interopRequireDefault(require("@atlaskit/lozenge"));
|
|
19
20
|
var _item = require("@atlaskit/mention/item");
|
|
20
21
|
var _resource = require("@atlaskit/mention/resource");
|
|
21
22
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
@@ -240,17 +241,77 @@ var buildNodesForTeamMention = function buildNodesForTeamMention(schema, selecte
|
|
|
240
241
|
inlineNodes.push(closeBracketText);
|
|
241
242
|
return _model.Fragment.fromArray(inlineNodes);
|
|
242
243
|
};
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Shared mentions → typeahead-items transformer used by both the
|
|
246
|
+
* single-shot `getItems` Promise path and the multi-emit
|
|
247
|
+
* `subscribeToItemsUpdates` path. Factoring this out avoids any
|
|
248
|
+
* chance the two paths drift in subtle item-shape behaviour (invite
|
|
249
|
+
* item injection, analytics emission, no-results bookkeeping).
|
|
250
|
+
*
|
|
251
|
+
* NOTE: `firstQueryWithoutResults` is captured by closure in
|
|
252
|
+
* `createTypeAheadConfig` and intentionally mutated here as a
|
|
253
|
+
* side-effect — preserves the existing single-shot semantics.
|
|
254
|
+
*/
|
|
255
|
+
var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToTypeAheadItems(_ref6) {
|
|
256
|
+
var fireEvent = _ref6.fireEvent,
|
|
257
|
+
getFirstQueryWithoutResults = _ref6.getFirstQueryWithoutResults,
|
|
258
|
+
setFirstQueryWithoutResults = _ref6.setFirstQueryWithoutResults;
|
|
259
|
+
return function (_ref7) {
|
|
260
|
+
var mentions = _ref7.mentions,
|
|
261
|
+
query = _ref7.query,
|
|
262
|
+
stats = _ref7.stats,
|
|
263
|
+
mentionProvider = _ref7.mentionProvider,
|
|
264
|
+
contextIdentifierProvider = _ref7.contextIdentifierProvider,
|
|
265
|
+
sessionId = _ref7.sessionId;
|
|
266
|
+
var mentionItems = mentions.map(function (mention) {
|
|
267
|
+
return memoizedToItem.call(mention);
|
|
268
|
+
});
|
|
269
|
+
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
270
|
+
query: query,
|
|
271
|
+
mentions: mentions,
|
|
272
|
+
stats: stats
|
|
273
|
+
});
|
|
274
|
+
if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
|
|
275
|
+
setFirstQueryWithoutResults(query);
|
|
276
|
+
}
|
|
277
|
+
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
278
|
+
return mentionItems;
|
|
279
|
+
}
|
|
280
|
+
var emailDomain = mentionProvider.userEmailDomain;
|
|
281
|
+
return withInviteItem({
|
|
282
|
+
mentionProvider: mentionProvider,
|
|
283
|
+
firstQueryWithoutResults: getFirstQueryWithoutResults() || '',
|
|
284
|
+
currentQuery: query,
|
|
285
|
+
onInviteItemMount: function onInviteItemMount() {
|
|
286
|
+
var _mentionProvider$getS2;
|
|
287
|
+
fireEvent((0, _analytics.buildTypeAheadInviteItemViewedPayload)(sessionId, contextIdentifierProvider, mentionProvider.userRole, (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
288
|
+
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
289
|
+
} : {}));
|
|
290
|
+
},
|
|
291
|
+
emailDomain: emailDomain
|
|
292
|
+
})(mentionItems);
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
|
|
296
|
+
var sanitizePrivateContent = _ref8.sanitizePrivateContent,
|
|
297
|
+
mentionInsertDisplayName = _ref8.mentionInsertDisplayName,
|
|
298
|
+
fireEvent = _ref8.fireEvent,
|
|
299
|
+
HighlightComponent = _ref8.HighlightComponent,
|
|
300
|
+
api = _ref8.api,
|
|
301
|
+
handleMentionsChanged = _ref8.handleMentionsChanged;
|
|
250
302
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
251
303
|
var sessionId = (0, _uuid.default)();
|
|
252
304
|
var firstQueryWithoutResults = null;
|
|
253
305
|
var subscriptionKeys = new Set();
|
|
306
|
+
var transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
|
|
307
|
+
fireEvent: fireEvent,
|
|
308
|
+
getFirstQueryWithoutResults: function getFirstQueryWithoutResults() {
|
|
309
|
+
return firstQueryWithoutResults;
|
|
310
|
+
},
|
|
311
|
+
setFirstQueryWithoutResults: function setFirstQueryWithoutResults(query) {
|
|
312
|
+
firstQueryWithoutResults = query;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
254
315
|
var typeAhead = {
|
|
255
316
|
id: _typeAhead.TypeAheadAvailableNodes.MENTION,
|
|
256
317
|
trigger: '@',
|
|
@@ -264,17 +325,17 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
264
325
|
}
|
|
265
326
|
return null;
|
|
266
327
|
},
|
|
267
|
-
getItems: function getItems(
|
|
328
|
+
getItems: function getItems(_ref9) {
|
|
268
329
|
var _api$contextIdentifie, _api$contextIdentifie2;
|
|
269
|
-
var query =
|
|
270
|
-
editorState =
|
|
330
|
+
var query = _ref9.query,
|
|
331
|
+
editorState = _ref9.editorState;
|
|
271
332
|
var pluginState = (0, _utils2.getMentionPluginState)(editorState);
|
|
272
333
|
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
273
334
|
return Promise.resolve([]);
|
|
274
335
|
}
|
|
275
336
|
var mentionProvider = pluginState.mentionProvider;
|
|
276
|
-
var
|
|
277
|
-
contextIdentifierProvider =
|
|
337
|
+
var _ref0 = (_api$contextIdentifie = api === null || api === void 0 || (_api$contextIdentifie2 = api.contextIdentifier) === null || _api$contextIdentifie2 === void 0 ? void 0 : _api$contextIdentifie2.sharedState.currentState()) !== null && _api$contextIdentifie !== void 0 ? _api$contextIdentifie : {},
|
|
338
|
+
contextIdentifierProvider = _ref0.contextIdentifierProvider;
|
|
278
339
|
return new Promise(function (resolve, reject) {
|
|
279
340
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
280
341
|
var key = "loadingMentionsForTypeAhead_".concat((0, _uuid.default)());
|
|
@@ -286,35 +347,15 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
286
347
|
}
|
|
287
348
|
mentionProvider.unsubscribe(key);
|
|
288
349
|
subscriptionKeys.delete(key);
|
|
289
|
-
var
|
|
290
|
-
return memoizedToItem.call(mention);
|
|
291
|
-
});
|
|
292
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
293
|
-
query: query,
|
|
350
|
+
var items = transformMentionsToTypeAheadItems({
|
|
294
351
|
mentions: mentions,
|
|
295
|
-
|
|
352
|
+
query: query,
|
|
353
|
+
stats: stats,
|
|
354
|
+
mentionProvider: mentionProvider,
|
|
355
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
356
|
+
sessionId: sessionId
|
|
296
357
|
});
|
|
297
|
-
|
|
298
|
-
firstQueryWithoutResults = query;
|
|
299
|
-
}
|
|
300
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
301
|
-
resolve(mentionItems);
|
|
302
|
-
} else {
|
|
303
|
-
var emailDomain = mentionProvider.userEmailDomain;
|
|
304
|
-
var items = withInviteItem({
|
|
305
|
-
mentionProvider: mentionProvider,
|
|
306
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
307
|
-
currentQuery: query,
|
|
308
|
-
onInviteItemMount: function onInviteItemMount() {
|
|
309
|
-
var _mentionProvider$getS2;
|
|
310
|
-
fireEvent((0, _analytics.buildTypeAheadInviteItemViewedPayload)(sessionId, contextIdentifierProvider, mentionProvider.userRole, (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
311
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
312
|
-
} : {}));
|
|
313
|
-
},
|
|
314
|
-
emailDomain: emailDomain
|
|
315
|
-
})(mentionItems);
|
|
316
|
-
resolve(items);
|
|
317
|
-
}
|
|
358
|
+
resolve(items);
|
|
318
359
|
};
|
|
319
360
|
subscriptionKeys.add(key);
|
|
320
361
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
@@ -329,8 +370,8 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
329
370
|
}));
|
|
330
371
|
});
|
|
331
372
|
},
|
|
332
|
-
getSections: function getSections(
|
|
333
|
-
var intl =
|
|
373
|
+
getSections: function getSections(_ref1) {
|
|
374
|
+
var intl = _ref1.intl;
|
|
334
375
|
return [_objectSpread({
|
|
335
376
|
id: 'people',
|
|
336
377
|
title: intl.formatMessage(_messages.mentionMessages.typeAheadSectionPeople),
|
|
@@ -343,7 +384,7 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
343
384
|
showWhenQueryPresent: false,
|
|
344
385
|
showWhenOnlySection: true
|
|
345
386
|
}
|
|
346
|
-
} : {}), _objectSpread({
|
|
387
|
+
} : {}), _objectSpread(_objectSpread({
|
|
347
388
|
id: 'agents',
|
|
348
389
|
title: intl.formatMessage(_messages.mentionMessages.typeAheadSectionAgents),
|
|
349
390
|
filter: function filter(item) {
|
|
@@ -355,17 +396,21 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
355
396
|
showWhenQueryPresent: false,
|
|
356
397
|
showWhenOnlySection: true
|
|
357
398
|
}
|
|
399
|
+
} : {}), (0, _expVal.expVal)('platform_editor_agent_mentions', 'isEnabled', false) ? {
|
|
400
|
+
lozenge: /*#__PURE__*/_react.default.createElement(_lozenge.default, {
|
|
401
|
+
appearance: "new"
|
|
402
|
+
}, intl.formatMessage(_messages.mentionMessages.typeAheadSectionAgentsLabs))
|
|
358
403
|
} : {})];
|
|
359
404
|
},
|
|
360
405
|
onOpen: function onOpen() {
|
|
361
406
|
firstQueryWithoutResults = null;
|
|
362
407
|
},
|
|
363
|
-
selectItem: function selectItem(state, item, insert,
|
|
408
|
+
selectItem: function selectItem(state, item, insert, _ref10) {
|
|
364
409
|
var _api$contextIdentifie3, _api$contextIdentifie4;
|
|
365
|
-
var mode =
|
|
366
|
-
stats =
|
|
367
|
-
query =
|
|
368
|
-
sourceListItem =
|
|
410
|
+
var mode = _ref10.mode,
|
|
411
|
+
stats = _ref10.stats,
|
|
412
|
+
query = _ref10.query,
|
|
413
|
+
sourceListItem = _ref10.sourceListItem;
|
|
369
414
|
var schema = state.schema;
|
|
370
415
|
var pluginState = (0, _utils2.getMentionPluginState)(state);
|
|
371
416
|
var mentionProvider = pluginState.mentionProvider;
|
|
@@ -376,8 +421,8 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
376
421
|
accessLevel = _item$mention.accessLevel,
|
|
377
422
|
userType = _item$mention.userType,
|
|
378
423
|
isXProductUser = _item$mention.isXProductUser;
|
|
379
|
-
var
|
|
380
|
-
contextIdentifierProvider =
|
|
424
|
+
var _ref11 = (_api$contextIdentifie3 = api === null || api === void 0 || (_api$contextIdentifie4 = api.contextIdentifier) === null || _api$contextIdentifie4 === void 0 ? void 0 : _api$contextIdentifie4.sharedState.currentState()) !== null && _api$contextIdentifie3 !== void 0 ? _api$contextIdentifie3 : {},
|
|
425
|
+
contextIdentifierProvider = _ref11.contextIdentifierProvider;
|
|
381
426
|
var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
382
427
|
sessionId: sessionId
|
|
383
428
|
});
|
|
@@ -490,11 +535,11 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
490
535
|
}
|
|
491
536
|
return tr;
|
|
492
537
|
},
|
|
493
|
-
dismiss: function dismiss(
|
|
494
|
-
var editorState =
|
|
495
|
-
query =
|
|
496
|
-
stats =
|
|
497
|
-
wasItemInserted =
|
|
538
|
+
dismiss: function dismiss(_ref12) {
|
|
539
|
+
var editorState = _ref12.editorState,
|
|
540
|
+
query = _ref12.query,
|
|
541
|
+
stats = _ref12.stats,
|
|
542
|
+
wasItemInserted = _ref12.wasItemInserted;
|
|
498
543
|
firstQueryWithoutResults = null;
|
|
499
544
|
var pickerElapsedTime = stats.startedAt ? performance.now() - stats.startedAt : 0;
|
|
500
545
|
if (!wasItemInserted) {
|
|
@@ -522,5 +567,122 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
522
567
|
sessionId = (0, _uuid.default)();
|
|
523
568
|
}
|
|
524
569
|
};
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Opt-in multi-emit path. Subscribes to the provider's stream of
|
|
573
|
+
* results for the lifetime of the type-ahead session — does NOT
|
|
574
|
+
* unsubscribe after the first emission. Lets providers like
|
|
575
|
+
* `RovoChatMentionResource` deliver people-first then merged
|
|
576
|
+
* people + agents to the dropdown without the typeahead dropping
|
|
577
|
+
* the second emission on the floor.
|
|
578
|
+
*
|
|
579
|
+
* Gated behind `rovo_chat_agent_selection` (the same gate that drives
|
|
580
|
+
* agent mentions in the Rovo chat input). The generic type-ahead hook
|
|
581
|
+
* opts a handler into streaming purely by the presence of this method,
|
|
582
|
+
* so we only attach it when the gate is on — otherwise the proven
|
|
583
|
+
* single-shot `getItems` path continues to drive every consumer.
|
|
584
|
+
*/
|
|
585
|
+
var subscribeToItemsUpdates = function subscribeToItemsUpdates(_ref13) {
|
|
586
|
+
var _api$contextIdentifie5, _api$contextIdentifie6;
|
|
587
|
+
var query = _ref13.query,
|
|
588
|
+
editorState = _ref13.editorState;
|
|
589
|
+
var pluginState = (0, _utils2.getMentionPluginState)(editorState);
|
|
590
|
+
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
591
|
+
return {
|
|
592
|
+
initial: Promise.resolve([]),
|
|
593
|
+
subscribe: function subscribe() {
|
|
594
|
+
return function () {};
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
var mentionProvider = pluginState.mentionProvider;
|
|
599
|
+
var _ref14 = (_api$contextIdentifie5 = api === null || api === void 0 || (_api$contextIdentifie6 = api.contextIdentifier) === null || _api$contextIdentifie6 === void 0 ? void 0 : _api$contextIdentifie6.sharedState.currentState()) !== null && _api$contextIdentifie5 !== void 0 ? _api$contextIdentifie5 : {},
|
|
600
|
+
contextIdentifierProvider = _ref14.contextIdentifierProvider;
|
|
601
|
+
|
|
602
|
+
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
603
|
+
var key = "loadingMentionsForTypeAhead_".concat((0, _uuid.default)());
|
|
604
|
+
var initialResolve = null;
|
|
605
|
+
var initialReject = null;
|
|
606
|
+
var initialResolved = false;
|
|
607
|
+
var updateCallback = null;
|
|
608
|
+
var unsubscribed = false;
|
|
609
|
+
var initial = new Promise(function (resolve, reject) {
|
|
610
|
+
initialResolve = resolve;
|
|
611
|
+
initialReject = reject;
|
|
612
|
+
});
|
|
613
|
+
var mentionsSubscribeCallback = function mentionsSubscribeCallback(mentions) {
|
|
614
|
+
var resultQuery = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
615
|
+
var stats = arguments.length > 2 ? arguments[2] : undefined;
|
|
616
|
+
// Drop emissions tagged with a query that has moved on.
|
|
617
|
+
// Mirrors the same guard in the single-shot `getItems`.
|
|
618
|
+
if (query !== resultQuery) {
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
if (unsubscribed) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
var items = transformMentionsToTypeAheadItems({
|
|
625
|
+
mentions: mentions,
|
|
626
|
+
query: query,
|
|
627
|
+
stats: stats,
|
|
628
|
+
mentionProvider: mentionProvider,
|
|
629
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
630
|
+
sessionId: sessionId
|
|
631
|
+
});
|
|
632
|
+
if (!initialResolved) {
|
|
633
|
+
var _initialResolve;
|
|
634
|
+
initialResolved = true;
|
|
635
|
+
(_initialResolve = initialResolve) === null || _initialResolve === void 0 || _initialResolve(items);
|
|
636
|
+
} else {
|
|
637
|
+
var _updateCallback;
|
|
638
|
+
(_updateCallback = updateCallback) === null || _updateCallback === void 0 || _updateCallback(items);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
subscriptionKeys.add(key);
|
|
642
|
+
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
643
|
+
if ((0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true)) {
|
|
644
|
+
mentionProvider.unsubscribe(key);
|
|
645
|
+
subscriptionKeys.delete(key);
|
|
646
|
+
if (!initialResolved) {
|
|
647
|
+
var _initialReject;
|
|
648
|
+
initialResolved = true;
|
|
649
|
+
(_initialReject = initialReject) === null || _initialReject === void 0 || _initialReject('FETCH_ERROR');
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
mentionProvider.filter(query || '', _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
654
|
+
sessionId: sessionId
|
|
655
|
+
}));
|
|
656
|
+
return {
|
|
657
|
+
initial: initial,
|
|
658
|
+
subscribe: function subscribe(update) {
|
|
659
|
+
if (updateCallback) {
|
|
660
|
+
throw new Error('TypeAhead mention updates support only one subscriber');
|
|
661
|
+
}
|
|
662
|
+
updateCallback = update;
|
|
663
|
+
return function () {
|
|
664
|
+
unsubscribed = true;
|
|
665
|
+
updateCallback = null;
|
|
666
|
+
mentionProvider.unsubscribe(key);
|
|
667
|
+
subscriptionKeys.delete(key);
|
|
668
|
+
// If cleanup runs before the first emission, settle the initial
|
|
669
|
+
// promise so its `.then` chain (and the closures it holds) is
|
|
670
|
+
// released instead of pending forever.
|
|
671
|
+
if (!initialResolved) {
|
|
672
|
+
var _initialResolve2;
|
|
673
|
+
initialResolved = true;
|
|
674
|
+
(_initialResolve2 = initialResolve) === null || _initialResolve2 === void 0 || _initialResolve2([]);
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
// Presence of `subscribeToItemsUpdates` is how the type-ahead hook
|
|
682
|
+
// opts a handler into the multi-emit path, so only expose it when the
|
|
683
|
+
// agent-selection gate is on.
|
|
684
|
+
if ((0, _platformFeatureFlags.fg)('rovo_chat_agent_selection')) {
|
|
685
|
+
typeAhead.subscribeToItemsUpdates = subscribeToItemsUpdates;
|
|
686
|
+
}
|
|
525
687
|
return typeAhead;
|
|
526
688
|
};
|
|
@@ -24,7 +24,7 @@ const isAgentUserType = userType => {
|
|
|
24
24
|
const AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
25
25
|
const AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
26
26
|
const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
27
|
-
const PACKAGE_VERSION = "14.
|
|
27
|
+
const PACKAGE_VERSION = "14.3.0";
|
|
28
28
|
const setProvider = provider => (state, dispatch) => {
|
|
29
29
|
if (dispatch) {
|
|
30
30
|
dispatch(state.tr.setMeta(mentionPluginKey, {
|
|
@@ -333,8 +333,7 @@ export function createMentionPlugin({
|
|
|
333
333
|
}
|
|
334
334
|
(_insm$session2 = insm.session) === null || _insm$session2 === void 0 ? void 0 : _insm$session2.endFeature('mentionDeletionDetection');
|
|
335
335
|
}
|
|
336
|
-
|
|
337
|
-
if (tr.docChanged && !tr.getMeta('replaceDocument') && !isAIStreaming && isAgentMentionsExperimentEnabled) {
|
|
336
|
+
if (isAgentMentionsExperimentEnabled && isQualifyingLocalUserDocChange(tr)) {
|
|
338
337
|
const mentionSchema = newState.schema.nodes.mention;
|
|
339
338
|
const newDocRanges = [];
|
|
340
339
|
const oldDocRanges = [];
|
|
@@ -6,6 +6,7 @@ import { mentionMessages } from '@atlaskit/editor-common/messages';
|
|
|
6
6
|
import { TypeAheadAvailableNodes } from '@atlaskit/editor-common/type-ahead';
|
|
7
7
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
8
8
|
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
9
|
+
import Lozenge from '@atlaskit/lozenge';
|
|
9
10
|
import { MENTION_ITEM_HEIGHT, MENTION_ITEM_HEIGHT_REFRESHED, MentionItem } from '@atlaskit/mention/item';
|
|
10
11
|
import { isResolvingMentionProvider } from '@atlaskit/mention/resource';
|
|
11
12
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -213,6 +214,57 @@ const buildNodesForTeamMention = (schema, selectedMention, mentionProvider, sani
|
|
|
213
214
|
inlineNodes.push(closeBracketText);
|
|
214
215
|
return Fragment.fromArray(inlineNodes);
|
|
215
216
|
};
|
|
217
|
+
/**
|
|
218
|
+
* Shared mentions → typeahead-items transformer used by both the
|
|
219
|
+
* single-shot `getItems` Promise path and the multi-emit
|
|
220
|
+
* `subscribeToItemsUpdates` path. Factoring this out avoids any
|
|
221
|
+
* chance the two paths drift in subtle item-shape behaviour (invite
|
|
222
|
+
* item injection, analytics emission, no-results bookkeeping).
|
|
223
|
+
*
|
|
224
|
+
* NOTE: `firstQueryWithoutResults` is captured by closure in
|
|
225
|
+
* `createTypeAheadConfig` and intentionally mutated here as a
|
|
226
|
+
* side-effect — preserves the existing single-shot semantics.
|
|
227
|
+
*/
|
|
228
|
+
const makeTransformMentionsToTypeAheadItems = ({
|
|
229
|
+
fireEvent,
|
|
230
|
+
getFirstQueryWithoutResults,
|
|
231
|
+
setFirstQueryWithoutResults
|
|
232
|
+
}) => {
|
|
233
|
+
return ({
|
|
234
|
+
mentions,
|
|
235
|
+
query,
|
|
236
|
+
stats,
|
|
237
|
+
mentionProvider,
|
|
238
|
+
contextIdentifierProvider,
|
|
239
|
+
sessionId
|
|
240
|
+
}) => {
|
|
241
|
+
const mentionItems = mentions.map(mention => memoizedToItem.call(mention));
|
|
242
|
+
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
243
|
+
query,
|
|
244
|
+
mentions,
|
|
245
|
+
stats
|
|
246
|
+
});
|
|
247
|
+
if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
|
|
248
|
+
setFirstQueryWithoutResults(query);
|
|
249
|
+
}
|
|
250
|
+
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
251
|
+
return mentionItems;
|
|
252
|
+
}
|
|
253
|
+
const emailDomain = mentionProvider.userEmailDomain;
|
|
254
|
+
return withInviteItem({
|
|
255
|
+
mentionProvider,
|
|
256
|
+
firstQueryWithoutResults: getFirstQueryWithoutResults() || '',
|
|
257
|
+
currentQuery: query,
|
|
258
|
+
onInviteItemMount: () => {
|
|
259
|
+
var _mentionProvider$getS2;
|
|
260
|
+
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
261
|
+
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
262
|
+
} : {}));
|
|
263
|
+
},
|
|
264
|
+
emailDomain
|
|
265
|
+
})(mentionItems);
|
|
266
|
+
};
|
|
267
|
+
};
|
|
216
268
|
export const createTypeAheadConfig = ({
|
|
217
269
|
sanitizePrivateContent,
|
|
218
270
|
mentionInsertDisplayName,
|
|
@@ -225,6 +277,13 @@ export const createTypeAheadConfig = ({
|
|
|
225
277
|
let sessionId = uuid();
|
|
226
278
|
let firstQueryWithoutResults = null;
|
|
227
279
|
const subscriptionKeys = new Set();
|
|
280
|
+
const transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
|
|
281
|
+
fireEvent,
|
|
282
|
+
getFirstQueryWithoutResults: () => firstQueryWithoutResults,
|
|
283
|
+
setFirstQueryWithoutResults: query => {
|
|
284
|
+
firstQueryWithoutResults = query;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
228
287
|
const typeAhead = {
|
|
229
288
|
id: TypeAheadAvailableNodes.MENTION,
|
|
230
289
|
trigger: '@',
|
|
@@ -262,33 +321,15 @@ export const createTypeAheadConfig = ({
|
|
|
262
321
|
}
|
|
263
322
|
mentionProvider.unsubscribe(key);
|
|
264
323
|
subscriptionKeys.delete(key);
|
|
265
|
-
const
|
|
266
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
267
|
-
query,
|
|
324
|
+
const items = transformMentionsToTypeAheadItems({
|
|
268
325
|
mentions,
|
|
269
|
-
|
|
326
|
+
query,
|
|
327
|
+
stats,
|
|
328
|
+
mentionProvider,
|
|
329
|
+
contextIdentifierProvider,
|
|
330
|
+
sessionId
|
|
270
331
|
});
|
|
271
|
-
|
|
272
|
-
firstQueryWithoutResults = query;
|
|
273
|
-
}
|
|
274
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
275
|
-
resolve(mentionItems);
|
|
276
|
-
} else {
|
|
277
|
-
const emailDomain = mentionProvider.userEmailDomain;
|
|
278
|
-
const items = withInviteItem({
|
|
279
|
-
mentionProvider,
|
|
280
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
281
|
-
currentQuery: query,
|
|
282
|
-
onInviteItemMount: () => {
|
|
283
|
-
var _mentionProvider$getS2;
|
|
284
|
-
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
285
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
286
|
-
} : {}));
|
|
287
|
-
},
|
|
288
|
-
emailDomain
|
|
289
|
-
})(mentionItems);
|
|
290
|
-
resolve(items);
|
|
291
|
-
}
|
|
332
|
+
resolve(items);
|
|
292
333
|
};
|
|
293
334
|
subscriptionKeys.add(key);
|
|
294
335
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, () => {
|
|
@@ -328,6 +369,11 @@ export const createTypeAheadConfig = ({
|
|
|
328
369
|
showWhenQueryPresent: false,
|
|
329
370
|
showWhenOnlySection: true
|
|
330
371
|
}
|
|
372
|
+
} : {}),
|
|
373
|
+
...(expVal('platform_editor_agent_mentions', 'isEnabled', false) ? {
|
|
374
|
+
lozenge: /*#__PURE__*/React.createElement(Lozenge, {
|
|
375
|
+
appearance: "new"
|
|
376
|
+
}, intl.formatMessage(mentionMessages.typeAheadSectionAgentsLabs))
|
|
331
377
|
} : {})
|
|
332
378
|
}];
|
|
333
379
|
},
|
|
@@ -498,5 +544,123 @@ export const createTypeAheadConfig = ({
|
|
|
498
544
|
sessionId = uuid();
|
|
499
545
|
}
|
|
500
546
|
};
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Opt-in multi-emit path. Subscribes to the provider's stream of
|
|
550
|
+
* results for the lifetime of the type-ahead session — does NOT
|
|
551
|
+
* unsubscribe after the first emission. Lets providers like
|
|
552
|
+
* `RovoChatMentionResource` deliver people-first then merged
|
|
553
|
+
* people + agents to the dropdown without the typeahead dropping
|
|
554
|
+
* the second emission on the floor.
|
|
555
|
+
*
|
|
556
|
+
* Gated behind `rovo_chat_agent_selection` (the same gate that drives
|
|
557
|
+
* agent mentions in the Rovo chat input). The generic type-ahead hook
|
|
558
|
+
* opts a handler into streaming purely by the presence of this method,
|
|
559
|
+
* so we only attach it when the gate is on — otherwise the proven
|
|
560
|
+
* single-shot `getItems` path continues to drive every consumer.
|
|
561
|
+
*/
|
|
562
|
+
const subscribeToItemsUpdates = ({
|
|
563
|
+
query,
|
|
564
|
+
editorState
|
|
565
|
+
}) => {
|
|
566
|
+
var _api$contextIdentifie5, _api$contextIdentifie6;
|
|
567
|
+
const pluginState = getMentionPluginState(editorState);
|
|
568
|
+
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
569
|
+
return {
|
|
570
|
+
initial: Promise.resolve([]),
|
|
571
|
+
subscribe: () => () => {}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
const {
|
|
575
|
+
mentionProvider
|
|
576
|
+
} = pluginState;
|
|
577
|
+
const {
|
|
578
|
+
contextIdentifierProvider
|
|
579
|
+
} = (_api$contextIdentifie5 = api === null || api === void 0 ? void 0 : (_api$contextIdentifie6 = api.contextIdentifier) === null || _api$contextIdentifie6 === void 0 ? void 0 : _api$contextIdentifie6.sharedState.currentState()) !== null && _api$contextIdentifie5 !== void 0 ? _api$contextIdentifie5 : {};
|
|
580
|
+
|
|
581
|
+
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
582
|
+
const key = `loadingMentionsForTypeAhead_${uuid()}`;
|
|
583
|
+
let initialResolve = null;
|
|
584
|
+
let initialReject = null;
|
|
585
|
+
let initialResolved = false;
|
|
586
|
+
let updateCallback = null;
|
|
587
|
+
let unsubscribed = false;
|
|
588
|
+
const initial = new Promise((resolve, reject) => {
|
|
589
|
+
initialResolve = resolve;
|
|
590
|
+
initialReject = reject;
|
|
591
|
+
});
|
|
592
|
+
const mentionsSubscribeCallback = (mentions, resultQuery = '', stats) => {
|
|
593
|
+
// Drop emissions tagged with a query that has moved on.
|
|
594
|
+
// Mirrors the same guard in the single-shot `getItems`.
|
|
595
|
+
if (query !== resultQuery) {
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (unsubscribed) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const items = transformMentionsToTypeAheadItems({
|
|
602
|
+
mentions,
|
|
603
|
+
query,
|
|
604
|
+
stats,
|
|
605
|
+
mentionProvider,
|
|
606
|
+
contextIdentifierProvider,
|
|
607
|
+
sessionId
|
|
608
|
+
});
|
|
609
|
+
if (!initialResolved) {
|
|
610
|
+
var _initialResolve;
|
|
611
|
+
initialResolved = true;
|
|
612
|
+
(_initialResolve = initialResolve) === null || _initialResolve === void 0 ? void 0 : _initialResolve(items);
|
|
613
|
+
} else {
|
|
614
|
+
var _updateCallback;
|
|
615
|
+
(_updateCallback = updateCallback) === null || _updateCallback === void 0 ? void 0 : _updateCallback(items);
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
subscriptionKeys.add(key);
|
|
619
|
+
mentionProvider.subscribe(key, mentionsSubscribeCallback, () => {
|
|
620
|
+
if (editorExperiment('platform_editor_offline_editing_web', true)) {
|
|
621
|
+
mentionProvider.unsubscribe(key);
|
|
622
|
+
subscriptionKeys.delete(key);
|
|
623
|
+
if (!initialResolved) {
|
|
624
|
+
var _initialReject;
|
|
625
|
+
initialResolved = true;
|
|
626
|
+
(_initialReject = initialReject) === null || _initialReject === void 0 ? void 0 : _initialReject('FETCH_ERROR');
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
mentionProvider.filter(query || '', {
|
|
631
|
+
...contextIdentifierProvider,
|
|
632
|
+
sessionId
|
|
633
|
+
});
|
|
634
|
+
return {
|
|
635
|
+
initial,
|
|
636
|
+
subscribe: update => {
|
|
637
|
+
if (updateCallback) {
|
|
638
|
+
throw new Error('TypeAhead mention updates support only one subscriber');
|
|
639
|
+
}
|
|
640
|
+
updateCallback = update;
|
|
641
|
+
return () => {
|
|
642
|
+
unsubscribed = true;
|
|
643
|
+
updateCallback = null;
|
|
644
|
+
mentionProvider.unsubscribe(key);
|
|
645
|
+
subscriptionKeys.delete(key);
|
|
646
|
+
// If cleanup runs before the first emission, settle the initial
|
|
647
|
+
// promise so its `.then` chain (and the closures it holds) is
|
|
648
|
+
// released instead of pending forever.
|
|
649
|
+
if (!initialResolved) {
|
|
650
|
+
var _initialResolve2;
|
|
651
|
+
initialResolved = true;
|
|
652
|
+
(_initialResolve2 = initialResolve) === null || _initialResolve2 === void 0 ? void 0 : _initialResolve2([]);
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
// Presence of `subscribeToItemsUpdates` is how the type-ahead hook
|
|
660
|
+
// opts a handler into the multi-emit path, so only expose it when the
|
|
661
|
+
// agent-selection gate is on.
|
|
662
|
+
if (fg('rovo_chat_agent_selection')) {
|
|
663
|
+
typeAhead.subscribeToItemsUpdates = subscribeToItemsUpdates;
|
|
664
|
+
}
|
|
501
665
|
return typeAhead;
|
|
502
666
|
};
|
|
@@ -31,7 +31,7 @@ var isAgentUserType = function isAgentUserType(userType) {
|
|
|
31
31
|
var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
32
32
|
var AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
33
33
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
34
|
-
var PACKAGE_VERSION = "14.
|
|
34
|
+
var PACKAGE_VERSION = "14.3.0";
|
|
35
35
|
var setProvider = function setProvider(provider) {
|
|
36
36
|
return function (state, dispatch) {
|
|
37
37
|
if (dispatch) {
|
|
@@ -347,8 +347,7 @@ export function createMentionPlugin(_ref2) {
|
|
|
347
347
|
}
|
|
348
348
|
(_insm$session2 = insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('mentionDeletionDetection');
|
|
349
349
|
}
|
|
350
|
-
|
|
351
|
-
if (tr.docChanged && !tr.getMeta('replaceDocument') && !isAIStreaming && isAgentMentionsExperimentEnabled) {
|
|
350
|
+
if (isAgentMentionsExperimentEnabled && isQualifyingLocalUserDocChange(tr)) {
|
|
352
351
|
var _mentionSchema = newState.schema.nodes.mention;
|
|
353
352
|
var newDocRanges = [];
|
|
354
353
|
var oldDocRanges = [];
|
|
@@ -13,6 +13,7 @@ import { mentionMessages } from '@atlaskit/editor-common/messages';
|
|
|
13
13
|
import { TypeAheadAvailableNodes } from '@atlaskit/editor-common/type-ahead';
|
|
14
14
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
15
15
|
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
16
|
+
import Lozenge from '@atlaskit/lozenge';
|
|
16
17
|
import { MENTION_ITEM_HEIGHT, MENTION_ITEM_HEIGHT_REFRESHED, MentionItem } from '@atlaskit/mention/item';
|
|
17
18
|
import { isResolvingMentionProvider } from '@atlaskit/mention/resource';
|
|
18
19
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -231,17 +232,77 @@ var buildNodesForTeamMention = function buildNodesForTeamMention(schema, selecte
|
|
|
231
232
|
inlineNodes.push(closeBracketText);
|
|
232
233
|
return Fragment.fromArray(inlineNodes);
|
|
233
234
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Shared mentions → typeahead-items transformer used by both the
|
|
237
|
+
* single-shot `getItems` Promise path and the multi-emit
|
|
238
|
+
* `subscribeToItemsUpdates` path. Factoring this out avoids any
|
|
239
|
+
* chance the two paths drift in subtle item-shape behaviour (invite
|
|
240
|
+
* item injection, analytics emission, no-results bookkeeping).
|
|
241
|
+
*
|
|
242
|
+
* NOTE: `firstQueryWithoutResults` is captured by closure in
|
|
243
|
+
* `createTypeAheadConfig` and intentionally mutated here as a
|
|
244
|
+
* side-effect — preserves the existing single-shot semantics.
|
|
245
|
+
*/
|
|
246
|
+
var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToTypeAheadItems(_ref6) {
|
|
247
|
+
var fireEvent = _ref6.fireEvent,
|
|
248
|
+
getFirstQueryWithoutResults = _ref6.getFirstQueryWithoutResults,
|
|
249
|
+
setFirstQueryWithoutResults = _ref6.setFirstQueryWithoutResults;
|
|
250
|
+
return function (_ref7) {
|
|
251
|
+
var mentions = _ref7.mentions,
|
|
252
|
+
query = _ref7.query,
|
|
253
|
+
stats = _ref7.stats,
|
|
254
|
+
mentionProvider = _ref7.mentionProvider,
|
|
255
|
+
contextIdentifierProvider = _ref7.contextIdentifierProvider,
|
|
256
|
+
sessionId = _ref7.sessionId;
|
|
257
|
+
var mentionItems = mentions.map(function (mention) {
|
|
258
|
+
return memoizedToItem.call(mention);
|
|
259
|
+
});
|
|
260
|
+
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
261
|
+
query: query,
|
|
262
|
+
mentions: mentions,
|
|
263
|
+
stats: stats
|
|
264
|
+
});
|
|
265
|
+
if (mentions.length === 0 && getFirstQueryWithoutResults() === null) {
|
|
266
|
+
setFirstQueryWithoutResults(query);
|
|
267
|
+
}
|
|
268
|
+
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
269
|
+
return mentionItems;
|
|
270
|
+
}
|
|
271
|
+
var emailDomain = mentionProvider.userEmailDomain;
|
|
272
|
+
return withInviteItem({
|
|
273
|
+
mentionProvider: mentionProvider,
|
|
274
|
+
firstQueryWithoutResults: getFirstQueryWithoutResults() || '',
|
|
275
|
+
currentQuery: query,
|
|
276
|
+
onInviteItemMount: function onInviteItemMount() {
|
|
277
|
+
var _mentionProvider$getS2;
|
|
278
|
+
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
279
|
+
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
280
|
+
} : {}));
|
|
281
|
+
},
|
|
282
|
+
emailDomain: emailDomain
|
|
283
|
+
})(mentionItems);
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
|
|
287
|
+
var sanitizePrivateContent = _ref8.sanitizePrivateContent,
|
|
288
|
+
mentionInsertDisplayName = _ref8.mentionInsertDisplayName,
|
|
289
|
+
fireEvent = _ref8.fireEvent,
|
|
290
|
+
HighlightComponent = _ref8.HighlightComponent,
|
|
291
|
+
api = _ref8.api,
|
|
292
|
+
handleMentionsChanged = _ref8.handleMentionsChanged;
|
|
241
293
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
242
294
|
var sessionId = uuid();
|
|
243
295
|
var firstQueryWithoutResults = null;
|
|
244
296
|
var subscriptionKeys = new Set();
|
|
297
|
+
var transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
|
|
298
|
+
fireEvent: fireEvent,
|
|
299
|
+
getFirstQueryWithoutResults: function getFirstQueryWithoutResults() {
|
|
300
|
+
return firstQueryWithoutResults;
|
|
301
|
+
},
|
|
302
|
+
setFirstQueryWithoutResults: function setFirstQueryWithoutResults(query) {
|
|
303
|
+
firstQueryWithoutResults = query;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
245
306
|
var typeAhead = {
|
|
246
307
|
id: TypeAheadAvailableNodes.MENTION,
|
|
247
308
|
trigger: '@',
|
|
@@ -255,17 +316,17 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
255
316
|
}
|
|
256
317
|
return null;
|
|
257
318
|
},
|
|
258
|
-
getItems: function getItems(
|
|
319
|
+
getItems: function getItems(_ref9) {
|
|
259
320
|
var _api$contextIdentifie, _api$contextIdentifie2;
|
|
260
|
-
var query =
|
|
261
|
-
editorState =
|
|
321
|
+
var query = _ref9.query,
|
|
322
|
+
editorState = _ref9.editorState;
|
|
262
323
|
var pluginState = getMentionPluginState(editorState);
|
|
263
324
|
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
264
325
|
return Promise.resolve([]);
|
|
265
326
|
}
|
|
266
327
|
var mentionProvider = pluginState.mentionProvider;
|
|
267
|
-
var
|
|
268
|
-
contextIdentifierProvider =
|
|
328
|
+
var _ref0 = (_api$contextIdentifie = api === null || api === void 0 || (_api$contextIdentifie2 = api.contextIdentifier) === null || _api$contextIdentifie2 === void 0 ? void 0 : _api$contextIdentifie2.sharedState.currentState()) !== null && _api$contextIdentifie !== void 0 ? _api$contextIdentifie : {},
|
|
329
|
+
contextIdentifierProvider = _ref0.contextIdentifierProvider;
|
|
269
330
|
return new Promise(function (resolve, reject) {
|
|
270
331
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
271
332
|
var key = "loadingMentionsForTypeAhead_".concat(uuid());
|
|
@@ -277,35 +338,15 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
277
338
|
}
|
|
278
339
|
mentionProvider.unsubscribe(key);
|
|
279
340
|
subscriptionKeys.delete(key);
|
|
280
|
-
var
|
|
281
|
-
return memoizedToItem.call(mention);
|
|
282
|
-
});
|
|
283
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
284
|
-
query: query,
|
|
341
|
+
var items = transformMentionsToTypeAheadItems({
|
|
285
342
|
mentions: mentions,
|
|
286
|
-
|
|
343
|
+
query: query,
|
|
344
|
+
stats: stats,
|
|
345
|
+
mentionProvider: mentionProvider,
|
|
346
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
347
|
+
sessionId: sessionId
|
|
287
348
|
});
|
|
288
|
-
|
|
289
|
-
firstQueryWithoutResults = query;
|
|
290
|
-
}
|
|
291
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
292
|
-
resolve(mentionItems);
|
|
293
|
-
} else {
|
|
294
|
-
var emailDomain = mentionProvider.userEmailDomain;
|
|
295
|
-
var items = withInviteItem({
|
|
296
|
-
mentionProvider: mentionProvider,
|
|
297
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
298
|
-
currentQuery: query,
|
|
299
|
-
onInviteItemMount: function onInviteItemMount() {
|
|
300
|
-
var _mentionProvider$getS2;
|
|
301
|
-
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
302
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
303
|
-
} : {}));
|
|
304
|
-
},
|
|
305
|
-
emailDomain: emailDomain
|
|
306
|
-
})(mentionItems);
|
|
307
|
-
resolve(items);
|
|
308
|
-
}
|
|
349
|
+
resolve(items);
|
|
309
350
|
};
|
|
310
351
|
subscriptionKeys.add(key);
|
|
311
352
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
@@ -320,8 +361,8 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
320
361
|
}));
|
|
321
362
|
});
|
|
322
363
|
},
|
|
323
|
-
getSections: function getSections(
|
|
324
|
-
var intl =
|
|
364
|
+
getSections: function getSections(_ref1) {
|
|
365
|
+
var intl = _ref1.intl;
|
|
325
366
|
return [_objectSpread({
|
|
326
367
|
id: 'people',
|
|
327
368
|
title: intl.formatMessage(mentionMessages.typeAheadSectionPeople),
|
|
@@ -334,7 +375,7 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
334
375
|
showWhenQueryPresent: false,
|
|
335
376
|
showWhenOnlySection: true
|
|
336
377
|
}
|
|
337
|
-
} : {}), _objectSpread({
|
|
378
|
+
} : {}), _objectSpread(_objectSpread({
|
|
338
379
|
id: 'agents',
|
|
339
380
|
title: intl.formatMessage(mentionMessages.typeAheadSectionAgents),
|
|
340
381
|
filter: function filter(item) {
|
|
@@ -346,17 +387,21 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
346
387
|
showWhenQueryPresent: false,
|
|
347
388
|
showWhenOnlySection: true
|
|
348
389
|
}
|
|
390
|
+
} : {}), expVal('platform_editor_agent_mentions', 'isEnabled', false) ? {
|
|
391
|
+
lozenge: /*#__PURE__*/React.createElement(Lozenge, {
|
|
392
|
+
appearance: "new"
|
|
393
|
+
}, intl.formatMessage(mentionMessages.typeAheadSectionAgentsLabs))
|
|
349
394
|
} : {})];
|
|
350
395
|
},
|
|
351
396
|
onOpen: function onOpen() {
|
|
352
397
|
firstQueryWithoutResults = null;
|
|
353
398
|
},
|
|
354
|
-
selectItem: function selectItem(state, item, insert,
|
|
399
|
+
selectItem: function selectItem(state, item, insert, _ref10) {
|
|
355
400
|
var _api$contextIdentifie3, _api$contextIdentifie4;
|
|
356
|
-
var mode =
|
|
357
|
-
stats =
|
|
358
|
-
query =
|
|
359
|
-
sourceListItem =
|
|
401
|
+
var mode = _ref10.mode,
|
|
402
|
+
stats = _ref10.stats,
|
|
403
|
+
query = _ref10.query,
|
|
404
|
+
sourceListItem = _ref10.sourceListItem;
|
|
360
405
|
var schema = state.schema;
|
|
361
406
|
var pluginState = getMentionPluginState(state);
|
|
362
407
|
var mentionProvider = pluginState.mentionProvider;
|
|
@@ -367,8 +412,8 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
367
412
|
accessLevel = _item$mention.accessLevel,
|
|
368
413
|
userType = _item$mention.userType,
|
|
369
414
|
isXProductUser = _item$mention.isXProductUser;
|
|
370
|
-
var
|
|
371
|
-
contextIdentifierProvider =
|
|
415
|
+
var _ref11 = (_api$contextIdentifie3 = api === null || api === void 0 || (_api$contextIdentifie4 = api.contextIdentifier) === null || _api$contextIdentifie4 === void 0 ? void 0 : _api$contextIdentifie4.sharedState.currentState()) !== null && _api$contextIdentifie3 !== void 0 ? _api$contextIdentifie3 : {},
|
|
416
|
+
contextIdentifierProvider = _ref11.contextIdentifierProvider;
|
|
372
417
|
var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
373
418
|
sessionId: sessionId
|
|
374
419
|
});
|
|
@@ -481,11 +526,11 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
481
526
|
}
|
|
482
527
|
return tr;
|
|
483
528
|
},
|
|
484
|
-
dismiss: function dismiss(
|
|
485
|
-
var editorState =
|
|
486
|
-
query =
|
|
487
|
-
stats =
|
|
488
|
-
wasItemInserted =
|
|
529
|
+
dismiss: function dismiss(_ref12) {
|
|
530
|
+
var editorState = _ref12.editorState,
|
|
531
|
+
query = _ref12.query,
|
|
532
|
+
stats = _ref12.stats,
|
|
533
|
+
wasItemInserted = _ref12.wasItemInserted;
|
|
489
534
|
firstQueryWithoutResults = null;
|
|
490
535
|
var pickerElapsedTime = stats.startedAt ? performance.now() - stats.startedAt : 0;
|
|
491
536
|
if (!wasItemInserted) {
|
|
@@ -513,5 +558,122 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
513
558
|
sessionId = uuid();
|
|
514
559
|
}
|
|
515
560
|
};
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Opt-in multi-emit path. Subscribes to the provider's stream of
|
|
564
|
+
* results for the lifetime of the type-ahead session — does NOT
|
|
565
|
+
* unsubscribe after the first emission. Lets providers like
|
|
566
|
+
* `RovoChatMentionResource` deliver people-first then merged
|
|
567
|
+
* people + agents to the dropdown without the typeahead dropping
|
|
568
|
+
* the second emission on the floor.
|
|
569
|
+
*
|
|
570
|
+
* Gated behind `rovo_chat_agent_selection` (the same gate that drives
|
|
571
|
+
* agent mentions in the Rovo chat input). The generic type-ahead hook
|
|
572
|
+
* opts a handler into streaming purely by the presence of this method,
|
|
573
|
+
* so we only attach it when the gate is on — otherwise the proven
|
|
574
|
+
* single-shot `getItems` path continues to drive every consumer.
|
|
575
|
+
*/
|
|
576
|
+
var subscribeToItemsUpdates = function subscribeToItemsUpdates(_ref13) {
|
|
577
|
+
var _api$contextIdentifie5, _api$contextIdentifie6;
|
|
578
|
+
var query = _ref13.query,
|
|
579
|
+
editorState = _ref13.editorState;
|
|
580
|
+
var pluginState = getMentionPluginState(editorState);
|
|
581
|
+
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
582
|
+
return {
|
|
583
|
+
initial: Promise.resolve([]),
|
|
584
|
+
subscribe: function subscribe() {
|
|
585
|
+
return function () {};
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
var mentionProvider = pluginState.mentionProvider;
|
|
590
|
+
var _ref14 = (_api$contextIdentifie5 = api === null || api === void 0 || (_api$contextIdentifie6 = api.contextIdentifier) === null || _api$contextIdentifie6 === void 0 ? void 0 : _api$contextIdentifie6.sharedState.currentState()) !== null && _api$contextIdentifie5 !== void 0 ? _api$contextIdentifie5 : {},
|
|
591
|
+
contextIdentifierProvider = _ref14.contextIdentifierProvider;
|
|
592
|
+
|
|
593
|
+
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
594
|
+
var key = "loadingMentionsForTypeAhead_".concat(uuid());
|
|
595
|
+
var initialResolve = null;
|
|
596
|
+
var initialReject = null;
|
|
597
|
+
var initialResolved = false;
|
|
598
|
+
var updateCallback = null;
|
|
599
|
+
var unsubscribed = false;
|
|
600
|
+
var initial = new Promise(function (resolve, reject) {
|
|
601
|
+
initialResolve = resolve;
|
|
602
|
+
initialReject = reject;
|
|
603
|
+
});
|
|
604
|
+
var mentionsSubscribeCallback = function mentionsSubscribeCallback(mentions) {
|
|
605
|
+
var resultQuery = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
606
|
+
var stats = arguments.length > 2 ? arguments[2] : undefined;
|
|
607
|
+
// Drop emissions tagged with a query that has moved on.
|
|
608
|
+
// Mirrors the same guard in the single-shot `getItems`.
|
|
609
|
+
if (query !== resultQuery) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (unsubscribed) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
var items = transformMentionsToTypeAheadItems({
|
|
616
|
+
mentions: mentions,
|
|
617
|
+
query: query,
|
|
618
|
+
stats: stats,
|
|
619
|
+
mentionProvider: mentionProvider,
|
|
620
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
621
|
+
sessionId: sessionId
|
|
622
|
+
});
|
|
623
|
+
if (!initialResolved) {
|
|
624
|
+
var _initialResolve;
|
|
625
|
+
initialResolved = true;
|
|
626
|
+
(_initialResolve = initialResolve) === null || _initialResolve === void 0 || _initialResolve(items);
|
|
627
|
+
} else {
|
|
628
|
+
var _updateCallback;
|
|
629
|
+
(_updateCallback = updateCallback) === null || _updateCallback === void 0 || _updateCallback(items);
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
subscriptionKeys.add(key);
|
|
633
|
+
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
634
|
+
if (editorExperiment('platform_editor_offline_editing_web', true)) {
|
|
635
|
+
mentionProvider.unsubscribe(key);
|
|
636
|
+
subscriptionKeys.delete(key);
|
|
637
|
+
if (!initialResolved) {
|
|
638
|
+
var _initialReject;
|
|
639
|
+
initialResolved = true;
|
|
640
|
+
(_initialReject = initialReject) === null || _initialReject === void 0 || _initialReject('FETCH_ERROR');
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
mentionProvider.filter(query || '', _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
645
|
+
sessionId: sessionId
|
|
646
|
+
}));
|
|
647
|
+
return {
|
|
648
|
+
initial: initial,
|
|
649
|
+
subscribe: function subscribe(update) {
|
|
650
|
+
if (updateCallback) {
|
|
651
|
+
throw new Error('TypeAhead mention updates support only one subscriber');
|
|
652
|
+
}
|
|
653
|
+
updateCallback = update;
|
|
654
|
+
return function () {
|
|
655
|
+
unsubscribed = true;
|
|
656
|
+
updateCallback = null;
|
|
657
|
+
mentionProvider.unsubscribe(key);
|
|
658
|
+
subscriptionKeys.delete(key);
|
|
659
|
+
// If cleanup runs before the first emission, settle the initial
|
|
660
|
+
// promise so its `.then` chain (and the closures it holds) is
|
|
661
|
+
// released instead of pending forever.
|
|
662
|
+
if (!initialResolved) {
|
|
663
|
+
var _initialResolve2;
|
|
664
|
+
initialResolved = true;
|
|
665
|
+
(_initialResolve2 = initialResolve) === null || _initialResolve2 === void 0 || _initialResolve2([]);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
// Presence of `subscribeToItemsUpdates` is how the type-ahead hook
|
|
673
|
+
// opts a handler into the multi-emit path, so only expose it when the
|
|
674
|
+
// agent-selection gate is on.
|
|
675
|
+
if (fg('rovo_chat_agent_selection')) {
|
|
676
|
+
typeAhead.subscribeToItemsUpdates = subscribeToItemsUpdates;
|
|
677
|
+
}
|
|
516
678
|
return typeAhead;
|
|
517
679
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-mentions",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.4.0",
|
|
4
4
|
"description": "Mentions plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,12 +27,13 @@
|
|
|
27
27
|
"@atlaskit/editor-plugin-base": "^13.0.0",
|
|
28
28
|
"@atlaskit/editor-plugin-context-identifier": "^12.0.0",
|
|
29
29
|
"@atlaskit/editor-plugin-selection": "^12.0.0",
|
|
30
|
-
"@atlaskit/editor-plugin-type-ahead": "^12.
|
|
30
|
+
"@atlaskit/editor-plugin-type-ahead": "^12.1.0",
|
|
31
31
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
32
32
|
"@atlaskit/icon": "^36.0.0",
|
|
33
33
|
"@atlaskit/insm": "^1.0.0",
|
|
34
34
|
"@atlaskit/link": "^4.0.0",
|
|
35
|
-
"@atlaskit/
|
|
35
|
+
"@atlaskit/lozenge": "^14.0.0",
|
|
36
|
+
"@atlaskit/mention": "^27.2.0",
|
|
36
37
|
"@atlaskit/platform-feature-flags": "^2.0.0",
|
|
37
38
|
"@atlaskit/popper": "^8.0.0",
|
|
38
39
|
"@atlaskit/portal": "^6.0.0",
|
|
@@ -40,10 +41,10 @@
|
|
|
40
41
|
"@atlaskit/profilecard": "^26.1.0",
|
|
41
42
|
"@atlaskit/teams-app-config": "^2.0.0",
|
|
42
43
|
"@atlaskit/theme": "^26.0.0",
|
|
43
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
44
|
-
"@atlaskit/tokens": "^
|
|
44
|
+
"@atlaskit/tmp-editor-statsig": "^110.0.0",
|
|
45
|
+
"@atlaskit/tokens": "^15.0.0",
|
|
45
46
|
"@atlaskit/tooltip": "^23.0.0",
|
|
46
|
-
"@atlaskit/user-picker": "^13.
|
|
47
|
+
"@atlaskit/user-picker": "^13.2.0",
|
|
47
48
|
"@babel/runtime": "^7.0.0",
|
|
48
49
|
"@compiled/react": "^0.20.0",
|
|
49
50
|
"bind-event-listener": "^3.0.0",
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"uuid": "^3.1.0"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
|
-
"@atlaskit/editor-common": "^116.
|
|
56
|
+
"@atlaskit/editor-common": "^116.11.0",
|
|
56
57
|
"react": "^18.2.0",
|
|
57
58
|
"react-dom": "^18.2.0",
|
|
58
59
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
"@testing-library/react": "^16.3.0",
|
|
62
63
|
"react": "^18.2.0",
|
|
63
64
|
"react-dom": "^18.2.0",
|
|
64
|
-
"react-intl": "^
|
|
65
|
+
"react-intl": "^7.0.0",
|
|
65
66
|
"wait-for-expect": "^1.2.0"
|
|
66
67
|
},
|
|
67
68
|
"techstack": {
|
|
@@ -119,6 +120,9 @@
|
|
|
119
120
|
},
|
|
120
121
|
"platform_editor_agent_mentions": {
|
|
121
122
|
"type": "boolean"
|
|
123
|
+
},
|
|
124
|
+
"rovo_chat_agent_selection": {
|
|
125
|
+
"type": "boolean"
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
}
|