@atlaskit/editor-plugin-mentions 15.2.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/editor-plugin-mentions
2
2
 
3
+ ## 16.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
3
9
  ## 15.2.0
4
10
 
5
11
  ### Minor Changes
@@ -27,7 +27,8 @@ var _mentionNodeSpec = require("./nodeviews/mentionNodeSpec");
27
27
  var _agent = require("./pm-plugins/agent");
28
28
  var _key = require("./pm-plugins/key");
29
29
  var _main = require("./pm-plugins/main");
30
- var _InlineInvitePopupContainer = require("./ui/InlineInvitePopupContainer");
30
+ var _mentionPlaceholder = require("./pm-plugins/mentionPlaceholder");
31
+ var _InlineInviteRecaptchaContainer = require("./ui/InlineInviteRecaptchaContainer");
31
32
  var _SecondaryToolbarComponent = require("./ui/SecondaryToolbarComponent");
32
33
  var _typeAhead = require("./ui/type-ahead");
33
34
  var _excluded2 = ["pendingPastedAgentMention"]; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -144,6 +145,14 @@ var mentionsPlugin = exports.mentionsPlugin = function mentionsPlugin(_ref3) {
144
145
  }
145
146
  });
146
147
  }
148
+ if ((0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg')) {
149
+ plugins.push({
150
+ name: 'mentionPlaceholder',
151
+ plugin: function plugin() {
152
+ return (0, _mentionPlaceholder.createMentionPlaceholderPlugin)();
153
+ }
154
+ });
155
+ }
147
156
  return plugins;
148
157
  },
149
158
  contentComponent: function contentComponent(_ref4) {
@@ -164,10 +173,9 @@ var mentionsPlugin = exports.mentionsPlugin = function mentionsPlugin(_ref3) {
164
173
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(Component, {
165
174
  mentionProvider: mentionProvider,
166
175
  api: api
167
- }), (0, _platformFeatureFlags.fg)('inline_invite_from_mentions_kill_switch') && /*#__PURE__*/_react.default.createElement(_InlineInvitePopupContainer.InlineInvitePopupContainer, {
176
+ }), (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') && /*#__PURE__*/_react.default.createElement(_InlineInviteRecaptchaContainer.InlineInviteRecaptchaContainer, {
168
177
  mentionProvider: mentionProvider,
169
- api: api,
170
- editorView: editorView
178
+ api: api
171
179
  }));
172
180
  }
173
181
  });
@@ -67,7 +67,7 @@ var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
67
67
  var AGENT_MENTION_INACTIVITY_MS = 3000;
68
68
  var MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
69
69
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
70
- var PACKAGE_VERSION = "15.1.1";
70
+ var PACKAGE_VERSION = "15.2.0";
71
71
  var setProvider = function setProvider(provider) {
72
72
  return function (state, dispatch) {
73
73
  if (dispatch) {
@@ -0,0 +1,52 @@
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
+ }
@@ -0,0 +1,100 @@
1
+ /* InlineInviteRecaptchaContainer.tsx generated by @compiled/babel-plugin v2.0.0 */
2
+ "use strict";
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.InlineInviteRecaptchaContainer = void 0;
10
+ var _runtime = require("@compiled/react/runtime");
11
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
+ var _react = _interopRequireWildcard(require("react"));
13
+ var _mentionPlaceholder = require("../pm-plugins/mentionPlaceholder");
14
+ var _analytics = require("../ui/type-ahead/analytics");
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
16
+ /**
17
+ * Container that renders the recaptcha component from the mention provider and manages handleSuccess.
18
+ * Does NOT pass email - the provider's component uses useInlineInviteRecaptcha hook internally
19
+ * and wires showRecaptcha to the provider. When user clicks invite item, type-ahead calls
20
+ * mentionProvider.showInlineInviteRecaptcha(email) which passes email to the component.
21
+ */
22
+ var InlineInviteRecaptchaContainer = exports.InlineInviteRecaptchaContainer = function InlineInviteRecaptchaContainer(_ref) {
23
+ var _api$mention2, _api$core3;
24
+ var mentionProvider = _ref.mentionProvider,
25
+ api = _ref.api;
26
+ var _useState = (0, _react.useState)(null),
27
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
28
+ provider = _useState2[0],
29
+ setProvider = _useState2[1];
30
+ (0, _react.useEffect)(function () {
31
+ if (!mentionProvider) {
32
+ return;
33
+ }
34
+ var isMounted = true;
35
+ mentionProvider.then(function (resolvedProvider) {
36
+ if (!isMounted) {
37
+ return;
38
+ }
39
+ setProvider(resolvedProvider);
40
+ }).catch(function () {
41
+ // Silently handle promise rejection
42
+ });
43
+ return function () {
44
+ isMounted = false;
45
+ setProvider(null);
46
+ };
47
+ }, [mentionProvider]);
48
+ var handleSuccess = (0, _react.useCallback)(function (userId, email) {
49
+ var _api$mention, _api$core;
50
+ if (!(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) || !(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)) {
51
+ return;
52
+ }
53
+ var name = email.split('@')[0] || email;
54
+ api.core.actions.execute(api.mention.commands.insertMention({
55
+ id: userId,
56
+ name: name,
57
+ userType: 'DEFAULT',
58
+ accessLevel: 'CONTAINER'
59
+ }));
60
+ api.core.actions.execute(function (_ref2) {
61
+ var tr = _ref2.tr;
62
+ tr.setMeta(_mentionPlaceholder.mentionPlaceholderPluginKey, {
63
+ action: _mentionPlaceholder.MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER
64
+ });
65
+ return tr;
66
+ });
67
+ }, [api]);
68
+ var handleClose = (0, _react.useCallback)(function () {
69
+ var _api$core2;
70
+ if (!(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)) {
71
+ return;
72
+ }
73
+ api.core.actions.execute(function (_ref3) {
74
+ var tr = _ref3.tr;
75
+ tr.setMeta(_mentionPlaceholder.mentionPlaceholderPluginKey, {
76
+ action: _mentionPlaceholder.MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER
77
+ });
78
+ return tr;
79
+ });
80
+ }, [api]);
81
+ var handleReady = (0, _react.useCallback)(function (showRecaptcha) {
82
+ if (provider) {
83
+ if (showRecaptcha) {
84
+ provider.showInlineInviteRecaptcha = showRecaptcha;
85
+ } else {
86
+ delete provider.showInlineInviteRecaptcha;
87
+ }
88
+ }
89
+ }, [provider]);
90
+ if (!(provider !== null && provider !== void 0 && provider.InlineInviteRecaptcha) || !(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)) {
91
+ return null;
92
+ }
93
+ var RecaptchaComponent = provider.InlineInviteRecaptcha;
94
+ return /*#__PURE__*/_react.default.createElement(RecaptchaComponent, {
95
+ analyticsSource: _analytics.MENTION_SOURCE,
96
+ onSuccess: handleSuccess,
97
+ onClose: handleClose,
98
+ onReady: handleReady
99
+ });
100
+ };
@@ -26,6 +26,7 @@ var _expVal = require("@atlaskit/tmp-editor-statsig/expVal");
26
26
  var _editorCommands = require("../../editor-commands");
27
27
  var _key = require("../../pm-plugins/key");
28
28
  var _main = require("../../pm-plugins/main");
29
+ var _mentionPlaceholder = require("../../pm-plugins/mentionPlaceholder");
29
30
  var _utils2 = require("../../pm-plugins/utils");
30
31
  var _InviteItem = _interopRequireWildcard(require("../InviteItem"));
31
32
  var _InviteItemWithEmailDomain = _interopRequireDefault(require("../InviteItem/InviteItemWithEmailDomain"));
@@ -66,7 +67,7 @@ var createInviteItem = function createInviteItem(_ref) {
66
67
  var isSelected = _ref2.isSelected,
67
68
  onClick = _ref2.onClick,
68
69
  onHover = _ref2.onHover;
69
- return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && (0, _platformFeatureFlags.fg)('inline_invite_from_mentions_kill_switch') ? /*#__PURE__*/_react.default.createElement(_InviteItemWithEmailDomain.default, {
70
+ return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') ? /*#__PURE__*/_react.default.createElement(_InviteItemWithEmailDomain.default, {
70
71
  productName: mentionProvider ? mentionProvider.productName : undefined,
71
72
  selected: isSelected,
72
73
  onMount: onInviteItemMount,
@@ -489,10 +490,10 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
489
490
  // Don't fire event and the callback with selection by space press
490
491
  if (mode !== 'space') {
491
492
  var _mentionProvider$getS3, _mentionProvider$getS4;
492
- fireEvent((0, _analytics.buildTypeAheadInviteItemClickedPayload)(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, (0, _platformFeatureFlags.fg)('inline_invite_from_mentions_kill_switch') ? {
493
+ fireEvent((0, _analytics.buildTypeAheadInviteItemClickedPayload)(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
493
494
  isInlineInviteMentionsEnabled: (_mentionProvider$getS3 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS3 === void 0 ? void 0 : _mentionProvider$getS3.call(mentionProvider)
494
495
  } : {}));
495
- if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && (0, _platformFeatureFlags.fg)('inline_invite_from_mentions_kill_switch')) {
496
+ if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && (0, _platformFeatureFlags.fg)('jira_invites_auto_tag_new_user_in_mentions_fg')) {
496
497
  // Get the email from query, using the same logic as InviteItemWithEmailDomain
497
498
  var emailDomain = mentionProvider.userEmailDomain;
498
499
  var email = query || '';
@@ -501,23 +502,13 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
501
502
  email = "".concat(email.toLowerCase(), "@").concat(emailDomain);
502
503
  }
503
504
  // If query already includes @, use it as is
504
- if (email && mentionProvider.showInlineInvitePopup) {
505
- // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
506
- var pendingLocalId = (0, _uuid.default)();
507
- var pendingName = email.split('@')[0] || email;
508
- var _tr = insert((0, _editorCommands.createSingleMentionFragment)({
509
- mentionProvider: mentionProvider,
510
- mentionInsertDisplayName: mentionInsertDisplayName,
511
- tr: state.tr,
512
- sanitizePrivateContent: sanitizePrivateContent
513
- })({
514
- name: pendingName,
515
- id: pendingLocalId,
516
- userType: 'DEFAULT',
517
- localId: pendingLocalId,
518
- accessLevel: 'CONTAINER'
519
- }));
520
- mentionProvider.showInlineInvitePopup(email, pendingLocalId);
505
+ if (email && mentionProvider.showInlineInviteRecaptcha) {
506
+ mentionProvider.showInlineInviteRecaptcha(email);
507
+ var _tr = state.tr;
508
+ _tr.setMeta(_mentionPlaceholder.mentionPlaceholderPluginKey, {
509
+ action: _mentionPlaceholder.MENTION_PLACEHOLDER_ACTIONS.SHOW_PLACEHOLDER,
510
+ placeholder: "@".concat(query)
511
+ });
521
512
  return _tr;
522
513
  }
523
514
  } else if (mentionProvider.onInviteItemClick) {
@@ -16,7 +16,8 @@ import { mentionNodeSpec } from './nodeviews/mentionNodeSpec';
16
16
  import { agentMentionPluginKey, createAgentMentionPlugin } from './pm-plugins/agent';
17
17
  import { mentionPluginKey } from './pm-plugins/key';
18
18
  import { ACTIONS, createMentionPlugin } from './pm-plugins/main';
19
- import { InlineInvitePopupContainer } from './ui/InlineInvitePopupContainer';
19
+ import { createMentionPlaceholderPlugin } from './pm-plugins/mentionPlaceholder';
20
+ import { InlineInviteRecaptchaContainer } from './ui/InlineInviteRecaptchaContainer';
20
21
  import { SecondaryToolbarComponent } from './ui/SecondaryToolbarComponent';
21
22
  import { createTypeAheadConfig } from './ui/type-ahead';
22
23
  const processName = (name, intl) => {
@@ -136,6 +137,12 @@ const mentionsPlugin = ({
136
137
  })
137
138
  });
138
139
  }
140
+ if (fg('jira_invites_auto_tag_new_user_in_mentions_fg')) {
141
+ plugins.push({
142
+ name: 'mentionPlaceholder',
143
+ plugin: () => createMentionPlaceholderPlugin()
144
+ });
145
+ }
139
146
  return plugins;
140
147
  },
141
148
  contentComponent({
@@ -158,10 +165,9 @@ const mentionsPlugin = ({
158
165
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Component, {
159
166
  mentionProvider: mentionProvider,
160
167
  api: api
161
- }), fg('inline_invite_from_mentions_kill_switch') && /*#__PURE__*/React.createElement(InlineInvitePopupContainer, {
168
+ }), fg('jira_invites_auto_tag_new_user_in_mentions_fg') && /*#__PURE__*/React.createElement(InlineInviteRecaptchaContainer, {
162
169
  mentionProvider: mentionProvider,
163
- api: api,
164
- editorView: editorView
170
+ api: api
165
171
  }));
166
172
  }
167
173
  });
@@ -51,7 +51,7 @@ const AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
51
51
  const AGENT_MENTION_INACTIVITY_MS = 3000;
52
52
  const MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
53
53
  const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
54
- const PACKAGE_VERSION = "15.1.1";
54
+ const PACKAGE_VERSION = "15.2.0";
55
55
  const setProvider = provider => (state, dispatch) => {
56
56
  if (dispatch) {
57
57
  dispatch(state.tr.setMeta(mentionPluginKey, {
@@ -0,0 +1,44 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
+ export const mentionPlaceholderPluginKey = new PluginKey('mentionPlaceholderPlugin');
5
+ export const MENTION_PLACEHOLDER_ACTIONS = {
6
+ SHOW_PLACEHOLDER: 'SHOW_PLACEHOLDER',
7
+ HIDE_PLACEHOLDER: 'HIDE_PLACEHOLDER'
8
+ };
9
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
10
+ export function createMentionPlaceholderPlugin() {
11
+ return new SafePlugin({
12
+ key: mentionPlaceholderPluginKey,
13
+ state: {
14
+ init: () => ({}),
15
+ apply(tr, pluginState) {
16
+ const meta = tr.getMeta(mentionPlaceholderPluginKey);
17
+ if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.SHOW_PLACEHOLDER) {
18
+ return {
19
+ placeholder: meta.placeholder
20
+ };
21
+ }
22
+ if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER) {
23
+ return {};
24
+ }
25
+ return pluginState;
26
+ }
27
+ },
28
+ props: {
29
+ decorations: state => {
30
+ const pluginState = mentionPlaceholderPluginKey.getState(state);
31
+ if (pluginState !== null && pluginState !== void 0 && pluginState.placeholder) {
32
+ const {
33
+ selection
34
+ } = state;
35
+ const span = document.createElement('span');
36
+ span.textContent = pluginState.placeholder;
37
+ span.style.setProperty('color', "var(--ds-text-accent-blue, #1558BC)");
38
+ return DecorationSet.create(state.doc, [Decoration.widget(selection.from, span)]);
39
+ }
40
+ return null;
41
+ }
42
+ }
43
+ });
44
+ }
@@ -0,0 +1,90 @@
1
+ /* InlineInviteRecaptchaContainer.tsx generated by @compiled/babel-plugin v2.0.0 */
2
+ import { ax, ix } from "@compiled/react/runtime";
3
+ import React, { useCallback, useEffect, useState } from 'react';
4
+ import { mentionPlaceholderPluginKey, MENTION_PLACEHOLDER_ACTIONS } from '../pm-plugins/mentionPlaceholder';
5
+ import { MENTION_SOURCE } from '../ui/type-ahead/analytics';
6
+ /**
7
+ * Container that renders the recaptcha component from the mention provider and manages handleSuccess.
8
+ * Does NOT pass email - the provider's component uses useInlineInviteRecaptcha hook internally
9
+ * and wires showRecaptcha to the provider. When user clicks invite item, type-ahead calls
10
+ * mentionProvider.showInlineInviteRecaptcha(email) which passes email to the component.
11
+ */
12
+ export const InlineInviteRecaptchaContainer = ({
13
+ mentionProvider,
14
+ api
15
+ }) => {
16
+ var _api$mention2, _api$mention2$command, _api$core3, _api$core3$actions;
17
+ const [provider, setProvider] = useState(null);
18
+ useEffect(() => {
19
+ if (!mentionProvider) {
20
+ return;
21
+ }
22
+ let isMounted = true;
23
+ mentionProvider.then(resolvedProvider => {
24
+ if (!isMounted) {
25
+ return;
26
+ }
27
+ setProvider(resolvedProvider);
28
+ }).catch(() => {
29
+ // Silently handle promise rejection
30
+ });
31
+ return () => {
32
+ isMounted = false;
33
+ setProvider(null);
34
+ };
35
+ }, [mentionProvider]);
36
+ const handleSuccess = useCallback((userId, email) => {
37
+ var _api$mention, _api$mention$commands, _api$core, _api$core$actions;
38
+ if (!(api !== null && api !== void 0 && (_api$mention = api.mention) !== null && _api$mention !== void 0 && (_api$mention$commands = _api$mention.commands) !== null && _api$mention$commands !== void 0 && _api$mention$commands.insertMention) || !(api !== null && api !== void 0 && (_api$core = api.core) !== null && _api$core !== void 0 && (_api$core$actions = _api$core.actions) !== null && _api$core$actions !== void 0 && _api$core$actions.execute)) {
39
+ return;
40
+ }
41
+ const name = email.split('@')[0] || email;
42
+ api.core.actions.execute(api.mention.commands.insertMention({
43
+ id: userId,
44
+ name,
45
+ userType: 'DEFAULT',
46
+ accessLevel: 'CONTAINER'
47
+ }));
48
+ api.core.actions.execute(({
49
+ tr
50
+ }) => {
51
+ tr.setMeta(mentionPlaceholderPluginKey, {
52
+ action: MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER
53
+ });
54
+ return tr;
55
+ });
56
+ }, [api]);
57
+ const handleClose = useCallback(() => {
58
+ var _api$core2, _api$core2$actions;
59
+ if (!(api !== null && api !== void 0 && (_api$core2 = api.core) !== null && _api$core2 !== void 0 && (_api$core2$actions = _api$core2.actions) !== null && _api$core2$actions !== void 0 && _api$core2$actions.execute)) {
60
+ return;
61
+ }
62
+ api.core.actions.execute(({
63
+ tr
64
+ }) => {
65
+ tr.setMeta(mentionPlaceholderPluginKey, {
66
+ action: MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER
67
+ });
68
+ return tr;
69
+ });
70
+ }, [api]);
71
+ const handleReady = useCallback(showRecaptcha => {
72
+ if (provider) {
73
+ if (showRecaptcha) {
74
+ provider.showInlineInviteRecaptcha = showRecaptcha;
75
+ } else {
76
+ delete provider.showInlineInviteRecaptcha;
77
+ }
78
+ }
79
+ }, [provider]);
80
+ if (!(provider !== null && provider !== void 0 && provider.InlineInviteRecaptcha) || !(api !== null && api !== void 0 && (_api$mention2 = api.mention) !== null && _api$mention2 !== void 0 && (_api$mention2$command = _api$mention2.commands) !== null && _api$mention2$command !== void 0 && _api$mention2$command.insertMention) || !(api !== null && api !== void 0 && (_api$core3 = api.core) !== null && _api$core3 !== void 0 && (_api$core3$actions = _api$core3.actions) !== null && _api$core3$actions !== void 0 && _api$core3$actions.execute)) {
81
+ return null;
82
+ }
83
+ const RecaptchaComponent = provider.InlineInviteRecaptcha;
84
+ return /*#__PURE__*/React.createElement(RecaptchaComponent, {
85
+ analyticsSource: MENTION_SOURCE,
86
+ onSuccess: handleSuccess,
87
+ onClose: handleClose,
88
+ onReady: handleReady
89
+ });
90
+ };
@@ -16,6 +16,7 @@ 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';
19
20
  import { getMentionPluginState } from '../../pm-plugins/utils';
20
21
  import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
21
22
  import InviteItemWithEmailDomain from '../InviteItem/InviteItemWithEmailDomain';
@@ -43,7 +44,7 @@ const createInviteItem = ({
43
44
  onHover
44
45
  }) => {
45
46
  var _mentionProvider$getS;
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, {
47
+ return emailDomain && (_mentionProvider$getS = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS !== void 0 && _mentionProvider$getS.call(mentionProvider) && fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? /*#__PURE__*/React.createElement(InviteItemWithEmailDomain, {
47
48
  productName: mentionProvider ? mentionProvider.productName : undefined,
48
49
  selected: isSelected,
49
50
  onMount: onInviteItemMount,
@@ -459,10 +460,10 @@ export const createTypeAheadConfig = ({
459
460
  // Don't fire event and the callback with selection by space press
460
461
  if (mode !== 'space') {
461
462
  var _mentionProvider$getS3, _mentionProvider$getS4;
462
- fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('inline_invite_from_mentions_kill_switch') ? {
463
+ fireEvent(buildTypeAheadInviteItemClickedPayload(pickerElapsedTime, stats.keyCount.arrowUp, stats.keyCount.arrowDown, sessionId, mode, query, contextIdentifierProvider, mentionProvider.userRole, fg('jira_invites_auto_tag_new_user_in_mentions_fg') ? {
463
464
  isInlineInviteMentionsEnabled: (_mentionProvider$getS3 = mentionProvider.getShouldEnableInlineInvite) === null || _mentionProvider$getS3 === void 0 ? void 0 : _mentionProvider$getS3.call(mentionProvider)
464
465
  } : {}));
465
- if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('inline_invite_from_mentions_kill_switch')) {
466
+ if ((_mentionProvider$getS4 = mentionProvider.getShouldEnableInlineInvite) !== null && _mentionProvider$getS4 !== void 0 && _mentionProvider$getS4.call(mentionProvider) && fg('jira_invites_auto_tag_new_user_in_mentions_fg')) {
466
467
  // Get the email from query, using the same logic as InviteItemWithEmailDomain
467
468
  const emailDomain = mentionProvider.userEmailDomain;
468
469
  let email = query || '';
@@ -471,23 +472,15 @@ export const createTypeAheadConfig = ({
471
472
  email = `${email.toLowerCase()}@${emailDomain}`;
472
473
  }
473
474
  // If query already includes @, use it as is
474
- if (email && mentionProvider.showInlineInvitePopup) {
475
- // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
476
- const pendingLocalId = uuid();
477
- const pendingName = email.split('@')[0] || email;
478
- const tr = insert(createSingleMentionFragment({
479
- mentionProvider,
480
- mentionInsertDisplayName,
481
- tr: state.tr,
482
- sanitizePrivateContent
483
- })({
484
- name: pendingName,
485
- id: pendingLocalId,
486
- userType: 'DEFAULT',
487
- localId: pendingLocalId,
488
- accessLevel: 'CONTAINER'
489
- }));
490
- mentionProvider.showInlineInvitePopup(email, pendingLocalId);
475
+ if (email && mentionProvider.showInlineInviteRecaptcha) {
476
+ mentionProvider.showInlineInviteRecaptcha(email);
477
+ const {
478
+ tr
479
+ } = state;
480
+ tr.setMeta(mentionPlaceholderPluginKey, {
481
+ action: MENTION_PLACEHOLDER_ACTIONS.SHOW_PLACEHOLDER,
482
+ placeholder: `@${query}`
483
+ });
491
484
  return tr;
492
485
  }
493
486
  } else if (mentionProvider.onInviteItemClick) {
@@ -23,7 +23,8 @@ 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 { InlineInvitePopupContainer } from './ui/InlineInvitePopupContainer';
26
+ import { createMentionPlaceholderPlugin } from './pm-plugins/mentionPlaceholder';
27
+ import { InlineInviteRecaptchaContainer } from './ui/InlineInviteRecaptchaContainer';
27
28
  import { SecondaryToolbarComponent } from './ui/SecondaryToolbarComponent';
28
29
  import { createTypeAheadConfig } from './ui/type-ahead';
29
30
  var processName = function processName(name, intl) {
@@ -136,6 +137,14 @@ var mentionsPlugin = function mentionsPlugin(_ref3) {
136
137
  }
137
138
  });
138
139
  }
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
+ }
139
148
  return plugins;
140
149
  },
141
150
  contentComponent: function contentComponent(_ref4) {
@@ -156,10 +165,9 @@ var mentionsPlugin = function mentionsPlugin(_ref3) {
156
165
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Component, {
157
166
  mentionProvider: mentionProvider,
158
167
  api: api
159
- }), fg('inline_invite_from_mentions_kill_switch') && /*#__PURE__*/React.createElement(InlineInvitePopupContainer, {
168
+ }), fg('jira_invites_auto_tag_new_user_in_mentions_fg') && /*#__PURE__*/React.createElement(InlineInviteRecaptchaContainer, {
160
169
  mentionProvider: mentionProvider,
161
- api: api,
162
- editorView: editorView
170
+ api: api
163
171
  }));
164
172
  }
165
173
  });
@@ -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 = "15.1.1";
61
+ var PACKAGE_VERSION = "15.2.0";
62
62
  var setProvider = function setProvider(provider) {
63
63
  return function (state, dispatch) {
64
64
  if (dispatch) {
@@ -0,0 +1,44 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
+ export var mentionPlaceholderPluginKey = new PluginKey('mentionPlaceholderPlugin');
5
+ export var MENTION_PLACEHOLDER_ACTIONS = {
6
+ SHOW_PLACEHOLDER: 'SHOW_PLACEHOLDER',
7
+ HIDE_PLACEHOLDER: 'HIDE_PLACEHOLDER'
8
+ };
9
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
10
+ export function createMentionPlaceholderPlugin() {
11
+ return new SafePlugin({
12
+ key: mentionPlaceholderPluginKey,
13
+ state: {
14
+ init: function init() {
15
+ return {};
16
+ },
17
+ apply: function apply(tr, pluginState) {
18
+ var meta = tr.getMeta(mentionPlaceholderPluginKey);
19
+ if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.SHOW_PLACEHOLDER) {
20
+ return {
21
+ placeholder: meta.placeholder
22
+ };
23
+ }
24
+ if ((meta === null || meta === void 0 ? void 0 : meta.action) === MENTION_PLACEHOLDER_ACTIONS.HIDE_PLACEHOLDER) {
25
+ return {};
26
+ }
27
+ return pluginState;
28
+ }
29
+ },
30
+ props: {
31
+ decorations: function decorations(state) {
32
+ var pluginState = mentionPlaceholderPluginKey.getState(state);
33
+ if (pluginState !== null && pluginState !== void 0 && pluginState.placeholder) {
34
+ var selection = state.selection;
35
+ var span = document.createElement('span');
36
+ span.textContent = pluginState.placeholder;
37
+ span.style.setProperty('color', "var(--ds-text-accent-blue, #1558BC)");
38
+ return DecorationSet.create(state.doc, [Decoration.widget(selection.from, span)]);
39
+ }
40
+ return null;
41
+ }
42
+ }
43
+ });
44
+ }