@atlaskit/editor-plugin-quick-insert 13.1.1 → 13.1.3

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-quick-insert
2
2
 
3
+ ## 13.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`cdb267f0c9d61`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cdb267f0c9d61) -
8
+ Add experiment-gated passive Quick Insert information analytics with queryable app counts for
9
+ current and legacy categories. Consumers can map legacy provider categories to current Quick
10
+ Insert sections with `getQuickInsertMenuItemParents` from
11
+ `@atlaskit/editor-common/quick-insert/get-menu-item-parents`.
12
+ - Updated dependencies
13
+
14
+ ## 13.1.2
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+
3
20
  ## 13.1.1
4
21
 
5
22
  ### Patch Changes
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createQuickInsertItemsAnalyticsScheduler = exports.calculateQuickInsertItemsAttributes = exports.QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _analytics = require("@atlaskit/editor-common/analytics");
10
+ var _getMenuItemParents = require("@atlaskit/editor-common/quick-insert/get-menu-item-parents");
11
+ var _keys = require("@atlaskit/editor-common/quick-insert/keys");
12
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
13
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
14
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
15
+ var QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = exports.QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = 10000;
16
+ var sectionCategoryKeys = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _keys.BLOCK_TEMPLATES_SECTION.key, 'blockTemplates'), _keys.DATA_AND_CHARTS_SECTION.key, 'dataAndCharts'), _keys.EMBED_SECTION.key, 'embed'), _keys.MEDIA_SECTION.key, 'media'), _keys.OTHER_SECTION.key, 'other'), _keys.ROVO_SECTION.key, 'rovo'), _keys.STRUCTURE_SECTION.key, 'structure'), _keys.TEXT_FORMATTING_SECTION.key, 'textFormatting');
17
+ var legacyCategoryKeys = new Set(['admin', 'ai', 'block-templates', 'communication', 'confluence-content', 'data-and-charts', 'development', 'embed', 'external-content', 'formatting', 'media', 'navigation', 'other', 'reporting', 'skills', 'structure', 'text-formatting', 'visuals']);
18
+ var isLegacyCategoryKey = function isLegacyCategoryKey(category) {
19
+ return legacyCategoryKeys.has(category);
20
+ };
21
+ var calculateQuickInsertItemsAttributes = exports.calculateQuickInsertItemsAttributes = function calculateQuickInsertItemsAttributes(items) {
22
+ var attributes = {
23
+ category: {
24
+ blockTemplates: {
25
+ appCount: 0
26
+ },
27
+ dataAndCharts: {
28
+ appCount: 0
29
+ },
30
+ embed: {
31
+ appCount: 0
32
+ },
33
+ media: {
34
+ appCount: 0
35
+ },
36
+ other: {
37
+ appCount: 0
38
+ },
39
+ rovo: {
40
+ appCount: 0
41
+ },
42
+ structure: {
43
+ appCount: 0
44
+ },
45
+ textFormatting: {
46
+ appCount: 0
47
+ }
48
+ },
49
+ legacyCategory: {
50
+ admin: {
51
+ appCount: 0
52
+ },
53
+ ai: {
54
+ appCount: 0
55
+ },
56
+ 'block-templates': {
57
+ appCount: 0
58
+ },
59
+ communication: {
60
+ appCount: 0
61
+ },
62
+ 'confluence-content': {
63
+ appCount: 0
64
+ },
65
+ 'data-and-charts': {
66
+ appCount: 0
67
+ },
68
+ development: {
69
+ appCount: 0
70
+ },
71
+ embed: {
72
+ appCount: 0
73
+ },
74
+ 'external-content': {
75
+ appCount: 0
76
+ },
77
+ formatting: {
78
+ appCount: 0
79
+ },
80
+ media: {
81
+ appCount: 0
82
+ },
83
+ navigation: {
84
+ appCount: 0
85
+ },
86
+ other: {
87
+ appCount: 0
88
+ },
89
+ reporting: {
90
+ appCount: 0
91
+ },
92
+ skills: {
93
+ appCount: 0
94
+ },
95
+ structure: {
96
+ appCount: 0
97
+ },
98
+ 'text-formatting': {
99
+ appCount: 0
100
+ },
101
+ uncategorized: {
102
+ appCount: 0
103
+ },
104
+ visuals: {
105
+ appCount: 0
106
+ }
107
+ }
108
+ };
109
+ var _iterator = _createForOfIteratorHelper(items),
110
+ _step;
111
+ try {
112
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
113
+ var _item$categories$map$, _item$categories;
114
+ var item = _step.value;
115
+ var normalizedCategories = new Set((_item$categories$map$ = (_item$categories = item.categories) === null || _item$categories === void 0 ? void 0 : _item$categories.map(function (category) {
116
+ return category.trim().toLowerCase();
117
+ }).filter(Boolean)) !== null && _item$categories$map$ !== void 0 ? _item$categories$map$ : []);
118
+ var hasUnknownCategory = normalizedCategories.size === 0;
119
+ var _iterator2 = _createForOfIteratorHelper(normalizedCategories),
120
+ _step2;
121
+ try {
122
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
123
+ var category = _step2.value;
124
+ if (isLegacyCategoryKey(category)) {
125
+ attributes.legacyCategory[category].appCount += 1;
126
+ } else {
127
+ hasUnknownCategory = true;
128
+ }
129
+ }
130
+ } catch (err) {
131
+ _iterator2.e(err);
132
+ } finally {
133
+ _iterator2.f();
134
+ }
135
+ if (hasUnknownCategory) {
136
+ attributes.legacyCategory.uncategorized.appCount += 1;
137
+ }
138
+ var _iterator3 = _createForOfIteratorHelper((0, _getMenuItemParents.getQuickInsertMenuItemParents)({
139
+ categories: item.categories,
140
+ rank: 0
141
+ })),
142
+ _step3;
143
+ try {
144
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
145
+ var key = _step3.value.key;
146
+ var categoryKey = sectionCategoryKeys[key];
147
+ if (categoryKey) {
148
+ attributes.category[categoryKey].appCount += 1;
149
+ }
150
+ }
151
+ } catch (err) {
152
+ _iterator3.e(err);
153
+ } finally {
154
+ _iterator3.f();
155
+ }
156
+ }
157
+ } catch (err) {
158
+ _iterator.e(err);
159
+ } finally {
160
+ _iterator.f();
161
+ }
162
+ return attributes;
163
+ };
164
+ var createQuickInsertItemsAnalyticsScheduler = exports.createQuickInsertItemsAnalyticsScheduler = function createQuickInsertItemsAnalyticsScheduler(dispatchAnalyticsEvent) {
165
+ var timeoutId;
166
+ var animationFrameId;
167
+ var idleCallbackId;
168
+ var destroyed = false;
169
+ var scheduled = false;
170
+ var emit = function emit(items) {
171
+ if (destroyed) {
172
+ return;
173
+ }
174
+ dispatchAnalyticsEvent({
175
+ action: _analytics.ACTION.QUICK_INSERT_INFORMATION,
176
+ actionSubject: _analytics.ACTION_SUBJECT.QUICK_INSERT,
177
+ attributes: calculateQuickInsertItemsAttributes(items),
178
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL
179
+ });
180
+ };
181
+ return {
182
+ destroy: function destroy() {
183
+ destroyed = true;
184
+ if (timeoutId !== undefined) {
185
+ clearTimeout(timeoutId);
186
+ }
187
+ if (animationFrameId !== undefined && typeof window !== 'undefined') {
188
+ window.cancelAnimationFrame(animationFrameId);
189
+ }
190
+ if (idleCallbackId !== undefined && typeof window !== 'undefined' && typeof window.cancelIdleCallback === 'function') {
191
+ window.cancelIdleCallback(idleCallbackId);
192
+ }
193
+ },
194
+ schedule: function schedule(items) {
195
+ if (scheduled || destroyed) {
196
+ return;
197
+ }
198
+ scheduled = true;
199
+ timeoutId = setTimeout(function () {
200
+ if (destroyed || typeof window === 'undefined') {
201
+ return;
202
+ }
203
+ if (typeof window.requestIdleCallback === 'function') {
204
+ idleCallbackId = window.requestIdleCallback(function () {
205
+ return emit(items);
206
+ });
207
+ } else if (typeof window.requestAnimationFrame === 'function') {
208
+ animationFrameId = window.requestAnimationFrame(function () {
209
+ return emit(items);
210
+ });
211
+ }
212
+ }, QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS);
213
+ }
214
+ };
215
+ };
@@ -20,6 +20,7 @@ var _showMoreHorizontal = _interopRequireDefault(require("@atlaskit/icon/core/sh
20
20
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
21
21
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
22
22
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
23
+ var _appCategoryAnalytics = require("./app-category-analytics");
23
24
  var _commands = require("./pm-plugins/commands");
24
25
  var _quickInsertOpenExperience = require("./pm-plugins/experiences/quick-insert-open-experience");
25
26
  var _pluginKey = require("./pm-plugins/plugin-key");
@@ -127,8 +128,9 @@ var quickInsertPlugin = exports.quickInsertPlugin = function quickInsertPlugin(_
127
128
  plugin: function plugin(_ref6) {
128
129
  var providerFactory = _ref6.providerFactory,
129
130
  getIntl = _ref6.getIntl,
130
- dispatch = _ref6.dispatch;
131
- return quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, options === null || options === void 0 ? void 0 : options.emptyStateHandler);
131
+ dispatch = _ref6.dispatch,
132
+ dispatchAnalyticsEvent = _ref6.dispatchAnalyticsEvent;
133
+ return quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, options === null || options === void 0 ? void 0 : options.emptyStateHandler);
132
134
  }
133
135
  }, {
134
136
  name: 'quickInsertOpenExperience',
@@ -317,7 +319,7 @@ var setProviderState = function setProviderState(providerState) {
317
319
  return true;
318
320
  };
319
321
  };
320
- function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, emptyStateHandler) {
322
+ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, emptyStateHandler) {
321
323
  return new _safePlugin.SafePlugin({
322
324
  key: _pluginKey.pluginKey,
323
325
  state: {
@@ -351,6 +353,8 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
351
353
  }
352
354
  },
353
355
  view: function view(editorView) {
356
+ var quickInsertItemsAnalyticsScheduler;
357
+ var isDestroyed = false;
354
358
  var providerHandler = /*#__PURE__*/function () {
355
359
  var _ref14 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_name, providerPromise) {
356
360
  var provider, providedItems, _t;
@@ -374,6 +378,10 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
374
378
  provider: provider,
375
379
  providedItems: providedItems
376
380
  })(editorView.state, editorView.dispatch);
381
+ if (!isDestroyed && !quickInsertItemsAnalyticsScheduler && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_slash_app_category_analytics')) {
382
+ quickInsertItemsAnalyticsScheduler = (0, _appCategoryAnalytics.createQuickInsertItemsAnalyticsScheduler)(dispatchAnalyticsEvent);
383
+ quickInsertItemsAnalyticsScheduler.schedule(providedItems);
384
+ }
377
385
  _context.next = 5;
378
386
  break;
379
387
  case 4:
@@ -394,6 +402,9 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
394
402
  providerFactory.subscribe('quickInsertProvider', providerHandler);
395
403
  return {
396
404
  destroy: function destroy() {
405
+ var _quickInsertItemsAnal;
406
+ isDestroyed = true;
407
+ (_quickInsertItemsAnal = quickInsertItemsAnalyticsScheduler) === null || _quickInsertItemsAnal === void 0 || _quickInsertItemsAnal.destroy();
397
408
  providerFactory.unsubscribe('quickInsertProvider', providerHandler);
398
409
  }
399
410
  };
@@ -0,0 +1,180 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
+ import { getQuickInsertMenuItemParents } from '@atlaskit/editor-common/quick-insert/get-menu-item-parents';
3
+ import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, ROVO_SECTION, STRUCTURE_SECTION, TEXT_FORMATTING_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
4
+ export const QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = 10_000;
5
+ const sectionCategoryKeys = {
6
+ [BLOCK_TEMPLATES_SECTION.key]: 'blockTemplates',
7
+ [DATA_AND_CHARTS_SECTION.key]: 'dataAndCharts',
8
+ [EMBED_SECTION.key]: 'embed',
9
+ [MEDIA_SECTION.key]: 'media',
10
+ [OTHER_SECTION.key]: 'other',
11
+ [ROVO_SECTION.key]: 'rovo',
12
+ [STRUCTURE_SECTION.key]: 'structure',
13
+ [TEXT_FORMATTING_SECTION.key]: 'textFormatting'
14
+ };
15
+ const legacyCategoryKeys = new Set(['admin', 'ai', 'block-templates', 'communication', 'confluence-content', 'data-and-charts', 'development', 'embed', 'external-content', 'formatting', 'media', 'navigation', 'other', 'reporting', 'skills', 'structure', 'text-formatting', 'visuals']);
16
+ const isLegacyCategoryKey = category => legacyCategoryKeys.has(category);
17
+ export const calculateQuickInsertItemsAttributes = items => {
18
+ const attributes = {
19
+ category: {
20
+ blockTemplates: {
21
+ appCount: 0
22
+ },
23
+ dataAndCharts: {
24
+ appCount: 0
25
+ },
26
+ embed: {
27
+ appCount: 0
28
+ },
29
+ media: {
30
+ appCount: 0
31
+ },
32
+ other: {
33
+ appCount: 0
34
+ },
35
+ rovo: {
36
+ appCount: 0
37
+ },
38
+ structure: {
39
+ appCount: 0
40
+ },
41
+ textFormatting: {
42
+ appCount: 0
43
+ }
44
+ },
45
+ legacyCategory: {
46
+ admin: {
47
+ appCount: 0
48
+ },
49
+ ai: {
50
+ appCount: 0
51
+ },
52
+ 'block-templates': {
53
+ appCount: 0
54
+ },
55
+ communication: {
56
+ appCount: 0
57
+ },
58
+ 'confluence-content': {
59
+ appCount: 0
60
+ },
61
+ 'data-and-charts': {
62
+ appCount: 0
63
+ },
64
+ development: {
65
+ appCount: 0
66
+ },
67
+ embed: {
68
+ appCount: 0
69
+ },
70
+ 'external-content': {
71
+ appCount: 0
72
+ },
73
+ formatting: {
74
+ appCount: 0
75
+ },
76
+ media: {
77
+ appCount: 0
78
+ },
79
+ navigation: {
80
+ appCount: 0
81
+ },
82
+ other: {
83
+ appCount: 0
84
+ },
85
+ reporting: {
86
+ appCount: 0
87
+ },
88
+ skills: {
89
+ appCount: 0
90
+ },
91
+ structure: {
92
+ appCount: 0
93
+ },
94
+ 'text-formatting': {
95
+ appCount: 0
96
+ },
97
+ uncategorized: {
98
+ appCount: 0
99
+ },
100
+ visuals: {
101
+ appCount: 0
102
+ }
103
+ }
104
+ };
105
+ for (const item of items) {
106
+ var _item$categories$map$, _item$categories;
107
+ const normalizedCategories = new Set((_item$categories$map$ = (_item$categories = item.categories) === null || _item$categories === void 0 ? void 0 : _item$categories.map(category => category.trim().toLowerCase()).filter(Boolean)) !== null && _item$categories$map$ !== void 0 ? _item$categories$map$ : []);
108
+ let hasUnknownCategory = normalizedCategories.size === 0;
109
+ for (const category of normalizedCategories) {
110
+ if (isLegacyCategoryKey(category)) {
111
+ attributes.legacyCategory[category].appCount += 1;
112
+ } else {
113
+ hasUnknownCategory = true;
114
+ }
115
+ }
116
+ if (hasUnknownCategory) {
117
+ attributes.legacyCategory.uncategorized.appCount += 1;
118
+ }
119
+ for (const {
120
+ key
121
+ } of getQuickInsertMenuItemParents({
122
+ categories: item.categories,
123
+ rank: 0
124
+ })) {
125
+ const categoryKey = sectionCategoryKeys[key];
126
+ if (categoryKey) {
127
+ attributes.category[categoryKey].appCount += 1;
128
+ }
129
+ }
130
+ }
131
+ return attributes;
132
+ };
133
+ export const createQuickInsertItemsAnalyticsScheduler = dispatchAnalyticsEvent => {
134
+ let timeoutId;
135
+ let animationFrameId;
136
+ let idleCallbackId;
137
+ let destroyed = false;
138
+ let scheduled = false;
139
+ const emit = items => {
140
+ if (destroyed) {
141
+ return;
142
+ }
143
+ dispatchAnalyticsEvent({
144
+ action: ACTION.QUICK_INSERT_INFORMATION,
145
+ actionSubject: ACTION_SUBJECT.QUICK_INSERT,
146
+ attributes: calculateQuickInsertItemsAttributes(items),
147
+ eventType: EVENT_TYPE.OPERATIONAL
148
+ });
149
+ };
150
+ return {
151
+ destroy: () => {
152
+ destroyed = true;
153
+ if (timeoutId !== undefined) {
154
+ clearTimeout(timeoutId);
155
+ }
156
+ if (animationFrameId !== undefined && typeof window !== 'undefined') {
157
+ window.cancelAnimationFrame(animationFrameId);
158
+ }
159
+ if (idleCallbackId !== undefined && typeof window !== 'undefined' && typeof window.cancelIdleCallback === 'function') {
160
+ window.cancelIdleCallback(idleCallbackId);
161
+ }
162
+ },
163
+ schedule: items => {
164
+ if (scheduled || destroyed) {
165
+ return;
166
+ }
167
+ scheduled = true;
168
+ timeoutId = setTimeout(() => {
169
+ if (destroyed || typeof window === 'undefined') {
170
+ return;
171
+ }
172
+ if (typeof window.requestIdleCallback === 'function') {
173
+ idleCallbackId = window.requestIdleCallback(() => emit(items));
174
+ } else if (typeof window.requestAnimationFrame === 'function') {
175
+ animationFrameId = window.requestAnimationFrame(() => emit(items));
176
+ }
177
+ }, QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS);
178
+ }
179
+ };
180
+ };
@@ -9,6 +9,7 @@ import ShowMoreHorizontalIcon from '@atlaskit/icon/core/show-more-horizontal';
9
9
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
10
10
  import { fg } from '@atlaskit/platform-feature-flags';
11
11
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
12
+ import { createQuickInsertItemsAnalyticsScheduler } from './app-category-analytics';
12
13
  import { createInsertItem, openElementBrowser as openElementBrowserCommand, openElementBrowserModal } from './pm-plugins/commands';
13
14
  import { getQuickInsertOpenExperiencePlugin } from './pm-plugins/experiences/quick-insert-open-experience';
14
15
  import { pluginKey } from './pm-plugins/plugin-key';
@@ -117,8 +118,9 @@ export const quickInsertPlugin = ({
117
118
  plugin: ({
118
119
  providerFactory,
119
120
  getIntl,
120
- dispatch
121
- }) => quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, options === null || options === void 0 ? void 0 : options.emptyStateHandler)
121
+ dispatch,
122
+ dispatchAnalyticsEvent
123
+ }) => quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, options === null || options === void 0 ? void 0 : options.emptyStateHandler)
122
124
  }, {
123
125
  name: 'quickInsertOpenExperience',
124
126
  plugin: () => getQuickInsertOpenExperiencePlugin({
@@ -288,7 +290,7 @@ const setProviderState = providerState => (state, dispatch) => {
288
290
  }
289
291
  return true;
290
292
  };
291
- function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, emptyStateHandler) {
293
+ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, emptyStateHandler) {
292
294
  return new SafePlugin({
293
295
  key: pluginKey,
294
296
  state: {
@@ -323,6 +325,8 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
323
325
  }
324
326
  },
325
327
  view(editorView) {
328
+ let quickInsertItemsAnalyticsScheduler;
329
+ let isDestroyed = false;
326
330
  const providerHandler = async (_name, providerPromise) => {
327
331
  if (providerPromise) {
328
332
  try {
@@ -332,6 +336,10 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
332
336
  provider,
333
337
  providedItems
334
338
  })(editorView.state, editorView.dispatch);
339
+ if (!isDestroyed && !quickInsertItemsAnalyticsScheduler && isExperimentEnabled('platform_editor_slash_app_category_analytics')) {
340
+ quickInsertItemsAnalyticsScheduler = createQuickInsertItemsAnalyticsScheduler(dispatchAnalyticsEvent);
341
+ quickInsertItemsAnalyticsScheduler.schedule(providedItems);
342
+ }
335
343
  } catch (e) {
336
344
  // eslint-disable-next-line no-console
337
345
  console.error('Error getting items from quick insert provider', e);
@@ -341,6 +349,9 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
341
349
  providerFactory.subscribe('quickInsertProvider', providerHandler);
342
350
  return {
343
351
  destroy() {
352
+ var _quickInsertItemsAnal;
353
+ isDestroyed = true;
354
+ (_quickInsertItemsAnal = quickInsertItemsAnalyticsScheduler) === null || _quickInsertItemsAnal === void 0 ? void 0 : _quickInsertItemsAnal.destroy();
344
355
  providerFactory.unsubscribe('quickInsertProvider', providerHandler);
345
356
  }
346
357
  };
@@ -0,0 +1,208 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
6
+ import { getQuickInsertMenuItemParents } from '@atlaskit/editor-common/quick-insert/get-menu-item-parents';
7
+ import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, ROVO_SECTION, STRUCTURE_SECTION, TEXT_FORMATTING_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
8
+ export var QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = 10000;
9
+ var sectionCategoryKeys = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, BLOCK_TEMPLATES_SECTION.key, 'blockTemplates'), DATA_AND_CHARTS_SECTION.key, 'dataAndCharts'), EMBED_SECTION.key, 'embed'), MEDIA_SECTION.key, 'media'), OTHER_SECTION.key, 'other'), ROVO_SECTION.key, 'rovo'), STRUCTURE_SECTION.key, 'structure'), TEXT_FORMATTING_SECTION.key, 'textFormatting');
10
+ var legacyCategoryKeys = new Set(['admin', 'ai', 'block-templates', 'communication', 'confluence-content', 'data-and-charts', 'development', 'embed', 'external-content', 'formatting', 'media', 'navigation', 'other', 'reporting', 'skills', 'structure', 'text-formatting', 'visuals']);
11
+ var isLegacyCategoryKey = function isLegacyCategoryKey(category) {
12
+ return legacyCategoryKeys.has(category);
13
+ };
14
+ export var calculateQuickInsertItemsAttributes = function calculateQuickInsertItemsAttributes(items) {
15
+ var attributes = {
16
+ category: {
17
+ blockTemplates: {
18
+ appCount: 0
19
+ },
20
+ dataAndCharts: {
21
+ appCount: 0
22
+ },
23
+ embed: {
24
+ appCount: 0
25
+ },
26
+ media: {
27
+ appCount: 0
28
+ },
29
+ other: {
30
+ appCount: 0
31
+ },
32
+ rovo: {
33
+ appCount: 0
34
+ },
35
+ structure: {
36
+ appCount: 0
37
+ },
38
+ textFormatting: {
39
+ appCount: 0
40
+ }
41
+ },
42
+ legacyCategory: {
43
+ admin: {
44
+ appCount: 0
45
+ },
46
+ ai: {
47
+ appCount: 0
48
+ },
49
+ 'block-templates': {
50
+ appCount: 0
51
+ },
52
+ communication: {
53
+ appCount: 0
54
+ },
55
+ 'confluence-content': {
56
+ appCount: 0
57
+ },
58
+ 'data-and-charts': {
59
+ appCount: 0
60
+ },
61
+ development: {
62
+ appCount: 0
63
+ },
64
+ embed: {
65
+ appCount: 0
66
+ },
67
+ 'external-content': {
68
+ appCount: 0
69
+ },
70
+ formatting: {
71
+ appCount: 0
72
+ },
73
+ media: {
74
+ appCount: 0
75
+ },
76
+ navigation: {
77
+ appCount: 0
78
+ },
79
+ other: {
80
+ appCount: 0
81
+ },
82
+ reporting: {
83
+ appCount: 0
84
+ },
85
+ skills: {
86
+ appCount: 0
87
+ },
88
+ structure: {
89
+ appCount: 0
90
+ },
91
+ 'text-formatting': {
92
+ appCount: 0
93
+ },
94
+ uncategorized: {
95
+ appCount: 0
96
+ },
97
+ visuals: {
98
+ appCount: 0
99
+ }
100
+ }
101
+ };
102
+ var _iterator = _createForOfIteratorHelper(items),
103
+ _step;
104
+ try {
105
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
106
+ var _item$categories$map$, _item$categories;
107
+ var item = _step.value;
108
+ var normalizedCategories = new Set((_item$categories$map$ = (_item$categories = item.categories) === null || _item$categories === void 0 ? void 0 : _item$categories.map(function (category) {
109
+ return category.trim().toLowerCase();
110
+ }).filter(Boolean)) !== null && _item$categories$map$ !== void 0 ? _item$categories$map$ : []);
111
+ var hasUnknownCategory = normalizedCategories.size === 0;
112
+ var _iterator2 = _createForOfIteratorHelper(normalizedCategories),
113
+ _step2;
114
+ try {
115
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
116
+ var category = _step2.value;
117
+ if (isLegacyCategoryKey(category)) {
118
+ attributes.legacyCategory[category].appCount += 1;
119
+ } else {
120
+ hasUnknownCategory = true;
121
+ }
122
+ }
123
+ } catch (err) {
124
+ _iterator2.e(err);
125
+ } finally {
126
+ _iterator2.f();
127
+ }
128
+ if (hasUnknownCategory) {
129
+ attributes.legacyCategory.uncategorized.appCount += 1;
130
+ }
131
+ var _iterator3 = _createForOfIteratorHelper(getQuickInsertMenuItemParents({
132
+ categories: item.categories,
133
+ rank: 0
134
+ })),
135
+ _step3;
136
+ try {
137
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
138
+ var key = _step3.value.key;
139
+ var categoryKey = sectionCategoryKeys[key];
140
+ if (categoryKey) {
141
+ attributes.category[categoryKey].appCount += 1;
142
+ }
143
+ }
144
+ } catch (err) {
145
+ _iterator3.e(err);
146
+ } finally {
147
+ _iterator3.f();
148
+ }
149
+ }
150
+ } catch (err) {
151
+ _iterator.e(err);
152
+ } finally {
153
+ _iterator.f();
154
+ }
155
+ return attributes;
156
+ };
157
+ export var createQuickInsertItemsAnalyticsScheduler = function createQuickInsertItemsAnalyticsScheduler(dispatchAnalyticsEvent) {
158
+ var timeoutId;
159
+ var animationFrameId;
160
+ var idleCallbackId;
161
+ var destroyed = false;
162
+ var scheduled = false;
163
+ var emit = function emit(items) {
164
+ if (destroyed) {
165
+ return;
166
+ }
167
+ dispatchAnalyticsEvent({
168
+ action: ACTION.QUICK_INSERT_INFORMATION,
169
+ actionSubject: ACTION_SUBJECT.QUICK_INSERT,
170
+ attributes: calculateQuickInsertItemsAttributes(items),
171
+ eventType: EVENT_TYPE.OPERATIONAL
172
+ });
173
+ };
174
+ return {
175
+ destroy: function destroy() {
176
+ destroyed = true;
177
+ if (timeoutId !== undefined) {
178
+ clearTimeout(timeoutId);
179
+ }
180
+ if (animationFrameId !== undefined && typeof window !== 'undefined') {
181
+ window.cancelAnimationFrame(animationFrameId);
182
+ }
183
+ if (idleCallbackId !== undefined && typeof window !== 'undefined' && typeof window.cancelIdleCallback === 'function') {
184
+ window.cancelIdleCallback(idleCallbackId);
185
+ }
186
+ },
187
+ schedule: function schedule(items) {
188
+ if (scheduled || destroyed) {
189
+ return;
190
+ }
191
+ scheduled = true;
192
+ timeoutId = setTimeout(function () {
193
+ if (destroyed || typeof window === 'undefined') {
194
+ return;
195
+ }
196
+ if (typeof window.requestIdleCallback === 'function') {
197
+ idleCallbackId = window.requestIdleCallback(function () {
198
+ return emit(items);
199
+ });
200
+ } else if (typeof window.requestAnimationFrame === 'function') {
201
+ animationFrameId = window.requestAnimationFrame(function () {
202
+ return emit(items);
203
+ });
204
+ }
205
+ }, QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS);
206
+ }
207
+ };
208
+ };
@@ -15,6 +15,7 @@ import ShowMoreHorizontalIcon from '@atlaskit/icon/core/show-more-horizontal';
15
15
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
16
16
  import { fg } from '@atlaskit/platform-feature-flags';
17
17
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
18
+ import { createQuickInsertItemsAnalyticsScheduler } from './app-category-analytics';
18
19
  import { createInsertItem, openElementBrowser as openElementBrowserCommand, openElementBrowserModal as _openElementBrowserModal } from './pm-plugins/commands';
19
20
  import { getQuickInsertOpenExperiencePlugin } from './pm-plugins/experiences/quick-insert-open-experience';
20
21
  import { pluginKey } from './pm-plugins/plugin-key';
@@ -120,8 +121,9 @@ export var quickInsertPlugin = function quickInsertPlugin(_ref) {
120
121
  plugin: function plugin(_ref6) {
121
122
  var providerFactory = _ref6.providerFactory,
122
123
  getIntl = _ref6.getIntl,
123
- dispatch = _ref6.dispatch;
124
- return quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, options === null || options === void 0 ? void 0 : options.emptyStateHandler);
124
+ dispatch = _ref6.dispatch,
125
+ dispatchAnalyticsEvent = _ref6.dispatchAnalyticsEvent;
126
+ return quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, options === null || options === void 0 ? void 0 : options.emptyStateHandler);
125
127
  }
126
128
  }, {
127
129
  name: 'quickInsertOpenExperience',
@@ -310,7 +312,7 @@ var setProviderState = function setProviderState(providerState) {
310
312
  return true;
311
313
  };
312
314
  };
313
- function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, emptyStateHandler) {
315
+ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, dispatchAnalyticsEvent, emptyStateHandler) {
314
316
  return new SafePlugin({
315
317
  key: pluginKey,
316
318
  state: {
@@ -344,6 +346,8 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
344
346
  }
345
347
  },
346
348
  view: function view(editorView) {
349
+ var quickInsertItemsAnalyticsScheduler;
350
+ var isDestroyed = false;
347
351
  var providerHandler = /*#__PURE__*/function () {
348
352
  var _ref14 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_name, providerPromise) {
349
353
  var provider, providedItems, _t;
@@ -367,6 +371,10 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
367
371
  provider: provider,
368
372
  providedItems: providedItems
369
373
  })(editorView.state, editorView.dispatch);
374
+ if (!isDestroyed && !quickInsertItemsAnalyticsScheduler && isExperimentEnabled('platform_editor_slash_app_category_analytics')) {
375
+ quickInsertItemsAnalyticsScheduler = createQuickInsertItemsAnalyticsScheduler(dispatchAnalyticsEvent);
376
+ quickInsertItemsAnalyticsScheduler.schedule(providedItems);
377
+ }
370
378
  _context.next = 5;
371
379
  break;
372
380
  case 4:
@@ -387,6 +395,9 @@ function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispat
387
395
  providerFactory.subscribe('quickInsertProvider', providerHandler);
388
396
  return {
389
397
  destroy: function destroy() {
398
+ var _quickInsertItemsAnal;
399
+ isDestroyed = true;
400
+ (_quickInsertItemsAnal = quickInsertItemsAnalyticsScheduler) === null || _quickInsertItemsAnal === void 0 || _quickInsertItemsAnal.destroy();
390
401
  providerFactory.unsubscribe('quickInsertProvider', providerHandler);
391
402
  }
392
403
  };
@@ -0,0 +1,9 @@
1
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
2
+ import type { QuickInsertInformationAttributes } from '@atlaskit/editor-common/analytics/types/quick-insert-events';
3
+ import type { QuickInsertItem } from '@atlaskit/editor-common/provider-factory';
4
+ export declare const QUICK_INSERT_ITEMS_ANALYTICS_DELAY_MS = 10000;
5
+ export declare const calculateQuickInsertItemsAttributes: (items: readonly QuickInsertItem[]) => QuickInsertInformationAttributes;
6
+ export declare const createQuickInsertItemsAnalyticsScheduler: (dispatchAnalyticsEvent: DispatchAnalyticsEvent) => {
7
+ destroy: () => void;
8
+ schedule: (items: readonly QuickInsertItem[]) => void;
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-quick-insert",
3
- "version": "13.1.1",
3
+ "version": "13.1.3",
4
4
  "description": "Quick insert plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -30,16 +30,16 @@
30
30
  "@atlaskit/editor-prosemirror": "^8.0.0",
31
31
  "@atlaskit/editor-ui-control-model": "^2.4.0",
32
32
  "@atlaskit/icon": "^37.3.0",
33
- "@atlaskit/modal-dialog": "^16.2.0",
33
+ "@atlaskit/modal-dialog": "^16.3.0",
34
34
  "@atlaskit/platform-feature-experiments": "^0.3.0",
35
35
  "@atlaskit/platform-feature-flags": "^2.1.0",
36
- "@atlaskit/tmp-editor-statsig": "^140.0.0",
36
+ "@atlaskit/tmp-editor-statsig": "^141.1.0",
37
37
  "@atlaskit/tokens": "^16.3.0",
38
38
  "@babel/runtime": "^7.0.0",
39
39
  "@emotion/react": "^11.7.1"
40
40
  },
41
41
  "peerDependencies": {
42
- "@atlaskit/editor-common": "^117.2.0",
42
+ "@atlaskit/editor-common": "^117.3.0",
43
43
  "react": "^18.2.0 || ^19.2.0",
44
44
  "react-dom": "^18.2.0 || ^19.2.0",
45
45
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"