@atlaskit/editor-common 126.1.0 → 126.1.2

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,26 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 126.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`a13383c3c99b2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a13383c3c99b2) -
8
+ [FFCLEANUP-192944] clean up code references to patch gates
9
+ `platform_editor_lovability_text_bg_color_patch_1` and
10
+ `platform_editor_lovability_text_bg_color_patch_2`.
11
+ - Updated dependencies
12
+
13
+ ## 126.1.1
14
+
15
+ ### Patch Changes
16
+
17
+ - [`534c9253b7fab`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/534c9253b7fab) -
18
+ Add operational mention avatar failure events and reasons behind
19
+ `platform_editor_mention_avatar_observability`, covering image failures, provider failures,
20
+ missing avatar URLs, and missing providers. Events identify the editor or renderer surface without
21
+ adding mention user data. Successful image loads emit no events.
22
+ - Updated dependencies
23
+
3
24
  ## 126.1.0
4
25
 
5
26
  ### Minor Changes
@@ -27,7 +27,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
27
27
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
28
28
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
29
29
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
30
- var packageVersion = "126.0.0";
30
+ var packageVersion = "126.1.1";
31
31
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
32
32
  // Remove URL as it has UGC
33
33
  // Ignored via go/ees007
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
24
24
  * @jsx jsx
25
25
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
26
26
  var packageName = "@atlaskit/editor-common";
27
- var packageVersion = "126.0.0";
27
+ var packageVersion = "126.1.1";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -14,6 +14,7 @@ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits
14
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
15
  var _react = _interopRequireWildcard(require("react"));
16
16
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
17
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
17
18
  var _providerFactory = require("../../provider-factory");
18
19
  var _mentionWithProviders = require("./mention-with-providers");
19
20
  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); }
@@ -39,7 +40,9 @@ var Mention = exports.default = /*#__PURE__*/function (_PureComponent) {
39
40
  mentionNodeDataProvider = _this$props.mentionNodeDataProvider;
40
41
  var mentionProvider = providers.mentionProvider,
41
42
  profilecardProvider = providers.profilecardProvider;
42
- var isAvatarEnabled = Boolean(mentionNodeDataProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_mention_node_avatar') || (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_mention_node_graphql_provider'));
43
+ var hasProvider = Boolean(mentionNodeDataProvider);
44
+ var canReportMissingProvider = !hasProvider && (0, _fg.fg)('platform_editor_mention_avatar_observability');
45
+ var isAvatarEnabled = (hasProvider || canReportMissingProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_mention_node_avatar') || (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_mention_node_graphql_provider'));
43
46
  if (isAvatarEnabled && mentionNodeDataProvider) {
44
47
  return /*#__PURE__*/_react.default.createElement(_mentionWithProviders.MentionWithAvatarProviders, {
45
48
  id: id,
@@ -55,7 +58,9 @@ var Mention = exports.default = /*#__PURE__*/function (_PureComponent) {
55
58
  profilecardProvider: profilecardProvider
56
59
  });
57
60
  }
58
- return /*#__PURE__*/_react.default.createElement(_mentionWithProviders.MentionWithProviders, {
61
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, canReportMissingProvider && isAvatarEnabled && /*#__PURE__*/_react.default.createElement(_mentionWithProviders.MissingMentionAvatarProvider, {
62
+ mentionKey: "".concat(userType !== null && userType !== void 0 ? userType : 'DEFAULT', ":").concat(id)
63
+ }), /*#__PURE__*/_react.default.createElement(_mentionWithProviders.MentionWithProviders, {
59
64
  id: id,
60
65
  text: text,
61
66
  accessLevel: accessLevel,
@@ -66,7 +71,7 @@ var Mention = exports.default = /*#__PURE__*/function (_PureComponent) {
66
71
  eventHandlers: eventHandlers,
67
72
  mentionProvider: mentionProvider,
68
73
  profilecardProvider: profilecardProvider
69
- });
74
+ }));
70
75
  });
71
76
  _this.providerFactory = props.providers || new _providerFactory.ProviderFactory();
72
77
  return _this;
@@ -5,24 +5,61 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.MentionWithProviders = exports.MentionWithAvatarProviders = void 0;
8
+ exports.MissingMentionAvatarProvider = exports.MentionWithProviders = exports.MentionWithAvatarProviders = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
11
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
12
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
13
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
14
  var _react = _interopRequireWildcard(require("react"));
15
+ var _useAnalyticsEvents2 = require("@atlaskit/analytics-next/useAnalyticsEvents");
16
+ var _constants = require("@atlaskit/mention/constants");
15
17
  var _resourcedMention = _interopRequireDefault(require("@atlaskit/mention/resourced-mention"));
16
18
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
19
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
17
20
  var _mentionWithProfilecard = _interopRequireDefault(require("./mention-with-profilecard"));
18
21
  var _excluded = ["id", "mentionNodeDataProvider", "userType"];
19
22
  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 _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
20
23
  var GENERIC_USER_IDS = ['HipChat', 'all', 'here'];
21
- var useMentionNodeData = function useMentionNodeData(_ref) {
24
+ var useAvatarFailureReporter = function useAvatarFailureReporter() {
25
+ var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(),
26
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
27
+ var createEventRef = (0, _react.useRef)(createAnalyticsEvent);
28
+ createEventRef.current = createAnalyticsEvent;
29
+ return (0, _react.useCallback)(function (reason) {
30
+ if ((0, _fg.fg)('platform_editor_mention_avatar_observability')) {
31
+ createEventRef.current({
32
+ action: 'failed',
33
+ actionSubject: 'mentionAvatar',
34
+ eventType: 'operational',
35
+ attributes: {
36
+ componentName: 'mention',
37
+ reason: reason,
38
+ surface: 'renderer'
39
+ }
40
+ }).fire(_constants.ELEMENTS_CHANNEL);
41
+ }
42
+ }, []);
43
+ };
44
+ var MissingMentionAvatarProvider = exports.MissingMentionAvatarProvider = function MissingMentionAvatarProvider(_ref) {
45
+ var mentionKey = _ref.mentionKey;
46
+ var reportFailure = useAvatarFailureReporter();
47
+ var reportedKey = (0, _react.useRef)();
48
+ (0, _react.useEffect)(function () {
49
+ if (reportedKey.current !== mentionKey) {
50
+ reportedKey.current = mentionKey;
51
+ reportFailure('missing_provider');
52
+ }
53
+ }, [mentionKey, reportFailure]);
54
+ return null;
55
+ };
56
+ var useMentionNodeData = function useMentionNodeData(_ref2) {
22
57
  var _state$data;
23
- var id = _ref.id,
24
- mentionNodeDataProvider = _ref.mentionNodeDataProvider,
25
- userType = _ref.userType;
58
+ var id = _ref2.id,
59
+ mentionNodeDataProvider = _ref2.mentionNodeDataProvider,
60
+ userType = _ref2.userType;
61
+ var reportFailure = useAvatarFailureReporter();
62
+ var reportedResolution = (0, _react.useRef)();
26
63
  var mention = (0, _react.useMemo)(function () {
27
64
  return {
28
65
  id: id,
@@ -44,38 +81,60 @@ var useMentionNodeData = function useMentionNodeData(_ref) {
44
81
  setState = _useState2[1];
45
82
  var data = state.key === mentionKey ? (_state$data = state.data) !== null && _state$data !== void 0 ? _state$data : synchronousData : synchronousData;
46
83
  (0, _react.useEffect)(function () {
84
+ var reportResolution = function reportResolution(data, error) {
85
+ var _reportedResolution$c;
86
+ if (!error && (!data || data.avatarUrl)) {
87
+ return;
88
+ }
89
+ if (((_reportedResolution$c = reportedResolution.current) === null || _reportedResolution$c === void 0 ? void 0 : _reportedResolution$c.mention) === mention && reportedResolution.current.provider === mentionNodeDataProvider) {
90
+ return;
91
+ }
92
+ reportedResolution.current = {
93
+ mention: mention,
94
+ provider: mentionNodeDataProvider
95
+ };
96
+ if (error) {
97
+ reportFailure('provider_failed');
98
+ } else if (data && !data.avatarUrl) {
99
+ reportFailure('missing_avatar_url');
100
+ }
101
+ };
47
102
  if (synchronousData) {
103
+ reportResolution(synchronousData);
48
104
  return;
49
105
  }
50
106
  var isActive = true;
51
107
  mentionNodeDataProvider.getMentionData(mention, function (payload) {
52
- if (isActive && payload.data) {
53
- setState({
54
- data: payload.data,
55
- key: mentionKey
56
- });
108
+ if (isActive) {
109
+ reportResolution(payload.data, payload.error);
110
+ if (payload.data) {
111
+ setState({
112
+ data: payload.data,
113
+ key: mentionKey
114
+ });
115
+ }
57
116
  }
58
117
  });
59
118
  return function () {
60
119
  isActive = false;
61
120
  };
62
- }, [mention, mentionKey, mentionNodeDataProvider, synchronousData]);
121
+ }, [mention, mentionKey, mentionNodeDataProvider, synchronousData, reportFailure]);
63
122
  return data;
64
123
  };
65
- var MentionWithProviders = exports.MentionWithProviders = /*#__PURE__*/_react.default.memo(function (_ref2) {
66
- var accessLevel = _ref2.accessLevel,
67
- disabledTooltip = _ref2.disabledTooltip,
68
- eventHandlers = _ref2.eventHandlers,
69
- id = _ref2.id,
70
- isDisabled = _ref2.isDisabled,
71
- mentionNodeData = _ref2.mentionNodeData,
72
- mentionProvider = _ref2.mentionProvider,
73
- profilecardProviderResolver = _ref2.profilecardProvider,
74
- _ref2$renderAvatarSlo = _ref2.renderAvatarSlot,
75
- renderAvatarSlot = _ref2$renderAvatarSlo === void 0 ? false : _ref2$renderAvatarSlo,
76
- text = _ref2.text,
77
- localId = _ref2.localId,
78
- userType = _ref2.userType;
124
+ var MentionWithProviders = exports.MentionWithProviders = /*#__PURE__*/_react.default.memo(function (_ref3) {
125
+ var accessLevel = _ref3.accessLevel,
126
+ disabledTooltip = _ref3.disabledTooltip,
127
+ eventHandlers = _ref3.eventHandlers,
128
+ id = _ref3.id,
129
+ isDisabled = _ref3.isDisabled,
130
+ mentionNodeData = _ref3.mentionNodeData,
131
+ mentionProvider = _ref3.mentionProvider,
132
+ profilecardProviderResolver = _ref3.profilecardProvider,
133
+ _ref3$renderAvatarSlo = _ref3.renderAvatarSlot,
134
+ renderAvatarSlot = _ref3$renderAvatarSlo === void 0 ? false : _ref3$renderAvatarSlo,
135
+ text = _ref3.text,
136
+ localId = _ref3.localId,
137
+ userType = _ref3.userType;
79
138
  var _useState3 = (0, _react.useState)(null),
80
139
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
81
140
  profilecardProvider = _useState4[0],
@@ -117,7 +176,7 @@ var MentionWithProviders = exports.MentionWithProviders = /*#__PURE__*/_react.de
117
176
  }
118
177
  var isActive = true;
119
178
  var resolveRovoChatIdentity = /*#__PURE__*/function () {
120
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
179
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
121
180
  var _provider$getRovoChat, provider, identityAccountId, _t;
122
181
  return _regenerator.default.wrap(function (_context) {
123
182
  while (1) switch (_context.prev = _context.next) {
@@ -149,7 +208,7 @@ var MentionWithProviders = exports.MentionWithProviders = /*#__PURE__*/_react.de
149
208
  }, _callee, null, [[0, 3]]);
150
209
  }));
151
210
  return function resolveRovoChatIdentity() {
152
- return _ref3.apply(this, arguments);
211
+ return _ref4.apply(this, arguments);
153
212
  };
154
213
  }();
155
214
  void resolveRovoChatIdentity();
@@ -204,11 +263,11 @@ var MentionWithProviders = exports.MentionWithProviders = /*#__PURE__*/_react.de
204
263
  isRovoChat: isRovoChat
205
264
  });
206
265
  });
207
- var MentionWithAvatarProviders = exports.MentionWithAvatarProviders = /*#__PURE__*/_react.default.memo(function (_ref4) {
208
- var id = _ref4.id,
209
- mentionNodeDataProvider = _ref4.mentionNodeDataProvider,
210
- userType = _ref4.userType,
211
- props = (0, _objectWithoutProperties2.default)(_ref4, _excluded);
266
+ var MentionWithAvatarProviders = exports.MentionWithAvatarProviders = /*#__PURE__*/_react.default.memo(function (_ref5) {
267
+ var id = _ref5.id,
268
+ mentionNodeDataProvider = _ref5.mentionNodeDataProvider,
269
+ userType = _ref5.userType,
270
+ props = (0, _objectWithoutProperties2.default)(_ref5, _excluded);
212
271
  var mentionNodeData = useMentionNodeData({
213
272
  id: id,
214
273
  mentionNodeDataProvider: mentionNodeDataProvider,
@@ -13,7 +13,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
13
13
  const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
14
14
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
15
15
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
16
- const packageVersion = "126.0.0";
16
+ const packageVersion = "126.1.1";
17
17
  const sanitiseSentryEvents = (data, _hint) => {
18
18
  // Remove URL as it has UGC
19
19
  // Ignored via go/ees007
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags/fg';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "126.0.0";
17
+ const packageVersion = "126.1.1";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -3,8 +3,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
 
4
4
  import React, { PureComponent } from 'react';
5
5
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
6
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
7
  import { ProviderFactory, WithProviders } from '../../provider-factory';
7
- import { MentionWithAvatarProviders, MentionWithProviders } from './mention-with-providers';
8
+ import { MissingMentionAvatarProvider, MentionWithAvatarProviders, MentionWithProviders } from './mention-with-providers';
8
9
  const MENTION_PROVIDERS = ['mentionProvider', 'profilecardProvider'];
9
10
  const GENERIC_MENTION_IDS = ['HipChat', 'all', 'here'];
10
11
  export default class Mention extends PureComponent {
@@ -26,7 +27,9 @@ export default class Mention extends PureComponent {
26
27
  mentionProvider,
27
28
  profilecardProvider
28
29
  } = providers;
29
- const isAvatarEnabled = Boolean(mentionNodeDataProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && (isExperimentEnabled('platform_editor_mention_node_avatar') || isExperimentEnabled('platform_editor_mention_node_graphql_provider'));
30
+ const hasProvider = Boolean(mentionNodeDataProvider);
31
+ const canReportMissingProvider = !hasProvider && fg('platform_editor_mention_avatar_observability');
32
+ const isAvatarEnabled = (hasProvider || canReportMissingProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && (isExperimentEnabled('platform_editor_mention_node_avatar') || isExperimentEnabled('platform_editor_mention_node_graphql_provider'));
30
33
  if (isAvatarEnabled && mentionNodeDataProvider) {
31
34
  return /*#__PURE__*/React.createElement(MentionWithAvatarProviders, {
32
35
  id: id,
@@ -42,7 +45,9 @@ export default class Mention extends PureComponent {
42
45
  profilecardProvider: profilecardProvider
43
46
  });
44
47
  }
45
- return /*#__PURE__*/React.createElement(MentionWithProviders, {
48
+ return /*#__PURE__*/React.createElement(React.Fragment, null, canReportMissingProvider && isAvatarEnabled && /*#__PURE__*/React.createElement(MissingMentionAvatarProvider, {
49
+ mentionKey: `${userType !== null && userType !== void 0 ? userType : 'DEFAULT'}:${id}`
50
+ }), /*#__PURE__*/React.createElement(MentionWithProviders, {
46
51
  id: id,
47
52
  text: text,
48
53
  accessLevel: accessLevel,
@@ -53,7 +58,7 @@ export default class Mention extends PureComponent {
53
58
  eventHandlers: eventHandlers,
54
59
  mentionProvider: mentionProvider,
55
60
  profilecardProvider: profilecardProvider
56
- });
61
+ }));
57
62
  });
58
63
  this.providerFactory = props.providers || new ProviderFactory();
59
64
  }
@@ -1,15 +1,54 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
2
+ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
4
+ import { ELEMENTS_CHANNEL } from '@atlaskit/mention/constants';
3
5
  import ResourcedMention from '@atlaskit/mention/resourced-mention';
4
6
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
7
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
5
8
  import ResourcedMentionWithProfilecard from './mention-with-profilecard';
6
9
  const GENERIC_USER_IDS = ['HipChat', 'all', 'here'];
10
+ const useAvatarFailureReporter = () => {
11
+ const {
12
+ createAnalyticsEvent
13
+ } = useAnalyticsEvents();
14
+ const createEventRef = useRef(createAnalyticsEvent);
15
+ createEventRef.current = createAnalyticsEvent;
16
+ return useCallback(reason => {
17
+ if (fg('platform_editor_mention_avatar_observability')) {
18
+ createEventRef.current({
19
+ action: 'failed',
20
+ actionSubject: 'mentionAvatar',
21
+ eventType: 'operational',
22
+ attributes: {
23
+ componentName: 'mention',
24
+ reason,
25
+ surface: 'renderer'
26
+ }
27
+ }).fire(ELEMENTS_CHANNEL);
28
+ }
29
+ }, []);
30
+ };
31
+ export const MissingMentionAvatarProvider = ({
32
+ mentionKey
33
+ }) => {
34
+ const reportFailure = useAvatarFailureReporter();
35
+ const reportedKey = useRef();
36
+ useEffect(() => {
37
+ if (reportedKey.current !== mentionKey) {
38
+ reportedKey.current = mentionKey;
39
+ reportFailure('missing_provider');
40
+ }
41
+ }, [mentionKey, reportFailure]);
42
+ return null;
43
+ };
7
44
  const useMentionNodeData = ({
8
45
  id,
9
46
  mentionNodeDataProvider,
10
47
  userType
11
48
  }) => {
12
49
  var _state$data;
50
+ const reportFailure = useAvatarFailureReporter();
51
+ const reportedResolution = useRef();
13
52
  const mention = useMemo(() => ({
14
53
  id,
15
54
  userType
@@ -22,22 +61,44 @@ const useMentionNodeData = ({
22
61
  }));
23
62
  const data = state.key === mentionKey ? (_state$data = state.data) !== null && _state$data !== void 0 ? _state$data : synchronousData : synchronousData;
24
63
  useEffect(() => {
64
+ const reportResolution = (data, error) => {
65
+ var _reportedResolution$c;
66
+ if (!error && (!data || data.avatarUrl)) {
67
+ return;
68
+ }
69
+ if (((_reportedResolution$c = reportedResolution.current) === null || _reportedResolution$c === void 0 ? void 0 : _reportedResolution$c.mention) === mention && reportedResolution.current.provider === mentionNodeDataProvider) {
70
+ return;
71
+ }
72
+ reportedResolution.current = {
73
+ mention,
74
+ provider: mentionNodeDataProvider
75
+ };
76
+ if (error) {
77
+ reportFailure('provider_failed');
78
+ } else if (data && !data.avatarUrl) {
79
+ reportFailure('missing_avatar_url');
80
+ }
81
+ };
25
82
  if (synchronousData) {
83
+ reportResolution(synchronousData);
26
84
  return;
27
85
  }
28
86
  let isActive = true;
29
87
  mentionNodeDataProvider.getMentionData(mention, payload => {
30
- if (isActive && payload.data) {
31
- setState({
32
- data: payload.data,
33
- key: mentionKey
34
- });
88
+ if (isActive) {
89
+ reportResolution(payload.data, payload.error);
90
+ if (payload.data) {
91
+ setState({
92
+ data: payload.data,
93
+ key: mentionKey
94
+ });
95
+ }
35
96
  }
36
97
  });
37
98
  return () => {
38
99
  isActive = false;
39
100
  };
40
- }, [mention, mentionKey, mentionNodeDataProvider, synchronousData]);
101
+ }, [mention, mentionKey, mentionNodeDataProvider, synchronousData, reportFailure]);
41
102
  return data;
42
103
  };
43
104
  export const MentionWithProviders = /*#__PURE__*/React.memo(({
@@ -19,7 +19,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
19
19
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
20
20
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
21
21
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
22
- var packageVersion = "126.0.0";
22
+ var packageVersion = "126.1.1";
23
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
24
24
  // Remove URL as it has UGC
25
25
  // Ignored via go/ees007
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import { fg } from '@atlaskit/platform-feature-flags/fg';
22
22
  import Layer from '../Layer';
23
23
  var packageName = "@atlaskit/editor-common";
24
- var packageVersion = "126.0.0";
24
+ var packageVersion = "126.1.1";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -10,8 +10,9 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
10
10
 
11
11
  import React, { PureComponent } from 'react';
12
12
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
13
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
13
14
  import { ProviderFactory, WithProviders } from '../../provider-factory';
14
- import { MentionWithAvatarProviders, MentionWithProviders } from './mention-with-providers';
15
+ import { MissingMentionAvatarProvider, MentionWithAvatarProviders, MentionWithProviders } from './mention-with-providers';
15
16
  var MENTION_PROVIDERS = ['mentionProvider', 'profilecardProvider'];
16
17
  var GENERIC_MENTION_IDS = ['HipChat', 'all', 'here'];
17
18
  var Mention = /*#__PURE__*/function (_PureComponent) {
@@ -32,7 +33,9 @@ var Mention = /*#__PURE__*/function (_PureComponent) {
32
33
  mentionNodeDataProvider = _this$props.mentionNodeDataProvider;
33
34
  var mentionProvider = providers.mentionProvider,
34
35
  profilecardProvider = providers.profilecardProvider;
35
- var isAvatarEnabled = Boolean(mentionNodeDataProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && (isExperimentEnabled('platform_editor_mention_node_avatar') || isExperimentEnabled('platform_editor_mention_node_graphql_provider'));
36
+ var hasProvider = Boolean(mentionNodeDataProvider);
37
+ var canReportMissingProvider = !hasProvider && fg('platform_editor_mention_avatar_observability');
38
+ var isAvatarEnabled = (hasProvider || canReportMissingProvider) && userType !== 'SPECIAL' && !GENERIC_MENTION_IDS.includes(id) && (isExperimentEnabled('platform_editor_mention_node_avatar') || isExperimentEnabled('platform_editor_mention_node_graphql_provider'));
36
39
  if (isAvatarEnabled && mentionNodeDataProvider) {
37
40
  return /*#__PURE__*/React.createElement(MentionWithAvatarProviders, {
38
41
  id: id,
@@ -48,7 +51,9 @@ var Mention = /*#__PURE__*/function (_PureComponent) {
48
51
  profilecardProvider: profilecardProvider
49
52
  });
50
53
  }
51
- return /*#__PURE__*/React.createElement(MentionWithProviders, {
54
+ return /*#__PURE__*/React.createElement(React.Fragment, null, canReportMissingProvider && isAvatarEnabled && /*#__PURE__*/React.createElement(MissingMentionAvatarProvider, {
55
+ mentionKey: "".concat(userType !== null && userType !== void 0 ? userType : 'DEFAULT', ":").concat(id)
56
+ }), /*#__PURE__*/React.createElement(MentionWithProviders, {
52
57
  id: id,
53
58
  text: text,
54
59
  accessLevel: accessLevel,
@@ -59,7 +64,7 @@ var Mention = /*#__PURE__*/function (_PureComponent) {
59
64
  eventHandlers: eventHandlers,
60
65
  mentionProvider: mentionProvider,
61
66
  profilecardProvider: profilecardProvider
62
- });
67
+ }));
63
68
  });
64
69
  _this.providerFactory = props.providers || new ProviderFactory();
65
70
  return _this;
@@ -4,16 +4,53 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  var _excluded = ["id", "mentionNodeDataProvider", "userType"];
6
6
  import _regeneratorRuntime from "@babel/runtime/regenerator";
7
- import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
7
+ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
8
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
9
+ import { ELEMENTS_CHANNEL } from '@atlaskit/mention/constants';
8
10
  import ResourcedMention from '@atlaskit/mention/resourced-mention';
9
11
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
12
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
10
13
  import ResourcedMentionWithProfilecard from './mention-with-profilecard';
11
14
  var GENERIC_USER_IDS = ['HipChat', 'all', 'here'];
12
- var useMentionNodeData = function useMentionNodeData(_ref) {
15
+ var useAvatarFailureReporter = function useAvatarFailureReporter() {
16
+ var _useAnalyticsEvents = useAnalyticsEvents(),
17
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
18
+ var createEventRef = useRef(createAnalyticsEvent);
19
+ createEventRef.current = createAnalyticsEvent;
20
+ return useCallback(function (reason) {
21
+ if (fg('platform_editor_mention_avatar_observability')) {
22
+ createEventRef.current({
23
+ action: 'failed',
24
+ actionSubject: 'mentionAvatar',
25
+ eventType: 'operational',
26
+ attributes: {
27
+ componentName: 'mention',
28
+ reason: reason,
29
+ surface: 'renderer'
30
+ }
31
+ }).fire(ELEMENTS_CHANNEL);
32
+ }
33
+ }, []);
34
+ };
35
+ export var MissingMentionAvatarProvider = function MissingMentionAvatarProvider(_ref) {
36
+ var mentionKey = _ref.mentionKey;
37
+ var reportFailure = useAvatarFailureReporter();
38
+ var reportedKey = useRef();
39
+ useEffect(function () {
40
+ if (reportedKey.current !== mentionKey) {
41
+ reportedKey.current = mentionKey;
42
+ reportFailure('missing_provider');
43
+ }
44
+ }, [mentionKey, reportFailure]);
45
+ return null;
46
+ };
47
+ var useMentionNodeData = function useMentionNodeData(_ref2) {
13
48
  var _state$data;
14
- var id = _ref.id,
15
- mentionNodeDataProvider = _ref.mentionNodeDataProvider,
16
- userType = _ref.userType;
49
+ var id = _ref2.id,
50
+ mentionNodeDataProvider = _ref2.mentionNodeDataProvider,
51
+ userType = _ref2.userType;
52
+ var reportFailure = useAvatarFailureReporter();
53
+ var reportedResolution = useRef();
17
54
  var mention = useMemo(function () {
18
55
  return {
19
56
  id: id,
@@ -35,38 +72,60 @@ var useMentionNodeData = function useMentionNodeData(_ref) {
35
72
  setState = _useState2[1];
36
73
  var data = state.key === mentionKey ? (_state$data = state.data) !== null && _state$data !== void 0 ? _state$data : synchronousData : synchronousData;
37
74
  useEffect(function () {
75
+ var reportResolution = function reportResolution(data, error) {
76
+ var _reportedResolution$c;
77
+ if (!error && (!data || data.avatarUrl)) {
78
+ return;
79
+ }
80
+ if (((_reportedResolution$c = reportedResolution.current) === null || _reportedResolution$c === void 0 ? void 0 : _reportedResolution$c.mention) === mention && reportedResolution.current.provider === mentionNodeDataProvider) {
81
+ return;
82
+ }
83
+ reportedResolution.current = {
84
+ mention: mention,
85
+ provider: mentionNodeDataProvider
86
+ };
87
+ if (error) {
88
+ reportFailure('provider_failed');
89
+ } else if (data && !data.avatarUrl) {
90
+ reportFailure('missing_avatar_url');
91
+ }
92
+ };
38
93
  if (synchronousData) {
94
+ reportResolution(synchronousData);
39
95
  return;
40
96
  }
41
97
  var isActive = true;
42
98
  mentionNodeDataProvider.getMentionData(mention, function (payload) {
43
- if (isActive && payload.data) {
44
- setState({
45
- data: payload.data,
46
- key: mentionKey
47
- });
99
+ if (isActive) {
100
+ reportResolution(payload.data, payload.error);
101
+ if (payload.data) {
102
+ setState({
103
+ data: payload.data,
104
+ key: mentionKey
105
+ });
106
+ }
48
107
  }
49
108
  });
50
109
  return function () {
51
110
  isActive = false;
52
111
  };
53
- }, [mention, mentionKey, mentionNodeDataProvider, synchronousData]);
112
+ }, [mention, mentionKey, mentionNodeDataProvider, synchronousData, reportFailure]);
54
113
  return data;
55
114
  };
56
- export var MentionWithProviders = /*#__PURE__*/React.memo(function (_ref2) {
57
- var accessLevel = _ref2.accessLevel,
58
- disabledTooltip = _ref2.disabledTooltip,
59
- eventHandlers = _ref2.eventHandlers,
60
- id = _ref2.id,
61
- isDisabled = _ref2.isDisabled,
62
- mentionNodeData = _ref2.mentionNodeData,
63
- mentionProvider = _ref2.mentionProvider,
64
- profilecardProviderResolver = _ref2.profilecardProvider,
65
- _ref2$renderAvatarSlo = _ref2.renderAvatarSlot,
66
- renderAvatarSlot = _ref2$renderAvatarSlo === void 0 ? false : _ref2$renderAvatarSlo,
67
- text = _ref2.text,
68
- localId = _ref2.localId,
69
- userType = _ref2.userType;
115
+ export var MentionWithProviders = /*#__PURE__*/React.memo(function (_ref3) {
116
+ var accessLevel = _ref3.accessLevel,
117
+ disabledTooltip = _ref3.disabledTooltip,
118
+ eventHandlers = _ref3.eventHandlers,
119
+ id = _ref3.id,
120
+ isDisabled = _ref3.isDisabled,
121
+ mentionNodeData = _ref3.mentionNodeData,
122
+ mentionProvider = _ref3.mentionProvider,
123
+ profilecardProviderResolver = _ref3.profilecardProvider,
124
+ _ref3$renderAvatarSlo = _ref3.renderAvatarSlot,
125
+ renderAvatarSlot = _ref3$renderAvatarSlo === void 0 ? false : _ref3$renderAvatarSlo,
126
+ text = _ref3.text,
127
+ localId = _ref3.localId,
128
+ userType = _ref3.userType;
70
129
  var _useState3 = useState(null),
71
130
  _useState4 = _slicedToArray(_useState3, 2),
72
131
  profilecardProvider = _useState4[0],
@@ -108,7 +167,7 @@ export var MentionWithProviders = /*#__PURE__*/React.memo(function (_ref2) {
108
167
  }
109
168
  var isActive = true;
110
169
  var resolveRovoChatIdentity = /*#__PURE__*/function () {
111
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
170
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
112
171
  var _provider$getRovoChat, provider, identityAccountId, _t;
113
172
  return _regeneratorRuntime.wrap(function (_context) {
114
173
  while (1) switch (_context.prev = _context.next) {
@@ -140,7 +199,7 @@ export var MentionWithProviders = /*#__PURE__*/React.memo(function (_ref2) {
140
199
  }, _callee, null, [[0, 3]]);
141
200
  }));
142
201
  return function resolveRovoChatIdentity() {
143
- return _ref3.apply(this, arguments);
202
+ return _ref4.apply(this, arguments);
144
203
  };
145
204
  }();
146
205
  void resolveRovoChatIdentity();
@@ -195,11 +254,11 @@ export var MentionWithProviders = /*#__PURE__*/React.memo(function (_ref2) {
195
254
  isRovoChat: isRovoChat
196
255
  });
197
256
  });
198
- export var MentionWithAvatarProviders = /*#__PURE__*/React.memo(function (_ref4) {
199
- var id = _ref4.id,
200
- mentionNodeDataProvider = _ref4.mentionNodeDataProvider,
201
- userType = _ref4.userType,
202
- props = _objectWithoutProperties(_ref4, _excluded);
257
+ export var MentionWithAvatarProviders = /*#__PURE__*/React.memo(function (_ref5) {
258
+ var id = _ref5.id,
259
+ mentionNodeDataProvider = _ref5.mentionNodeDataProvider,
260
+ userType = _ref5.userType,
261
+ props = _objectWithoutProperties(_ref5, _excluded);
203
262
  var mentionNodeData = useMentionNodeData({
204
263
  id: id,
205
264
  mentionNodeDataProvider: mentionNodeDataProvider,
@@ -19,7 +19,7 @@ export interface MentionProps {
19
19
  export interface MentionState {
20
20
  profilecardProvider: ProfilecardProvider | null;
21
21
  }
22
- export default class Mention extends PureComponent<MentionProps, Object> {
22
+ export default class Mention extends PureComponent<MentionProps, object> {
23
23
  private providerFactory;
24
24
  constructor(props: MentionProps);
25
25
  componentWillUnmount(): void;
@@ -24,6 +24,9 @@ export interface MentionWithProvidersProps extends Props {
24
24
  export interface State {
25
25
  profilecardProvider: ProfilecardProvider | null;
26
26
  }
27
+ export declare const MissingMentionAvatarProvider: ({ mentionKey }: {
28
+ mentionKey: string;
29
+ }) => null;
27
30
  export declare const MentionWithProviders: React.MemoExoticComponent<(props: MentionWithProvidersProps) => React.JSX.Element>;
28
31
  export declare const MentionWithAvatarProviders: React.MemoExoticComponent<(props: Props & {
29
32
  mentionNodeDataProvider: MentionNodeDataProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "126.1.0",
3
+ "version": "126.1.2",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -75,7 +75,7 @@
75
75
  "@atlaskit/popper": "^9.4.0",
76
76
  "@atlaskit/primitives": "^22.5.0",
77
77
  "@atlaskit/profilecard": "^27.0.0",
78
- "@atlaskit/prosemirror-history": "^1.2.0",
78
+ "@atlaskit/prosemirror-history": "^1.3.0",
79
79
  "@atlaskit/react-compiler-gating": "^0.2.0",
80
80
  "@atlaskit/react-ufo": "^8.0.0",
81
81
  "@atlaskit/section-message": "^10.2.0",
@@ -85,7 +85,7 @@
85
85
  "@atlaskit/task-decision": "^21.11.0",
86
86
  "@atlaskit/teams-app-config": "^3.1.0",
87
87
  "@atlaskit/textfield": "^10.2.0",
88
- "@atlaskit/tmp-editor-statsig": "^210.0.0",
88
+ "@atlaskit/tmp-editor-statsig": "^211.0.0",
89
89
  "@atlaskit/tokens": "^20.1.0",
90
90
  "@atlaskit/tooltip": "^24.3.0",
91
91
  "@atlaskit/width-detector": "^7.2.0",
@@ -146,6 +146,10 @@
146
146
  "sinon": "^2.2.0"
147
147
  },
148
148
  "platform-feature-flags": {
149
+ "platform_editor_mention_avatar_observability": {
150
+ "type": "boolean",
151
+ "referenceOnly": true
152
+ },
149
153
  "confluence_ncs_step_diffing_version_history": {
150
154
  "type": "boolean",
151
155
  "referenceOnly": true
@@ -178,9 +182,6 @@
178
182
  "type": "boolean",
179
183
  "referenceOnly": true
180
184
  },
181
- "platform_editor_lovability_text_bg_color_patch_2": {
182
- "type": "boolean"
183
- },
184
185
  "editor_inline_comments_on_inline_nodes": {
185
186
  "type": "boolean"
186
187
  },
@@ -229,9 +230,6 @@
229
230
  "platform_editor_fix_scroll_to_pos": {
230
231
  "type": "boolean"
231
232
  },
232
- "platform_editor_lovability_text_bg_color_patch_1": {
233
- "type": "boolean"
234
- },
235
233
  "platform_editor_embed_height_only_fallback": {
236
234
  "type": "boolean"
237
235
  },