@atlaskit/editor-plugin-mentions 9.0.2 → 9.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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-mentions
2
2
 
3
+ ## 9.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 9.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`16a4fadabeff7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/16a4fadabeff7) -
14
+ [ux] New invite CTA for mentions
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+
3
20
  ## 9.0.2
4
21
 
5
22
  ### Patch Changes
@@ -23,7 +23,7 @@ var ACTIONS = exports.ACTIONS = {
23
23
  SET_PROVIDER: 'SET_PROVIDER'
24
24
  };
25
25
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
26
- var PACKAGE_VERSION = "9.0.1";
26
+ var PACKAGE_VERSION = "9.1.0";
27
27
  var setProvider = function setProvider(provider) {
28
28
  return function (state, dispatch) {
29
29
  if (dispatch) {
@@ -0,0 +1,31 @@
1
+ ._16jlidpf{flex-grow:0}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m915vq{overflow-y:hidden}
4
+ ._18u0utpp{margin-left:var(--ds-space-150,9pt)}
5
+ ._19bvutpp{padding-left:var(--ds-space-150,9pt)}
6
+ ._19pkv77o{margin-top:var(--ds-space-025,2px)}
7
+ ._1bah1h6o{justify-content:center}
8
+ ._1bsb14no{width:36px}
9
+ ._1bto1l2s{text-overflow:ellipsis}
10
+ ._1e0c1txw{display:flex}
11
+ ._1e0c1ule{display:block}
12
+ ._1n261g80{flex-wrap:wrap}
13
+ ._1o9zkb7n{flex-shrink:1}
14
+ ._1p1d1dk0{text-transform:capitalize}
15
+ ._1reo15vq{overflow-x:hidden}
16
+ ._1ul9idpf{min-width:0}
17
+ ._2lx2vrvc{flex-direction:row}
18
+ ._2mzuglyw{list-style-type:none}
19
+ ._4cvr1h6o{align-items:center}
20
+ ._4t3i14no{height:36px}
21
+ ._80omtlke{cursor:pointer}
22
+ ._bfhk1j28{background-color:transparent}
23
+ ._bfhk2tgk{background-color:var(--_1y60f1n)}
24
+ ._ca0q12x7{padding-top:var(--ds-space-075,6px)}
25
+ ._i0dl1wug{flex-basis:auto}
26
+ ._i0dlf1ug{flex-basis:0%}
27
+ ._kqswh2mm{position:relative}
28
+ ._n3td12x7{padding-bottom:var(--ds-space-075,6px)}
29
+ ._s7n4nkob{vertical-align:middle}
30
+ ._syaz1n3s{color:var(--ds-text-subtle,#5e6c84)}
31
+ ._u5f3utpp{padding-right:var(--ds-space-150,9pt)}
@@ -0,0 +1,209 @@
1
+ /* InviteItemWithEmailDomain.tsx generated by @compiled/babel-plugin v0.38.1 */
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.default = exports.INVITE_ITEM_DESCRIPTION = void 0;
10
+ require("./InviteItemWithEmailDomain.compiled.css");
11
+ var _runtime = require("@compiled/react/runtime");
12
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
+ var _react = _interopRequireWildcard(require("react"));
15
+ var _reactIntlNext = require("react-intl-next");
16
+ var _messages = require("@atlaskit/editor-common/messages");
17
+ var _email = _interopRequireDefault(require("@atlaskit/icon/core/email"));
18
+ var _statusError = _interopRequireDefault(require("@atlaskit/icon/core/status-error"));
19
+ var _colors = require("@atlaskit/theme/colors");
20
+ var _userPicker = require("@atlaskit/user-picker");
21
+ 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); }
22
+ var mentionItemStyle = null;
23
+ var mentionItemSelectedStyle = null;
24
+ var style = {
25
+ byline: "_19pkv77o",
26
+ rowStyle: "_1reo15vq _18m915vq _4cvr1h6o _1e0c1txw _2lx2vrvc _1n261g80 _ca0q12x7 _n3td12x7 _19bvutpp _u5f3utpp _1bto1l2s _s7n4nkob",
27
+ avatar: "_16jlidpf _1o9zkb7n _i0dl1wug _1e0c1txw _4cvr1h6o _1bah1h6o _kqswh2mm _1bsb14no _4t3i14no",
28
+ nameSection: "_16jlkb7n _1o9zkb7n _i0dlf1ug _1ul9idpf _18u0utpp _syaz1n3s",
29
+ capitalize: "_1p1d1dk0"
30
+ };
31
+ var VALID_OPTION = 'VALID';
32
+ var POTENTIAL_OPTION = 'POTENTIAL';
33
+ // eslint-disable-next-line require-unicode-regexp
34
+ var COMPLETE_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
35
+ var ERROR_DELAY_MS = 750;
36
+ var getInviteOption = function getInviteOption(inputValue, suggestedEmailDomain) {
37
+ if (inputValue.includes(' ') && inputValue.includes('@')) {
38
+ return inputValue;
39
+ }
40
+ var isEmail = inputValue && [VALID_OPTION, POTENTIAL_OPTION].includes((0, _userPicker.isValidEmail)(inputValue));
41
+ if (isEmail || !suggestedEmailDomain) {
42
+ return inputValue;
43
+ }
44
+ return "".concat(inputValue.toLocaleLowerCase(), "@").concat(suggestedEmailDomain);
45
+ };
46
+ var getIsEmailValid = function getIsEmailValid(inputValue) {
47
+ if (!inputValue || inputValue.length === 0) {
48
+ return false;
49
+ }
50
+ if (inputValue.includes(' ')) {
51
+ return false;
52
+ }
53
+ if (inputValue.includes('@') && !COMPLETE_EMAIL_REGEX.test(inputValue)) {
54
+ return false;
55
+ }
56
+ return true;
57
+ };
58
+ var INVITE_ITEM_DESCRIPTION = exports.INVITE_ITEM_DESCRIPTION = {
59
+ id: 'invite-teammate'
60
+ };
61
+ var InviteItemWithEmailDomain = function InviteItemWithEmailDomain(_ref) {
62
+ var productName = _ref.productName,
63
+ onMount = _ref.onMount,
64
+ onMouseEnter = _ref.onMouseEnter,
65
+ onSelection = _ref.onSelection,
66
+ selected = _ref.selected,
67
+ userRole = _ref.userRole,
68
+ _ref$query = _ref.query,
69
+ query = _ref$query === void 0 ? '' : _ref$query,
70
+ emailDomain = _ref.emailDomain,
71
+ intl = _ref.intl;
72
+ var _useState = (0, _react.useState)(false),
73
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
74
+ showErrorIcon = _useState2[0],
75
+ setShowErrorIcon = _useState2[1];
76
+ var timeoutRef = (0, _react.useRef)();
77
+ var possibleEmail = getInviteOption(query, emailDomain);
78
+ var isEmailValid = getIsEmailValid(query);
79
+
80
+ // Use debounced error state for icon and byline display
81
+ var shouldShowError = !isEmailValid && showErrorIcon;
82
+ // Use debounced error state for byline: show invalid message only after delay
83
+ var isValidForByline = isEmailValid || !shouldShowError;
84
+ var getByline = function getByline() {
85
+ if (!isValidForByline) {
86
+ return intl.formatMessage(_messages.mentionMessages.inviteTeammateInvalidEmail);
87
+ }
88
+ if (userRole === 'admin') {
89
+ return /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage
90
+ // Ignored via go/ees005
91
+ // eslint-disable-next-line react/jsx-props-no-spreading
92
+ , (0, _extends2.default)({}, _messages.mentionMessages.inviteItemTitle, {
93
+ values: {
94
+ userRole: userRole || 'basic',
95
+ productName: /*#__PURE__*/_react.default.createElement("span", {
96
+ "data-testid": "capitalized-message",
97
+ className: (0, _runtime.ax)([style.capitalize])
98
+ }, productName)
99
+ }
100
+ }));
101
+ }
102
+ return intl.formatMessage(_messages.mentionMessages.sendInvite);
103
+ };
104
+ var onSelected = (0, _react.useCallback)(
105
+ // Ignored via go/ees005
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ function (event) {
108
+ if (onSelection) {
109
+ // For mouse events, only handle left click
110
+ if ('button' in event && event.button !== 0) {
111
+ return;
112
+ }
113
+ // For keyboard events, only handle Enter and Space
114
+ if ('key' in event && event.key !== 'Enter' && event.key !== ' ') {
115
+ return;
116
+ }
117
+ event.preventDefault();
118
+ onSelection(INVITE_ITEM_DESCRIPTION, event);
119
+ }
120
+ }, [onSelection]);
121
+ var onItemMouseEnter = (0, _react.useCallback)(
122
+ // Ignored via go/ees005
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ function (event) {
125
+ if (onMouseEnter) {
126
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
127
+ }
128
+ }, [onMouseEnter]);
129
+ var onItemFocus = (0, _react.useCallback)(
130
+ // Ignored via go/ees005
131
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
132
+ function (event) {
133
+ if (onMouseEnter) {
134
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
135
+ }
136
+ }, [onMouseEnter]);
137
+ (0, _react.useEffect)(function () {
138
+ if (onMount) {
139
+ onMount();
140
+ }
141
+ }, [onMount]);
142
+
143
+ // Debounce error icon display: only show error after user stops typing invalid input
144
+ (0, _react.useEffect)(function () {
145
+ // Clear existing timeout
146
+ if (timeoutRef.current) {
147
+ clearTimeout(timeoutRef.current);
148
+ timeoutRef.current = undefined;
149
+ }
150
+
151
+ // Reset error icon immediately if input becomes valid or empty
152
+ if (isEmailValid || query.length === 0) {
153
+ setShowErrorIcon(false);
154
+ } else {
155
+ // Debounce: only show error icon after delay if input remains invalid
156
+ timeoutRef.current = setTimeout(function () {
157
+ setShowErrorIcon(true);
158
+ }, ERROR_DELAY_MS);
159
+ }
160
+
161
+ // Cleanup timeout on unmount or when query changes
162
+ return function () {
163
+ if (timeoutRef.current) {
164
+ clearTimeout(timeoutRef.current);
165
+ }
166
+ };
167
+ }, [query, isEmailValid]);
168
+ var displayName = query && emailDomain ? possibleEmail : undefined;
169
+ return /*#__PURE__*/_react.default.createElement("div", {
170
+ role: "button",
171
+ tabIndex: 0,
172
+ onMouseDown: onSelected,
173
+ onKeyDown: onSelected,
174
+ onMouseEnter: onItemMouseEnter,
175
+ onFocus: onItemFocus,
176
+ "data-id": INVITE_ITEM_DESCRIPTION.id,
177
+ className: (0, _runtime.ax)(["_1reo15vq _18m915vq _bfhk1j28 _1e0c1ule _2mzuglyw _80omtlke", selected && "_bfhk2tgk"]),
178
+ style: {
179
+ "--_1y60f1n": (0, _runtime.ix)("var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N30, ")"))
180
+ }
181
+ }, /*#__PURE__*/_react.default.createElement("div", {
182
+ className: (0, _runtime.ax)([style.rowStyle])
183
+ }, /*#__PURE__*/_react.default.createElement("span", {
184
+ className: (0, _runtime.ax)([style.avatar])
185
+ }, shouldShowError ? /*#__PURE__*/_react.default.createElement(_statusError.default, {
186
+ label: "Error",
187
+ color: "var(--ds-icon-danger, #C9372C)"
188
+ }) : /*#__PURE__*/_react.default.createElement(_email.default, {
189
+ label: "Email",
190
+ color: "var(--ds-icon-subtle, ".concat(_colors.N300, ")")
191
+ })), /*#__PURE__*/_react.default.createElement("div", {
192
+ "data-testid": "name-section",
193
+ className: (0, _runtime.ax)([style.nameSection])
194
+ }, displayName ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", null, displayName), /*#__PURE__*/_react.default.createElement("div", {
195
+ className: (0, _runtime.ax)([style.byline])
196
+ }, getByline())) : /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage
197
+ // Ignored via go/ees005
198
+ // eslint-disable-next-line react/jsx-props-no-spreading
199
+ , (0, _extends2.default)({}, _messages.mentionMessages.inviteItemTitle, {
200
+ values: {
201
+ userRole: userRole || 'basic',
202
+ productName: /*#__PURE__*/_react.default.createElement("span", {
203
+ "data-testid": "capitalized-message",
204
+ className: (0, _runtime.ax)([style.capitalize])
205
+ }, productName)
206
+ }
207
+ })))));
208
+ };
209
+ var _default = exports.default = (0, _reactIntlNext.injectIntl)(InviteItemWithEmailDomain);
@@ -22,6 +22,7 @@ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
22
22
  var _editorCommands = require("../../editor-commands");
23
23
  var _utils2 = require("../../pm-plugins/utils");
24
24
  var _InviteItem = _interopRequireWildcard(require("../InviteItem"));
25
+ var _InviteItemWithEmailDomain = _interopRequireDefault(require("../InviteItem/InviteItemWithEmailDomain"));
25
26
  var _analytics = require("./analytics");
26
27
  var _utils3 = require("./utils");
27
28
  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); }
@@ -32,14 +33,26 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
32
33
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
33
34
  var createInviteItem = function createInviteItem(_ref) {
34
35
  var mentionProvider = _ref.mentionProvider,
35
- onInviteItemMount = _ref.onInviteItemMount;
36
+ onInviteItemMount = _ref.onInviteItemMount,
37
+ query = _ref.query,
38
+ emailDomain = _ref.emailDomain;
36
39
  return {
37
40
  title: _InviteItem.INVITE_ITEM_DESCRIPTION.id,
38
41
  render: function render(_ref2) {
42
+ var _mentionProvider$getS;
39
43
  var isSelected = _ref2.isSelected,
40
44
  onClick = _ref2.onClick,
41
45
  onHover = _ref2.onHover;
42
- return /*#__PURE__*/_react.default.createElement(_InviteItem.default, {
46
+ return (_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, {
47
+ productName: mentionProvider ? mentionProvider.productName : undefined,
48
+ selected: isSelected,
49
+ onMount: onInviteItemMount,
50
+ onMouseEnter: onHover,
51
+ onSelection: onClick,
52
+ userRole: mentionProvider.userRole,
53
+ query: query,
54
+ emailDomain: emailDomain
55
+ }) : /*#__PURE__*/_react.default.createElement(_InviteItem.default, {
43
56
  productName: mentionProvider ? mentionProvider.productName : undefined,
44
57
  selected: isSelected,
45
58
  onMount: onInviteItemMount,
@@ -55,11 +68,14 @@ var withInviteItem = function withInviteItem(_ref3) {
55
68
  var mentionProvider = _ref3.mentionProvider,
56
69
  firstQueryWithoutResults = _ref3.firstQueryWithoutResults,
57
70
  currentQuery = _ref3.currentQuery,
58
- onInviteItemMount = _ref3.onInviteItemMount;
71
+ onInviteItemMount = _ref3.onInviteItemMount,
72
+ emailDomain = _ref3.emailDomain;
59
73
  return function (mentionItems) {
60
74
  var inviteItem = createInviteItem({
61
75
  mentionProvider: mentionProvider,
62
- onInviteItemMount: onInviteItemMount
76
+ onInviteItemMount: onInviteItemMount,
77
+ query: currentQuery,
78
+ emailDomain: emailDomain
63
79
  });
64
80
  var keepInviteItem = (0, _utils3.shouldKeepInviteItem)(currentQuery, firstQueryWithoutResults);
65
81
  if (mentionItems.length === 0) {
@@ -225,7 +241,7 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
225
241
  // Custom regex must have a capture group around trigger
226
242
  // so it's possible to use it without needing to scan through all triggers again
227
243
  customRegex: '\\(?(@)',
228
- getHighlight: function getHighlight(state) {
244
+ getHighlight: function getHighlight(_state) {
229
245
  var CustomHighlightComponent = HighlightComponent;
230
246
  if (CustomHighlightComponent) {
231
247
  return /*#__PURE__*/_react.default.createElement(CustomHighlightComponent, null);
@@ -268,13 +284,15 @@ var createTypeAheadConfig = exports.createTypeAheadConfig = function createTypeA
268
284
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
269
285
  resolve(mentionItems);
270
286
  } else {
287
+ var emailDomain = mentionProvider.userEmailDomain;
271
288
  var items = withInviteItem({
272
289
  mentionProvider: mentionProvider,
273
290
  firstQueryWithoutResults: firstQueryWithoutResults || '',
274
291
  currentQuery: query,
275
292
  onInviteItemMount: function onInviteItemMount() {
276
293
  fireEvent((0, _analytics.buildTypeAheadInviteItemViewedPayload)(sessionId, contextIdentifierProvider, mentionProvider.userRole));
277
- }
294
+ },
295
+ emailDomain: emailDomain
278
296
  })(mentionItems);
279
297
  resolve(items);
280
298
  }
@@ -12,7 +12,7 @@ export const ACTIONS = {
12
12
  SET_PROVIDER: 'SET_PROVIDER'
13
13
  };
14
14
  const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
15
- const PACKAGE_VERSION = "9.0.1";
15
+ const PACKAGE_VERSION = "9.1.0";
16
16
  const setProvider = provider => (state, dispatch) => {
17
17
  if (dispatch) {
18
18
  dispatch(state.tr.setMeta(mentionPluginKey, {
@@ -0,0 +1,31 @@
1
+ ._16jlidpf{flex-grow:0}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m915vq{overflow-y:hidden}
4
+ ._18u0utpp{margin-left:var(--ds-space-150,9pt)}
5
+ ._19bvutpp{padding-left:var(--ds-space-150,9pt)}
6
+ ._19pkv77o{margin-top:var(--ds-space-025,2px)}
7
+ ._1bah1h6o{justify-content:center}
8
+ ._1bsb14no{width:36px}
9
+ ._1bto1l2s{text-overflow:ellipsis}
10
+ ._1e0c1txw{display:flex}
11
+ ._1e0c1ule{display:block}
12
+ ._1n261g80{flex-wrap:wrap}
13
+ ._1o9zkb7n{flex-shrink:1}
14
+ ._1p1d1dk0{text-transform:capitalize}
15
+ ._1reo15vq{overflow-x:hidden}
16
+ ._1ul9idpf{min-width:0}
17
+ ._2lx2vrvc{flex-direction:row}
18
+ ._2mzuglyw{list-style-type:none}
19
+ ._4cvr1h6o{align-items:center}
20
+ ._4t3i14no{height:36px}
21
+ ._80omtlke{cursor:pointer}
22
+ ._bfhk14ae{background-color:var(--ds-background-neutral-subtle-hovered,#ebecf0)}
23
+ ._bfhk1j28{background-color:transparent}
24
+ ._ca0q12x7{padding-top:var(--ds-space-075,6px)}
25
+ ._i0dl1wug{flex-basis:auto}
26
+ ._i0dlf1ug{flex-basis:0%}
27
+ ._kqswh2mm{position:relative}
28
+ ._n3td12x7{padding-bottom:var(--ds-space-075,6px)}
29
+ ._s7n4nkob{vertical-align:middle}
30
+ ._syaz1n3s{color:var(--ds-text-subtle,#5e6c84)}
31
+ ._u5f3utpp{padding-right:var(--ds-space-150,9pt)}
@@ -0,0 +1,193 @@
1
+ /* InviteItemWithEmailDomain.tsx generated by @compiled/babel-plugin v0.38.1 */
2
+ import _extends from "@babel/runtime/helpers/extends";
3
+ import "./InviteItemWithEmailDomain.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
6
+ import { FormattedMessage, injectIntl } from 'react-intl-next';
7
+ import { mentionMessages as messages } from '@atlaskit/editor-common/messages';
8
+ import EmailIcon from '@atlaskit/icon/core/email';
9
+ import StatusErrorIcon from '@atlaskit/icon/core/status-error';
10
+ import { N30, N300 } from '@atlaskit/theme/colors';
11
+ import { isValidEmail } from '@atlaskit/user-picker';
12
+ const mentionItemStyle = null;
13
+ const mentionItemSelectedStyle = null;
14
+ const style = {
15
+ byline: "_19pkv77o",
16
+ rowStyle: "_1reo15vq _18m915vq _4cvr1h6o _1e0c1txw _2lx2vrvc _1n261g80 _ca0q12x7 _n3td12x7 _19bvutpp _u5f3utpp _1bto1l2s _s7n4nkob",
17
+ avatar: "_16jlidpf _1o9zkb7n _i0dl1wug _1e0c1txw _4cvr1h6o _1bah1h6o _kqswh2mm _1bsb14no _4t3i14no",
18
+ nameSection: "_16jlkb7n _1o9zkb7n _i0dlf1ug _1ul9idpf _18u0utpp _syaz1n3s",
19
+ capitalize: "_1p1d1dk0"
20
+ };
21
+ const VALID_OPTION = 'VALID';
22
+ const POTENTIAL_OPTION = 'POTENTIAL';
23
+ // eslint-disable-next-line require-unicode-regexp
24
+ const COMPLETE_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
25
+ const ERROR_DELAY_MS = 750;
26
+ const getInviteOption = (inputValue, suggestedEmailDomain) => {
27
+ if (inputValue.includes(' ') && inputValue.includes('@')) {
28
+ return inputValue;
29
+ }
30
+ const isEmail = inputValue && [VALID_OPTION, POTENTIAL_OPTION].includes(isValidEmail(inputValue));
31
+ if (isEmail || !suggestedEmailDomain) {
32
+ return inputValue;
33
+ }
34
+ return `${inputValue.toLocaleLowerCase()}@${suggestedEmailDomain}`;
35
+ };
36
+ const getIsEmailValid = inputValue => {
37
+ if (!inputValue || inputValue.length === 0) {
38
+ return false;
39
+ }
40
+ if (inputValue.includes(' ')) {
41
+ return false;
42
+ }
43
+ if (inputValue.includes('@') && !COMPLETE_EMAIL_REGEX.test(inputValue)) {
44
+ return false;
45
+ }
46
+ return true;
47
+ };
48
+ export const INVITE_ITEM_DESCRIPTION = {
49
+ id: 'invite-teammate'
50
+ };
51
+ const InviteItemWithEmailDomain = ({
52
+ productName,
53
+ onMount,
54
+ onMouseEnter,
55
+ onSelection,
56
+ selected,
57
+ userRole,
58
+ query = '',
59
+ emailDomain,
60
+ intl
61
+ }) => {
62
+ const [showErrorIcon, setShowErrorIcon] = useState(false);
63
+ const timeoutRef = useRef();
64
+ const possibleEmail = getInviteOption(query, emailDomain);
65
+ const isEmailValid = getIsEmailValid(query);
66
+
67
+ // Use debounced error state for icon and byline display
68
+ const shouldShowError = !isEmailValid && showErrorIcon;
69
+ // Use debounced error state for byline: show invalid message only after delay
70
+ const isValidForByline = isEmailValid || !shouldShowError;
71
+ const getByline = () => {
72
+ if (!isValidForByline) {
73
+ return intl.formatMessage(messages.inviteTeammateInvalidEmail);
74
+ }
75
+ if (userRole === 'admin') {
76
+ return /*#__PURE__*/React.createElement(FormattedMessage
77
+ // Ignored via go/ees005
78
+ // eslint-disable-next-line react/jsx-props-no-spreading
79
+ , _extends({}, messages.inviteItemTitle, {
80
+ values: {
81
+ userRole: userRole || 'basic',
82
+ productName: /*#__PURE__*/React.createElement("span", {
83
+ "data-testid": "capitalized-message",
84
+ className: ax([style.capitalize])
85
+ }, productName)
86
+ }
87
+ }));
88
+ }
89
+ return intl.formatMessage(messages.sendInvite);
90
+ };
91
+ const onSelected = useCallback(
92
+ // Ignored via go/ees005
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ event => {
95
+ if (onSelection) {
96
+ // For mouse events, only handle left click
97
+ if ('button' in event && event.button !== 0) {
98
+ return;
99
+ }
100
+ // For keyboard events, only handle Enter and Space
101
+ if ('key' in event && event.key !== 'Enter' && event.key !== ' ') {
102
+ return;
103
+ }
104
+ event.preventDefault();
105
+ onSelection(INVITE_ITEM_DESCRIPTION, event);
106
+ }
107
+ }, [onSelection]);
108
+ const onItemMouseEnter = useCallback(
109
+ // Ignored via go/ees005
110
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
+ event => {
112
+ if (onMouseEnter) {
113
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
114
+ }
115
+ }, [onMouseEnter]);
116
+ const onItemFocus = useCallback(
117
+ // Ignored via go/ees005
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
+ event => {
120
+ if (onMouseEnter) {
121
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
122
+ }
123
+ }, [onMouseEnter]);
124
+ useEffect(() => {
125
+ if (onMount) {
126
+ onMount();
127
+ }
128
+ }, [onMount]);
129
+
130
+ // Debounce error icon display: only show error after user stops typing invalid input
131
+ useEffect(() => {
132
+ // Clear existing timeout
133
+ if (timeoutRef.current) {
134
+ clearTimeout(timeoutRef.current);
135
+ timeoutRef.current = undefined;
136
+ }
137
+
138
+ // Reset error icon immediately if input becomes valid or empty
139
+ if (isEmailValid || query.length === 0) {
140
+ setShowErrorIcon(false);
141
+ } else {
142
+ // Debounce: only show error icon after delay if input remains invalid
143
+ timeoutRef.current = setTimeout(() => {
144
+ setShowErrorIcon(true);
145
+ }, ERROR_DELAY_MS);
146
+ }
147
+
148
+ // Cleanup timeout on unmount or when query changes
149
+ return () => {
150
+ if (timeoutRef.current) {
151
+ clearTimeout(timeoutRef.current);
152
+ }
153
+ };
154
+ }, [query, isEmailValid]);
155
+ const displayName = query && emailDomain ? possibleEmail : undefined;
156
+ return /*#__PURE__*/React.createElement("div", {
157
+ role: "button",
158
+ tabIndex: 0,
159
+ onMouseDown: onSelected,
160
+ onKeyDown: onSelected,
161
+ onMouseEnter: onItemMouseEnter,
162
+ onFocus: onItemFocus,
163
+ "data-id": INVITE_ITEM_DESCRIPTION.id,
164
+ className: ax(["_1reo15vq _18m915vq _bfhk1j28 _1e0c1ule _2mzuglyw _80omtlke", selected && "_bfhk14ae"])
165
+ }, /*#__PURE__*/React.createElement("div", {
166
+ className: ax([style.rowStyle])
167
+ }, /*#__PURE__*/React.createElement("span", {
168
+ className: ax([style.avatar])
169
+ }, shouldShowError ? /*#__PURE__*/React.createElement(StatusErrorIcon, {
170
+ label: "Error",
171
+ color: "var(--ds-icon-danger, #C9372C)"
172
+ }) : /*#__PURE__*/React.createElement(EmailIcon, {
173
+ label: "Email",
174
+ color: `var(--ds-icon-subtle, ${N300})`
175
+ })), /*#__PURE__*/React.createElement("div", {
176
+ "data-testid": "name-section",
177
+ className: ax([style.nameSection])
178
+ }, displayName ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, displayName), /*#__PURE__*/React.createElement("div", {
179
+ className: ax([style.byline])
180
+ }, getByline())) : /*#__PURE__*/React.createElement(FormattedMessage
181
+ // Ignored via go/ees005
182
+ // eslint-disable-next-line react/jsx-props-no-spreading
183
+ , _extends({}, messages.inviteItemTitle, {
184
+ values: {
185
+ userRole: userRole || 'basic',
186
+ productName: /*#__PURE__*/React.createElement("span", {
187
+ "data-testid": "capitalized-message",
188
+ className: ax([style.capitalize])
189
+ }, productName)
190
+ }
191
+ })))));
192
+ };
193
+ export default injectIntl(InviteItemWithEmailDomain);
@@ -12,36 +12,54 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
12
12
  import { createSingleMentionFragment } from '../../editor-commands';
13
13
  import { getMentionPluginState } from '../../pm-plugins/utils';
14
14
  import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
15
+ import InviteItemWithEmailDomain from '../InviteItem/InviteItemWithEmailDomain';
15
16
  import { buildTypeAheadCancelPayload, buildTypeAheadInsertedPayload, buildTypeAheadInviteItemClickedPayload, buildTypeAheadInviteItemViewedPayload, buildTypeAheadRenderedPayload } from './analytics';
16
17
  import { isInviteItem, isTeamStats, isTeamType, shouldKeepInviteItem } from './utils';
17
18
  const createInviteItem = ({
18
19
  mentionProvider,
19
- onInviteItemMount
20
+ onInviteItemMount,
21
+ query,
22
+ emailDomain
20
23
  }) => ({
21
24
  title: INVITE_ITEM_DESCRIPTION.id,
22
25
  render: ({
23
26
  isSelected,
24
27
  onClick,
25
28
  onHover
26
- }) => /*#__PURE__*/React.createElement(InviteItem, {
27
- productName: mentionProvider ? mentionProvider.productName : undefined,
28
- selected: isSelected,
29
- onMount: onInviteItemMount,
30
- onMouseEnter: onHover,
31
- onSelection: onClick,
32
- userRole: mentionProvider.userRole
33
- }),
29
+ }) => {
30
+ var _mentionProvider$getS;
31
+ return (_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, {
32
+ productName: mentionProvider ? mentionProvider.productName : undefined,
33
+ selected: isSelected,
34
+ onMount: onInviteItemMount,
35
+ onMouseEnter: onHover,
36
+ onSelection: onClick,
37
+ userRole: mentionProvider.userRole,
38
+ query: query,
39
+ emailDomain: emailDomain
40
+ }) : /*#__PURE__*/React.createElement(InviteItem, {
41
+ productName: mentionProvider ? mentionProvider.productName : undefined,
42
+ selected: isSelected,
43
+ onMount: onInviteItemMount,
44
+ onMouseEnter: onHover,
45
+ onSelection: onClick,
46
+ userRole: mentionProvider.userRole
47
+ });
48
+ },
34
49
  mention: INVITE_ITEM_DESCRIPTION
35
50
  });
36
51
  const withInviteItem = ({
37
52
  mentionProvider,
38
53
  firstQueryWithoutResults,
39
54
  currentQuery,
40
- onInviteItemMount
55
+ onInviteItemMount,
56
+ emailDomain
41
57
  }) => mentionItems => {
42
58
  const inviteItem = createInviteItem({
43
59
  mentionProvider,
44
- onInviteItemMount
60
+ onInviteItemMount,
61
+ query: currentQuery,
62
+ emailDomain
45
63
  });
46
64
  const keepInviteItem = shouldKeepInviteItem(currentQuery, firstQueryWithoutResults);
47
65
  if (mentionItems.length === 0) {
@@ -203,7 +221,7 @@ export const createTypeAheadConfig = ({
203
221
  // Custom regex must have a capture group around trigger
204
222
  // so it's possible to use it without needing to scan through all triggers again
205
223
  customRegex: '\\(?(@)',
206
- getHighlight: state => {
224
+ getHighlight: _state => {
207
225
  const CustomHighlightComponent = HighlightComponent;
208
226
  if (CustomHighlightComponent) {
209
227
  return /*#__PURE__*/React.createElement(CustomHighlightComponent, null);
@@ -246,13 +264,15 @@ export const createTypeAheadConfig = ({
246
264
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
247
265
  resolve(mentionItems);
248
266
  } else {
267
+ const emailDomain = mentionProvider.userEmailDomain;
249
268
  const items = withInviteItem({
250
269
  mentionProvider,
251
270
  firstQueryWithoutResults: firstQueryWithoutResults || '',
252
271
  currentQuery: query,
253
272
  onInviteItemMount: () => {
254
273
  fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole));
255
- }
274
+ },
275
+ emailDomain
256
276
  })(mentionItems);
257
277
  resolve(items);
258
278
  }
@@ -15,7 +15,7 @@ export var ACTIONS = {
15
15
  SET_PROVIDER: 'SET_PROVIDER'
16
16
  };
17
17
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
18
- var PACKAGE_VERSION = "9.0.1";
18
+ var PACKAGE_VERSION = "9.1.0";
19
19
  var setProvider = function setProvider(provider) {
20
20
  return function (state, dispatch) {
21
21
  if (dispatch) {
@@ -0,0 +1,31 @@
1
+ ._16jlidpf{flex-grow:0}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m915vq{overflow-y:hidden}
4
+ ._18u0utpp{margin-left:var(--ds-space-150,9pt)}
5
+ ._19bvutpp{padding-left:var(--ds-space-150,9pt)}
6
+ ._19pkv77o{margin-top:var(--ds-space-025,2px)}
7
+ ._1bah1h6o{justify-content:center}
8
+ ._1bsb14no{width:36px}
9
+ ._1bto1l2s{text-overflow:ellipsis}
10
+ ._1e0c1txw{display:flex}
11
+ ._1e0c1ule{display:block}
12
+ ._1n261g80{flex-wrap:wrap}
13
+ ._1o9zkb7n{flex-shrink:1}
14
+ ._1p1d1dk0{text-transform:capitalize}
15
+ ._1reo15vq{overflow-x:hidden}
16
+ ._1ul9idpf{min-width:0}
17
+ ._2lx2vrvc{flex-direction:row}
18
+ ._2mzuglyw{list-style-type:none}
19
+ ._4cvr1h6o{align-items:center}
20
+ ._4t3i14no{height:36px}
21
+ ._80omtlke{cursor:pointer}
22
+ ._bfhk1j28{background-color:transparent}
23
+ ._bfhk2tgk{background-color:var(--_1y60f1n)}
24
+ ._ca0q12x7{padding-top:var(--ds-space-075,6px)}
25
+ ._i0dl1wug{flex-basis:auto}
26
+ ._i0dlf1ug{flex-basis:0%}
27
+ ._kqswh2mm{position:relative}
28
+ ._n3td12x7{padding-bottom:var(--ds-space-075,6px)}
29
+ ._s7n4nkob{vertical-align:middle}
30
+ ._syaz1n3s{color:var(--ds-text-subtle,#5e6c84)}
31
+ ._u5f3utpp{padding-right:var(--ds-space-150,9pt)}
@@ -0,0 +1,200 @@
1
+ /* InviteItemWithEmailDomain.tsx generated by @compiled/babel-plugin v0.38.1 */
2
+ import _extends from "@babel/runtime/helpers/extends";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import "./InviteItemWithEmailDomain.compiled.css";
5
+ import { ax, ix } from "@compiled/react/runtime";
6
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
7
+ import { FormattedMessage, injectIntl } from 'react-intl-next';
8
+ import { mentionMessages as messages } from '@atlaskit/editor-common/messages';
9
+ import EmailIcon from '@atlaskit/icon/core/email';
10
+ import StatusErrorIcon from '@atlaskit/icon/core/status-error';
11
+ import { N30, N300 } from '@atlaskit/theme/colors';
12
+ import { isValidEmail } from '@atlaskit/user-picker';
13
+ var mentionItemStyle = null;
14
+ var mentionItemSelectedStyle = null;
15
+ var style = {
16
+ byline: "_19pkv77o",
17
+ rowStyle: "_1reo15vq _18m915vq _4cvr1h6o _1e0c1txw _2lx2vrvc _1n261g80 _ca0q12x7 _n3td12x7 _19bvutpp _u5f3utpp _1bto1l2s _s7n4nkob",
18
+ avatar: "_16jlidpf _1o9zkb7n _i0dl1wug _1e0c1txw _4cvr1h6o _1bah1h6o _kqswh2mm _1bsb14no _4t3i14no",
19
+ nameSection: "_16jlkb7n _1o9zkb7n _i0dlf1ug _1ul9idpf _18u0utpp _syaz1n3s",
20
+ capitalize: "_1p1d1dk0"
21
+ };
22
+ var VALID_OPTION = 'VALID';
23
+ var POTENTIAL_OPTION = 'POTENTIAL';
24
+ // eslint-disable-next-line require-unicode-regexp
25
+ var COMPLETE_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
26
+ var ERROR_DELAY_MS = 750;
27
+ var getInviteOption = function getInviteOption(inputValue, suggestedEmailDomain) {
28
+ if (inputValue.includes(' ') && inputValue.includes('@')) {
29
+ return inputValue;
30
+ }
31
+ var isEmail = inputValue && [VALID_OPTION, POTENTIAL_OPTION].includes(isValidEmail(inputValue));
32
+ if (isEmail || !suggestedEmailDomain) {
33
+ return inputValue;
34
+ }
35
+ return "".concat(inputValue.toLocaleLowerCase(), "@").concat(suggestedEmailDomain);
36
+ };
37
+ var getIsEmailValid = function getIsEmailValid(inputValue) {
38
+ if (!inputValue || inputValue.length === 0) {
39
+ return false;
40
+ }
41
+ if (inputValue.includes(' ')) {
42
+ return false;
43
+ }
44
+ if (inputValue.includes('@') && !COMPLETE_EMAIL_REGEX.test(inputValue)) {
45
+ return false;
46
+ }
47
+ return true;
48
+ };
49
+ export var INVITE_ITEM_DESCRIPTION = {
50
+ id: 'invite-teammate'
51
+ };
52
+ var InviteItemWithEmailDomain = function InviteItemWithEmailDomain(_ref) {
53
+ var productName = _ref.productName,
54
+ onMount = _ref.onMount,
55
+ onMouseEnter = _ref.onMouseEnter,
56
+ onSelection = _ref.onSelection,
57
+ selected = _ref.selected,
58
+ userRole = _ref.userRole,
59
+ _ref$query = _ref.query,
60
+ query = _ref$query === void 0 ? '' : _ref$query,
61
+ emailDomain = _ref.emailDomain,
62
+ intl = _ref.intl;
63
+ var _useState = useState(false),
64
+ _useState2 = _slicedToArray(_useState, 2),
65
+ showErrorIcon = _useState2[0],
66
+ setShowErrorIcon = _useState2[1];
67
+ var timeoutRef = useRef();
68
+ var possibleEmail = getInviteOption(query, emailDomain);
69
+ var isEmailValid = getIsEmailValid(query);
70
+
71
+ // Use debounced error state for icon and byline display
72
+ var shouldShowError = !isEmailValid && showErrorIcon;
73
+ // Use debounced error state for byline: show invalid message only after delay
74
+ var isValidForByline = isEmailValid || !shouldShowError;
75
+ var getByline = function getByline() {
76
+ if (!isValidForByline) {
77
+ return intl.formatMessage(messages.inviteTeammateInvalidEmail);
78
+ }
79
+ if (userRole === 'admin') {
80
+ return /*#__PURE__*/React.createElement(FormattedMessage
81
+ // Ignored via go/ees005
82
+ // eslint-disable-next-line react/jsx-props-no-spreading
83
+ , _extends({}, messages.inviteItemTitle, {
84
+ values: {
85
+ userRole: userRole || 'basic',
86
+ productName: /*#__PURE__*/React.createElement("span", {
87
+ "data-testid": "capitalized-message",
88
+ className: ax([style.capitalize])
89
+ }, productName)
90
+ }
91
+ }));
92
+ }
93
+ return intl.formatMessage(messages.sendInvite);
94
+ };
95
+ var onSelected = useCallback(
96
+ // Ignored via go/ees005
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ function (event) {
99
+ if (onSelection) {
100
+ // For mouse events, only handle left click
101
+ if ('button' in event && event.button !== 0) {
102
+ return;
103
+ }
104
+ // For keyboard events, only handle Enter and Space
105
+ if ('key' in event && event.key !== 'Enter' && event.key !== ' ') {
106
+ return;
107
+ }
108
+ event.preventDefault();
109
+ onSelection(INVITE_ITEM_DESCRIPTION, event);
110
+ }
111
+ }, [onSelection]);
112
+ var onItemMouseEnter = useCallback(
113
+ // Ignored via go/ees005
114
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ function (event) {
116
+ if (onMouseEnter) {
117
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
118
+ }
119
+ }, [onMouseEnter]);
120
+ var onItemFocus = useCallback(
121
+ // Ignored via go/ees005
122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
+ function (event) {
124
+ if (onMouseEnter) {
125
+ onMouseEnter(INVITE_ITEM_DESCRIPTION, event);
126
+ }
127
+ }, [onMouseEnter]);
128
+ useEffect(function () {
129
+ if (onMount) {
130
+ onMount();
131
+ }
132
+ }, [onMount]);
133
+
134
+ // Debounce error icon display: only show error after user stops typing invalid input
135
+ useEffect(function () {
136
+ // Clear existing timeout
137
+ if (timeoutRef.current) {
138
+ clearTimeout(timeoutRef.current);
139
+ timeoutRef.current = undefined;
140
+ }
141
+
142
+ // Reset error icon immediately if input becomes valid or empty
143
+ if (isEmailValid || query.length === 0) {
144
+ setShowErrorIcon(false);
145
+ } else {
146
+ // Debounce: only show error icon after delay if input remains invalid
147
+ timeoutRef.current = setTimeout(function () {
148
+ setShowErrorIcon(true);
149
+ }, ERROR_DELAY_MS);
150
+ }
151
+
152
+ // Cleanup timeout on unmount or when query changes
153
+ return function () {
154
+ if (timeoutRef.current) {
155
+ clearTimeout(timeoutRef.current);
156
+ }
157
+ };
158
+ }, [query, isEmailValid]);
159
+ var displayName = query && emailDomain ? possibleEmail : undefined;
160
+ return /*#__PURE__*/React.createElement("div", {
161
+ role: "button",
162
+ tabIndex: 0,
163
+ onMouseDown: onSelected,
164
+ onKeyDown: onSelected,
165
+ onMouseEnter: onItemMouseEnter,
166
+ onFocus: onItemFocus,
167
+ "data-id": INVITE_ITEM_DESCRIPTION.id,
168
+ className: ax(["_1reo15vq _18m915vq _bfhk1j28 _1e0c1ule _2mzuglyw _80omtlke", selected && "_bfhk2tgk"]),
169
+ style: {
170
+ "--_1y60f1n": ix("var(--ds-background-neutral-subtle-hovered, ".concat(N30, ")"))
171
+ }
172
+ }, /*#__PURE__*/React.createElement("div", {
173
+ className: ax([style.rowStyle])
174
+ }, /*#__PURE__*/React.createElement("span", {
175
+ className: ax([style.avatar])
176
+ }, shouldShowError ? /*#__PURE__*/React.createElement(StatusErrorIcon, {
177
+ label: "Error",
178
+ color: "var(--ds-icon-danger, #C9372C)"
179
+ }) : /*#__PURE__*/React.createElement(EmailIcon, {
180
+ label: "Email",
181
+ color: "var(--ds-icon-subtle, ".concat(N300, ")")
182
+ })), /*#__PURE__*/React.createElement("div", {
183
+ "data-testid": "name-section",
184
+ className: ax([style.nameSection])
185
+ }, displayName ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, displayName), /*#__PURE__*/React.createElement("div", {
186
+ className: ax([style.byline])
187
+ }, getByline())) : /*#__PURE__*/React.createElement(FormattedMessage
188
+ // Ignored via go/ees005
189
+ // eslint-disable-next-line react/jsx-props-no-spreading
190
+ , _extends({}, messages.inviteItemTitle, {
191
+ values: {
192
+ userRole: userRole || 'basic',
193
+ productName: /*#__PURE__*/React.createElement("span", {
194
+ "data-testid": "capitalized-message",
195
+ className: ax([style.capitalize])
196
+ }, productName)
197
+ }
198
+ })))));
199
+ };
200
+ export default injectIntl(InviteItemWithEmailDomain);
@@ -19,18 +19,31 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
19
19
  import { createSingleMentionFragment } from '../../editor-commands';
20
20
  import { getMentionPluginState } from '../../pm-plugins/utils';
21
21
  import InviteItem, { INVITE_ITEM_DESCRIPTION } from '../InviteItem';
22
+ import InviteItemWithEmailDomain from '../InviteItem/InviteItemWithEmailDomain';
22
23
  import { buildTypeAheadCancelPayload, buildTypeAheadInsertedPayload, buildTypeAheadInviteItemClickedPayload, buildTypeAheadInviteItemViewedPayload, buildTypeAheadRenderedPayload } from './analytics';
23
24
  import { isInviteItem, isTeamStats, isTeamType, shouldKeepInviteItem } from './utils';
24
25
  var createInviteItem = function createInviteItem(_ref) {
25
26
  var mentionProvider = _ref.mentionProvider,
26
- onInviteItemMount = _ref.onInviteItemMount;
27
+ onInviteItemMount = _ref.onInviteItemMount,
28
+ query = _ref.query,
29
+ emailDomain = _ref.emailDomain;
27
30
  return {
28
31
  title: INVITE_ITEM_DESCRIPTION.id,
29
32
  render: function render(_ref2) {
33
+ var _mentionProvider$getS;
30
34
  var isSelected = _ref2.isSelected,
31
35
  onClick = _ref2.onClick,
32
36
  onHover = _ref2.onHover;
33
- return /*#__PURE__*/React.createElement(InviteItem, {
37
+ return (_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, {
38
+ productName: mentionProvider ? mentionProvider.productName : undefined,
39
+ selected: isSelected,
40
+ onMount: onInviteItemMount,
41
+ onMouseEnter: onHover,
42
+ onSelection: onClick,
43
+ userRole: mentionProvider.userRole,
44
+ query: query,
45
+ emailDomain: emailDomain
46
+ }) : /*#__PURE__*/React.createElement(InviteItem, {
34
47
  productName: mentionProvider ? mentionProvider.productName : undefined,
35
48
  selected: isSelected,
36
49
  onMount: onInviteItemMount,
@@ -46,11 +59,14 @@ var withInviteItem = function withInviteItem(_ref3) {
46
59
  var mentionProvider = _ref3.mentionProvider,
47
60
  firstQueryWithoutResults = _ref3.firstQueryWithoutResults,
48
61
  currentQuery = _ref3.currentQuery,
49
- onInviteItemMount = _ref3.onInviteItemMount;
62
+ onInviteItemMount = _ref3.onInviteItemMount,
63
+ emailDomain = _ref3.emailDomain;
50
64
  return function (mentionItems) {
51
65
  var inviteItem = createInviteItem({
52
66
  mentionProvider: mentionProvider,
53
- onInviteItemMount: onInviteItemMount
67
+ onInviteItemMount: onInviteItemMount,
68
+ query: currentQuery,
69
+ emailDomain: emailDomain
54
70
  });
55
71
  var keepInviteItem = shouldKeepInviteItem(currentQuery, firstQueryWithoutResults);
56
72
  if (mentionItems.length === 0) {
@@ -216,7 +232,7 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
216
232
  // Custom regex must have a capture group around trigger
217
233
  // so it's possible to use it without needing to scan through all triggers again
218
234
  customRegex: '\\(?(@)',
219
- getHighlight: function getHighlight(state) {
235
+ getHighlight: function getHighlight(_state) {
220
236
  var CustomHighlightComponent = HighlightComponent;
221
237
  if (CustomHighlightComponent) {
222
238
  return /*#__PURE__*/React.createElement(CustomHighlightComponent, null);
@@ -259,13 +275,15 @@ export var createTypeAheadConfig = function createTypeAheadConfig(_ref6) {
259
275
  if (!mentionProvider.shouldEnableInvite || mentionItems.length > 2) {
260
276
  resolve(mentionItems);
261
277
  } else {
278
+ var emailDomain = mentionProvider.userEmailDomain;
262
279
  var items = withInviteItem({
263
280
  mentionProvider: mentionProvider,
264
281
  firstQueryWithoutResults: firstQueryWithoutResults || '',
265
282
  currentQuery: query,
266
283
  onInviteItemMount: function onInviteItemMount() {
267
284
  fireEvent(buildTypeAheadInviteItemViewedPayload(sessionId, contextIdentifierProvider, mentionProvider.userRole));
268
- }
285
+ },
286
+ emailDomain: emailDomain
269
287
  })(mentionItems);
270
288
  resolve(items);
271
289
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ * @jsxFrag React.Fragment
5
+ */
6
+ import type { SyntheticEvent } from 'react';
7
+ import React from 'react';
8
+ import type { WrappedComponentProps } from 'react-intl-next';
9
+ import type { UserRole } from '@atlaskit/mention';
10
+ import type { MentionDescription } from '@atlaskit/mention/resource';
11
+ interface OnMentionEvent {
12
+ (mention: MentionDescription, event?: SyntheticEvent<any>): void;
13
+ }
14
+ export declare const INVITE_ITEM_DESCRIPTION: {
15
+ id: string;
16
+ };
17
+ interface Props {
18
+ emailDomain?: string;
19
+ onMount?: () => void;
20
+ onMouseEnter?: OnMentionEvent;
21
+ onSelection?: OnMentionEvent;
22
+ productName?: string;
23
+ query?: string;
24
+ selected?: boolean;
25
+ userRole?: UserRole;
26
+ }
27
+ declare const _default: React.FC<import("react-intl-next").WithIntlProps<Props & WrappedComponentProps>> & {
28
+ WrappedComponent: React.ComponentType<Props & WrappedComponentProps>;
29
+ };
30
+ export default _default;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ * @jsxFrag React.Fragment
5
+ */
6
+ import type { SyntheticEvent } from 'react';
7
+ import React from 'react';
8
+ import type { WrappedComponentProps } from 'react-intl-next';
9
+ import type { UserRole } from '@atlaskit/mention';
10
+ import type { MentionDescription } from '@atlaskit/mention/resource';
11
+ interface OnMentionEvent {
12
+ (mention: MentionDescription, event?: SyntheticEvent<any>): void;
13
+ }
14
+ export declare const INVITE_ITEM_DESCRIPTION: {
15
+ id: string;
16
+ };
17
+ interface Props {
18
+ emailDomain?: string;
19
+ onMount?: () => void;
20
+ onMouseEnter?: OnMentionEvent;
21
+ onSelection?: OnMentionEvent;
22
+ productName?: string;
23
+ query?: string;
24
+ selected?: boolean;
25
+ userRole?: UserRole;
26
+ }
27
+ declare const _default: React.FC<import("react-intl-next").WithIntlProps<Props & WrappedComponentProps>> & {
28
+ WrappedComponent: React.ComponentType<Props & WrappedComponentProps>;
29
+ };
30
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-mentions",
3
- "version": "9.0.2",
3
+ "version": "9.1.1",
4
4
  "description": "Mentions plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -37,17 +37,19 @@
37
37
  "@atlaskit/editor-plugin-selection": "^7.0.0",
38
38
  "@atlaskit/editor-plugin-type-ahead": "^7.0.0",
39
39
  "@atlaskit/editor-prosemirror": "^7.2.0",
40
- "@atlaskit/icon": "^29.4.0",
40
+ "@atlaskit/icon": "^30.0.0",
41
41
  "@atlaskit/insm": "^0.2.0",
42
42
  "@atlaskit/link": "^3.3.0",
43
43
  "@atlaskit/mention": "^24.4.0",
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/popper": "^7.1.0",
46
46
  "@atlaskit/portal": "^5.2.0",
47
- "@atlaskit/profilecard": "^24.30.0",
47
+ "@atlaskit/primitives": "^17.1.0",
48
+ "@atlaskit/profilecard": "^24.32.0",
48
49
  "@atlaskit/theme": "^21.0.0",
49
- "@atlaskit/tmp-editor-statsig": "^16.23.0",
50
- "@atlaskit/tokens": "^10.0.0",
50
+ "@atlaskit/tmp-editor-statsig": "^16.30.0",
51
+ "@atlaskit/tokens": "^10.1.0",
52
+ "@atlaskit/user-picker": "^11.20.0",
51
53
  "@babel/runtime": "^7.0.0",
52
54
  "@compiled/react": "^0.18.6",
53
55
  "bind-event-listener": "^3.0.0",
@@ -113,6 +115,9 @@
113
115
  },
114
116
  "dst-a11y__replace-anchor-with-link__editor-ai": {
115
117
  "type": "boolean"
118
+ },
119
+ "jira_invites_auto_tag_new_user_in_mentions_fg": {
120
+ "type": "boolean"
116
121
  }
117
122
  }
118
123
  }