@atlaskit/editor-plugin-mentions 16.0.3 → 16.1.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 +19 -0
- package/anchored-popup/package.json +10 -0
- package/dist/cjs/entry-points/anchored-popup.js +12 -0
- package/dist/cjs/mentionsPlugin.js +4 -12
- package/dist/cjs/pm-plugins/main.js +1 -1
- package/dist/cjs/ui/AnchoredPopup.js +37 -0
- package/dist/cjs/ui/InlineInvitePopupContainer.js +157 -0
- package/dist/cjs/ui/type-ahead/analytics.js +2 -1
- package/dist/cjs/ui/type-ahead/index.js +26 -18
- package/dist/es2019/entry-points/anchored-popup.js +2 -0
- package/dist/es2019/mentionsPlugin.js +4 -10
- package/dist/es2019/pm-plugins/main.js +1 -1
- package/dist/es2019/ui/AnchoredPopup.js +28 -0
- package/dist/es2019/ui/InlineInvitePopupContainer.js +146 -0
- package/dist/es2019/ui/type-ahead/analytics.js +2 -1
- package/dist/es2019/ui/type-ahead/index.js +26 -20
- package/dist/esm/entry-points/anchored-popup.js +2 -0
- package/dist/esm/mentionsPlugin.js +4 -12
- package/dist/esm/pm-plugins/main.js +1 -1
- package/dist/esm/ui/AnchoredPopup.js +29 -0
- package/dist/esm/ui/InlineInvitePopupContainer.js +148 -0
- package/dist/esm/ui/type-ahead/analytics.js +2 -1
- package/dist/esm/ui/type-ahead/index.js +26 -18
- package/dist/types/entry-points/anchored-popup.d.ts +2 -0
- package/dist/types/ui/AnchoredPopup.d.ts +13 -0
- package/dist/types/ui/InlineInvitePopupContainer.d.ts +11 -0
- package/dist/types/ui/type-ahead/analytics.d.ts +1 -1
- package/package.json +11 -5
- package/dist/cjs/pm-plugins/mentionPlaceholder.js +0 -52
- package/dist/cjs/ui/InlineInviteRecaptchaContainer.js +0 -100
- package/dist/es2019/pm-plugins/mentionPlaceholder.js +0 -44
- package/dist/es2019/ui/InlineInviteRecaptchaContainer.js +0 -90
- package/dist/esm/pm-plugins/mentionPlaceholder.js +0 -44
- package/dist/esm/ui/InlineInviteRecaptchaContainer.js +0 -91
- package/dist/types/pm-plugins/mentionPlaceholder.d.ts +0 -11
- package/dist/types/ui/InlineInviteRecaptchaContainer.d.ts +0 -15
|
@@ -16,7 +16,6 @@ import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
|
16
16
|
import { createSingleMentionFragment } from '../../editor-commands';
|
|
17
17
|
import { mentionPluginKey } from '../../pm-plugins/key';
|
|
18
18
|
import { ACTIONS } from '../../pm-plugins/main';
|
|
19
|
-
import { mentionPlaceholderPluginKey, MENTION_PLACEHOLDER_ACTIONS } from '../../pm-plugins/mentionPlaceholder';
|
|
20
19
|
import { getMentionPluginState } from '../../pm-plugins/utils';
|
|
21
20
|
import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
|
|
22
21
|
import InviteItemWithEmailDomain from '../InviteItem/InviteItemWithEmailDomain';
|
|
@@ -44,7 +43,7 @@ const createInviteItem = ({
|
|
|
44
43
|
onHover
|
|
45
44
|
}) => {
|
|
46
45
|
var _mentionProvider$getS;
|
|
47
|
-
return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && fg('
|
|
46
|
+
return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && fg('inline_invite_from_mentions_kill_switch') ? /*#__PURE__*/React.createElement(InviteItemWithEmailDomain, {
|
|
48
47
|
productName: mentionProvider ? mentionProvider.productName : undefined,
|
|
49
48
|
selected: isSelected,
|
|
50
49
|
onMount: onInviteItemMount,
|
|
@@ -137,6 +136,7 @@ const buildAndSendElementsTypeAheadAnalytics = fireEvent => ({
|
|
|
137
136
|
query,
|
|
138
137
|
mentions,
|
|
139
138
|
stats,
|
|
139
|
+
mentionTypeaheadSessionId,
|
|
140
140
|
agentAnalytics
|
|
141
141
|
}) => {
|
|
142
142
|
let duration = 0;
|
|
@@ -163,7 +163,7 @@ const buildAndSendElementsTypeAheadAnalytics = fireEvent => ({
|
|
|
163
163
|
memberCount: mention.context.memberCount
|
|
164
164
|
} : null).filter(m => !!m);
|
|
165
165
|
}
|
|
166
|
-
const payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, agentAnalytics);
|
|
166
|
+
const payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, mentionTypeaheadSessionId, agentAnalytics);
|
|
167
167
|
fireEvent(payload, 'fabric-elements');
|
|
168
168
|
};
|
|
169
169
|
|
|
@@ -253,20 +253,20 @@ const makeTransformMentionsToTypeAheadItems = ({
|
|
|
253
253
|
sessionId
|
|
254
254
|
}) => {
|
|
255
255
|
const mentionItems = mentions.map(mention => toItem(mention));
|
|
256
|
-
const agentCount = mentions.filter(isAgentMention).length;
|
|
257
|
-
const agentAnalytics = {
|
|
258
|
-
agentCount,
|
|
259
|
-
agentSectioningEnabled: enableAgentSectioning
|
|
260
|
-
};
|
|
261
|
-
|
|
262
256
|
// The loading placeholder is a rendered-only row — keep it in
|
|
263
257
|
// `mentionItems` so the shimmer shows, but exclude it from analytics
|
|
264
258
|
// and no-results bookkeeping so it isn't counted as a real result.
|
|
265
259
|
const realMentions = mentions.filter(mention => !isLoadingPlaceholder(mention));
|
|
260
|
+
const agentCount = realMentions.filter(isAgentMention).length;
|
|
261
|
+
const agentAnalytics = {
|
|
262
|
+
agentCount,
|
|
263
|
+
agentSectioningEnabled: enableAgentSectioning
|
|
264
|
+
};
|
|
266
265
|
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
267
266
|
query,
|
|
268
267
|
mentions: realMentions,
|
|
269
268
|
stats,
|
|
269
|
+
mentionTypeaheadSessionId: sessionId,
|
|
270
270
|
agentAnalytics
|
|
271
271
|
});
|
|
272
272
|
|
|
@@ -460,10 +460,10 @@ export const createTypeAheadConfig = ({
|
|
|
460
460
|
// Don't fire event and the callback with selection by space press
|
|
461
461
|
if (mode !== 'space') {
|
|
462
462
|
var _mentionProvider$getS3, _mentionProvider$getS4;
|
|
463
|
-
fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('
|
|
463
|
+
fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('inline_invite_from_mentions_kill_switch') ? {
|
|
464
464
|
isInlineInviteMentionsEnabled: (_mentionProvider$getS3 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS3 === void 0 ? void 0 : _mentionProvider$getS3.call(mentionProvider)
|
|
465
465
|
} : {}));
|
|
466
|
-
if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('
|
|
466
|
+
if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('inline_invite_from_mentions_kill_switch')) {
|
|
467
467
|
// Get the email from query, using the same logic as InviteItemWithEmailDomain
|
|
468
468
|
const emailDomain = mentionProvider.userEmailDomain;
|
|
469
469
|
let email = query || '';
|
|
@@ -472,15 +472,21 @@ export const createTypeAheadConfig = ({
|
|
|
472
472
|
email = `${email.toLowerCase()}@${emailDomain}`;
|
|
473
473
|
}
|
|
474
474
|
// If query already includes @, use it as is
|
|
475
|
-
if (email && mentionProvider.
|
|
476
|
-
|
|
477
|
-
const {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
475
|
+
if (email && mentionProvider.showInlineInvitePopup) {
|
|
476
|
+
const pendingLocalId = crypto.randomUUID();
|
|
477
|
+
const tr = insert(createSingleMentionFragment({
|
|
478
|
+
mentionProvider,
|
|
479
|
+
mentionInsertDisplayName,
|
|
480
|
+
tr: state.tr,
|
|
481
|
+
sanitizePrivateContent
|
|
482
|
+
})({
|
|
483
|
+
name: email,
|
|
484
|
+
id: pendingLocalId,
|
|
485
|
+
userType: 'DEFAULT',
|
|
486
|
+
localId: pendingLocalId,
|
|
487
|
+
accessLevel: 'CONTAINER'
|
|
488
|
+
}));
|
|
489
|
+
mentionProvider.showInlineInvitePopup(email, pendingLocalId);
|
|
484
490
|
return tr;
|
|
485
491
|
}
|
|
486
492
|
} else if (mentionProvider.onInviteItemClick) {
|
|
@@ -23,8 +23,7 @@ import { mentionNodeSpec } from './nodeviews/mentionNodeSpec';
|
|
|
23
23
|
import { agentMentionPluginKey, createAgentMentionPlugin } from './pm-plugins/agent';
|
|
24
24
|
import { mentionPluginKey } from './pm-plugins/key';
|
|
25
25
|
import { ACTIONS, createMentionPlugin } from './pm-plugins/main';
|
|
26
|
-
import {
|
|
27
|
-
import { InlineInviteRecaptchaContainer } from './ui/InlineInviteRecaptchaContainer';
|
|
26
|
+
import { InlineInvitePopupContainer } from './ui/InlineInvitePopupContainer';
|
|
28
27
|
import { SecondaryToolbarComponent } from './ui/SecondaryToolbarComponent';
|
|
29
28
|
import { createTypeAheadConfig } from './ui/type-ahead';
|
|
30
29
|
var processName = function processName(name, intl) {
|
|
@@ -137,14 +136,6 @@ var mentionsPlugin = function mentionsPlugin(_ref3) {
|
|
|
137
136
|
}
|
|
138
137
|
});
|
|
139
138
|
}
|
|
140
|
-
if (fg('jira_invites_auto_tag_new_user_in_mentions_fg')) {
|
|
141
|
-
plugins.push({
|
|
142
|
-
name: 'mentionPlaceholder',
|
|
143
|
-
plugin: function plugin() {
|
|
144
|
-
return createMentionPlaceholderPlugin();
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
139
|
return plugins;
|
|
149
140
|
},
|
|
150
141
|
contentComponent: function contentComponent(_ref4) {
|
|
@@ -165,9 +156,10 @@ var mentionsPlugin = function mentionsPlugin(_ref3) {
|
|
|
165
156
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Component, {
|
|
166
157
|
mentionProvider: mentionProvider,
|
|
167
158
|
api: api
|
|
168
|
-
}), fg('
|
|
159
|
+
}), fg('inline_invite_from_mentions_kill_switch') && /*#__PURE__*/React.createElement(InlineInvitePopupContainer, {
|
|
169
160
|
mentionProvider: mentionProvider,
|
|
170
|
-
api: api
|
|
161
|
+
api: api,
|
|
162
|
+
editorView: editorView
|
|
171
163
|
}));
|
|
172
164
|
}
|
|
173
165
|
});
|
|
@@ -58,7 +58,7 @@ var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
|
|
|
58
58
|
var AGENT_MENTION_INACTIVITY_MS = 3000;
|
|
59
59
|
var MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
|
|
60
60
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
61
|
-
var PACKAGE_VERSION = "16.0
|
|
61
|
+
var PACKAGE_VERSION = "16.1.0";
|
|
62
62
|
var setProvider = function setProvider(provider) {
|
|
63
63
|
return function (state, dispatch) {
|
|
64
64
|
if (dispatch) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { Popup } from '@atlaskit/popup/popup';
|
|
3
|
+
/**
|
|
4
|
+
* A `<Popup>` anchored to an externally-supplied DOM node. Unlike `PopupTrigger`, it has no
|
|
5
|
+
* clickable trigger of its own — it opens whenever `isOpen` becomes true, so callers can drive
|
|
6
|
+
* it from any external signal.
|
|
7
|
+
*/
|
|
8
|
+
export function AnchoredPopup(_ref) {
|
|
9
|
+
var anchorElement = _ref.anchorElement,
|
|
10
|
+
content = _ref.content,
|
|
11
|
+
isOpen = _ref.isOpen,
|
|
12
|
+
onClose = _ref.onClose;
|
|
13
|
+
var renderContent = useCallback(function () {
|
|
14
|
+
return isOpen ? content : null;
|
|
15
|
+
}, [isOpen, content]);
|
|
16
|
+
var renderTrigger = useCallback(function (triggerProps) {
|
|
17
|
+
if (anchorElement && typeof triggerProps.ref === 'function') {
|
|
18
|
+
triggerProps.ref(anchorElement);
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}, [anchorElement]);
|
|
22
|
+
return /*#__PURE__*/React.createElement(Popup, {
|
|
23
|
+
isOpen: isOpen,
|
|
24
|
+
onClose: onClose,
|
|
25
|
+
placement: "bottom-start",
|
|
26
|
+
content: renderContent,
|
|
27
|
+
trigger: renderTrigger
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/* InlineInvitePopupContainer.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
4
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
var findMentionRange = function findMentionRange(doc, localId) {
|
|
6
|
+
var range = null;
|
|
7
|
+
doc.descendants(function (node, pos) {
|
|
8
|
+
if (range) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (node.type.name === 'mention' && node.attrs.localId === localId) {
|
|
12
|
+
range = {
|
|
13
|
+
from: pos,
|
|
14
|
+
to: pos + node.nodeSize
|
|
15
|
+
};
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
});
|
|
20
|
+
return range;
|
|
21
|
+
};
|
|
22
|
+
export var InlineInvitePopupContainer = function InlineInvitePopupContainer(_ref) {
|
|
23
|
+
var _api$mention2, _api$core3;
|
|
24
|
+
var mentionProvider = _ref.mentionProvider,
|
|
25
|
+
api = _ref.api,
|
|
26
|
+
editorView = _ref.editorView;
|
|
27
|
+
var _useState = useState(null),
|
|
28
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
29
|
+
provider = _useState2[0],
|
|
30
|
+
setProvider = _useState2[1];
|
|
31
|
+
var _useState3 = useState(null),
|
|
32
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
33
|
+
anchorElement = _useState4[0],
|
|
34
|
+
setAnchorElement = _useState4[1];
|
|
35
|
+
var pendingMentionRef = useRef(null);
|
|
36
|
+
useEffect(function () {
|
|
37
|
+
if (!mentionProvider) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
var isMounted = true;
|
|
41
|
+
var cleanupProvider;
|
|
42
|
+
mentionProvider.then(function (resolvedProvider) {
|
|
43
|
+
var _providerWithPopup$ge;
|
|
44
|
+
if (!isMounted) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
var providerWithPopup = resolvedProvider;
|
|
48
|
+
var originalGetMentionDisabledState = (_providerWithPopup$ge = providerWithPopup.getMentionDisabledState) === null || _providerWithPopup$ge === void 0 ? void 0 : _providerWithPopup$ge.bind(providerWithPopup);
|
|
49
|
+
providerWithPopup.getMentionDisabledState = function (mention) {
|
|
50
|
+
var _pendingMentionRef$cu;
|
|
51
|
+
if (((_pendingMentionRef$cu = pendingMentionRef.current) === null || _pendingMentionRef$cu === void 0 ? void 0 : _pendingMentionRef$cu.localId) === mention.id) {
|
|
52
|
+
return {
|
|
53
|
+
disabled: true
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return originalGetMentionDisabledState === null || originalGetMentionDisabledState === void 0 ? void 0 : originalGetMentionDisabledState(mention);
|
|
57
|
+
};
|
|
58
|
+
cleanupProvider = function cleanupProvider() {
|
|
59
|
+
if (originalGetMentionDisabledState) {
|
|
60
|
+
providerWithPopup.getMentionDisabledState = originalGetMentionDisabledState;
|
|
61
|
+
} else {
|
|
62
|
+
delete providerWithPopup.getMentionDisabledState;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
setProvider(providerWithPopup);
|
|
66
|
+
}).catch(function () {});
|
|
67
|
+
return function () {
|
|
68
|
+
var _cleanupProvider;
|
|
69
|
+
isMounted = false;
|
|
70
|
+
(_cleanupProvider = cleanupProvider) === null || _cleanupProvider === void 0 || _cleanupProvider();
|
|
71
|
+
setProvider(null);
|
|
72
|
+
};
|
|
73
|
+
}, [mentionProvider]);
|
|
74
|
+
var removePendingMention = useCallback(function () {
|
|
75
|
+
var _api$core;
|
|
76
|
+
var pending = pendingMentionRef.current;
|
|
77
|
+
if (pending && api !== null && api !== void 0 && (_api$core = api.core) !== null && _api$core !== void 0 && (_api$core = _api$core.actions) !== null && _api$core !== void 0 && _api$core.execute) {
|
|
78
|
+
api.core.actions.execute(function (_ref2) {
|
|
79
|
+
var tr = _ref2.tr;
|
|
80
|
+
var range = findMentionRange(tr.doc, pending.localId);
|
|
81
|
+
return range ? tr.delete(range.from, range.to) : null;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
pendingMentionRef.current = null;
|
|
85
|
+
setAnchorElement(null);
|
|
86
|
+
}, [api]);
|
|
87
|
+
var handleDismiss = useCallback(function () {
|
|
88
|
+
removePendingMention();
|
|
89
|
+
}, [removePendingMention]);
|
|
90
|
+
var handleInviteComplete = useCallback(function (result) {
|
|
91
|
+
var _result$invited$, _api$core2, _api$mention;
|
|
92
|
+
var pending = pendingMentionRef.current;
|
|
93
|
+
if (!pending) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
var invitedUser = (_result$invited$ = result.invited[0]) !== null && _result$invited$ !== void 0 ? _result$invited$ : result.requested[0];
|
|
97
|
+
if (!invitedUser || !(api !== null && api !== void 0 && (_api$core2 = api.core) !== null && _api$core2 !== void 0 && (_api$core2 = _api$core2.actions) !== null && _api$core2 !== void 0 && _api$core2.execute) || !(api !== null && api !== void 0 && (_api$mention = api.mention) !== null && _api$mention !== void 0 && (_api$mention = _api$mention.commands) !== null && _api$mention !== void 0 && _api$mention.insertMention)) {
|
|
98
|
+
removePendingMention();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
var userId = invitedUser.id,
|
|
102
|
+
email = invitedUser.email;
|
|
103
|
+
api.core.actions.execute(function (_ref3) {
|
|
104
|
+
var tr = _ref3.tr;
|
|
105
|
+
var range = findMentionRange(tr.doc, pending.localId);
|
|
106
|
+
return range ? tr.delete(range.from, range.to) : null;
|
|
107
|
+
});
|
|
108
|
+
api.core.actions.execute(api.mention.commands.insertMention({
|
|
109
|
+
id: userId,
|
|
110
|
+
name: email,
|
|
111
|
+
userType: 'DEFAULT',
|
|
112
|
+
accessLevel: 'CONTAINER'
|
|
113
|
+
}));
|
|
114
|
+
pendingMentionRef.current = null;
|
|
115
|
+
setAnchorElement(null);
|
|
116
|
+
}, [api, removePendingMention]);
|
|
117
|
+
var handleReady = useCallback(function (show) {
|
|
118
|
+
if (!provider) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (show) {
|
|
122
|
+
provider.showInlineInvitePopup = function (email, localId) {
|
|
123
|
+
pendingMentionRef.current = {
|
|
124
|
+
email: email,
|
|
125
|
+
localId: localId
|
|
126
|
+
};
|
|
127
|
+
setTimeout(function () {
|
|
128
|
+
var range = findMentionRange(editorView.state.doc, localId);
|
|
129
|
+
var dom = range ? editorView.nodeDOM(range.from) : null;
|
|
130
|
+
setAnchorElement(dom instanceof HTMLElement ? dom : null);
|
|
131
|
+
show(email);
|
|
132
|
+
}, 0);
|
|
133
|
+
};
|
|
134
|
+
} else {
|
|
135
|
+
delete provider.showInlineInvitePopup;
|
|
136
|
+
}
|
|
137
|
+
}, [provider, editorView]);
|
|
138
|
+
if (!(provider !== null && provider !== void 0 && provider.InlineInvitePopup) || !(api !== null && api !== void 0 && (_api$mention2 = api.mention) !== null && _api$mention2 !== void 0 && (_api$mention2 = _api$mention2.commands) !== null && _api$mention2 !== void 0 && _api$mention2.insertMention) || !(api !== null && api !== void 0 && (_api$core3 = api.core) !== null && _api$core3 !== void 0 && (_api$core3 = _api$core3.actions) !== null && _api$core3 !== void 0 && _api$core3.execute)) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
var PopupComponent = provider.InlineInvitePopup;
|
|
142
|
+
return /*#__PURE__*/React.createElement(PopupComponent, {
|
|
143
|
+
anchorElement: anchorElement,
|
|
144
|
+
onInviteComplete: handleInviteComplete,
|
|
145
|
+
onDismiss: handleDismiss,
|
|
146
|
+
onReady: handleReady
|
|
147
|
+
});
|
|
148
|
+
};
|
|
@@ -146,7 +146,7 @@ export var buildTypeAheadInsertedPayload = function buildTypeAheadInsertedPayloa
|
|
|
146
146
|
})
|
|
147
147
|
};
|
|
148
148
|
};
|
|
149
|
-
export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength, agentAnalytics) {
|
|
149
|
+
export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayload(duration, userIds, query, teams, xProductMentionsLength, mentionTypeaheadSessionId, agentAnalytics) {
|
|
150
150
|
var _extractAttributesFro4 = extractAttributesFromQuery(query),
|
|
151
151
|
queryLength = _extractAttributesFro4.queryLength,
|
|
152
152
|
spaceInQuery = _extractAttributesFro4.spaceInQuery;
|
|
@@ -163,6 +163,7 @@ export var buildTypeAheadRenderedPayload = function buildTypeAheadRenderedPayloa
|
|
|
163
163
|
attributes: _objectSpread({
|
|
164
164
|
componentName: componentName,
|
|
165
165
|
duration: duration,
|
|
166
|
+
mentionTypeaheadSessionId: mentionTypeaheadSessionId,
|
|
166
167
|
userIds: userIds,
|
|
167
168
|
teams: teams,
|
|
168
169
|
queryLength: queryLength,
|
|
@@ -23,7 +23,6 @@ import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
|
23
23
|
import { createSingleMentionFragment } from '../../editor-commands';
|
|
24
24
|
import { mentionPluginKey } from '../../pm-plugins/key';
|
|
25
25
|
import { ACTIONS } from '../../pm-plugins/main';
|
|
26
|
-
import { mentionPlaceholderPluginKey, MENTION_PLACEHOLDER_ACTIONS } from '../../pm-plugins/mentionPlaceholder';
|
|
27
26
|
import { getMentionPluginState } from '../../pm-plugins/utils';
|
|
28
27
|
import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
|
|
29
28
|
import InviteItemWithEmailDomain from '../InviteItem/InviteItemWithEmailDomain';
|
|
@@ -58,7 +57,7 @@ var createInviteItem = function createInviteItem(_ref) {
|
|
|
58
57
|
var isSelected = _ref2.isSelected,
|
|
59
58
|
onClick = _ref2.onClick,
|
|
60
59
|
onHover = _ref2.onHover;
|
|
61
|
-
return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && fg('
|
|
60
|
+
return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && fg('inline_invite_from_mentions_kill_switch') ? /*#__PURE__*/React.createElement(InviteItemWithEmailDomain, {
|
|
62
61
|
productName: mentionProvider ? mentionProvider.productName : undefined,
|
|
63
62
|
selected: isSelected,
|
|
64
63
|
onMount: onInviteItemMount,
|
|
@@ -159,6 +158,7 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
|
|
|
159
158
|
var query = _ref5.query,
|
|
160
159
|
mentions = _ref5.mentions,
|
|
161
160
|
stats = _ref5.stats,
|
|
161
|
+
mentionTypeaheadSessionId = _ref5.mentionTypeaheadSessionId,
|
|
162
162
|
agentAnalytics = _ref5.agentAnalytics;
|
|
163
163
|
var duration = 0;
|
|
164
164
|
var userOrTeamIds = null;
|
|
@@ -192,7 +192,7 @@ var buildAndSendElementsTypeAheadAnalytics = function buildAndSendElementsTypeAh
|
|
|
192
192
|
return !!m;
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
|
-
var payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, agentAnalytics);
|
|
195
|
+
var payload = buildTypeAheadRenderedPayload(duration, userOrTeamIds, query, teams, xProductMentionsLength, mentionTypeaheadSessionId, agentAnalytics);
|
|
196
196
|
fireEvent(payload, 'fabric-elements');
|
|
197
197
|
};
|
|
198
198
|
};
|
|
@@ -277,22 +277,22 @@ var makeTransformMentionsToTypeAheadItems = function makeTransformMentionsToType
|
|
|
277
277
|
var mentionItems = mentions.map(function (mention) {
|
|
278
278
|
return toItem(mention);
|
|
279
279
|
});
|
|
280
|
-
var agentCount = mentions.filter(isAgentMention).length;
|
|
281
|
-
var agentAnalytics = {
|
|
282
|
-
agentCount: agentCount,
|
|
283
|
-
agentSectioningEnabled: enableAgentSectioning
|
|
284
|
-
};
|
|
285
|
-
|
|
286
280
|
// The loading placeholder is a rendered-only row — keep it in
|
|
287
281
|
// `mentionItems` so the shimmer shows, but exclude it from analytics
|
|
288
282
|
// and no-results bookkeeping so it isn't counted as a real result.
|
|
289
283
|
var realMentions = mentions.filter(function (mention) {
|
|
290
284
|
return !isLoadingPlaceholder(mention);
|
|
291
285
|
});
|
|
286
|
+
var agentCount = realMentions.filter(isAgentMention).length;
|
|
287
|
+
var agentAnalytics = {
|
|
288
|
+
agentCount: agentCount,
|
|
289
|
+
agentSectioningEnabled: enableAgentSectioning
|
|
290
|
+
};
|
|
292
291
|
buildAndSendElementsTypeAheadAnalytics(fireEvent)({
|
|
293
292
|
query: query,
|
|
294
293
|
mentions: realMentions,
|
|
295
294
|
stats: stats,
|
|
295
|
+
mentionTypeaheadSessionId: sessionId,
|
|
296
296
|
agentAnalytics: agentAnalytics
|
|
297
297
|
});
|
|
298
298
|
|
|
@@ -481,10 +481,10 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
|
|
|
481
481
|
// Don't fire event and the callback with selection by space press
|
|
482
482
|
if (mode !== 'space') {
|
|
483
483
|
var _mentionProvider$getS3, _mentionProvider$getS4;
|
|
484
|
-
fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('
|
|
484
|
+
fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('inline_invite_from_mentions_kill_switch') ? {
|
|
485
485
|
isInlineInviteMentionsEnabled: (_mentionProvider$getS3 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS3 === void 0 ? void 0 : _mentionProvider$getS3.call(mentionProvider)
|
|
486
486
|
} : {}));
|
|
487
|
-
if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('
|
|
487
|
+
if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('inline_invite_from_mentions_kill_switch')) {
|
|
488
488
|
// Get the email from query, using the same logic as InviteItemWithEmailDomain
|
|
489
489
|
var emailDomain = mentionProvider.userEmailDomain;
|
|
490
490
|
var email = query || '';
|
|
@@ -493,13 +493,21 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref8) {
|
|
|
493
493
|
email = "".concat(email.toLowerCase(), "@").concat(emailDomain);
|
|
494
494
|
}
|
|
495
495
|
// If query already includes @, use it as is
|
|
496
|
-
if (email && mentionProvider.
|
|
497
|
-
|
|
498
|
-
var _tr =
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
496
|
+
if (email && mentionProvider.showInlineInvitePopup) {
|
|
497
|
+
var pendingLocalId = crypto.randomUUID();
|
|
498
|
+
var _tr = insert(createSingleMentionFragment({
|
|
499
|
+
mentionProvider: mentionProvider,
|
|
500
|
+
mentionInsertDisplayName: mentionInsertDisplayName,
|
|
501
|
+
tr: state.tr,
|
|
502
|
+
sanitizePrivateContent: sanitizePrivateContent
|
|
503
|
+
})({
|
|
504
|
+
name: email,
|
|
505
|
+
id: pendingLocalId,
|
|
506
|
+
userType: 'DEFAULT',
|
|
507
|
+
localId: pendingLocalId,
|
|
508
|
+
accessLevel: 'CONTAINER'
|
|
509
|
+
}));
|
|
510
|
+
mentionProvider.showInlineInvitePopup(email, pendingLocalId);
|
|
503
511
|
return _tr;
|
|
504
512
|
}
|
|
505
513
|
} else if (mentionProvider.onInviteItemClick) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export type AnchoredPopupProps = {
|
|
3
|
+
anchorElement: HTMLElement | null;
|
|
4
|
+
content: ReactNode;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* A `<Popup>` anchored to an externally-supplied DOM node. Unlike `PopupTrigger`, it has no
|
|
10
|
+
* clickable trigger of its own — it opens whenever `isOpen` becomes true, so callers can drive
|
|
11
|
+
* it from any external signal.
|
|
12
|
+
*/
|
|
13
|
+
export declare function AnchoredPopup({ anchorElement, content, isOpen, onClose, }: AnchoredPopupProps): JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import type { MentionProvider } from '@atlaskit/mention/resource';
|
|
4
|
+
import type { MentionsPlugin } from '../mentionsPluginType';
|
|
5
|
+
interface Props {
|
|
6
|
+
api: ExtractInjectionAPI<MentionsPlugin> | undefined;
|
|
7
|
+
editorView: EditorView;
|
|
8
|
+
mentionProvider: Promise<MentionProvider> | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare const InlineInvitePopupContainer: ({ mentionProvider, api, editorView, }: Props) => JSX.Element | null;
|
|
11
|
+
export {};
|
|
@@ -9,7 +9,7 @@ export declare const buildTypeAheadCancelPayload: (duration: number, upKeyCount:
|
|
|
9
9
|
export declare const buildTypeAheadInviteItemViewedPayload: (sessionId: string, contextIdentifierProvider?: ContextIdentifierProvider, userRole?: UserRole, additionalAttributes?: Record<string, unknown>) => AnalyticsEventPayload;
|
|
10
10
|
export declare const buildTypeAheadInviteItemClickedPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, insertType: SelectItemMode, query?: string, contextIdentifierProvider?: ContextIdentifierProvider, userRole?: UserRole, additionalAttributes?: Record<string, unknown>) => AnalyticsEventPayload;
|
|
11
11
|
export declare const buildTypeAheadInsertedPayload: (duration: number, upKeyCount: number, downKeyCount: number, sessionId: string, insertType: SelectItemMode, mention: MentionDescription, mentionLocalId: string, mentionList?: MentionDescription[], query?: string, contextIdentifierProvider?: ContextIdentifierProvider, taskListId?: string, taskItemId?: string, isAgent?: boolean, agentSectioningEnabled?: boolean) => AnalyticsEventPayload;
|
|
12
|
-
export declare const buildTypeAheadRenderedPayload: (duration: number, userIds: Array<string> | null, query: string, teams: TeamInfoAttrAnalytics[] | null, xProductMentionsLength: number, agentAnalytics?: {
|
|
12
|
+
export declare const buildTypeAheadRenderedPayload: (duration: number, userIds: Array<string> | null, query: string, teams: TeamInfoAttrAnalytics[] | null, xProductMentionsLength: number, mentionTypeaheadSessionId: string, agentAnalytics?: {
|
|
13
13
|
agentCount: number;
|
|
14
14
|
agentSectioningEnabled: boolean;
|
|
15
15
|
}) => AnalyticsEventPayload;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-mentions",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.1.1",
|
|
4
4
|
"description": "Mentions plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -34,17 +34,18 @@
|
|
|
34
34
|
"@atlaskit/insm": "^1.2.0",
|
|
35
35
|
"@atlaskit/link": "^5.0.0",
|
|
36
36
|
"@atlaskit/lozenge": "^15.0.0",
|
|
37
|
-
"@atlaskit/mention": "^27.
|
|
37
|
+
"@atlaskit/mention": "^27.15.0",
|
|
38
38
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
39
39
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
40
40
|
"@atlaskit/popper": "^9.1.0",
|
|
41
|
+
"@atlaskit/popup": "^6.0.0",
|
|
41
42
|
"@atlaskit/portal": "^6.2.0",
|
|
42
43
|
"@atlaskit/primitives": "^22.2.0",
|
|
43
44
|
"@atlaskit/profilecard": "^26.16.0",
|
|
44
45
|
"@atlaskit/teams-app-config": "^2.2.0",
|
|
45
46
|
"@atlaskit/theme": "^28.0.0",
|
|
46
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
47
|
-
"@atlaskit/tokens": "^16.
|
|
47
|
+
"@atlaskit/tmp-editor-statsig": "^145.0.0",
|
|
48
|
+
"@atlaskit/tokens": "^16.5.0",
|
|
48
49
|
"@atlaskit/tooltip": "^24.0.0",
|
|
49
50
|
"@atlaskit/user-picker": "^13.8.0",
|
|
50
51
|
"@babel/runtime": "^7.0.0",
|
|
@@ -55,12 +56,14 @@
|
|
|
55
56
|
"uuid": "^3.1.0"
|
|
56
57
|
},
|
|
57
58
|
"peerDependencies": {
|
|
58
|
-
"@atlaskit/editor-common": "^118.
|
|
59
|
+
"@atlaskit/editor-common": "^118.3.0",
|
|
59
60
|
"react": "^18.2.0 || ^19.2.0",
|
|
60
61
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
61
62
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
65
|
+
"@atlaskit/button": "^25.0.0",
|
|
66
|
+
"@atlaskit/editor-core": "^223.0.0",
|
|
64
67
|
"@testing-library/react": "^16.3.0",
|
|
65
68
|
"react": "^19.2.0",
|
|
66
69
|
"react-dom": "^19.2.0",
|
|
@@ -117,6 +120,9 @@
|
|
|
117
120
|
"jira_invites_auto_tag_new_user_in_mentions_fg": {
|
|
118
121
|
"type": "boolean"
|
|
119
122
|
},
|
|
123
|
+
"inline_invite_from_mentions_kill_switch": {
|
|
124
|
+
"type": "boolean"
|
|
125
|
+
},
|
|
120
126
|
"people-teams_migrate-user-profile-card": {
|
|
121
127
|
"type": "boolean"
|
|
122
128
|
},
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.MENTION_PLACEHOLDER_ACTIONS = void 0;
|
|
7
|
-
exports.createMentionPlaceholderPlugin = createMentionPlaceholderPlugin;
|
|
8
|
-
exports.mentionPlaceholderPluginKey = void 0;
|
|
9
|
-
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
10
|
-
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
11
|
-
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
12
|
-
var mentionPlaceholderPluginKey = exports.mentionPlaceholderPluginKey = new _state.PluginKey('mentionPlaceholderPlugin');
|
|
13
|
-
var MENTION_PLACEHOLDER_ACTIONS = exports.MENTION_PLACEHOLDER_ACTIONS = {
|
|
14
|
-
SHOW_PLACEHOLDER: 'SHOW_PLACEHOLDER',
|
|
15
|
-
HIDE_PLACEHOLDER: 'HIDE_PLACEHOLDER'
|
|
16
|
-
};
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
18
|
-
function createMentionPlaceholderPlugin() {
|
|
19
|
-
return new _safePlugin.SafePlugin({
|
|
20
|
-
key: mentionPlaceholderPluginKey,
|
|
21
|
-
state: {
|
|
22
|
-
init: function init() {
|
|
23
|
-
return {};
|
|
24
|
-
},
|
|
25
|
-
apply: function apply(tr, pluginState) {
|
|
26
|
-
var meta = tr.getMeta(mentionPlaceholderPluginKey);
|
|
27
|
-
if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.SHOW_PLACEHOLDER) {
|
|
28
|
-
return {
|
|
29
|
-
placeholder: meta.placeholder
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER) {
|
|
33
|
-
return {};
|
|
34
|
-
}
|
|
35
|
-
return pluginState;
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
props: {
|
|
39
|
-
decorations: function decorations(state) {
|
|
40
|
-
var pluginState = mentionPlaceholderPluginKey.getState(state);
|
|
41
|
-
if (pluginState !== null && pluginState !== void 0 && pluginState.placeholder) {
|
|
42
|
-
var selection = state.selection;
|
|
43
|
-
var span = document.createElement('span');
|
|
44
|
-
span.textContent = pluginState.placeholder;
|
|
45
|
-
span.style.setProperty('color', "var(--ds-text-accent-blue, #1558BC)");
|
|
46
|
-
return _view.DecorationSet.create(state.doc, [_view.Decoration.widget(selection.from, span)]);
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|