@atlaskit/editor-plugin-mentions 14.3.0 → 14.4.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.
- package/CHANGELOG.md +25 -0
- package/dist/cjs/pm-plugins/main.js +2 -3
- package/dist/cjs/ui/type-ahead/index.js +210 -53
- package/dist/es2019/pm-plugins/main.js +2 -3
- package/dist/es2019/ui/type-ahead/index.js +183 -25
- package/dist/esm/pm-plugins/main.js +2 -3
- package/dist/esm/ui/type-ahead/index.js +210 -53
- package/package.json +8 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-mentions
|
|
2
2
|
|
|
3
|
+
## 14.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 14.4.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`dbf22f118dd9e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dbf22f118dd9e) -
|
|
14
|
+
Rewrite Rovo Chat @-mention provider on a single Relay-native RovoChatMentionResource that fires
|
|
15
|
+
people + agents in parallel via Promise. People render as soon as URS resolves and agents pop in
|
|
16
|
+
below when ready. New aliased agentStudio_getAgents query consolidates 3 prefetch round trips into
|
|
17
|
+
1, drops over-fetched fields, and uses real abort plumbing. Adds opt-in subscribeToItemsUpdates
|
|
18
|
+
multi-emit contract to the editor mention typeahead so progressive emissions are no longer dropped
|
|
19
|
+
after the first frame.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [`ddeae9a5f8bdf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ddeae9a5f8bdf) -
|
|
24
|
+
Prevent remote collaborative agent mention insertions from publishing local agent mention
|
|
25
|
+
insertion state.
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
|
|
3
28
|
## 14.3.0
|
|
4
29
|
|
|
5
30
|
### Minor 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.4.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 = [];
|
|
@@ -241,17 +241,77 @@ var buildNodesForTeamMention = function buildNodesForTeamMention(schema, selecte
|
|
|
241
241
|
inlineNodes.push(closeBracketText);
|
|
242
242
|
return _model.Fragment.fromArray(inlineNodes);
|
|
243
243
|
};
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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;
|
|
251
302
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
252
303
|
var sessionId = (0, _uuid.default)();
|
|
253
304
|
var firstQueryWithoutResults = null;
|
|
254
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
|
+
});
|
|
255
315
|
var typeAhead = {
|
|
256
316
|
id: _typeAhead.TypeAheadAvailableNodes.MENTION,
|
|
257
317
|
trigger: '@',
|
|
@@ -265,17 +325,17 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
265
325
|
}
|
|
266
326
|
return null;
|
|
267
327
|
},
|
|
268
|
-
getItems: function getItems(
|
|
328
|
+
getItems: function getItems(_ref9) {
|
|
269
329
|
var _api$contextIdentifie, _api$contextIdentifie2;
|
|
270
|
-
var query =
|
|
271
|
-
editorState =
|
|
330
|
+
var query = _ref9.query,
|
|
331
|
+
editorState = _ref9.editorState;
|
|
272
332
|
var pluginState = (0, _utils2.getMentionPluginState)(editorState);
|
|
273
333
|
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
274
334
|
return Promise.resolve([]);
|
|
275
335
|
}
|
|
276
336
|
var mentionProvider = pluginState.mentionProvider;
|
|
277
|
-
var
|
|
278
|
-
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;
|
|
279
339
|
return new Promise(function (resolve, reject) {
|
|
280
340
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
281
341
|
var key = "loadingMentionsForTypeAhead_".concat((0, _uuid.default)());
|
|
@@ -287,35 +347,15 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
287
347
|
}
|
|
288
348
|
mentionProvider.unsubscribe(key);
|
|
289
349
|
subscriptionKeys.delete(key);
|
|
290
|
-
var
|
|
291
|
-
return memoizedToItem.call(mention);
|
|
292
|
-
});
|
|
293
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
294
|
-
query: query,
|
|
350
|
+
var items = transformMentionsToTypeAheadItems({
|
|
295
351
|
mentions: mentions,
|
|
296
|
-
|
|
352
|
+
query: query,
|
|
353
|
+
stats: stats,
|
|
354
|
+
mentionProvider: mentionProvider,
|
|
355
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
356
|
+
sessionId: sessionId
|
|
297
357
|
});
|
|
298
|
-
|
|
299
|
-
firstQueryWithoutResults = query;
|
|
300
|
-
}
|
|
301
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
302
|
-
resolve(mentionItems);
|
|
303
|
-
} else {
|
|
304
|
-
var emailDomain = mentionProvider.userEmailDomain;
|
|
305
|
-
var items = withInviteItem({
|
|
306
|
-
mentionProvider: mentionProvider,
|
|
307
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
308
|
-
currentQuery: query,
|
|
309
|
-
onInviteItemMount: function onInviteItemMount() {
|
|
310
|
-
var _mentionProvider$getS2;
|
|
311
|
-
fireEvent((0, _analytics.buildTypeAheadInviteItemViewedPayload)(sessionId, contextIdentifierProvider, mentionProvider.userRole, (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
312
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
313
|
-
} : {}));
|
|
314
|
-
},
|
|
315
|
-
emailDomain: emailDomain
|
|
316
|
-
})(mentionItems);
|
|
317
|
-
resolve(items);
|
|
318
|
-
}
|
|
358
|
+
resolve(items);
|
|
319
359
|
};
|
|
320
360
|
subscriptionKeys.add(key);
|
|
321
361
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
@@ -330,8 +370,8 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
330
370
|
}));
|
|
331
371
|
});
|
|
332
372
|
},
|
|
333
|
-
getSections: function getSections(
|
|
334
|
-
var intl =
|
|
373
|
+
getSections: function getSections(_ref1) {
|
|
374
|
+
var intl = _ref1.intl;
|
|
335
375
|
return [_objectSpread({
|
|
336
376
|
id: 'people',
|
|
337
377
|
title: intl.formatMessage(_messages.mentionMessages.typeAheadSectionPeople),
|
|
@@ -365,12 +405,12 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
365
405
|
onOpen: function onOpen() {
|
|
366
406
|
firstQueryWithoutResults = null;
|
|
367
407
|
},
|
|
368
|
-
selectItem: function selectItem(state, item, insert,
|
|
408
|
+
selectItem: function selectItem(state, item, insert, _ref10) {
|
|
369
409
|
var _api$contextIdentifie3, _api$contextIdentifie4;
|
|
370
|
-
var mode =
|
|
371
|
-
stats =
|
|
372
|
-
query =
|
|
373
|
-
sourceListItem =
|
|
410
|
+
var mode = _ref10.mode,
|
|
411
|
+
stats = _ref10.stats,
|
|
412
|
+
query = _ref10.query,
|
|
413
|
+
sourceListItem = _ref10.sourceListItem;
|
|
374
414
|
var schema = state.schema;
|
|
375
415
|
var pluginState = (0, _utils2.getMentionPluginState)(state);
|
|
376
416
|
var mentionProvider = pluginState.mentionProvider;
|
|
@@ -381,8 +421,8 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
381
421
|
accessLevel = _item$mention.accessLevel,
|
|
382
422
|
userType = _item$mention.userType,
|
|
383
423
|
isXProductUser = _item$mention.isXProductUser;
|
|
384
|
-
var
|
|
385
|
-
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;
|
|
386
426
|
var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
387
427
|
sessionId: sessionId
|
|
388
428
|
});
|
|
@@ -495,11 +535,11 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
495
535
|
}
|
|
496
536
|
return tr;
|
|
497
537
|
},
|
|
498
|
-
dismiss: function dismiss(
|
|
499
|
-
var editorState =
|
|
500
|
-
query =
|
|
501
|
-
stats =
|
|
502
|
-
wasItemInserted =
|
|
538
|
+
dismiss: function dismiss(_ref12) {
|
|
539
|
+
var editorState = _ref12.editorState,
|
|
540
|
+
query = _ref12.query,
|
|
541
|
+
stats = _ref12.stats,
|
|
542
|
+
wasItemInserted = _ref12.wasItemInserted;
|
|
503
543
|
firstQueryWithoutResults = null;
|
|
504
544
|
var pickerElapsedTime = stats.startedAt ? performance.now() - stats.startedAt : 0;
|
|
505
545
|
if (!wasItemInserted) {
|
|
@@ -527,5 +567,122 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
|
|
|
527
567
|
sessionId = (0, _uuid.default)();
|
|
528
568
|
}
|
|
529
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
|
+
}
|
|
530
687
|
return typeAhead;
|
|
531
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.4.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 = [];
|
|
@@ -214,6 +214,57 @@ const buildNodesForTeamMention = (schema, selectedMention, mentionProvider, sani
|
|
|
214
214
|
inlineNodes.push(closeBracketText);
|
|
215
215
|
return Fragment.fromArray(inlineNodes);
|
|
216
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
|
+
};
|
|
217
268
|
export const createTypeAheadConfig = ({
|
|
218
269
|
sanitizePrivateContent,
|
|
219
270
|
mentionInsertDisplayName,
|
|
@@ -226,6 +277,13 @@ export const createTypeAheadConfig = ({
|
|
|
226
277
|
let sessionId = uuid();
|
|
227
278
|
let firstQueryWithoutResults = null;
|
|
228
279
|
const subscriptionKeys = new Set();
|
|
280
|
+
const transformMentionsToTypeAheadItems = makeTransformMentionsToTypeAheadItems({
|
|
281
|
+
fireEvent,
|
|
282
|
+
getFirstQueryWithoutResults: () => firstQueryWithoutResults,
|
|
283
|
+
setFirstQueryWithoutResults: query => {
|
|
284
|
+
firstQueryWithoutResults = query;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
229
287
|
const typeAhead = {
|
|
230
288
|
id: TypeAheadAvailableNodes.MENTION,
|
|
231
289
|
trigger: '@',
|
|
@@ -263,33 +321,15 @@ export const createTypeAheadConfig = ({
|
|
|
263
321
|
}
|
|
264
322
|
mentionProvider.unsubscribe(key);
|
|
265
323
|
subscriptionKeys.delete(key);
|
|
266
|
-
const
|
|
267
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
268
|
-
query,
|
|
324
|
+
const items = transformMentionsToTypeAheadItems({
|
|
269
325
|
mentions,
|
|
270
|
-
|
|
326
|
+
query,
|
|
327
|
+
stats,
|
|
328
|
+
mentionProvider,
|
|
329
|
+
contextIdentifierProvider,
|
|
330
|
+
sessionId
|
|
271
331
|
});
|
|
272
|
-
|
|
273
|
-
firstQueryWithoutResults = query;
|
|
274
|
-
}
|
|
275
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
276
|
-
resolve(mentionItems);
|
|
277
|
-
} else {
|
|
278
|
-
const emailDomain = mentionProvider.userEmailDomain;
|
|
279
|
-
const items = withInviteItem({
|
|
280
|
-
mentionProvider,
|
|
281
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
282
|
-
currentQuery: query,
|
|
283
|
-
onInviteItemMount: () => {
|
|
284
|
-
var _mentionProvider$getS2;
|
|
285
|
-
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
286
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
287
|
-
} : {}));
|
|
288
|
-
},
|
|
289
|
-
emailDomain
|
|
290
|
-
})(mentionItems);
|
|
291
|
-
resolve(items);
|
|
292
|
-
}
|
|
332
|
+
resolve(items);
|
|
293
333
|
};
|
|
294
334
|
subscriptionKeys.add(key);
|
|
295
335
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, () => {
|
|
@@ -504,5 +544,123 @@ export const createTypeAheadConfig = ({
|
|
|
504
544
|
sessionId = uuid();
|
|
505
545
|
}
|
|
506
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
|
+
}
|
|
507
665
|
return typeAhead;
|
|
508
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.4.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 = [];
|
|
@@ -232,17 +232,77 @@ var buildNodesForTeamMention = function buildNodesForTeamMention(schema, selecte
|
|
|
232
232
|
inlineNodes.push(closeBracketText);
|
|
233
233
|
return Fragment.fromArray(inlineNodes);
|
|
234
234
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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;
|
|
242
293
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
243
294
|
var sessionId = uuid();
|
|
244
295
|
var firstQueryWithoutResults = null;
|
|
245
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
|
+
});
|
|
246
306
|
var typeAhead = {
|
|
247
307
|
id: TypeAheadAvailableNodes.MENTION,
|
|
248
308
|
trigger: '@',
|
|
@@ -256,17 +316,17 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
256
316
|
}
|
|
257
317
|
return null;
|
|
258
318
|
},
|
|
259
|
-
getItems: function getItems(
|
|
319
|
+
getItems: function getItems(_ref9) {
|
|
260
320
|
var _api$contextIdentifie, _api$contextIdentifie2;
|
|
261
|
-
var query =
|
|
262
|
-
editorState =
|
|
321
|
+
var query = _ref9.query,
|
|
322
|
+
editorState = _ref9.editorState;
|
|
263
323
|
var pluginState = getMentionPluginState(editorState);
|
|
264
324
|
if (!(pluginState !== null && pluginState !== void 0 && pluginState.mentionProvider)) {
|
|
265
325
|
return Promise.resolve([]);
|
|
266
326
|
}
|
|
267
327
|
var mentionProvider = pluginState.mentionProvider;
|
|
268
|
-
var
|
|
269
|
-
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;
|
|
270
330
|
return new Promise(function (resolve, reject) {
|
|
271
331
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
272
332
|
var key = "loadingMentionsForTypeAhead_".concat(uuid());
|
|
@@ -278,35 +338,15 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
278
338
|
}
|
|
279
339
|
mentionProvider.unsubscribe(key);
|
|
280
340
|
subscriptionKeys.delete(key);
|
|
281
|
-
var
|
|
282
|
-
return memoizedToItem.call(mention);
|
|
283
|
-
});
|
|
284
|
-
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
285
|
-
query: query,
|
|
341
|
+
var items = transformMentionsToTypeAheadItems({
|
|
286
342
|
mentions: mentions,
|
|
287
|
-
|
|
343
|
+
query: query,
|
|
344
|
+
stats: stats,
|
|
345
|
+
mentionProvider: mentionProvider,
|
|
346
|
+
contextIdentifierProvider: contextIdentifierProvider,
|
|
347
|
+
sessionId: sessionId
|
|
288
348
|
});
|
|
289
|
-
|
|
290
|
-
firstQueryWithoutResults = query;
|
|
291
|
-
}
|
|
292
|
-
if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
|
|
293
|
-
resolve(mentionItems);
|
|
294
|
-
} else {
|
|
295
|
-
var emailDomain = mentionProvider.userEmailDomain;
|
|
296
|
-
var items = withInviteItem({
|
|
297
|
-
mentionProvider: mentionProvider,
|
|
298
|
-
firstQueryWithoutResults: firstQueryWithoutResults || '',
|
|
299
|
-
currentQuery: query,
|
|
300
|
-
onInviteItemMount: function onInviteItemMount() {
|
|
301
|
-
var _mentionProvider$getS2;
|
|
302
|
-
fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
|
|
303
|
-
isInlineInviteMentionsEnabled: (_mentionProvider$getS2 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS2 === void 0 ? void 0 : _mentionProvider$getS2.call(mentionProvider)
|
|
304
|
-
} : {}));
|
|
305
|
-
},
|
|
306
|
-
emailDomain: emailDomain
|
|
307
|
-
})(mentionItems);
|
|
308
|
-
resolve(items);
|
|
309
|
-
}
|
|
349
|
+
resolve(items);
|
|
310
350
|
};
|
|
311
351
|
subscriptionKeys.add(key);
|
|
312
352
|
mentionProvider.subscribe(key, mentionsSubscribeCallback, function () {
|
|
@@ -321,8 +361,8 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
321
361
|
}));
|
|
322
362
|
});
|
|
323
363
|
},
|
|
324
|
-
getSections: function getSections(
|
|
325
|
-
var intl =
|
|
364
|
+
getSections: function getSections(_ref1) {
|
|
365
|
+
var intl = _ref1.intl;
|
|
326
366
|
return [_objectSpread({
|
|
327
367
|
id: 'people',
|
|
328
368
|
title: intl.formatMessage(mentionMessages.typeAheadSectionPeople),
|
|
@@ -356,12 +396,12 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
356
396
|
onOpen: function onOpen() {
|
|
357
397
|
firstQueryWithoutResults = null;
|
|
358
398
|
},
|
|
359
|
-
selectItem: function selectItem(state, item, insert,
|
|
399
|
+
selectItem: function selectItem(state, item, insert, _ref10) {
|
|
360
400
|
var _api$contextIdentifie3, _api$contextIdentifie4;
|
|
361
|
-
var mode =
|
|
362
|
-
stats =
|
|
363
|
-
query =
|
|
364
|
-
sourceListItem =
|
|
401
|
+
var mode = _ref10.mode,
|
|
402
|
+
stats = _ref10.stats,
|
|
403
|
+
query = _ref10.query,
|
|
404
|
+
sourceListItem = _ref10.sourceListItem;
|
|
365
405
|
var schema = state.schema;
|
|
366
406
|
var pluginState = getMentionPluginState(state);
|
|
367
407
|
var mentionProvider = pluginState.mentionProvider;
|
|
@@ -372,8 +412,8 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
372
412
|
accessLevel = _item$mention.accessLevel,
|
|
373
413
|
userType = _item$mention.userType,
|
|
374
414
|
isXProductUser = _item$mention.isXProductUser;
|
|
375
|
-
var
|
|
376
|
-
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;
|
|
377
417
|
var mentionContext = _objectSpread(_objectSpread({}, contextIdentifierProvider), {}, {
|
|
378
418
|
sessionId: sessionId
|
|
379
419
|
});
|
|
@@ -486,11 +526,11 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
486
526
|
}
|
|
487
527
|
return tr;
|
|
488
528
|
},
|
|
489
|
-
dismiss: function dismiss(
|
|
490
|
-
var editorState =
|
|
491
|
-
query =
|
|
492
|
-
stats =
|
|
493
|
-
wasItemInserted =
|
|
529
|
+
dismiss: function dismiss(_ref12) {
|
|
530
|
+
var editorState = _ref12.editorState,
|
|
531
|
+
query = _ref12.query,
|
|
532
|
+
stats = _ref12.stats,
|
|
533
|
+
wasItemInserted = _ref12.wasItemInserted;
|
|
494
534
|
firstQueryWithoutResults = null;
|
|
495
535
|
var pickerElapsedTime = stats.startedAt ? performance.now() - stats.startedAt : 0;
|
|
496
536
|
if (!wasItemInserted) {
|
|
@@ -518,5 +558,122 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
|
|
|
518
558
|
sessionId = uuid();
|
|
519
559
|
}
|
|
520
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
|
+
}
|
|
521
678
|
return typeAhead;
|
|
522
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.1",
|
|
4
4
|
"description": "Mentions plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
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",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"@atlaskit/profilecard": "^26.1.0",
|
|
42
42
|
"@atlaskit/teams-app-config": "^2.0.0",
|
|
43
43
|
"@atlaskit/theme": "^26.0.0",
|
|
44
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
45
|
-
"@atlaskit/tokens": "^
|
|
44
|
+
"@atlaskit/tmp-editor-statsig": "^111.0.0",
|
|
45
|
+
"@atlaskit/tokens": "^15.0.0",
|
|
46
46
|
"@atlaskit/tooltip": "^23.0.0",
|
|
47
47
|
"@atlaskit/user-picker": "^13.2.0",
|
|
48
48
|
"@babel/runtime": "^7.0.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"uuid": "^3.1.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@atlaskit/editor-common": "^116.
|
|
56
|
+
"@atlaskit/editor-common": "^116.11.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"
|
|
@@ -120,6 +120,9 @@
|
|
|
120
120
|
},
|
|
121
121
|
"platform_editor_agent_mentions": {
|
|
122
122
|
"type": "boolean"
|
|
123
|
+
},
|
|
124
|
+
"rovo_chat_agent_selection": {
|
|
125
|
+
"type": "boolean"
|
|
123
126
|
}
|
|
124
127
|
}
|
|
125
128
|
}
|