@atlaskit/editor-plugin-synced-block 5.3.10 → 5.3.12

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/editor-commands/index.js +72 -7
  3. package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +221 -81
  4. package/dist/cjs/syncedBlockPlugin.js +2 -2
  5. package/dist/cjs/types/index.js +5 -1
  6. package/dist/cjs/ui/CreateSyncedBlockDropdownItem.js +2 -1
  7. package/dist/cjs/ui/SyncedLocationDropdown.js +32 -6
  8. package/dist/cjs/ui/floating-toolbar.js +8 -4
  9. package/dist/es2019/editor-commands/index.js +72 -7
  10. package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +206 -71
  11. package/dist/es2019/syncedBlockPlugin.js +1 -1
  12. package/dist/es2019/types/index.js +5 -1
  13. package/dist/es2019/ui/CreateSyncedBlockDropdownItem.js +2 -1
  14. package/dist/es2019/ui/SyncedLocationDropdown.js +30 -6
  15. package/dist/es2019/ui/floating-toolbar.js +7 -3
  16. package/dist/esm/editor-commands/index.js +72 -7
  17. package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +221 -81
  18. package/dist/esm/syncedBlockPlugin.js +2 -2
  19. package/dist/esm/types/index.js +5 -1
  20. package/dist/esm/ui/CreateSyncedBlockDropdownItem.js +2 -1
  21. package/dist/esm/ui/SyncedLocationDropdown.js +32 -6
  22. package/dist/esm/ui/floating-toolbar.js +8 -4
  23. package/dist/types/editor-commands/index.d.ts +3 -2
  24. package/dist/types/syncedBlockPluginType.d.ts +2 -1
  25. package/dist/types/types/index.d.ts +4 -0
  26. package/dist/types/ui/SyncedLocationDropdown.d.ts +4 -1
  27. package/dist/types-ts4.5/editor-commands/index.d.ts +3 -2
  28. package/dist/types-ts4.5/syncedBlockPluginType.d.ts +2 -1
  29. package/dist/types-ts4.5/types/index.d.ts +4 -0
  30. package/dist/types-ts4.5/ui/SyncedLocationDropdown.d.ts +4 -1
  31. package/package.json +13 -10
@@ -18,6 +18,7 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
18
18
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
19
19
  var _react2 = require("@compiled/react");
20
20
  var _dropdownMenu = _interopRequireWildcard(require("@atlaskit/dropdown-menu"));
21
+ var _analytics = require("@atlaskit/editor-common/analytics");
21
22
  var _messages = require("@atlaskit/editor-common/messages");
22
23
  var _ui = require("@atlaskit/editor-common/ui");
23
24
  var _icon = require("@atlaskit/icon");
@@ -28,6 +29,7 @@ var _quotationMark = _interopRequireDefault(require("@atlaskit/icon/core/quotati
28
29
  var _statusError = _interopRequireDefault(require("@atlaskit/icon/core/status-error"));
29
30
  var _logo = require("@atlaskit/logo");
30
31
  var _lozenge = _interopRequireDefault(require("@atlaskit/lozenge"));
32
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
31
33
  var _compiled = require("@atlaskit/primitives/compiled");
32
34
  var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
33
35
  var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
@@ -168,7 +170,8 @@ var SyncedLocationDropdown = exports.SyncedLocationDropdown = function SyncedLoc
168
170
  resourceId = _ref4.resourceId,
169
171
  intl = _ref4.intl,
170
172
  isSource = _ref4.isSource,
171
- localId = _ref4.localId;
173
+ localId = _ref4.localId,
174
+ api = _ref4.api;
172
175
  var formatMessage = intl.formatMessage;
173
176
  var triggerTitle = formatMessage(_messages.syncBlockMessages.syncedLocationDropdownTitle);
174
177
  var _useState = (0, _react.useState)(false),
@@ -181,12 +184,14 @@ var SyncedLocationDropdown = exports.SyncedLocationDropdown = function SyncedLoc
181
184
  var isOpen = _ref5.isOpen;
182
185
  return setIsOpen(isOpen);
183
186
  },
187
+ testId: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? 'synced-block-synced-locations-dropdown' : undefined,
184
188
  trigger: function trigger(_ref6) {
185
189
  var triggerRef = _ref6.triggerRef,
186
190
  triggerProps = (0, _objectWithoutProperties2.default)(_ref6, _excluded);
187
191
  return /*#__PURE__*/React.createElement(_ui.FloatingToolbarButton, (0, _extends2.default)({
188
192
  ref: triggerRef,
189
193
  areAnyNewToolbarFlagsEnabled: true,
194
+ selected: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? isOpen : undefined,
190
195
  iconAfter: /*#__PURE__*/React.createElement(_chevronDown.default, {
191
196
  color: "currentColor",
192
197
  spacing: "spacious",
@@ -201,7 +206,8 @@ var SyncedLocationDropdown = exports.SyncedLocationDropdown = function SyncedLoc
201
206
  resourceId: resourceId,
202
207
  intl: intl,
203
208
  isSource: isSource,
204
- localId: localId
209
+ localId: localId,
210
+ api: api
205
211
  }));
206
212
  };
207
213
  var DropdownContent = function DropdownContent(_ref7) {
@@ -209,7 +215,8 @@ var DropdownContent = function DropdownContent(_ref7) {
209
215
  resourceId = _ref7.resourceId,
210
216
  intl = _ref7.intl,
211
217
  isSource = _ref7.isSource,
212
- localId = _ref7.localId;
218
+ localId = _ref7.localId,
219
+ api = _ref7.api;
213
220
  var formatMessage = intl.formatMessage;
214
221
  var _useState3 = (0, _react.useState)('none'),
215
222
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
@@ -252,6 +259,20 @@ var DropdownContent = function DropdownContent(_ref7) {
252
259
  }();
253
260
  getReferenceData();
254
261
  }, [syncBlockStore, intl, isSource, localId, resourceId]);
262
+ var handleLocationClick = function handleLocationClick() {
263
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_1')) {
264
+ var _api$analytics;
265
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.fireAnalyticsEvent({
266
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL,
267
+ action: _analytics.ACTION.CLICKED,
268
+ actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
269
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_CLICK_SYNCED_LOCATION,
270
+ attributes: {
271
+ resourceId: resourceId
272
+ }
273
+ });
274
+ }
275
+ };
255
276
  var content = function content() {
256
277
  switch (fetchStatus) {
257
278
  case 'loading':
@@ -281,7 +302,10 @@ var DropdownContent = function DropdownContent(_ref7) {
281
302
  }),
282
303
  href: reference.url,
283
304
  target: "_blank",
284
- key: reference.title
305
+ key: reference.title,
306
+ onClick: function onClick() {
307
+ return handleLocationClick();
308
+ }
285
309
  }, /*#__PURE__*/React.createElement(ItemTitle, {
286
310
  title: reference.title || reference.url || '',
287
311
  formatMessage: formatMessage,
@@ -308,7 +332,8 @@ var LoadingScreen = function LoadingScreen() {
308
332
  var ErrorScreen = function ErrorScreen(_ref9) {
309
333
  var formatMessage = _ref9.formatMessage;
310
334
  return /*#__PURE__*/React.createElement(_compiled.Box, {
311
- xcss: styles.errorContainer
335
+ xcss: styles.errorContainer,
336
+ testId: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? 'synced-locations-dropdown-content-error' : undefined
312
337
  }, /*#__PURE__*/React.createElement(_compiled.Box, {
313
338
  xcss: styles.errorIcon
314
339
  }, /*#__PURE__*/React.createElement(_statusError.default, {
@@ -325,7 +350,8 @@ var NoResultScreen = function NoResultScreen(_ref0) {
325
350
  var formatMessage = _ref0.formatMessage;
326
351
  return /*#__PURE__*/React.createElement(_compiled.Stack, {
327
352
  xcss: styles.noResultsContainer,
328
- space: "space.100"
353
+ space: "space.100",
354
+ testId: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? 'synced-locations-dropdown-content-no-results' : undefined
329
355
  }, /*#__PURE__*/React.createElement(_compiled.Text, {
330
356
  as: "p"
331
357
  }, formatMessage(_messages.syncBlockMessages.syncedLocationDropdownNoResults)), /*#__PURE__*/React.createElement(_compiled.Text, {
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.getToolbarConfig = void 0;
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
+ var _analytics = require("@atlaskit/editor-common/analytics");
11
12
  var _messages = _interopRequireWildcard(require("@atlaskit/editor-common/messages"));
12
13
  var _ui = require("@atlaskit/editor-common/ui");
13
14
  var _utils = require("@atlaskit/editor-prosemirror/utils");
@@ -71,7 +72,8 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(stat
71
72
  resourceId: resourceId,
72
73
  localId: localId,
73
74
  intl: intl,
74
- isSource: isBodiedSyncBlock
75
+ isSource: isBodiedSyncBlock,
76
+ api: api
75
77
  });
76
78
  }
77
79
  };
@@ -87,7 +89,8 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(stat
87
89
  title: formatMessage(_messages.syncBlockMessages.unsyncButton),
88
90
  onClick: function onClick() {
89
91
  return (0, _editorCommands.unsync)(syncBlockStore, isBodiedSyncBlock, view);
90
- }
92
+ },
93
+ testId: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? isBodiedSyncBlock ? _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceUnsync : _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceUnsync : undefined
91
94
  });
92
95
  }
93
96
  };
@@ -101,7 +104,7 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(stat
101
104
  title: formatMessage(_messages.syncBlockMessages.copySyncBlockLabel),
102
105
  showTitle: false,
103
106
  tooltipContent: formatMessage(_messages.syncBlockMessages.copySyncedBlockTooltip),
104
- onClick: (0, _editorCommands.copySyncedBlockReferenceToClipboard)(syncBlockStore, api)
107
+ onClick: (0, _editorCommands.copySyncedBlockReferenceToClipboard)(syncBlockStore, _analytics.INPUT_METHOD.SYNCED_BLOCK_TB, api)
105
108
  }, hoverDecorationProps(nodeType, _consts.akEditorSelectedNodeClassName));
106
109
  items.push(copyButton);
107
110
  var disabled = !syncBlockStore.referenceManager.getSyncBlockURL(syncBlockObject.node.attrs.resourceId);
@@ -131,7 +134,8 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(stat
131
134
  onClick: (0, _editorCommands.removeSyncedBlock)(api),
132
135
  icon: /*#__PURE__*/_react.default.createElement(_delete.default, {
133
136
  label: ""
134
- })
137
+ }),
138
+ testId: (0, _platformFeatureFlags.fg)('platform_synced_block_patch_1') ? isBodiedSyncBlock ? _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceDelete : _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceDelete : undefined
135
139
  }, hoverDecorationProps(nodeType))]
136
140
  }];
137
141
  items.push.apply(items, overflowMenuConfig);
@@ -98,20 +98,33 @@ export const createSyncedBlock = ({
98
98
  // see filterTransaction for more details
99
99
  return tr;
100
100
  };
101
- export const copySyncedBlockReferenceToClipboardEditorCommand = (syncBlockStore, api) => ({
101
+ export const copySyncedBlockReferenceToClipboardEditorCommand = (syncBlockStore, inputMethod, api) => ({
102
102
  tr
103
103
  }) => {
104
- if (copySyncedBlockReferenceToClipboardInternal(tr.doc.type.schema, tr.selection, syncBlockStore, api)) {
104
+ if (copySyncedBlockReferenceToClipboardInternal(tr.doc.type.schema, tr.selection, syncBlockStore, inputMethod, api)) {
105
105
  return tr;
106
106
  }
107
107
  return null;
108
108
  };
109
- export const copySyncedBlockReferenceToClipboard = (syncBlockStore, api) => (state, _dispatch, _view) => {
110
- return copySyncedBlockReferenceToClipboardInternal(state.tr.doc.type.schema, state.tr.selection, syncBlockStore, api);
109
+ export const copySyncedBlockReferenceToClipboard = (syncBlockStore, inputMethod, api) => (state, _dispatch, _view) => {
110
+ return copySyncedBlockReferenceToClipboardInternal(state.tr.doc.type.schema, state.tr.selection, syncBlockStore, inputMethod, api);
111
111
  };
112
- const copySyncedBlockReferenceToClipboardInternal = (schema, selection, syncBlockStore, api) => {
112
+ const copySyncedBlockReferenceToClipboardInternal = (schema, selection, syncBlockStore, inputMethod, api) => {
113
113
  const syncBlockFindResult = findSyncBlockOrBodiedSyncBlock(schema, selection);
114
114
  if (!syncBlockFindResult) {
115
+ if (fg('platform_synced_block_patch_1')) {
116
+ var _api$analytics, _api$analytics$action;
117
+ api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent({
118
+ eventType: EVENT_TYPE.OPERATIONAL,
119
+ action: ACTION.ERROR,
120
+ actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
121
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_COPY,
122
+ attributes: {
123
+ error: 'No sync block found in selection',
124
+ inputMethod
125
+ }
126
+ });
127
+ }
115
128
  return false;
116
129
  }
117
130
  const isBodiedSyncBlock = isBodiedSyncBlockNode(syncBlockFindResult.node, schema.nodes.bodiedSyncBlock);
@@ -128,12 +141,39 @@ const copySyncedBlockReferenceToClipboardInternal = (schema, selection, syncBloc
128
141
  resourceId: syncBlockStore.referenceManager.generateResourceIdForReference(syncBlockFindResult.node.attrs.resourceId)
129
142
  });
130
143
  if (!referenceSyncBlockNode) {
144
+ if (fg('platform_synced_block_patch_1')) {
145
+ var _api$analytics2, _api$analytics2$actio;
146
+ api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.fireAnalyticsEvent({
147
+ eventType: EVENT_TYPE.OPERATIONAL,
148
+ action: ACTION.ERROR,
149
+ actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
150
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_COPY,
151
+ attributes: {
152
+ error: 'Failed to create reference sync block node',
153
+ resourceId: syncBlockFindResult.node.attrs.resourceId,
154
+ inputMethod
155
+ }
156
+ });
157
+ }
131
158
  return false;
132
159
  }
133
160
  } else {
134
161
  referenceSyncBlockNode = syncBlockFindResult.node;
135
162
  }
136
163
  if (!referenceSyncBlockNode) {
164
+ if (fg('platform_synced_block_patch_1')) {
165
+ var _api$analytics3, _api$analytics3$actio;
166
+ api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : (_api$analytics3$actio = _api$analytics3.actions) === null || _api$analytics3$actio === void 0 ? void 0 : _api$analytics3$actio.fireAnalyticsEvent({
167
+ eventType: EVENT_TYPE.OPERATIONAL,
168
+ action: ACTION.ERROR,
169
+ actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
170
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_COPY,
171
+ attributes: {
172
+ error: 'No reference sync block node available',
173
+ inputMethod
174
+ }
175
+ });
176
+ }
137
177
  return false;
138
178
  }
139
179
  const domNode = toDOM(referenceSyncBlockNode, schema);
@@ -144,6 +184,19 @@ const copySyncedBlockReferenceToClipboardInternal = (schema, selection, syncBloc
144
184
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
145
185
  tr
146
186
  }) => {
187
+ if (fg('platform_synced_block_patch_1')) {
188
+ var _api$analytics4, _api$analytics4$actio;
189
+ api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : (_api$analytics4$actio = _api$analytics4.actions) === null || _api$analytics4$actio === void 0 ? void 0 : _api$analytics4$actio.fireAnalyticsEvent({
190
+ eventType: EVENT_TYPE.OPERATIONAL,
191
+ action: ACTION.COPIED,
192
+ actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
193
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_COPY,
194
+ attributes: {
195
+ resourceId: referenceSyncBlockNode.attrs.resourceId,
196
+ inputMethod
197
+ }
198
+ });
199
+ }
147
200
  return tr.setMeta(syncedBlockPluginKey, {
148
201
  activeFlag: {
149
202
  id: FLAG_ID.SYNC_BLOCK_COPIED
@@ -162,11 +215,23 @@ export const editSyncedBlockSource = (syncBlockStore, api) => (state, dispatch,
162
215
  }
163
216
  const syncBlockURL = syncBlockStore.referenceManager.getSyncBlockURL(resourceId);
164
217
  if (syncBlockURL) {
218
+ if (fg('platform_synced_block_patch_1')) {
219
+ var _api$analytics5;
220
+ api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions.fireAnalyticsEvent({
221
+ eventType: EVENT_TYPE.OPERATIONAL,
222
+ action: ACTION.SYNCED_BLOCK_EDIT_SOURCE,
223
+ actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
224
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_SOURCE_URL,
225
+ attributes: {
226
+ resourceId: resourceId
227
+ }
228
+ });
229
+ }
165
230
  window.open(syncBlockURL, '_blank');
166
231
  } else {
167
- var _api$analytics, _api$analytics$action;
232
+ var _api$analytics6, _api$analytics6$actio;
168
233
  const tr = state.tr;
169
- api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.attachAnalyticsEvent({
234
+ api === null || api === void 0 ? void 0 : (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : (_api$analytics6$actio = _api$analytics6.actions) === null || _api$analytics6$actio === void 0 ? void 0 : _api$analytics6$actio.attachAnalyticsEvent({
170
235
  eventType: EVENT_TYPE.OPERATIONAL,
171
236
  action: ACTION.ERROR,
172
237
  actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
@@ -3,6 +3,7 @@ import { ACTION, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
3
  import { Experience, EXPERIENCE_ID, ExperienceCheckDomMutation, ExperienceCheckTimeout, getNodeQuery, getPopupContainerFromEditorView, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
4
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
5
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
7
8
  const TIMEOUT_DURATION = 30000;
8
9
  const pluginKey = new PluginKey('syncedBlockMenuAndToolbarExperience');
@@ -21,22 +22,76 @@ export const getMenuAndToolbarExperiencesPlugin = ({
21
22
  }
22
23
  return popupsTargetEl;
23
24
  };
24
- const createSourcePrimaryToolbarExperience = getCreateSourcePrimaryToolbarExperience({
25
- refs,
26
- dispatchAnalyticsEvent
25
+ const createSourcePrimaryToolbarExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
26
+ action: ACTION.SYNCED_BLOCK_CREATE,
27
+ actionSubjectId: ACTION_SUBJECT_ID.PRIMARY_TOOLBAR,
28
+ dispatchAnalyticsEvent,
29
+ checks: [new ExperienceCheckTimeout({
30
+ durationMs: TIMEOUT_DURATION
31
+ }), syncedBlockAddedToDomCheck(refs)]
27
32
  });
28
- const createSourceBlockMenuExperience = getCreateSourceBlockMenuExperience({
29
- refs,
30
- dispatchAnalyticsEvent
33
+ const createSourceBlockMenuExperience = new Experience(EXPERIENCE_ID.MENU_ACTION, {
34
+ action: ACTION.SYNCED_BLOCK_CREATE,
35
+ actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
36
+ dispatchAnalyticsEvent,
37
+ checks: [new ExperienceCheckTimeout({
38
+ durationMs: TIMEOUT_DURATION
39
+ }), syncedBlockAddedToDomCheck(refs)]
31
40
  });
32
- const createSourceQuickInsertMenuExperience = getCreateSourceQuickInsertMenuExperience({
33
- refs,
34
- dispatchAnalyticsEvent
41
+ const createSourceQuickInsertMenuExperience = new Experience(EXPERIENCE_ID.MENU_ACTION, {
42
+ action: ACTION.SYNCED_BLOCK_CREATE,
43
+ actionSubjectId: ACTION_SUBJECT_ID.QUICK_INSERT,
44
+ dispatchAnalyticsEvent,
45
+ checks: [new ExperienceCheckTimeout({
46
+ durationMs: TIMEOUT_DURATION
47
+ }), syncedBlockAddedToDomCheck(refs)]
35
48
  });
36
- const deleteReferenceSyncedBlockExperience = getDeleteReferenceSyncedBlockToolbarExperience({
37
- refs,
38
- dispatchAnalyticsEvent
49
+ const deleteReferenceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
50
+ action: ACTION.REFERENCE_SYNCED_BLOCK_DELETE,
51
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
52
+ dispatchAnalyticsEvent,
53
+ checks: [new ExperienceCheckTimeout({
54
+ durationMs: TIMEOUT_DURATION
55
+ }), referenceSyncBlockRemovedFromDomCheck(refs)]
39
56
  });
57
+ let unsyncReferenceSyncedBlockExperience;
58
+ let unsyncSourceSyncedBlockExperience;
59
+ let deleteSourceSyncedBlockExperience;
60
+ let syncedLocationsExperience;
61
+ if (fg('platform_synced_block_patch_1')) {
62
+ unsyncReferenceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
63
+ action: ACTION.REFERENCE_SYNCED_BLOCK_UNSYNC,
64
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
65
+ dispatchAnalyticsEvent,
66
+ checks: [new ExperienceCheckTimeout({
67
+ durationMs: TIMEOUT_DURATION
68
+ }), referenceSyncBlockRemovedFromDomCheck(refs)]
69
+ });
70
+ unsyncSourceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
71
+ action: ACTION.SYNCED_BLOCK_UNSYNC,
72
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
73
+ dispatchAnalyticsEvent,
74
+ checks: [new ExperienceCheckTimeout({
75
+ durationMs: TIMEOUT_DURATION
76
+ }), syncBlockDeleteConfirmationModalAddedCheck(refs)]
77
+ });
78
+ deleteSourceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
79
+ action: ACTION.SYNCED_BLOCK_DELETE,
80
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
81
+ dispatchAnalyticsEvent,
82
+ checks: [new ExperienceCheckTimeout({
83
+ durationMs: TIMEOUT_DURATION
84
+ }), syncBlockDeleteConfirmationModalAddedCheck(refs)]
85
+ });
86
+ syncedLocationsExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
87
+ action: ACTION.SYNCED_BLOCK_VIEW_SYNCED_LOCATIONS,
88
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
89
+ dispatchAnalyticsEvent,
90
+ checks: [new ExperienceCheckTimeout({
91
+ durationMs: TIMEOUT_DURATION
92
+ }), syncedLocationsDropdownOpenedCheck(refs)]
93
+ });
94
+ }
40
95
  const unbindClickListener = bind(document, {
41
96
  type: 'click',
42
97
  listener: event => {
@@ -52,13 +107,24 @@ export const getMenuAndToolbarExperiencesPlugin = ({
52
107
  if (!isSyncedBlockButtonId(testId)) {
53
108
  return;
54
109
  }
110
+ if (button.disabled) {
111
+ return;
112
+ }
55
113
  handleButtonClick({
56
114
  testId,
115
+ button,
57
116
  createSourcePrimaryToolbarExperience,
58
117
  createSourceBlockMenuExperience,
59
118
  createSourceQuickInsertMenuExperience,
60
- deleteReferenceSyncedBlockExperience
119
+ deleteReferenceSyncedBlockExperience,
120
+ unsyncReferenceSyncedBlockExperience,
121
+ unsyncSourceSyncedBlockExperience,
122
+ deleteSourceSyncedBlockExperience,
123
+ syncedLocationsExperience
61
124
  });
125
+ },
126
+ options: {
127
+ capture: true
62
128
  }
63
129
  });
64
130
  const unbindKeydownListener = bind(document, {
@@ -89,6 +155,7 @@ export const getMenuAndToolbarExperiencesPlugin = ({
89
155
  editorViewEl = editorView.dom;
90
156
  return {
91
157
  destroy: () => {
158
+ var _deleteSourceSyncedBl, _unsyncReferenceSynce, _unsyncSourceSyncedBl, _syncedLocationsExper;
92
159
  createSourcePrimaryToolbarExperience.abort({
93
160
  reason: 'editorDestroyed'
94
161
  });
@@ -101,6 +168,18 @@ export const getMenuAndToolbarExperiencesPlugin = ({
101
168
  deleteReferenceSyncedBlockExperience.abort({
102
169
  reason: 'editorDestroyed'
103
170
  });
171
+ (_deleteSourceSyncedBl = deleteSourceSyncedBlockExperience) === null || _deleteSourceSyncedBl === void 0 ? void 0 : _deleteSourceSyncedBl.abort({
172
+ reason: 'editorDestroyed'
173
+ });
174
+ (_unsyncReferenceSynce = unsyncReferenceSyncedBlockExperience) === null || _unsyncReferenceSynce === void 0 ? void 0 : _unsyncReferenceSynce.abort({
175
+ reason: 'editorDestroyed'
176
+ });
177
+ (_unsyncSourceSyncedBl = unsyncSourceSyncedBlockExperience) === null || _unsyncSourceSyncedBl === void 0 ? void 0 : _unsyncSourceSyncedBl.abort({
178
+ reason: 'editorDestroyed'
179
+ });
180
+ (_syncedLocationsExper = syncedLocationsExperience) === null || _syncedLocationsExper === void 0 ? void 0 : _syncedLocationsExper.abort({
181
+ reason: 'editorDestroyed'
182
+ });
104
183
  unbindClickListener();
105
184
  unbindKeydownListener();
106
185
  }
@@ -108,80 +187,64 @@ export const getMenuAndToolbarExperiencesPlugin = ({
108
187
  }
109
188
  });
110
189
  };
111
- const getCreateSourcePrimaryToolbarExperience = ({
112
- refs,
113
- dispatchAnalyticsEvent
114
- }) => {
115
- return new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
116
- action: ACTION.SYNCED_BLOCK_CREATE,
117
- actionSubjectId: ACTION_SUBJECT_ID.PRIMARY_TOOLBAR,
118
- dispatchAnalyticsEvent,
119
- checks: [new ExperienceCheckTimeout({
120
- durationMs: TIMEOUT_DURATION
121
- }), syncedBlockAddedToDomCheck(refs)]
122
- });
123
- };
124
- const getCreateSourceBlockMenuExperience = ({
125
- refs,
126
- dispatchAnalyticsEvent
127
- }) => {
128
- return new Experience(EXPERIENCE_ID.MENU_ACTION, {
129
- action: ACTION.SYNCED_BLOCK_CREATE,
130
- actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
131
- dispatchAnalyticsEvent,
132
- checks: [new ExperienceCheckTimeout({
133
- durationMs: TIMEOUT_DURATION
134
- }), syncedBlockAddedToDomCheck(refs)]
135
- });
136
- };
137
- const getCreateSourceQuickInsertMenuExperience = ({
138
- refs,
139
- dispatchAnalyticsEvent
140
- }) => {
141
- return new Experience(EXPERIENCE_ID.MENU_ACTION, {
142
- action: ACTION.SYNCED_BLOCK_CREATE,
143
- actionSubjectId: ACTION_SUBJECT_ID.QUICK_INSERT,
144
- dispatchAnalyticsEvent,
145
- checks: [new ExperienceCheckTimeout({
146
- durationMs: TIMEOUT_DURATION
147
- }), syncedBlockAddedToDomCheck(refs)]
148
- });
149
- };
150
- const getDeleteReferenceSyncedBlockToolbarExperience = ({
151
- refs,
152
- dispatchAnalyticsEvent
153
- }) => {
154
- return new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
155
- action: ACTION.REFERENCE_SYNCED_BLOCK_DELETE,
156
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
157
- dispatchAnalyticsEvent,
158
- checks: [new ExperienceCheckTimeout({
159
- durationMs: TIMEOUT_DURATION
160
- }), referenceSyncBlockRemovedFromDomCheck(refs)]
161
- });
162
- };
163
190
  const isSyncedBlockButtonId = value => {
164
191
  return !!value && syncedBlockButtonIds.has(value);
165
192
  };
166
193
  const handleButtonClick = ({
167
194
  testId,
195
+ button,
168
196
  createSourcePrimaryToolbarExperience,
169
197
  createSourceBlockMenuExperience,
170
198
  createSourceQuickInsertMenuExperience,
171
- deleteReferenceSyncedBlockExperience
199
+ deleteReferenceSyncedBlockExperience,
200
+ unsyncReferenceSyncedBlockExperience,
201
+ unsyncSourceSyncedBlockExperience,
202
+ deleteSourceSyncedBlockExperience,
203
+ syncedLocationsExperience
172
204
  }) => {
173
205
  switch (testId) {
174
206
  case SYNCED_BLOCK_BUTTON_TEST_ID.primaryToolbarCreate:
175
- createSourcePrimaryToolbarExperience.start();
207
+ createSourcePrimaryToolbarExperience.start({
208
+ forceRestart: true
209
+ });
176
210
  break;
177
211
  case SYNCED_BLOCK_BUTTON_TEST_ID.blockMenuCreate:
178
- createSourceBlockMenuExperience.start();
212
+ createSourceBlockMenuExperience.start({
213
+ forceRestart: true
214
+ });
179
215
  break;
180
216
  case SYNCED_BLOCK_BUTTON_TEST_ID.quickInsertCreate:
181
- createSourceQuickInsertMenuExperience.start();
217
+ createSourceQuickInsertMenuExperience.start({
218
+ forceRestart: true
219
+ });
182
220
  break;
183
221
  case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceDelete:
184
- deleteReferenceSyncedBlockExperience.start();
222
+ deleteReferenceSyncedBlockExperience.start({
223
+ forceRestart: true
224
+ });
225
+ break;
226
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceUnsync:
227
+ unsyncReferenceSyncedBlockExperience === null || unsyncReferenceSyncedBlockExperience === void 0 ? void 0 : unsyncReferenceSyncedBlockExperience.start({
228
+ forceRestart: true
229
+ });
230
+ break;
231
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceUnsync:
232
+ unsyncSourceSyncedBlockExperience === null || unsyncSourceSyncedBlockExperience === void 0 ? void 0 : unsyncSourceSyncedBlockExperience.start({
233
+ forceRestart: true
234
+ });
235
+ break;
236
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceDelete:
237
+ deleteSourceSyncedBlockExperience === null || deleteSourceSyncedBlockExperience === void 0 ? void 0 : deleteSourceSyncedBlockExperience.start({
238
+ forceRestart: true
239
+ });
240
+ break;
241
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSyncedLocationsTrigger:
242
+ // Only track when opening the dropdown
243
+ if (button.getAttribute('aria-pressed') === 'false') {
244
+ syncedLocationsExperience === null || syncedLocationsExperience === void 0 ? void 0 : syncedLocationsExperience.start({
245
+ forceRestart: true
246
+ });
247
+ }
185
248
  break;
186
249
  default:
187
250
  {
@@ -258,4 +321,76 @@ const isSyncBlockRemovedInMutation = ({
258
321
  }) => {
259
322
  return type === 'childList' && [...removedNodes].some(isSyncBlockWithinNode);
260
323
  };
261
- const isSyncBlockWithinNode = node => getNodeQuery('[data-prosemirror-node-name="syncBlock"]')(node);
324
+ const isSyncBlockWithinNode = node => getNodeQuery('[data-prosemirror-node-name="syncBlock"]')(node);
325
+ const syncBlockDeleteConfirmationModalAddedCheck = refs => new ExperienceCheckDomMutation({
326
+ onDomMutation: ({
327
+ mutations
328
+ }) => {
329
+ if (mutations.some(isDeleteConfirmationModalAddedInMutation)) {
330
+ return {
331
+ status: 'success'
332
+ };
333
+ }
334
+ return undefined;
335
+ },
336
+ observeConfig: () => {
337
+ return {
338
+ target: document.body,
339
+ options: {
340
+ childList: true,
341
+ subtree: true
342
+ }
343
+ };
344
+ }
345
+ });
346
+ const isDeleteConfirmationModalAddedInMutation = ({
347
+ type,
348
+ addedNodes
349
+ }) => {
350
+ return type === 'childList' && [...addedNodes].some(isDeleteConfirmationModalWithinNode);
351
+ };
352
+ const isDeleteConfirmationModalWithinNode = node => getNodeQuery('[data-testid="sync-block-delete-confirmation"]')(node);
353
+ const syncedLocationsDropdownOpenedCheck = refs => new ExperienceCheckDomMutation({
354
+ onDomMutation: ({
355
+ mutations
356
+ }) => {
357
+ if (mutations.some(isSyncedLocationsDropdownErrorInMutation)) {
358
+ return {
359
+ status: 'failure'
360
+ };
361
+ }
362
+ if (mutations.some(isSyncedLocationsDropdownAddedInMutation)) {
363
+ return {
364
+ status: 'success'
365
+ };
366
+ }
367
+ return undefined;
368
+ },
369
+ observeConfig: () => {
370
+ return {
371
+ target: document.body,
372
+ options: {
373
+ childList: true,
374
+ subtree: true
375
+ }
376
+ };
377
+ }
378
+ });
379
+ const isSyncedLocationsDropdownAddedInMutation = ({
380
+ type,
381
+ addedNodes
382
+ }) => {
383
+ return type === 'childList' && [...addedNodes].some(isSyncedLocationsDropdownWithinNode);
384
+ };
385
+ const isSyncedLocationsDropdownErrorInMutation = ({
386
+ type,
387
+ addedNodes
388
+ }) => {
389
+ return type === 'childList' && [...addedNodes].some(isSyncedLocationsDropdownErrorWithinNode);
390
+ };
391
+ const isSyncedLocationsDropdownWithinNode = node => {
392
+ return !!(getNodeQuery('[data-testid="synced-locations-dropdown-content"]')(node) || getNodeQuery('[data-testid="synced-locations-dropdown-content-no-results"]')(node));
393
+ };
394
+ const isSyncedLocationsDropdownErrorWithinNode = node => {
395
+ return !!getNodeQuery('[data-testid="synced-locations-dropdown-content-error"]')(node);
396
+ };
@@ -53,7 +53,7 @@ export const syncedBlockPlugin = ({
53
53
  }] : [])];
54
54
  },
55
55
  commands: {
56
- copySyncedBlockReferenceToClipboard: () => copySyncedBlockReferenceToClipboardEditorCommand(syncBlockStore, api),
56
+ copySyncedBlockReferenceToClipboard: inputMethod => copySyncedBlockReferenceToClipboardEditorCommand(syncBlockStore, inputMethod, api),
57
57
  insertSyncedBlock: () => ({
58
58
  tr
59
59
  }) => {
@@ -11,5 +11,9 @@ export const SYNCED_BLOCK_BUTTON_TEST_ID = {
11
11
  primaryToolbarCreate: 'create-synced-block-toolbar-btn',
12
12
  blockMenuCreate: 'create-synced-block-block-menu-btn',
13
13
  quickInsertCreate: 'create-synced-block-quick-insert-btn',
14
- syncedBlockToolbarReferenceDelete: 'reference-synced-block-delete-btn'
14
+ syncedBlockToolbarReferenceDelete: 'reference-synced-block-delete-btn',
15
+ syncedBlockToolbarSourceDelete: 'source-synced-block-delete-btn',
16
+ syncedBlockToolbarReferenceUnsync: 'reference-synced-block-unsync-btn',
17
+ syncedBlockToolbarSourceUnsync: 'source-synced-block-unsync-btn',
18
+ syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger'
15
19
  };
@@ -1,5 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { useIntl } from 'react-intl-next';
3
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
4
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
5
  import { blockMenuMessages } from '@atlaskit/editor-common/messages';
5
6
  import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
@@ -66,7 +67,7 @@ const CopySyncedBlockDropdownItem = ({
66
67
  });
67
68
  const onClick = () => {
68
69
  var _api$core3, _api$core4, _api$blockControls2, _api$blockControls2$c;
69
- api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard());
70
+ api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard(INPUT_METHOD.BLOCK_MENU));
70
71
  api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
71
72
  closeMenu: true
72
73
  }));