@atlaskit/editor-plugin-metrics 3.1.1 → 3.2.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,26 @@
1
1
  # @atlaskit/editor-plugin-metrics
2
2
 
3
+ ## 3.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#114961](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/114961)
8
+ [`f31ba30a89a05`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f31ba30a89a05) -
9
+ ED-26301 Add logic to exclude transactions that shouldn't increment totalActionCount
10
+
11
+ ## 3.2.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#108974](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108974)
16
+ [`2ed04755a098e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2ed04755a098e) -
17
+ ED-26233 Start activity session in metrics plugin when user starts dragging nodes and opens
18
+ element browser
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 3.1.1
4
25
 
5
26
  ### Patch Changes
@@ -10,6 +10,7 @@ var _analytics = require("./pm-plugins/utils/analytics");
10
10
  * Metrics plugin to be added to an `EditorPresetBuilder` and used with `ComposableEditor`
11
11
  * from `@atlaskit/editor-core`.
12
12
  */
13
+
13
14
  var metricsPlugin = exports.metricsPlugin = function metricsPlugin(_ref) {
14
15
  var api = _ref.api;
15
16
  return {
@@ -23,25 +24,67 @@ var metricsPlugin = exports.metricsPlugin = function metricsPlugin(_ref) {
23
24
  }];
24
25
  },
25
26
  commands: {
26
- stopActiveSession: function stopActiveSession() {
27
+ startActiveSessionTimer: function startActiveSessionTimer() {
27
28
  return function (_ref2) {
28
29
  var tr = _ref2.tr;
30
+ var pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
31
+ if (!(pluginState !== null && pluginState !== void 0 && pluginState.intentToStartEditTime)) {
32
+ return tr;
33
+ }
34
+ return tr.setMeta(_main.metricsKey, {
35
+ shouldStartTimer: true,
36
+ shouldPersistActiveSession: false
37
+ });
38
+ };
39
+ },
40
+ stopActiveSession: function stopActiveSession() {
41
+ return function (_ref3) {
42
+ var tr = _ref3.tr;
29
43
  if (!api) {
30
44
  return tr;
31
45
  }
32
- var newTr = tr;
33
46
  var pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
47
+ if (pluginState !== null && pluginState !== void 0 && pluginState.shouldPersistActiveSession) {
48
+ return tr;
49
+ }
34
50
  if (pluginState && pluginState.totalActionCount > 0 && pluginState.activeSessionTime > 0) {
35
51
  var payloadToSend = (0, _analytics.getAnalyticsPayload)({
36
52
  currentContent: tr.doc.content,
37
53
  pluginState: pluginState
38
54
  });
39
- api === null || api === void 0 || api.analytics.actions.attachAnalyticsEvent(payloadToSend)(newTr);
55
+ api === null || api === void 0 || api.analytics.actions.attachAnalyticsEvent(payloadToSend)(tr);
40
56
  }
41
- newTr.setMeta(_main.metricsKey, {
57
+ tr.setMeta(_main.metricsKey, {
42
58
  stopActiveSession: true
43
59
  });
44
- return newTr;
60
+ return tr;
61
+ };
62
+ },
63
+ handleIntentToStartEdit: function handleIntentToStartEdit(_ref4) {
64
+ var newSelection = _ref4.newSelection,
65
+ _ref4$shouldStartTime = _ref4.shouldStartTimer,
66
+ shouldStartTimer = _ref4$shouldStartTime === void 0 ? true : _ref4$shouldStartTime,
67
+ shouldPersistActiveSession = _ref4.shouldPersistActiveSession;
68
+ return function (_ref5) {
69
+ var tr = _ref5.tr;
70
+ if (!api) {
71
+ return tr;
72
+ }
73
+ var pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
74
+ if (!pluginState || pluginState.intentToStartEditTime) {
75
+ if (shouldPersistActiveSession !== (pluginState === null || pluginState === void 0 ? void 0 : pluginState.shouldPersistActiveSession)) {
76
+ return tr.setMeta(_main.metricsKey, {
77
+ shouldPersistActiveSession: shouldPersistActiveSession
78
+ });
79
+ }
80
+ }
81
+ tr.setMeta(_main.metricsKey, {
82
+ intentToStartEditTime: performance.now(),
83
+ shouldStartTimer: shouldStartTimer,
84
+ newSelection: newSelection,
85
+ shouldPersistActiveSession: shouldPersistActiveSession
86
+ });
87
+ return tr;
45
88
  };
46
89
  }
47
90
  },
@@ -7,12 +7,12 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.metricsKey = exports.initialPluginState = exports.createPlugin = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _bindEventListener = require("bind-event-listener");
10
- var _steps = require("@atlaskit/adf-schema/steps");
11
10
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
12
- var _utils = require("@atlaskit/editor-common/utils");
13
11
  var _state = require("@atlaskit/editor-prosemirror/state");
12
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
14
13
  var _activeSessionTimer = require("./utils/active-session-timer");
15
14
  var _analytics = require("./utils/analytics");
15
+ var _checkTrActionType = require("./utils/check-tr-action-type");
16
16
  var _isNonTextUndo = require("./utils/is-non-text-undo");
17
17
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
18
  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; }
@@ -46,19 +46,36 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
46
46
  },
47
47
  // eslint-disable-next-line @typescript-eslint/max-params
48
48
  apply: function apply(tr, pluginState, oldState, newState) {
49
+ var _meta$shouldPersistAc, _tr$steps;
50
+ if (tr.getMeta('isRemote') || tr.getMeta('replaceDocument')) {
51
+ return pluginState;
52
+ }
49
53
  var meta = tr.getMeta(metricsKey);
50
- var intentToStartEditTime = (meta === null || meta === void 0 ? void 0 : meta.intentToStartEditTime) || pluginState.intentToStartEditTime;
54
+
55
+ // If the active session is stopped, reset the plugin state, and set initialContent to new doc content
51
56
  if (meta && meta.stopActiveSession) {
52
57
  return _objectSpread(_objectSpread({}, initialPluginState), {}, {
53
58
  initialContent: newState.doc.content
54
59
  });
55
60
  }
56
- if (!intentToStartEditTime) {
57
- if (tr.docChanged && !tr.getMeta('replaceDocument')) {
58
- intentToStartEditTime = performance.now();
59
- } else {
60
- return pluginState;
61
- }
61
+ var shouldPersistActiveSession = (_meta$shouldPersistAc = meta === null || meta === void 0 ? void 0 : meta.shouldPersistActiveSession) !== null && _meta$shouldPersistAc !== void 0 ? _meta$shouldPersistAc : pluginState.shouldPersistActiveSession;
62
+ var hasDocChanges = tr.steps.length > 0 && ((_tr$steps = tr.steps) === null || _tr$steps === void 0 ? void 0 : _tr$steps.some(function (step) {
63
+ return step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep || step instanceof _transform.AddMarkStep;
64
+ }));
65
+ var intentToStartEditTime = (meta === null || meta === void 0 ? void 0 : meta.intentToStartEditTime) || pluginState.intentToStartEditTime;
66
+ var now = performance.now();
67
+ if (!intentToStartEditTime && !hasDocChanges && !tr.storedMarksSet) {
68
+ return pluginState;
69
+ }
70
+ if (!intentToStartEditTime && (hasDocChanges || tr.storedMarksSet)) {
71
+ intentToStartEditTime = now;
72
+ }
73
+
74
+ // Start active session timer if intentToStartEditTime is set and shouldStartTimer is true
75
+ // shouldPersistActiveSession is set to true when dragging block controls and when insert menu is open
76
+ // Timer should start when menu closes or dragging stops
77
+ if (intentToStartEditTime && meta !== null && meta !== void 0 && meta.shouldStartTimer && !pluginState.shouldPersistActiveSession) {
78
+ timer.startTimer();
62
79
  }
63
80
  var undoCount = (0, _isNonTextUndo.isNonTextUndo)(tr) ? 1 : 0;
64
81
  var newActionTypeCount = pluginState.actionTypeCount ? _objectSpread(_objectSpread({}, pluginState.actionTypeCount), {}, {
@@ -66,47 +83,90 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
66
83
  }) : _objectSpread(_objectSpread({}, initialPluginState.actionTypeCount), {}, {
67
84
  undoCount: undoCount
68
85
  });
69
- var canIgnoreTr = function canIgnoreTr() {
70
- return !tr.steps.every(function (e) {
71
- return e instanceof _steps.AnalyticsStep;
72
- });
73
- };
74
- if (tr.docChanged && canIgnoreTr()) {
75
- var now = performance.now();
86
+ if (hasDocChanges) {
76
87
  timer.startTimer();
77
88
  var actionTypeCount = pluginState.actionTypeCount,
78
89
  timeOfLastTextInput = pluginState.timeOfLastTextInput,
79
90
  totalActionCount = pluginState.totalActionCount,
80
- activeSessionTime = pluginState.activeSessionTime;
81
- // If previous and current action is text insertion, then don't increase total action count
82
- var isActionTextInput = (0, _utils.isTextInput)(tr);
83
- var newActiveSessionTime = activeSessionTime + (now - intentToStartEditTime);
84
- var newTextInputCount = isActionTextInput ? actionTypeCount.textInputCount + 1 : actionTypeCount.textInputCount;
85
- var newTotalActionCount = pluginState.totalActionCount + 1;
86
- if (pluginState.timeOfLastTextInput && isActionTextInput) {
87
- newActiveSessionTime = activeSessionTime + (now - (timeOfLastTextInput || 0));
88
- newTextInputCount = actionTypeCount.textInputCount;
91
+ previousTrType = pluginState.previousTrType;
92
+ if ((0, _checkTrActionType.shouldSkipTr)(tr)) {
93
+ return pluginState;
94
+ }
95
+ var trType = (0, _checkTrActionType.checkTrActionType)(tr);
96
+ var shouldNotIncrementActionCount = false;
97
+ var shouldSetTimeOfLastTextInput = false;
98
+ var isTextInput = false;
99
+ if (trType) {
100
+ var _trType$extraData, _previousTrType$extra;
101
+ var isNotNewStatus = trType.type === _checkTrActionType.ActionType.UPDATING_STATUS && (previousTrType === null || previousTrType === void 0 ? void 0 : previousTrType.type) === _checkTrActionType.ActionType.UPDATING_STATUS && (trType === null || trType === void 0 || (_trType$extraData = trType.extraData) === null || _trType$extraData === void 0 ? void 0 : _trType$extraData.statusId) === (previousTrType === null || previousTrType === void 0 || (_previousTrType$extra = previousTrType.extraData) === null || _previousTrType$extra === void 0 ? void 0 : _previousTrType$extra.statusId);
102
+ var isAddingTextToListNode = trType.type === _checkTrActionType.ActionType.TEXT_INPUT && !!previousTrType && [_checkTrActionType.ActionType.UPDATING_NEW_LIST_TYPE_ITEM, _checkTrActionType.ActionType.INSERTING_NEW_LIST_TYPE_NODE].includes(previousTrType.type);
103
+ var isAddingNewListItemAfterTextInput = !!previousTrType && previousTrType.type === _checkTrActionType.ActionType.TEXT_INPUT && [_checkTrActionType.ActionType.UPDATING_NEW_LIST_TYPE_ITEM].includes(trType.type);
104
+
105
+ // Check if tr is textInput and only increment textInputCount if previous action was not textInput
106
+ isTextInput = [_checkTrActionType.ActionType.TEXT_INPUT, _checkTrActionType.ActionType.EMPTY_LINE_ADDED_OR_DELETED].includes(trType.type);
107
+
108
+ // timeOfLastTextInput should be set if tr includes continuous text input on the same node
109
+ shouldSetTimeOfLastTextInput = [_checkTrActionType.ActionType.TEXT_INPUT, _checkTrActionType.ActionType.EMPTY_LINE_ADDED_OR_DELETED, _checkTrActionType.ActionType.UPDATING_NEW_LIST_TYPE_ITEM, _checkTrActionType.ActionType.INSERTING_NEW_LIST_TYPE_NODE, _checkTrActionType.ActionType.UPDATING_STATUS].includes(trType.type) || isNotNewStatus;
110
+
111
+ // Should not increase action count if tr is text input,
112
+ // empty line added or deleted, updating new list item or is updating same status node
113
+
114
+ shouldNotIncrementActionCount = isTextInput || isNotNewStatus || isAddingTextToListNode || isAddingNewListItemAfterTextInput;
115
+ }
116
+ var newTextInputCount = isTextInput ? actionTypeCount.textInputCount + 1 : actionTypeCount.textInputCount;
117
+ var newTotalActionCount = totalActionCount + 1;
118
+ if (timeOfLastTextInput && shouldNotIncrementActionCount) {
89
119
  newTotalActionCount = totalActionCount;
90
120
  }
121
+ if (timeOfLastTextInput && isTextInput && previousTrType && [_checkTrActionType.ActionType.TEXT_INPUT, _checkTrActionType.ActionType.EMPTY_LINE_ADDED_OR_DELETED, _checkTrActionType.ActionType.UPDATING_NEW_LIST_TYPE_ITEM, _checkTrActionType.ActionType.INSERTING_NEW_LIST_TYPE_NODE].includes(previousTrType.type)) {
122
+ newTextInputCount = actionTypeCount.textInputCount;
123
+ }
91
124
  var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
92
- activeSessionTime: newActiveSessionTime,
125
+ activeSessionTime: now - intentToStartEditTime,
93
126
  totalActionCount: newTotalActionCount,
94
- timeOfLastTextInput: isActionTextInput ? now : undefined,
127
+ timeOfLastTextInput: shouldSetTimeOfLastTextInput ? now : undefined,
95
128
  contentSizeChanged: pluginState.contentSizeChanged + (newState.doc.content.size - oldState.doc.content.size),
96
129
  actionTypeCount: _objectSpread(_objectSpread({}, newActionTypeCount), {}, {
97
130
  textInputCount: newTextInputCount
98
- })
131
+ }),
132
+ intentToStartEditTime: intentToStartEditTime,
133
+ shouldPersistActiveSession: shouldPersistActiveSession,
134
+ previousTrType: trType
99
135
  });
100
136
  return newPluginState;
101
137
  }
102
138
  return _objectSpread(_objectSpread({}, pluginState), {}, {
103
139
  lastSelection: (meta === null || meta === void 0 ? void 0 : meta.newSelection) || pluginState.lastSelection,
104
140
  intentToStartEditTime: intentToStartEditTime,
105
- actionTypeCount: newActionTypeCount
141
+ actionTypeCount: newActionTypeCount,
142
+ shouldPersistActiveSession: shouldPersistActiveSession
106
143
  });
107
144
  }
108
145
  },
109
146
  view: function view(_view) {
147
+ var _api$blockControls;
148
+ var handleIsDraggingChanged = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.onChange(function (_ref) {
149
+ var nextSharedState = _ref.nextSharedState,
150
+ prevSharedState = _ref.prevSharedState;
151
+ if (nextSharedState) {
152
+ api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
153
+ var tr = _ref2.tr;
154
+ if (!(prevSharedState !== null && prevSharedState !== void 0 && prevSharedState.isDragging) && nextSharedState.isDragging) {
155
+ api === null || api === void 0 || api.metrics.commands.handleIntentToStartEdit({
156
+ shouldStartTimer: false,
157
+ shouldPersistActiveSession: true
158
+ })({
159
+ tr: tr
160
+ });
161
+ } else if (prevSharedState !== null && prevSharedState !== void 0 && prevSharedState.isDragging && !nextSharedState.isDragging) {
162
+ api === null || api === void 0 || api.metrics.commands.startActiveSessionTimer()({
163
+ tr: tr
164
+ });
165
+ }
166
+ return tr;
167
+ });
168
+ }
169
+ });
110
170
  var fireAnalyticsEvent = function fireAnalyticsEvent() {
111
171
  var pluginState = metricsKey.getState(_view.state);
112
172
  if (!pluginState) {
@@ -133,6 +193,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
133
193
  fireAnalyticsEvent();
134
194
  timer.cleanupTimer();
135
195
  unbindBeforeUnload();
196
+ handleIsDraggingChanged === null || handleIsDraggingChanged === void 0 || handleIsDraggingChanged();
136
197
  }
137
198
  };
138
199
  },
@@ -140,19 +201,12 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
140
201
  handleDOMEvents: {
141
202
  click: function click(view) {
142
203
  var _pluginState$lastSele, _pluginState$lastSele2;
143
- var pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
144
- if (!pluginState || pluginState.intentToStartEditTime) {
145
- return false;
146
- }
147
204
  var newSelection = view.state.tr.selection;
148
- var newTr = view.state.tr;
205
+ var pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
149
206
  if ((pluginState === null || pluginState === void 0 || (_pluginState$lastSele = pluginState.lastSelection) === null || _pluginState$lastSele === void 0 ? void 0 : _pluginState$lastSele.from) !== newSelection.from && (pluginState === null || pluginState === void 0 || (_pluginState$lastSele2 = pluginState.lastSelection) === null || _pluginState$lastSele2 === void 0 ? void 0 : _pluginState$lastSele2.to) !== newSelection.to) {
150
- newTr.setMeta(metricsKey, {
151
- intentToStartEditTime: performance.now(),
207
+ api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.metrics.commands.handleIntentToStartEdit({
152
208
  newSelection: newSelection
153
- });
154
- view.dispatch(newTr);
155
- timer.startTimer();
209
+ }));
156
210
  }
157
211
  return false;
158
212
  }
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.shouldSkipTr = exports.checkTrActionType = exports.ActionType = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _steps = require("@atlaskit/adf-schema/steps");
10
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
11
+ var ActionType = exports.ActionType = /*#__PURE__*/function (ActionType) {
12
+ ActionType["TEXT_INPUT"] = "textInput";
13
+ ActionType["EMPTY_LINE_ADDED_OR_DELETED"] = "emptyLineAddedOrDeleted";
14
+ ActionType["INSERTED_FROM_TYPE_AHEAD"] = "insertedFromTypeAhead";
15
+ ActionType["INSERTING_NEW_LIST_TYPE_NODE"] = "insertingNewListTypeNode";
16
+ ActionType["UPDATING_NEW_LIST_TYPE_ITEM"] = "updatingNewListItem";
17
+ ActionType["ADDING_LINK"] = "addingLink";
18
+ ActionType["UPDATING_STATUS"] = "updatingStatus";
19
+ return ActionType;
20
+ }({});
21
+ var isTextInput = function isTextInput(step) {
22
+ var _ref = step,
23
+ content = _ref.slice.content,
24
+ from = _ref.from,
25
+ to = _ref.to;
26
+ var node = content.firstChild;
27
+ var isAddingCharacter = from === to && content.childCount === 1 && !!node && !!node.text && node.text.length === 1;
28
+ var isDeletingCharacter = to - from === 1 && content.childCount === 0;
29
+ return isAddingCharacter || isDeletingCharacter;
30
+ };
31
+ var isEmptyLineAddedOrDeleted = function isEmptyLineAddedOrDeleted(step) {
32
+ var _ref2 = step,
33
+ content = _ref2.slice.content,
34
+ from = _ref2.from,
35
+ to = _ref2.to;
36
+ var isEmptyLineDeleted = to - from === 2 && content.size === 0;
37
+ if (isEmptyLineDeleted) {
38
+ return true;
39
+ }
40
+ var isEmptyLineAdded = false;
41
+ content.forEach(function (node) {
42
+ isEmptyLineAdded = node.type.name === 'paragraph' && node.content.size === 0;
43
+ });
44
+ return isEmptyLineAdded;
45
+ };
46
+ var isUpdatingListTypeNode = function isUpdatingListTypeNode(step) {
47
+ var slice = step.slice;
48
+ var childCount = slice.content.childCount;
49
+ if (childCount < 1) {
50
+ return false;
51
+ }
52
+ var isListTypeNode = false;
53
+ slice.content.forEach(function (node) {
54
+ isListTypeNode = ['decisionList', 'decisionItem', 'bulletList', 'listItem', 'orderedList', 'taskList', 'taskItem'].includes(node.type.name);
55
+ });
56
+ if (!isListTypeNode) {
57
+ return false;
58
+ }
59
+ return childCount === 1 ? ActionType.INSERTING_NEW_LIST_TYPE_NODE : ActionType.UPDATING_NEW_LIST_TYPE_ITEM;
60
+ };
61
+ var isUpdatingStatus = function isUpdatingStatus(step) {
62
+ var slice = step.slice;
63
+ var firstChild = slice.content.firstChild;
64
+ if (!firstChild) {
65
+ return undefined;
66
+ }
67
+ return firstChild.type.name === 'status' && firstChild.attrs.localId;
68
+ };
69
+ var isAddingLink = function isAddingLink(tr) {
70
+ var hasLinkStep = tr.steps.some(function (step) {
71
+ return step instanceof _steps.LinkMetaStep;
72
+ });
73
+ var hasReplaceStep = tr.steps.some(function (step) {
74
+ return step instanceof _transform.ReplaceStep;
75
+ });
76
+ return hasLinkStep && !hasReplaceStep;
77
+ };
78
+ var isTypeAheadRelatedTr = function isTypeAheadRelatedTr(tr) {
79
+ var _tr$getMeta;
80
+ if (((_tr$getMeta = tr.getMeta('typeAheadPlugin$')) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.action) === 'INSERT_RAW_QUERY') {
81
+ return 'INSERT_RAW_QUERY';
82
+ }
83
+ if (!tr.getMeta('appendedTransaction')) {
84
+ return false;
85
+ }
86
+ var insertTypeAheadStep = tr.steps.find(function (step) {
87
+ return step instanceof _steps.InsertTypeAheadStep;
88
+ });
89
+ var replaceStep = tr.steps.find(function (step) {
90
+ return step instanceof _transform.ReplaceStep;
91
+ });
92
+ if (!insertTypeAheadStep || !replaceStep) {
93
+ return false;
94
+ }
95
+ return insertTypeAheadStep instanceof _steps.InsertTypeAheadStep && insertTypeAheadStep.stage;
96
+ };
97
+ var shouldSkipTr = exports.shouldSkipTr = function shouldSkipTr(tr) {
98
+ var resolvingLink = isAddingLink(tr);
99
+ if (resolvingLink) {
100
+ return true;
101
+ }
102
+ var typeAheadRelatedTr = isTypeAheadRelatedTr(tr);
103
+ if (typeAheadRelatedTr) {
104
+ return typeAheadRelatedTr !== 'INSERTING_ITEM';
105
+ } else {
106
+ return tr.getMeta('appendedTransaction');
107
+ }
108
+ };
109
+ var checkTrActionType = exports.checkTrActionType = function checkTrActionType(tr) {
110
+ if (tr.getMeta('input_rule_plugin_transaction')) {
111
+ return {
112
+ type: ActionType.INSERTING_NEW_LIST_TYPE_NODE
113
+ };
114
+ }
115
+ var stepsLength = tr.steps.length;
116
+ if (stepsLength <= 0) {
117
+ return undefined;
118
+ }
119
+ if (isAddingLink(tr)) {
120
+ return {
121
+ type: ActionType.ADDING_LINK
122
+ };
123
+ }
124
+ var _tr$steps = (0, _slicedToArray2.default)(tr.steps, 1),
125
+ firstStep = _tr$steps[0];
126
+ var isReplaceStep = firstStep instanceof _transform.ReplaceStep;
127
+ var isReplaceAroundStep = firstStep instanceof _transform.ReplaceAroundStep;
128
+ if (!isReplaceStep && !isReplaceAroundStep) {
129
+ return undefined;
130
+ }
131
+ if (isReplaceStep) {
132
+ if (isTextInput(firstStep)) {
133
+ return {
134
+ type: ActionType.TEXT_INPUT
135
+ };
136
+ }
137
+ if (isEmptyLineAddedOrDeleted(firstStep)) {
138
+ return {
139
+ type: ActionType.EMPTY_LINE_ADDED_OR_DELETED
140
+ };
141
+ }
142
+ var statusId = isUpdatingStatus(firstStep);
143
+ if (statusId) {
144
+ return {
145
+ type: ActionType.UPDATING_STATUS,
146
+ extraData: {
147
+ statusId: statusId
148
+ }
149
+ };
150
+ }
151
+ }
152
+ var updatingListTypeNode = isUpdatingListTypeNode(firstStep);
153
+ if (updatingListTypeNode) {
154
+ return {
155
+ type: updatingListTypeNode
156
+ };
157
+ }
158
+ return undefined;
159
+ };
@@ -4,6 +4,7 @@ import { getAnalyticsPayload } from './pm-plugins/utils/analytics';
4
4
  * Metrics plugin to be added to an `EditorPresetBuilder` and used with `ComposableEditor`
5
5
  * from `@atlaskit/editor-core`.
6
6
  */
7
+
7
8
  export const metricsPlugin = ({
8
9
  api
9
10
  }) => ({
@@ -15,25 +16,65 @@ export const metricsPlugin = ({
15
16
  }];
16
17
  },
17
18
  commands: {
19
+ startActiveSessionTimer: () => ({
20
+ tr
21
+ }) => {
22
+ const pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
23
+ if (!(pluginState !== null && pluginState !== void 0 && pluginState.intentToStartEditTime)) {
24
+ return tr;
25
+ }
26
+ return tr.setMeta(metricsKey, {
27
+ shouldStartTimer: true,
28
+ shouldPersistActiveSession: false
29
+ });
30
+ },
18
31
  stopActiveSession: () => ({
19
32
  tr
20
33
  }) => {
21
34
  if (!api) {
22
35
  return tr;
23
36
  }
24
- const newTr = tr;
25
37
  const pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
38
+ if (pluginState !== null && pluginState !== void 0 && pluginState.shouldPersistActiveSession) {
39
+ return tr;
40
+ }
26
41
  if (pluginState && pluginState.totalActionCount > 0 && pluginState.activeSessionTime > 0) {
27
42
  const payloadToSend = getAnalyticsPayload({
28
43
  currentContent: tr.doc.content,
29
44
  pluginState
30
45
  });
31
- api === null || api === void 0 ? void 0 : api.analytics.actions.attachAnalyticsEvent(payloadToSend)(newTr);
46
+ api === null || api === void 0 ? void 0 : api.analytics.actions.attachAnalyticsEvent(payloadToSend)(tr);
32
47
  }
33
- newTr.setMeta(metricsKey, {
48
+ tr.setMeta(metricsKey, {
34
49
  stopActiveSession: true
35
50
  });
36
- return newTr;
51
+ return tr;
52
+ },
53
+ handleIntentToStartEdit: ({
54
+ newSelection,
55
+ shouldStartTimer = true,
56
+ shouldPersistActiveSession
57
+ }) => ({
58
+ tr
59
+ }) => {
60
+ if (!api) {
61
+ return tr;
62
+ }
63
+ const pluginState = api === null || api === void 0 ? void 0 : api.metrics.sharedState.currentState();
64
+ if (!pluginState || pluginState.intentToStartEditTime) {
65
+ if (shouldPersistActiveSession !== (pluginState === null || pluginState === void 0 ? void 0 : pluginState.shouldPersistActiveSession)) {
66
+ return tr.setMeta(metricsKey, {
67
+ shouldPersistActiveSession: shouldPersistActiveSession
68
+ });
69
+ }
70
+ }
71
+ tr.setMeta(metricsKey, {
72
+ intentToStartEditTime: performance.now(),
73
+ shouldStartTimer,
74
+ newSelection,
75
+ shouldPersistActiveSession
76
+ });
77
+ return tr;
37
78
  }
38
79
  },
39
80
  getSharedState(editorState) {