@atlaskit/editor-plugin-mentions 13.3.15 → 14.1.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 +44 -0
- package/dist/cjs/pm-plugins/main.js +252 -47
- package/dist/cjs/ui/type-ahead/analytics.js +7 -4
- package/dist/cjs/ui/type-ahead/index.js +46 -24
- package/dist/es2019/pm-plugins/main.js +242 -39
- package/dist/es2019/ui/type-ahead/analytics.js +4 -1
- package/dist/es2019/ui/type-ahead/index.js +35 -17
- package/dist/esm/pm-plugins/main.js +252 -47
- package/dist/esm/ui/type-ahead/analytics.js +7 -4
- package/dist/esm/ui/type-ahead/index.js +46 -24
- package/dist/types/pm-plugins/main.d.ts +2 -0
- package/dist/types/types/index.d.ts +24 -0
- package/dist/types/ui/type-ahead/analytics.d.ts +1 -1
- package/package.json +25 -33
|
@@ -12,6 +12,8 @@ import { fg } from '@atlaskit/platform-feature-flags';
|
|
|
12
12
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
13
13
|
import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
14
14
|
import { createSingleMentionFragment } from '../../editor-commands';
|
|
15
|
+
import { mentionPluginKey } from '../../pm-plugins/key';
|
|
16
|
+
import { ACTIONS } from '../../pm-plugins/main';
|
|
15
17
|
import { mentionPlaceholderPluginKey, MENTION_PLACEHOLDER_ACTIONS } from '../../pm-plugins/mentionPlaceholder';
|
|
16
18
|
import { getMentionPluginState } from '../../pm-plugins/utils';
|
|
17
19
|
import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
|
|
@@ -20,6 +22,7 @@ import { buildTypeAheadCancelPayload, buildTypeAheadInsertedPayload, buildTypeAh
|
|
|
20
22
|
import { isInviteItem, isTeamStats, isTeamType, shouldKeepInviteItem } from './utils';
|
|
21
23
|
const isAgentUserType = userType => userType === 'APP' || userType === 'AGENT';
|
|
22
24
|
const isAgentMention = mention => isAgentUserType(mention.userType) || mention.appType === 'agent';
|
|
25
|
+
const isAgentTypeAheadItem = item => item.mention ? isAgentMention(item.mention) : false;
|
|
23
26
|
const createInviteItem = ({
|
|
24
27
|
mentionProvider,
|
|
25
28
|
onInviteItemMount,
|
|
@@ -307,19 +310,25 @@ export const createTypeAheadConfig = ({
|
|
|
307
310
|
return [{
|
|
308
311
|
id: 'people',
|
|
309
312
|
title: intl.formatMessage(mentionMessages.typeAheadSectionPeople),
|
|
310
|
-
filter: item =>
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
filter: item => !isAgentTypeAheadItem(item),
|
|
314
|
+
limit: expVal('platform_editor_agent_mentions', 'isEnabled', false) ? 5 : 6,
|
|
315
|
+
...(expVal('platform_editor_agent_mentions', 'isEnabled', false) ? {
|
|
316
|
+
sectionTitleDisplay: {
|
|
317
|
+
showWhenQueryPresent: false,
|
|
318
|
+
showWhenOnlySection: true
|
|
319
|
+
}
|
|
320
|
+
} : {})
|
|
315
321
|
}, {
|
|
316
322
|
id: 'agents',
|
|
317
323
|
title: intl.formatMessage(mentionMessages.typeAheadSectionAgents),
|
|
318
|
-
filter: item =>
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
324
|
+
filter: item => isAgentTypeAheadItem(item),
|
|
325
|
+
limit: expVal('platform_editor_agent_mentions', 'isEnabled', false) ? 5 : undefined,
|
|
326
|
+
...(expVal('platform_editor_agent_mentions', 'isEnabled', false) ? {
|
|
327
|
+
sectionTitleDisplay: {
|
|
328
|
+
showWhenQueryPresent: false,
|
|
329
|
+
showWhenOnlySection: true
|
|
330
|
+
}
|
|
331
|
+
} : {})
|
|
323
332
|
}];
|
|
324
333
|
},
|
|
325
334
|
onOpen: () => {
|
|
@@ -355,10 +364,10 @@ export const createTypeAheadConfig = ({
|
|
|
355
364
|
sessionId
|
|
356
365
|
};
|
|
357
366
|
const isAgentMentionsExperimentEnabled = expVal('platform_editor_agent_mentions', 'isEnabled', false);
|
|
358
|
-
const
|
|
367
|
+
const isAgentMentionInsertion = isAgentMentionsExperimentEnabled && isAgentMention(item.mention);
|
|
359
368
|
// userType can be missing for provider-only agent mentions. Copy/paste cannot
|
|
360
369
|
// see appType, so persist APP only when there is no explicit userType.
|
|
361
|
-
const persistedUserType =
|
|
370
|
+
const persistedUserType = isAgentMentionInsertion && userType == null ? 'APP' : userType;
|
|
362
371
|
if (mentionProvider && !isInviteItem(item.mention)) {
|
|
363
372
|
mentionProvider.recordMentionSelection(item.mention, mentionContext);
|
|
364
373
|
}
|
|
@@ -417,7 +426,7 @@ export const createTypeAheadConfig = ({
|
|
|
417
426
|
localId: mentionLocalId,
|
|
418
427
|
method: 'typed',
|
|
419
428
|
type: 'added',
|
|
420
|
-
...(
|
|
429
|
+
...(isAgentMentionInsertion ? {
|
|
421
430
|
shouldSuppressMentionNotification: true
|
|
422
431
|
} : {})
|
|
423
432
|
};
|
|
@@ -430,22 +439,22 @@ export const createTypeAheadConfig = ({
|
|
|
430
439
|
handleMentionsChanged([mentionChange]);
|
|
431
440
|
}
|
|
432
441
|
}
|
|
433
|
-
fireEvent(buildTypeAheadInsertedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(x => x.mention), query, contextIdentifierProvider, taskListId, taskItemId));
|
|
442
|
+
fireEvent(buildTypeAheadInsertedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, item.mention, mentionLocalId, sourceListItem.map(x => x.mention), query, contextIdentifierProvider, taskListId, taskItemId, isAgentMentionInsertion));
|
|
434
443
|
|
|
435
444
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
436
445
|
sessionId = uuid();
|
|
437
446
|
if (mentionProvider && isTeamType(userType)) {
|
|
438
447
|
return insert(buildNodesForTeamMention(schema, item.mention, mentionProvider, sanitizePrivateContent));
|
|
439
448
|
}
|
|
440
|
-
if (!
|
|
449
|
+
if (!isAgentMentionInsertion && isXProductUser && mentionProvider && mentionProvider.inviteXProductUser) {
|
|
441
450
|
mentionProvider.inviteXProductUser(id, name);
|
|
442
451
|
}
|
|
443
|
-
|
|
452
|
+
const tr = insert(createSingleMentionFragment({
|
|
444
453
|
mentionProvider,
|
|
445
454
|
mentionInsertDisplayName,
|
|
446
455
|
tr: state.tr,
|
|
447
456
|
sanitizePrivateContent,
|
|
448
|
-
suppressInviteXProductUser:
|
|
457
|
+
suppressInviteXProductUser: isAgentMentionInsertion
|
|
449
458
|
})({
|
|
450
459
|
name,
|
|
451
460
|
id,
|
|
@@ -455,6 +464,15 @@ export const createTypeAheadConfig = ({
|
|
|
455
464
|
accessLevel,
|
|
456
465
|
isXProductUser
|
|
457
466
|
}));
|
|
467
|
+
if (isAgentMentionInsertion) {
|
|
468
|
+
tr.setMeta(mentionPluginKey, {
|
|
469
|
+
action: ACTIONS.SET_PENDING_TYPED_AGENT_MENTION,
|
|
470
|
+
params: {
|
|
471
|
+
localId: mentionLocalId
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
return tr;
|
|
458
476
|
},
|
|
459
477
|
dismiss({
|
|
460
478
|
editorState,
|
|
@@ -17,14 +17,17 @@ import { MENTION_PROVIDER_REJECTED, MENTION_PROVIDER_UNDEFINED } from '../types'
|
|
|
17
17
|
import { mentionPluginKey } from './key';
|
|
18
18
|
import { canMentionBeCreatedInRange } from './utils';
|
|
19
19
|
export var ACTIONS = {
|
|
20
|
+
COMMIT_PENDING_TYPED_AGENT_MENTION: 'COMMIT_PENDING_TYPED_AGENT_MENTION',
|
|
21
|
+
SET_PENDING_TYPED_AGENT_MENTION: 'SET_PENDING_TYPED_AGENT_MENTION',
|
|
20
22
|
SET_PROVIDER: 'SET_PROVIDER'
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
// 'AGENT' is not in the ADF schema UserType enum but is used at runtime.
|
|
24
26
|
var AGENT_USER_TYPES = new Set(['APP', 'AGENT']);
|
|
25
27
|
var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
28
|
+
var AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
26
29
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
27
|
-
var PACKAGE_VERSION = "
|
|
30
|
+
var PACKAGE_VERSION = "14.0.0";
|
|
28
31
|
var setProvider = function setProvider(provider) {
|
|
29
32
|
return function (state, dispatch) {
|
|
30
33
|
if (dispatch) {
|
|
@@ -38,11 +41,97 @@ var setProvider = function setProvider(provider) {
|
|
|
38
41
|
return true;
|
|
39
42
|
};
|
|
40
43
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns true when a transaction represents a local user document edit that
|
|
47
|
+
* should restart pending agent-mention inactivity tracking.
|
|
48
|
+
*
|
|
49
|
+
* Remote/collab updates, replace-document transactions, AI streaming transforms,
|
|
50
|
+
* selection-only movements, and metadata-only transactions are intentionally ignored.
|
|
51
|
+
*/
|
|
52
|
+
var isQualifyingLocalUserDocChange = function isQualifyingLocalUserDocChange(tr) {
|
|
53
|
+
var isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
|
|
54
|
+
return tr.docChanged && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Reads agent-mention details from a known document position without traversing
|
|
59
|
+
* the document. Callers pass a matcher so mapped positions are only accepted
|
|
60
|
+
* when they still point at the same pending/tracked mention.
|
|
61
|
+
*/
|
|
62
|
+
var getAgentMentionDetailsAtPos = function getAgentMentionDetailsAtPos(state, pos, matchesMention) {
|
|
63
|
+
var _parentNode$type$name;
|
|
64
|
+
if (pos < 0 || pos > state.doc.content.size) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
var node = state.doc.nodeAt(pos);
|
|
68
|
+
var mentionSchema = state.schema.nodes.mention;
|
|
69
|
+
if ((node === null || node === void 0 ? void 0 : node.type) !== mentionSchema || !AGENT_USER_TYPES.has(node.attrs.userType) || !matchesMention(node.attrs) || !node.attrs.id) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
var $mentionPos = state.doc.resolve(pos);
|
|
73
|
+
var parentNode = $mentionPos.node($mentionPos.depth);
|
|
74
|
+
return {
|
|
75
|
+
id: node.attrs.id,
|
|
76
|
+
context: parentNode.textContent.trim() || null,
|
|
77
|
+
nodeSize: node.nodeSize,
|
|
78
|
+
parentNodeType: (_parentNode$type$name = parentNode.type.name) !== null && _parentNode$type$name !== void 0 ? _parentNode$type$name : null,
|
|
79
|
+
pos: pos
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Finds an agent mention that survived a document change when the changed-range
|
|
85
|
+
* scan did not find one. Prefers the previously tracked mention ID when present;
|
|
86
|
+
* otherwise returns a surviving agent mention using the existing traversal order.
|
|
87
|
+
*/
|
|
88
|
+
var getSurvivingAgentMentionDetails = function getSurvivingAgentMentionDetails(state, preferredId) {
|
|
89
|
+
var mentionSchema = state.schema.nodes.mention;
|
|
90
|
+
var result = null;
|
|
91
|
+
state.doc.descendants(function (node, pos) {
|
|
92
|
+
var _result, _result2;
|
|
93
|
+
if (((_result = result) === null || _result === void 0 ? void 0 : _result.id) === preferredId) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (node.type !== mentionSchema || !AGENT_USER_TYPES.has(node.attrs.userType) || !node.attrs.id) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
result = getAgentMentionDetailsAtPos(state, pos, function (attrs) {
|
|
100
|
+
return attrs.id === node.attrs.id;
|
|
101
|
+
});
|
|
102
|
+
return ((_result2 = result) === null || _result2 === void 0 ? void 0 : _result2.id) !== preferredId;
|
|
103
|
+
});
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Maps a pending typed agent mention through a document-changing transaction and
|
|
109
|
+
* returns the updated pending state. If the mapped position was deleted or no
|
|
110
|
+
* longer points at the same local mention, the pending mention is cleared.
|
|
111
|
+
*/
|
|
112
|
+
var getPendingTypedAgentMentionAfterDocChange = function getPendingTypedAgentMentionAfterDocChange(state, tr, pendingTypedAgentMention, _ref) {
|
|
113
|
+
var resetTimer = _ref.resetTimer;
|
|
114
|
+
var mappedPos = tr.mapping.mapResult(pendingTypedAgentMention.pos, 1);
|
|
115
|
+
var resetCount = resetTimer ? pendingTypedAgentMention.resetCount + 1 : pendingTypedAgentMention.resetCount;
|
|
116
|
+
if (mappedPos.deleted) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
var pendingMentionDetails = getAgentMentionDetailsAtPos(state, mappedPos.pos, function (attrs) {
|
|
120
|
+
return attrs.localId === pendingTypedAgentMention.localId;
|
|
121
|
+
});
|
|
122
|
+
return pendingMentionDetails ? {
|
|
123
|
+
id: pendingMentionDetails.id,
|
|
124
|
+
localId: pendingTypedAgentMention.localId,
|
|
125
|
+
nodeSize: pendingMentionDetails.nodeSize,
|
|
126
|
+
pos: pendingMentionDetails.pos,
|
|
127
|
+
resetCount: resetCount
|
|
128
|
+
} : null;
|
|
129
|
+
};
|
|
130
|
+
export function createMentionPlugin(_ref2) {
|
|
131
|
+
var pmPluginFactoryParams = _ref2.pmPluginFactoryParams,
|
|
132
|
+
fireEvent = _ref2.fireEvent,
|
|
133
|
+
options = _ref2.options,
|
|
134
|
+
api = _ref2.api;
|
|
46
135
|
var mentionProvider;
|
|
47
136
|
var sendAnalytics = function sendAnalytics(event, actionSubject, action, attributes) {
|
|
48
137
|
if (event === SLI_EVENT_TYPE || event === SMART_EVENT_TYPE) {
|
|
@@ -68,36 +157,74 @@ export function createMentionPlugin(_ref) {
|
|
|
68
157
|
};
|
|
69
158
|
},
|
|
70
159
|
apply: function apply(tr, pluginState, oldState, newState) {
|
|
71
|
-
var
|
|
160
|
+
var _ref3 = tr.getMeta(mentionPluginKey) || {
|
|
72
161
|
action: null,
|
|
73
162
|
params: null
|
|
74
163
|
},
|
|
75
|
-
action =
|
|
76
|
-
params =
|
|
77
|
-
var
|
|
164
|
+
action = _ref3.action,
|
|
165
|
+
params = _ref3.params;
|
|
166
|
+
var hasPublicPluginStateChanged = false;
|
|
78
167
|
var newPluginState = pluginState;
|
|
168
|
+
var isAgentMentionsExperimentEnabled = editorExperiment('platform_editor_agent_mentions', true);
|
|
79
169
|
var hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to;
|
|
80
170
|
if (tr.docChanged || tr.selectionSet && hasPositionChanged) {
|
|
81
171
|
newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
82
172
|
canInsertMention: canMentionBeCreatedInRange(newState.selection.from, newState.selection.to)(newState)
|
|
83
173
|
});
|
|
84
|
-
|
|
174
|
+
hasPublicPluginStateChanged = true;
|
|
85
175
|
}
|
|
86
176
|
switch (action) {
|
|
177
|
+
case ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION:
|
|
178
|
+
{
|
|
179
|
+
var _newPluginState$lastA;
|
|
180
|
+
var pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
|
|
181
|
+
// Ignore stale timer callbacks. The localId and resetCount must still match the
|
|
182
|
+
// current pending mention so older timers cannot publish after later user edits.
|
|
183
|
+
if (!isAgentMentionsExperimentEnabled || !pendingTypedAgentMention || pendingTypedAgentMention.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMention.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
var pendingMentionDetails = getAgentMentionDetailsAtPos(newState, pendingTypedAgentMention.pos, function (attrs) {
|
|
187
|
+
return attrs.localId === pendingTypedAgentMention.localId;
|
|
188
|
+
});
|
|
189
|
+
if (!pendingMentionDetails) {
|
|
190
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
191
|
+
pendingTypedAgentMention: null
|
|
192
|
+
});
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
196
|
+
pendingTypedAgentMention: null,
|
|
197
|
+
lastInsertedAgentMentionId: pendingMentionDetails.id,
|
|
198
|
+
lastInsertedAgentMentionContext: pendingMentionDetails.context,
|
|
199
|
+
lastInsertedAgentMentionParentNodeType: pendingMentionDetails.parentNodeType,
|
|
200
|
+
lastAgentMentionInsertionCount: ((_newPluginState$lastA = newPluginState.lastAgentMentionInsertionCount) !== null && _newPluginState$lastA !== void 0 ? _newPluginState$lastA : 0) + 1
|
|
201
|
+
});
|
|
202
|
+
hasPublicPluginStateChanged = true;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
87
205
|
case ACTIONS.SET_PROVIDER:
|
|
88
206
|
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
89
207
|
mentionProvider: params.provider
|
|
90
208
|
});
|
|
91
|
-
|
|
209
|
+
hasPublicPluginStateChanged = true;
|
|
92
210
|
break;
|
|
93
211
|
}
|
|
94
212
|
|
|
95
213
|
// When the agent mentions experiment is off, dispatch immediately (original behaviour).
|
|
96
214
|
// When it's on, defer dispatch to after the agent tracking block below so that
|
|
97
215
|
// agent-mention state changes are included in the notification.
|
|
98
|
-
if (
|
|
216
|
+
if (hasPublicPluginStateChanged && !isAgentMentionsExperimentEnabled) {
|
|
99
217
|
pmPluginFactoryParams.dispatch(mentionPluginKey, newPluginState);
|
|
100
218
|
}
|
|
219
|
+
if (isAgentMentionsExperimentEnabled && tr.docChanged && tr.getMeta('replaceDocument')) {
|
|
220
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
221
|
+
pendingTypedAgentMention: null,
|
|
222
|
+
lastInsertedAgentMentionId: null,
|
|
223
|
+
lastInsertedAgentMentionContext: null,
|
|
224
|
+
lastInsertedAgentMentionParentNodeType: null
|
|
225
|
+
});
|
|
226
|
+
hasPublicPluginStateChanged = true;
|
|
227
|
+
}
|
|
101
228
|
if (options !== null && options !== void 0 && options.handleMentionsChanged && tr.docChanged) {
|
|
102
229
|
var _insm$session, _insm$session2;
|
|
103
230
|
(_insm$session = insm.session) === null || _insm$session === void 0 || _insm$session.startFeature('mentionDeletionDetection');
|
|
@@ -158,7 +285,7 @@ export function createMentionPlugin(_ref) {
|
|
|
158
285
|
(_insm$session2 = insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('mentionDeletionDetection');
|
|
159
286
|
}
|
|
160
287
|
var isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
|
|
161
|
-
if (tr.docChanged && !tr.getMeta('replaceDocument') && !isAIStreaming &&
|
|
288
|
+
if (tr.docChanged && !tr.getMeta('replaceDocument') && !isAIStreaming && isAgentMentionsExperimentEnabled) {
|
|
162
289
|
var _mentionSchema = newState.schema.nodes.mention;
|
|
163
290
|
var newDocRanges = [];
|
|
164
291
|
var oldDocRanges = [];
|
|
@@ -204,14 +331,16 @@ export function createMentionPlugin(_ref) {
|
|
|
204
331
|
oldDocRanges.push.apply(oldDocRanges, stepOldRanges);
|
|
205
332
|
}
|
|
206
333
|
});
|
|
207
|
-
|
|
208
|
-
|
|
334
|
+
var shouldResolveAgentMentionState = stepsTouchMentions || Boolean(newPluginState.lastInsertedAgentMentionId);
|
|
335
|
+
if (shouldResolveAgentMentionState) {
|
|
336
|
+
var _newPluginState$lastA2, _newPluginState$lastI, _newPluginState$lastI2, _newPluginState$lastI3;
|
|
209
337
|
var agentMentionId = null;
|
|
210
338
|
var agentMentionContext = null;
|
|
211
339
|
var agentMentionParentNodeType = null;
|
|
212
340
|
var newCount = 0;
|
|
213
341
|
var oldAgentMentionId = null;
|
|
214
342
|
var oldCount = 0;
|
|
343
|
+
var pendingTypedAgentMentionDetails = {};
|
|
215
344
|
if (stepsTouchMentions) {
|
|
216
345
|
var _iterator = _createForOfIteratorHelper(newDocRanges),
|
|
217
346
|
_step;
|
|
@@ -222,16 +351,26 @@ export function createMentionPlugin(_ref) {
|
|
|
222
351
|
to = _step$value[1];
|
|
223
352
|
var clampedTo = Math.min(to, newState.doc.content.size);
|
|
224
353
|
if (from >= clampedTo) continue;
|
|
225
|
-
newState.doc.nodesBetween(from, clampedTo, function (node,
|
|
354
|
+
newState.doc.nodesBetween(from, clampedTo, function (node, pos) {
|
|
226
355
|
if (node.type !== _mentionSchema || !AGENT_USER_TYPES.has(node.attrs.userType)) {
|
|
227
356
|
return true;
|
|
228
357
|
}
|
|
229
358
|
newCount++;
|
|
359
|
+
if (pendingTypedAgentMentionDetails.current === undefined && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && node.attrs.localId === (params === null || params === void 0 ? void 0 : params.localId)) {
|
|
360
|
+
var _getAgentMentionDetai;
|
|
361
|
+
pendingTypedAgentMentionDetails.current = (_getAgentMentionDetai = getAgentMentionDetailsAtPos(newState, pos, function (attrs) {
|
|
362
|
+
return attrs.localId === params.localId;
|
|
363
|
+
})) !== null && _getAgentMentionDetai !== void 0 ? _getAgentMentionDetai : undefined;
|
|
364
|
+
}
|
|
230
365
|
if (agentMentionId === null && node.attrs.id) {
|
|
231
|
-
var
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
366
|
+
var agentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, function (attrs) {
|
|
367
|
+
return attrs.id === node.attrs.id;
|
|
368
|
+
});
|
|
369
|
+
if (agentMentionDetails) {
|
|
370
|
+
agentMentionId = agentMentionDetails.id;
|
|
371
|
+
agentMentionContext = agentMentionDetails.context;
|
|
372
|
+
agentMentionParentNodeType = agentMentionDetails.parentNodeType;
|
|
373
|
+
}
|
|
235
374
|
}
|
|
236
375
|
return true;
|
|
237
376
|
});
|
|
@@ -271,33 +410,43 @@ export function createMentionPlugin(_ref) {
|
|
|
271
410
|
// When a deletion collapses the new-doc range to a zero-width point, or when
|
|
272
411
|
// the doc changed but no step covered the tracked mention, the new-doc scan
|
|
273
412
|
// above finds nothing. Check whether any agent mention survived in the document.
|
|
274
|
-
var
|
|
413
|
+
var resolvedFromFullDocFallback = false;
|
|
275
414
|
if (agentMentionId === null && newPluginState.lastInsertedAgentMentionId) {
|
|
276
|
-
var
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (node.type === _mentionSchema && AGENT_USER_TYPES.has(node.attrs.userType)) {
|
|
283
|
-
var _parent$type$name2;
|
|
284
|
-
// Prefer the previously tracked ID; otherwise keep the first found.
|
|
285
|
-
survivorId = node.attrs.id;
|
|
286
|
-
survivorParentNodeType = (_parent$type$name2 = parent === null || parent === void 0 ? void 0 : parent.type.name) !== null && _parent$type$name2 !== void 0 ? _parent$type$name2 : null;
|
|
287
|
-
survivorContext = (parent === null || parent === void 0 ? void 0 : parent.textContent.trim()) || null;
|
|
288
|
-
}
|
|
289
|
-
return survivorId !== prevId;
|
|
290
|
-
});
|
|
291
|
-
if (survivorId !== null) {
|
|
292
|
-
agentMentionId = survivorId;
|
|
293
|
-
agentMentionContext = survivorContext;
|
|
294
|
-
agentMentionParentNodeType = survivorParentNodeType;
|
|
295
|
-
resolvedFromSurvivor = true;
|
|
415
|
+
var survivorDetails = getSurvivingAgentMentionDetails(newState, newPluginState.lastInsertedAgentMentionId);
|
|
416
|
+
if (survivorDetails) {
|
|
417
|
+
agentMentionId = survivorDetails.id;
|
|
418
|
+
agentMentionContext = survivorDetails.context;
|
|
419
|
+
agentMentionParentNodeType = survivorDetails.parentNodeType;
|
|
420
|
+
resolvedFromFullDocFallback = true;
|
|
296
421
|
}
|
|
297
422
|
}
|
|
298
|
-
var isNewInsertion = agentMentionId !== null && !
|
|
299
|
-
var
|
|
300
|
-
|
|
423
|
+
var isNewInsertion = agentMentionId !== null && !resolvedFromFullDocFallback && (oldAgentMentionId !== agentMentionId || newCount > oldCount);
|
|
424
|
+
var isPendingTypedAgentMentionInsertion = isNewInsertion && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && typeof (params === null || params === void 0 ? void 0 : params.localId) === 'string';
|
|
425
|
+
var newInsertionCount = isNewInsertion ? ((_newPluginState$lastA2 = newPluginState.lastAgentMentionInsertionCount) !== null && _newPluginState$lastA2 !== void 0 ? _newPluginState$lastA2 : 0) + 1 : undefined;
|
|
426
|
+
if (isPendingTypedAgentMentionInsertion && pendingTypedAgentMentionDetails.current) {
|
|
427
|
+
var pendingTypedAgentMentionLocalId = params === null || params === void 0 ? void 0 : params.localId;
|
|
428
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
429
|
+
pendingTypedAgentMention: {
|
|
430
|
+
id: pendingTypedAgentMentionDetails.current.id,
|
|
431
|
+
localId: pendingTypedAgentMentionLocalId,
|
|
432
|
+
nodeSize: pendingTypedAgentMentionDetails.current.nodeSize,
|
|
433
|
+
pos: pendingTypedAgentMentionDetails.current.pos,
|
|
434
|
+
resetCount: 1
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
} else if (isPendingTypedAgentMentionInsertion) {
|
|
438
|
+
// Fallback: if the localId-specific scan missed the typed mention,
|
|
439
|
+
// publish immediately so the insertion is not dropped.
|
|
440
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
441
|
+
pendingTypedAgentMention: null,
|
|
442
|
+
lastInsertedAgentMentionId: agentMentionId,
|
|
443
|
+
lastInsertedAgentMentionContext: agentMentionContext,
|
|
444
|
+
lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType
|
|
445
|
+
}, newInsertionCount !== undefined ? {
|
|
446
|
+
lastAgentMentionInsertionCount: newInsertionCount
|
|
447
|
+
} : {});
|
|
448
|
+
hasPublicPluginStateChanged = true;
|
|
449
|
+
} else if (agentMentionId !== ((_newPluginState$lastI = newPluginState.lastInsertedAgentMentionId) !== null && _newPluginState$lastI !== void 0 ? _newPluginState$lastI : null) || agentMentionContext !== ((_newPluginState$lastI2 = newPluginState.lastInsertedAgentMentionContext) !== null && _newPluginState$lastI2 !== void 0 ? _newPluginState$lastI2 : null) || agentMentionParentNodeType !== ((_newPluginState$lastI3 = newPluginState.lastInsertedAgentMentionParentNodeType) !== null && _newPluginState$lastI3 !== void 0 ? _newPluginState$lastI3 : null) || newInsertionCount !== undefined) {
|
|
301
450
|
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
302
451
|
lastInsertedAgentMentionId: agentMentionId,
|
|
303
452
|
lastInsertedAgentMentionContext: agentMentionContext,
|
|
@@ -305,11 +454,18 @@ export function createMentionPlugin(_ref) {
|
|
|
305
454
|
}, newInsertionCount !== undefined ? {
|
|
306
455
|
lastAgentMentionInsertionCount: newInsertionCount
|
|
307
456
|
} : {});
|
|
308
|
-
|
|
457
|
+
hasPublicPluginStateChanged = true;
|
|
309
458
|
}
|
|
310
459
|
}
|
|
311
460
|
}
|
|
312
|
-
if (
|
|
461
|
+
if (isAgentMentionsExperimentEnabled && newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && tr.docChanged) {
|
|
462
|
+
newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
|
|
463
|
+
pendingTypedAgentMention: getPendingTypedAgentMentionAfterDocChange(newState, tr, newPluginState.pendingTypedAgentMention, {
|
|
464
|
+
resetTimer: isQualifyingLocalUserDocChange(tr)
|
|
465
|
+
})
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
if (hasPublicPluginStateChanged && isAgentMentionsExperimentEnabled) {
|
|
313
469
|
pmPluginFactoryParams.dispatch(mentionPluginKey, newPluginState);
|
|
314
470
|
}
|
|
315
471
|
return newPluginState;
|
|
@@ -327,6 +483,47 @@ export function createMentionPlugin(_ref) {
|
|
|
327
483
|
}
|
|
328
484
|
},
|
|
329
485
|
view: function view(editorView) {
|
|
486
|
+
var isAgentMentionsEnabled = editorExperiment('platform_editor_agent_mentions', true);
|
|
487
|
+
var pendingTypedAgentMentionTimer;
|
|
488
|
+
var pendingTypedAgentMentionTimerKey = null;
|
|
489
|
+
var clearPendingTypedAgentMentionTimer = function clearPendingTypedAgentMentionTimer() {
|
|
490
|
+
if (pendingTypedAgentMentionTimer) {
|
|
491
|
+
clearTimeout(pendingTypedAgentMentionTimer);
|
|
492
|
+
pendingTypedAgentMentionTimer = undefined;
|
|
493
|
+
}
|
|
494
|
+
pendingTypedAgentMentionTimerKey = null;
|
|
495
|
+
};
|
|
496
|
+
var schedulePendingTypedAgentMentionTimer = function schedulePendingTypedAgentMentionTimer(mentionPluginState) {
|
|
497
|
+
if (!isAgentMentionsEnabled) {
|
|
498
|
+
clearPendingTypedAgentMentionTimer();
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
var pendingTypedAgentMention = mentionPluginState === null || mentionPluginState === void 0 ? void 0 : mentionPluginState.pendingTypedAgentMention;
|
|
502
|
+
if (!pendingTypedAgentMention) {
|
|
503
|
+
clearPendingTypedAgentMentionTimer();
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
var timerKey = "".concat(pendingTypedAgentMention.localId, ":").concat(pendingTypedAgentMention.resetCount);
|
|
507
|
+
if (timerKey === pendingTypedAgentMentionTimerKey) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
clearPendingTypedAgentMentionTimer();
|
|
511
|
+
pendingTypedAgentMentionTimerKey = timerKey;
|
|
512
|
+
pendingTypedAgentMentionTimer = setTimeout(function () {
|
|
513
|
+
var _mentionPluginKey$get;
|
|
514
|
+
var latestPendingTypedAgentMention = (_mentionPluginKey$get = mentionPluginKey.getState(editorView.state)) === null || _mentionPluginKey$get === void 0 ? void 0 : _mentionPluginKey$get.pendingTypedAgentMention;
|
|
515
|
+
if (!latestPendingTypedAgentMention || latestPendingTypedAgentMention.localId !== pendingTypedAgentMention.localId || latestPendingTypedAgentMention.resetCount !== pendingTypedAgentMention.resetCount) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
editorView.dispatch(editorView.state.tr.setMeta(mentionPluginKey, {
|
|
519
|
+
action: ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION,
|
|
520
|
+
params: {
|
|
521
|
+
localId: pendingTypedAgentMention.localId,
|
|
522
|
+
resetCount: pendingTypedAgentMention.resetCount
|
|
523
|
+
}
|
|
524
|
+
}));
|
|
525
|
+
}, AGENT_MENTION_INACTIVITY_MS);
|
|
526
|
+
};
|
|
330
527
|
var providerHandler = function providerHandler(name, providerPromise) {
|
|
331
528
|
switch (name) {
|
|
332
529
|
case 'mentionProvider':
|
|
@@ -372,7 +569,15 @@ export function createMentionPlugin(_ref) {
|
|
|
372
569
|
pmPluginFactoryParams.providerFactory.subscribe('mentionProvider', providerHandler);
|
|
373
570
|
}
|
|
374
571
|
return {
|
|
572
|
+
update: function update(view, prevState) {
|
|
573
|
+
var mentionPluginState = mentionPluginKey.getState(view.state);
|
|
574
|
+
if (mentionPluginState === mentionPluginKey.getState(prevState)) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
schedulePendingTypedAgentMentionTimer(mentionPluginState);
|
|
578
|
+
},
|
|
375
579
|
destroy: function destroy() {
|
|
580
|
+
clearPendingTypedAgentMentionTimer();
|
|
376
581
|
if (pmPluginFactoryParams.providerFactory) {
|
|
377
582
|
pmPluginFactoryParams.providerFactory.unsubscribe('mentionProvider', providerHandler);
|
|
378
583
|
}
|
|
@@ -98,7 +98,7 @@ export var buildTypeAheadInviteItemClickedPayload = function buildTypeAheadInvit
|
|
|
98
98
|
}, additionalAttributes)
|
|
99
99
|
};
|
|
100
100
|
};
|
|
101
|
-
export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId) {
|
|
101
|
+
export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayload(duration, upKeyCount, downKeyCount, sessionId, insertType, mention, mentionLocalId, mentionList, query, contextIdentifierProvider, taskListId, taskItemId, isAgent) {
|
|
102
102
|
var _extractAttributesFro3 = extractAttributesFromQuery(query),
|
|
103
103
|
queryLength = _extractAttributesFro3.queryLength,
|
|
104
104
|
spaceInQuery = _extractAttributesFro3.spaceInQuery;
|
|
@@ -117,7 +117,7 @@ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayloa
|
|
|
117
117
|
containerId: containerId,
|
|
118
118
|
objectId: objectId,
|
|
119
119
|
childObjectId: childObjectId,
|
|
120
|
-
attributes: {
|
|
120
|
+
attributes: _objectSpread(_objectSpread({
|
|
121
121
|
sessionId: sessionId,
|
|
122
122
|
duration: duration,
|
|
123
123
|
position: getPosition(mentionList, mention),
|
|
@@ -132,14 +132,17 @@ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayloa
|
|
|
132
132
|
upKeyCount: upKeyCount,
|
|
133
133
|
downKeyCount: downKeyCount,
|
|
134
134
|
memberCount: isTeamType(mention.userType) && mention.context ? mention.context.memberCount : null,
|
|
135
|
-
includesYou: isTeamType(mention.userType) && mention.context ? mention.context.includesYou : null
|
|
135
|
+
includesYou: isTeamType(mention.userType) && mention.context ? mention.context.includesYou : null
|
|
136
|
+
}, isAgent ? {
|
|
137
|
+
isAgent: isAgent
|
|
138
|
+
} : {}), {}, {
|
|
136
139
|
taskListId: taskListId,
|
|
137
140
|
taskItemId: taskItemId,
|
|
138
141
|
localId: mentionLocalId,
|
|
139
142
|
containerId: containerId,
|
|
140
143
|
objectId: objectId,
|
|
141
144
|
childObjectId: childObjectId
|
|
142
|
-
}
|
|
145
|
+
})
|
|
143
146
|
};
|
|
144
147
|
};
|
|
145
148
|
export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength) {
|