@atlaskit/editor-plugin-card 0.5.11 → 0.7.0

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 (49) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/analytics/events-from-tr.js +1 -0
  3. package/dist/cjs/nodeviews/blockCard.js +20 -0
  4. package/dist/cjs/pm-plugins/doc.js +42 -28
  5. package/dist/cjs/toolbar.js +24 -6
  6. package/dist/cjs/ui/DatasourceModal/index.js +1 -1
  7. package/dist/cjs/ui/EditDatasourceButton.js +144 -0
  8. package/dist/cjs/ui/EditLinkToolbar.js +4 -27
  9. package/dist/cjs/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +141 -19
  10. package/dist/es2019/analytics/events-from-tr.js +1 -0
  11. package/dist/es2019/nodeviews/blockCard.js +15 -0
  12. package/dist/es2019/pm-plugins/doc.js +36 -22
  13. package/dist/es2019/toolbar.js +22 -6
  14. package/dist/es2019/ui/DatasourceModal/index.js +2 -2
  15. package/dist/es2019/ui/EditDatasourceButton.js +101 -0
  16. package/dist/es2019/ui/EditLinkToolbar.js +1 -23
  17. package/dist/es2019/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +146 -13
  18. package/dist/esm/analytics/events-from-tr.js +1 -0
  19. package/dist/esm/nodeviews/blockCard.js +20 -0
  20. package/dist/esm/pm-plugins/doc.js +40 -26
  21. package/dist/esm/toolbar.js +24 -6
  22. package/dist/esm/ui/DatasourceModal/index.js +2 -2
  23. package/dist/esm/ui/EditDatasourceButton.js +134 -0
  24. package/dist/esm/ui/EditLinkToolbar.js +1 -23
  25. package/dist/esm/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +141 -19
  26. package/dist/types/analytics/events-from-tr.d.ts +2 -2
  27. package/dist/types/analytics/types.d.ts +1 -1
  28. package/dist/types/nodeviews/blockCard.d.ts +5 -1
  29. package/dist/types/pm-plugins/doc.d.ts +9 -8
  30. package/dist/types/ui/DatasourceModal/index.d.ts +3 -3
  31. package/dist/types/ui/EditDatasourceButton.d.ts +17 -0
  32. package/dist/types/ui/EditLinkToolbar.d.ts +0 -1
  33. package/dist/types/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.d.ts +1 -1
  34. package/dist/types-ts4.5/analytics/events-from-tr.d.ts +2 -2
  35. package/dist/types-ts4.5/analytics/types.d.ts +1 -1
  36. package/dist/types-ts4.5/nodeviews/blockCard.d.ts +5 -1
  37. package/dist/types-ts4.5/pm-plugins/doc.d.ts +9 -8
  38. package/dist/types-ts4.5/ui/DatasourceModal/index.d.ts +3 -3
  39. package/dist/types-ts4.5/ui/EditDatasourceButton.d.ts +17 -0
  40. package/dist/types-ts4.5/ui/EditLinkToolbar.d.ts +0 -1
  41. package/dist/types-ts4.5/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.d.ts +1 -1
  42. package/package.json +4 -4
  43. package/report.api.md +1 -1
  44. package/tmp/api-report-tmp.d.ts +1 -1
  45. package/dist/cjs/ui/SmallerEditIcon.js +0 -22
  46. package/dist/es2019/ui/SmallerEditIcon.js +0 -14
  47. package/dist/esm/ui/SmallerEditIcon.js +0 -14
  48. package/dist/types/ui/SmallerEditIcon.d.ts +0 -3
  49. package/dist/types-ts4.5/ui/SmallerEditIcon.d.ts +0 -3
@@ -115,6 +115,21 @@ export class BlockCard extends ReactNodeView {
115
115
  }
116
116
  return domRef;
117
117
  }
118
+
119
+ // Need this function to check if the datasource attribute was added or not to a blockCard.
120
+ // If so, we return false so we can get the node to re-render properly as a datasource node instead.
121
+ // Otherwise, the node view will still consider the node as a blockCard and render a regular blockCard.
122
+ validUpdate(currentNode, newNode) {
123
+ var _currentNode$attrs, _newNode$attrs;
124
+ const isCurrentNodeBlockCard = !((_currentNode$attrs = currentNode.attrs) !== null && _currentNode$attrs !== void 0 && _currentNode$attrs.datasource);
125
+ const isNewNodeDatasource = (_newNode$attrs = newNode.attrs) === null || _newNode$attrs === void 0 ? void 0 : _newNode$attrs.datasource;
126
+
127
+ // need to return falsy to update node
128
+ return !(isCurrentNodeBlockCard && isNewNodeDatasource);
129
+ }
130
+ update(node, decorations, _innerDecorations) {
131
+ return super.update(node, decorations, _innerDecorations, this.validUpdate);
132
+ }
118
133
  render() {
119
134
  const {
120
135
  platform,
@@ -393,8 +393,8 @@ export const getLinkNodeType = (appearance, linkNodes) => {
393
393
  }
394
394
  };
395
395
 
396
- // Apply an update to a datasource (aka blockCard) node
397
- export const updateExistingDatasource = (state, node, newAdf, view) => {
396
+ // Apply an update made from the datasource edit modal to a card
397
+ export const updateCardFromDatasourceModal = (state, node, newAdf, view, sourceEvent) => {
398
398
  const {
399
399
  tr,
400
400
  selection: {
@@ -404,33 +404,43 @@ export const updateExistingDatasource = (state, node, newAdf, view) => {
404
404
  nodes: schemaNodes
405
405
  }
406
406
  } = state;
407
-
408
- // datasource to datasource
409
- if (newAdf.type === 'blockCard' && newAdf.attrs.datasource && node.attrs.datasource) {
410
- var _ref, _ref2, _newViews$properties, _oldViews$properties, _newAdf$attrs, _node$attrs;
411
- const [newViews] = (_ref = newAdf.attrs.datasource.views) !== null && _ref !== void 0 ? _ref : [];
412
- const [oldViews] = (_ref2 = node.attrs.datasource.views) !== null && _ref2 !== void 0 ? _ref2 : [];
413
- const newColumnKeys = newViews === null || newViews === void 0 ? void 0 : (_newViews$properties = newViews.properties) === null || _newViews$properties === void 0 ? void 0 : _newViews$properties.columns.map(column => column.key);
414
- const oldColumnKeys = oldViews === null || oldViews === void 0 ? void 0 : (_oldViews$properties = oldViews.properties) === null || _oldViews$properties === void 0 ? void 0 : _oldViews$properties.columns.map(column => column.key);
415
- const isColumnChange = !isEqual(oldColumnKeys, newColumnKeys);
416
- const isUrlChange = ((_newAdf$attrs = newAdf.attrs) === null || _newAdf$attrs === void 0 ? void 0 : _newAdf$attrs.url) !== ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.url);
417
- if (isColumnChange || isUrlChange) {
418
- tr.setNodeMarkup(from, schemaNodes.blockCard, {
419
- ...node.attrs,
420
- ...newAdf.attrs
421
- });
422
- addLinkMetadata(state.selection, tr, {
423
- action: ACTION.UPDATED
424
- });
407
+ if (newAdf.type === 'blockCard') {
408
+ var _node$attrs, _newAdf$attrs;
409
+ if ((_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.datasource && (_newAdf$attrs = newAdf.attrs) !== null && _newAdf$attrs !== void 0 && _newAdf$attrs.datasource) {
410
+ var _ref, _ref2, _newViews$properties, _oldViews$properties, _newAdf$attrs2, _node$attrs2;
411
+ // datasource to datasource
412
+ const [newViews] = (_ref = newAdf.attrs.datasource.views) !== null && _ref !== void 0 ? _ref : [];
413
+ const [oldViews] = (_ref2 = node.attrs.datasource.views) !== null && _ref2 !== void 0 ? _ref2 : [];
414
+ const newColumnKeys = newViews === null || newViews === void 0 ? void 0 : (_newViews$properties = newViews.properties) === null || _newViews$properties === void 0 ? void 0 : _newViews$properties.columns.map(column => column.key);
415
+ const oldColumnKeys = oldViews === null || oldViews === void 0 ? void 0 : (_oldViews$properties = oldViews.properties) === null || _oldViews$properties === void 0 ? void 0 : _oldViews$properties.columns.map(column => column.key);
416
+ const isColumnChange = !isEqual(oldColumnKeys, newColumnKeys);
417
+ const isUrlChange = ((_newAdf$attrs2 = newAdf.attrs) === null || _newAdf$attrs2 === void 0 ? void 0 : _newAdf$attrs2.url) !== ((_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.url);
418
+ if (isColumnChange || isUrlChange) {
419
+ tr.setNodeMarkup(from, schemaNodes.blockCard, {
420
+ ...node.attrs,
421
+ ...newAdf.attrs
422
+ });
423
+ addLinkMetadata(state.selection, tr, {
424
+ action: ACTION.UPDATED,
425
+ sourceEvent
426
+ });
427
+ }
428
+ } else {
429
+ // inline or blockCard to datasource
430
+ tr.setNodeMarkup(from, schemaNodes.blockCard, newAdf.attrs);
425
431
  }
426
432
  } else if (newAdf.type === 'inlineCard') {
427
- // datasource to inline
433
+ // card type to inlineCard
428
434
  tr.setNodeMarkup(from, schemaNodes.inlineCard, newAdf.attrs);
435
+ addLinkMetadata(state.selection, tr, {
436
+ action: ACTION.UPDATED,
437
+ sourceEvent
438
+ });
429
439
  }
430
440
  hideDatasourceModal(tr);
431
441
  view.dispatch(tr.scrollIntoView());
432
442
  };
433
- export const insertDatasource = (state, adf, view) => {
443
+ export const insertDatasource = (state, adf, view, sourceEvent) => {
434
444
  const {
435
445
  tr,
436
446
  selection: {
@@ -450,5 +460,9 @@ export const insertDatasource = (state, adf, view) => {
450
460
  // this will allow us to deal with insertions from multiple paths in a more consistent way
451
461
  newNode && tr.insert(from, newNode);
452
462
  hideDatasourceModal(tr);
463
+ addLinkMetadata(state.selection, tr, {
464
+ action: ACTION.INSERTED,
465
+ sourceEvent
466
+ });
453
467
  view.dispatch(tr.scrollIntoView());
454
468
  };
@@ -4,6 +4,7 @@ import { ACTION, ACTION_SUBJECT, buildOpenedSettingsPayload, buildVisitedLinkPay
4
4
  import { buildLayoutButtons, commandWithMetadata } from '@atlaskit/editor-common/card';
5
5
  import commonMessages, { linkMessages, linkToolbarMessages, cardMessages as messages } from '@atlaskit/editor-common/messages';
6
6
  import { FLOATING_TOOLBAR_LINKPICKER_CLASSNAME, richMediaClassName } from '@atlaskit/editor-common/styles';
7
+ import { SmallerEditIcon } from '@atlaskit/editor-common/ui';
7
8
  import { canRenderDatasource } from '@atlaskit/editor-common/utils';
8
9
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
9
10
  import { findDomRefAtPos, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils';
@@ -14,9 +15,9 @@ import OpenIcon from '@atlaskit/icon/glyph/shortcut';
14
15
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
15
16
  import { changeSelectedCardToText } from './pm-plugins/doc';
16
17
  import { pluginKey } from './pm-plugins/main';
17
- import { buildEditLinkToolbar, editDatasource, editLink, editLinkToolbarConfig } from './ui/EditLinkToolbar';
18
+ import { editDatasource, EditDatasourceButton } from './ui/EditDatasourceButton';
19
+ import { buildEditLinkToolbar, editLink, editLinkToolbarConfig } from './ui/EditLinkToolbar';
18
20
  import { LinkToolbarAppearance } from './ui/LinkToolbarAppearance';
19
- import { SmallerEditIcon } from './ui/SmallerEditIcon';
20
21
  import { ToolbarViewedEvent } from './ui/ToolbarViewedEvent';
21
22
  import { appearanceForNodeType, displayInfoForCard, findCardInfo, titleUrlPairFromNode } from './utils';
22
23
  export const removeCard = editorAnalyticsApi => commandWithMetadata((state, dispatch) => {
@@ -221,7 +222,7 @@ const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOp
221
222
  pluginInjectionApi
222
223
  })];
223
224
  } else if (shouldRenderDatasourceToolbar) {
224
- return getDatasourceButtonGroup(state, metadata, intl, editorAnalyticsApi, node, hoverDecoration);
225
+ return getDatasourceButtonGroup(metadata, intl, editorAnalyticsApi, node, hoverDecoration, node.attrs.datasource.id);
225
226
  } else {
226
227
  const {
227
228
  inlineCard
@@ -281,7 +282,8 @@ const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOp
281
282
  }
282
283
  const {
283
284
  allowBlockCards,
284
- allowEmbeds
285
+ allowEmbeds,
286
+ allowDatasource
285
287
  } = cardOptions;
286
288
 
287
289
  // This code will be executed only for appearances such as "inline", "block" & "embed"
@@ -307,6 +309,20 @@ const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOp
307
309
  type: 'separator'
308
310
  });
309
311
  }
312
+ const shouldShowDatasourceEditButton = platform !== 'mobile' && allowDatasource;
313
+ if (shouldShowDatasourceEditButton) {
314
+ toolbarItems.unshift({
315
+ type: 'custom',
316
+ fallback: [],
317
+ render: editorView => /*#__PURE__*/React.createElement(EditDatasourceButton, {
318
+ intl: intl,
319
+ editorAnalyticsApi: editorAnalyticsApi,
320
+ url: url,
321
+ editorView: editorView,
322
+ editorState: state
323
+ })
324
+ });
325
+ }
310
326
  return toolbarItems;
311
327
  }
312
328
  };
@@ -336,7 +352,7 @@ const getSettingsButtonGroup = (state, featureFlags, intl, editorAnalyticsApi) =
336
352
  type: 'separator'
337
353
  }] : [];
338
354
  };
339
- const getDatasourceButtonGroup = (state, metadata, intl, editorAnalyticsApi, node, hoverDecoration) => {
355
+ const getDatasourceButtonGroup = (metadata, intl, editorAnalyticsApi, node, hoverDecoration, datasourceId) => {
340
356
  var _node$attrs3;
341
357
  const toolbarItems = [{
342
358
  id: 'editor.edit.datasource',
@@ -345,7 +361,7 @@ const getDatasourceButtonGroup = (state, metadata, intl, editorAnalyticsApi, nod
345
361
  metadata: metadata,
346
362
  className: 'datasource-edit',
347
363
  title: intl.formatMessage(linkToolbarMessages.editDatasource),
348
- onClick: editDatasource(node, editorAnalyticsApi),
364
+ onClick: editDatasource(datasourceId, editorAnalyticsApi),
349
365
  testId: 'datasource-edit-button'
350
366
  }];
351
367
  if (node !== null && node !== void 0 && (_node$attrs3 = node.attrs) !== null && _node$attrs3 !== void 0 && _node$attrs3.url) {
@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
2
2
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { ASSETS_LIST_OF_LINKS_DATASOURCE_ID, AssetsConfigModal, JIRA_LIST_OF_LINKS_DATASOURCE_ID, JiraIssuesConfigModal } from '@atlaskit/link-datasource';
4
4
  import { hideDatasourceModal } from '../../pm-plugins/actions';
5
- import { insertDatasource, updateExistingDatasource } from '../../pm-plugins/doc';
5
+ import { insertDatasource, updateCardFromDatasourceModal } from '../../pm-plugins/doc';
6
6
  export const DatasourceModal = ({
7
7
  view,
8
8
  modalType
@@ -20,7 +20,7 @@ export const DatasourceModal = ({
20
20
  }, [dispatch, state.tr]);
21
21
  const onInsert = useCallback(newAdf => {
22
22
  if (existingNode) {
23
- updateExistingDatasource(state, existingNode, newAdf, view);
23
+ updateCardFromDatasourceModal(state, existingNode, newAdf, view);
24
24
  } else {
25
25
  insertDatasource(state, newAdf, view);
26
26
  }
@@ -0,0 +1,101 @@
1
+ /** @jsx jsx */
2
+ import { useEffect, useState } from 'react';
3
+ import { css, jsx } from '@emotion/react';
4
+ import { cardMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { FloatingToolbarButton as Button, FloatingToolbarSeparator as Separator, SmallerEditIcon } from '@atlaskit/editor-common/ui';
6
+ import { canRenderDatasource, getDatasourceType } from '@atlaskit/editor-common/utils';
7
+ import { showDatasourceModal } from '../pm-plugins/actions';
8
+ import { CardContextProvider } from './CardContextProvider';
9
+ const buttonStyles = css({
10
+ pointerEvents: 'auto'
11
+ });
12
+ const buttonWrapperStyles = css({
13
+ display: 'flex'
14
+ });
15
+ const EditDatasourceButtonWithCardContext = ({
16
+ cardContext,
17
+ intl,
18
+ editorAnalyticsApi,
19
+ url,
20
+ editorView,
21
+ editorState
22
+ }) => {
23
+ const [datasourceId, setDatasourceId] = useState(null);
24
+ useEffect(() => {
25
+ const fetchDatasource = async () => {
26
+ try {
27
+ var _cardContext$connecti, _cardContext$connecti2, _datasources$;
28
+ const response = url && cardContext && (await (cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$connecti = cardContext.connections) === null || _cardContext$connecti === void 0 ? void 0 : (_cardContext$connecti2 = _cardContext$connecti.client) === null || _cardContext$connecti2 === void 0 ? void 0 : _cardContext$connecti2.fetchData(url)));
29
+ const datasources = response && response.datasources || [];
30
+ setDatasourceId(((_datasources$ = datasources[0]) === null || _datasources$ === void 0 ? void 0 : _datasources$.id) || null);
31
+ } catch (e) {
32
+ setDatasourceId(null);
33
+ }
34
+ };
35
+ void fetchDatasource();
36
+ }, [cardContext, url]);
37
+ if (!datasourceId || !canRenderDatasource(datasourceId, false)) {
38
+ return null;
39
+ }
40
+ if (url) {
41
+ var _cardContext$store, _urlState$error;
42
+ const urlState = cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$store = cardContext.store) === null || _cardContext$store === void 0 ? void 0 : _cardContext$store.getState()[url];
43
+ if ((urlState === null || urlState === void 0 ? void 0 : (_urlState$error = urlState.error) === null || _urlState$error === void 0 ? void 0 : _urlState$error.kind) === 'fatal') {
44
+ return null;
45
+ }
46
+ }
47
+ const dispatchCommand = fn => {
48
+ fn && fn(editorState, editorView && editorView.dispatch);
49
+ if (editorView && !editorView.hasFocus()) {
50
+ editorView.focus();
51
+ }
52
+ };
53
+ return jsx("div", {
54
+ css: buttonWrapperStyles
55
+ }, jsx(Button, {
56
+ css: buttonStyles,
57
+ title: intl.formatMessage(messages.datasourceTitle),
58
+ icon: jsx(SmallerEditIcon, null),
59
+ selected: false,
60
+ onClick: () => dispatchCommand(editDatasource(datasourceId, editorAnalyticsApi)),
61
+ testId: 'card-edit-datasource-button'
62
+ }), jsx(Separator, null));
63
+ };
64
+ export const EditDatasourceButton = ({
65
+ intl,
66
+ editorAnalyticsApi,
67
+ url,
68
+ editorView,
69
+ editorState
70
+ }) => {
71
+ return jsx(CardContextProvider, null, ({
72
+ cardContext
73
+ }) => jsx(EditDatasourceButtonWithCardContext, {
74
+ url: url,
75
+ intl: intl,
76
+ editorAnalyticsApi: editorAnalyticsApi,
77
+ editorView: editorView,
78
+ editorState: editorState,
79
+ cardContext: cardContext
80
+ }));
81
+ };
82
+ export const editDatasource = (datasourceId, editorAnalyticsApi) => (state, dispatch) => {
83
+ const datasourceType = getDatasourceType(datasourceId);
84
+ if (dispatch && datasourceType) {
85
+ const {
86
+ tr
87
+ } = state;
88
+ showDatasourceModal(datasourceType)(tr);
89
+ // editorAnalyticsApi?.attachAnalyticsEvent(
90
+ // buildEditLinkPayload(
91
+ // type as
92
+ // | ACTION_SUBJECT_ID.CARD_INLINE
93
+ // | ACTION_SUBJECT_ID.CARD_BLOCK
94
+ // | ACTION_SUBJECT_ID.EMBEDS,
95
+ // ),
96
+ // )(tr);
97
+ dispatch(tr);
98
+ return true;
99
+ }
100
+ return false;
101
+ };
@@ -5,9 +5,8 @@ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
5
5
  import { HyperlinkAddToolbar as HyperlinkToolbar } from '@atlaskit/editor-common/link';
6
6
  import { linkToolbarMessages } from '@atlaskit/editor-common/messages';
7
7
  import { LINKPICKER_HEIGHT_IN_PX, RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
8
- import { getDatasourceType } from '@atlaskit/editor-common/utils';
9
8
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
10
- import { hideLinkToolbar, showDatasourceModal, showLinkToolbar } from '../pm-plugins/actions';
9
+ import { hideLinkToolbar, showLinkToolbar } from '../pm-plugins/actions';
11
10
  import { changeSelectedCardToLink, updateCard } from '../pm-plugins/doc';
12
11
  import { displayInfoForCard, findCardInfo } from '../utils';
13
12
  export function HyperlinkAddToolbarWithState({
@@ -191,25 +190,4 @@ export const editLinkToolbarConfig = (showLinkingToolbar, lpLinkPicker) => {
191
190
  width: RECENT_SEARCH_WIDTH_IN_PX,
192
191
  forcePlacement: true
193
192
  } : {};
194
- };
195
- export const editDatasource = (node, editorAnalyticsApi) => (state, dispatch) => {
196
- var _node$attrs;
197
- const modalType = getDatasourceType((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.datasource.id);
198
- if (dispatch && modalType) {
199
- const {
200
- tr
201
- } = state;
202
- showDatasourceModal(modalType)(tr);
203
- // editorAnalyticsApi?.attachAnalyticsEvent(
204
- // buildEditLinkPayload(
205
- // type as
206
- // | ACTION_SUBJECT_ID.CARD_INLINE
207
- // | ACTION_SUBJECT_ID.CARD_BLOCK
208
- // | ACTION_SUBJECT_ID.EMBEDS,
209
- // ),
210
- // )(tr);
211
- dispatch(tr);
212
- return true;
213
- }
214
- return false;
215
193
  };
@@ -1,5 +1,63 @@
1
1
  import { useEffect, useMemo } from 'react';
2
+ import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
3
+ import { useDatasourceLifecycleAnalytics } from '@atlaskit/link-analytics';
2
4
  import { EVENT, EVENT_SUBJECT } from '../../analytics/types';
5
+ import { getMethod } from './common';
6
+ function getDatasourceDisplay(datasourceAttrs) {
7
+ var _datasourceAttrs$data;
8
+ return (_datasourceAttrs$data = datasourceAttrs.datasource.views[0]) === null || _datasourceAttrs$data === void 0 ? void 0 : _datasourceAttrs$data.type;
9
+ }
10
+ function getDisplayedColumnCount(datasourceAttrs) {
11
+ var _datasourceAttrs$data2, _datasourceAttrs$data3, _datasourceAttrs$data4, _datasourceAttrs$data5;
12
+ return (_datasourceAttrs$data2 = (_datasourceAttrs$data3 = datasourceAttrs.datasource.views[0]) === null || _datasourceAttrs$data3 === void 0 ? void 0 : (_datasourceAttrs$data4 = _datasourceAttrs$data3.properties) === null || _datasourceAttrs$data4 === void 0 ? void 0 : (_datasourceAttrs$data5 = _datasourceAttrs$data4.columns) === null || _datasourceAttrs$data5 === void 0 ? void 0 : _datasourceAttrs$data5.length) !== null && _datasourceAttrs$data2 !== void 0 ? _datasourceAttrs$data2 : 0;
13
+ }
14
+ function getSearchMethod(creationMethod, metadata) {
15
+ if (creationMethod === 'editor_paste' || creationMethod === 'editor_type') {
16
+ return '';
17
+ }
18
+ const {
19
+ sourceEvent
20
+ } = metadata;
21
+ if (sourceEvent instanceof UIAnalyticsEvent) {
22
+ const event = sourceEvent;
23
+ return event.payload.searchMethod;
24
+ }
25
+ return 'unknown';
26
+ }
27
+ function getAnalyticAttributesFromNode(datasourceAttrs, metadata) {
28
+ const {
29
+ url,
30
+ datasource: {
31
+ id: datasourceId,
32
+ parameters
33
+ }
34
+ } = datasourceAttrs;
35
+ const display = getDatasourceDisplay(datasourceAttrs);
36
+ let inputMethod = '';
37
+ let actions = [];
38
+ if (metadata.inputMethod) {
39
+ var _getMethod;
40
+ inputMethod = (_getMethod = getMethod({
41
+ inputMethod: metadata.inputMethod
42
+ })) !== null && _getMethod !== void 0 ? _getMethod : '';
43
+ } else if (metadata.sourceEvent instanceof UIAnalyticsEvent) {
44
+ inputMethod = metadata.sourceEvent.payload.inputMethod;
45
+ actions = metadata.sourceEvent.payload.actions;
46
+ }
47
+ const displayedColumnCount = getDisplayedColumnCount(datasourceAttrs);
48
+ const searchMethod = getSearchMethod(inputMethod, metadata);
49
+ return {
50
+ actions,
51
+ inputMethod,
52
+ datasourceId,
53
+ display,
54
+ displayedColumnCount,
55
+ parameters,
56
+ searchMethod,
57
+ url
58
+ };
59
+ }
60
+
3
61
  /**
4
62
  * Subscribes to the events occuring in the card
5
63
  * plugin and fires analytics events accordingly
@@ -7,25 +65,100 @@ import { EVENT, EVENT_SUBJECT } from '../../analytics/types';
7
65
  export const DatasourceEventsBinding = ({
8
66
  cardPluginEvents
9
67
  }) => {
68
+ const {
69
+ datasourceCreated,
70
+ datasourceUpdated,
71
+ datasourceDeleted
72
+ } = useDatasourceLifecycleAnalytics();
10
73
  const eventHandlers = useMemo(() => {
11
74
  return {
12
- [EVENT.CREATED]: metadata => {
13
- // TODO Impl as part of https://product-fabric.atlassian.net/browse/EDM-7072
14
- // eslint-disable-next-line no-console
15
- console.log('CREATED', metadata.node, metadata.nodeContext);
75
+ [EVENT.CREATED]: ({
76
+ node,
77
+ nodeContext,
78
+ ...metadata
79
+ }) => {
80
+ const attributes = getAnalyticAttributesFromNode(node.attrs, metadata);
81
+ const {
82
+ actions,
83
+ inputMethod,
84
+ datasourceId,
85
+ display,
86
+ displayedColumnCount,
87
+ parameters,
88
+ searchMethod,
89
+ url
90
+ } = attributes;
91
+ datasourceCreated({
92
+ datasourceId,
93
+ parameters,
94
+ url
95
+ }, null, {
96
+ actions,
97
+ creationMethod: inputMethod,
98
+ display,
99
+ displayedColumnCount,
100
+ nodeContext: nodeContext,
101
+ searchMethod
102
+ });
16
103
  },
17
- [EVENT.UPDATED]: metadata => {
18
- // TODO Impl as part of https://product-fabric.atlassian.net/browse/EDM-7072
19
- // eslint-disable-next-line no-console
20
- console.log('UPDATED', metadata.node, metadata.nodeContext);
104
+ [EVENT.UPDATED]: ({
105
+ node,
106
+ nodeContext,
107
+ ...metadata
108
+ }) => {
109
+ const attributes = getAnalyticAttributesFromNode(node.attrs, metadata);
110
+ const {
111
+ actions,
112
+ datasourceId,
113
+ display,
114
+ displayedColumnCount,
115
+ inputMethod,
116
+ parameters,
117
+ searchMethod,
118
+ url
119
+ } = attributes;
120
+ datasourceUpdated({
121
+ datasourceId,
122
+ parameters,
123
+ url
124
+ }, null, {
125
+ actions,
126
+ display,
127
+ displayedColumnCount,
128
+ nodeContext: nodeContext,
129
+ searchMethod,
130
+ updateMethod: inputMethod
131
+ });
21
132
  },
22
- [EVENT.DELETED]: metadata => {
23
- // TODO Impl as part of https://product-fabric.atlassian.net/browse/EDM-7072
24
- // eslint-disable-next-line no-console
25
- console.log('DELETED', metadata.node, metadata.nodeContext);
133
+ [EVENT.DELETED]: ({
134
+ node,
135
+ nodeContext,
136
+ ...metadata
137
+ }) => {
138
+ const attributes = getAnalyticAttributesFromNode(node.attrs, metadata);
139
+ const {
140
+ datasourceId,
141
+ display,
142
+ displayedColumnCount,
143
+ inputMethod,
144
+ parameters,
145
+ searchMethod,
146
+ url
147
+ } = attributes;
148
+ datasourceDeleted({
149
+ datasourceId,
150
+ parameters,
151
+ url
152
+ }, null, {
153
+ deleteMethod: inputMethod,
154
+ display,
155
+ displayedColumnCount,
156
+ nodeContext: nodeContext,
157
+ searchMethod
158
+ });
26
159
  }
27
160
  };
28
- }, []);
161
+ }, [datasourceCreated, datasourceUpdated, datasourceDeleted]);
29
162
 
30
163
  /**
31
164
  * Subscribe to datasource events
@@ -133,6 +133,7 @@ export var findChanged = function findChanged(tr, state) {
133
133
  if (!isUpdate) {
134
134
  var _getLinkMetadataFromT = getLinkMetadataFromTransaction(tr),
135
135
  inputMethod = _getLinkMetadataFromT.inputMethod;
136
+
136
137
  /**
137
138
  * If there is no identifiable input method, and the links inserted and removed appear to be the same,
138
139
  * then this transaction likely is not intended to be consided to be the insertion and removal of links
@@ -1,3 +1,4 @@
1
+ import _get from "@babel/runtime/helpers/get";
1
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
3
  import _createClass from "@babel/runtime/helpers/createClass";
3
4
  import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
@@ -137,6 +138,25 @@ export var BlockCard = /*#__PURE__*/function (_ReactNodeView) {
137
138
  }
138
139
  return domRef;
139
140
  }
141
+
142
+ // Need this function to check if the datasource attribute was added or not to a blockCard.
143
+ // If so, we return false so we can get the node to re-render properly as a datasource node instead.
144
+ // Otherwise, the node view will still consider the node as a blockCard and render a regular blockCard.
145
+ }, {
146
+ key: "validUpdate",
147
+ value: function validUpdate(currentNode, newNode) {
148
+ var _currentNode$attrs, _newNode$attrs;
149
+ var isCurrentNodeBlockCard = !((_currentNode$attrs = currentNode.attrs) !== null && _currentNode$attrs !== void 0 && _currentNode$attrs.datasource);
150
+ var isNewNodeDatasource = (_newNode$attrs = newNode.attrs) === null || _newNode$attrs === void 0 ? void 0 : _newNode$attrs.datasource;
151
+
152
+ // need to return falsy to update node
153
+ return !(isCurrentNodeBlockCard && isNewNodeDatasource);
154
+ }
155
+ }, {
156
+ key: "update",
157
+ value: function update(node, decorations, _innerDecorations) {
158
+ return _get(_getPrototypeOf(BlockCard.prototype), "update", this).call(this, node, decorations, _innerDecorations, this.validUpdate);
159
+ }
140
160
  }, {
141
161
  key: "render",
142
162
  value: function render() {
@@ -411,43 +411,53 @@ export var getLinkNodeType = function getLinkNodeType(appearance, linkNodes) {
411
411
  }
412
412
  };
413
413
 
414
- // Apply an update to a datasource (aka blockCard) node
415
- export var updateExistingDatasource = function updateExistingDatasource(state, node, newAdf, view) {
414
+ // Apply an update made from the datasource edit modal to a card
415
+ export var updateCardFromDatasourceModal = function updateCardFromDatasourceModal(state, node, newAdf, view, sourceEvent) {
416
416
  var tr = state.tr,
417
417
  from = state.selection.from,
418
418
  schemaNodes = state.schema.nodes;
419
-
420
- // datasource to datasource
421
- if (newAdf.type === 'blockCard' && newAdf.attrs.datasource && node.attrs.datasource) {
422
- var _ref3, _ref6, _newViews$properties, _oldViews$properties, _newAdf$attrs, _node$attrs;
423
- var _ref = (_ref3 = newAdf.attrs.datasource.views) !== null && _ref3 !== void 0 ? _ref3 : [],
424
- _ref2 = _slicedToArray(_ref, 1),
425
- newViews = _ref2[0];
426
- var _ref4 = (_ref6 = node.attrs.datasource.views) !== null && _ref6 !== void 0 ? _ref6 : [],
427
- _ref5 = _slicedToArray(_ref4, 1),
428
- oldViews = _ref5[0];
429
- var newColumnKeys = newViews === null || newViews === void 0 ? void 0 : (_newViews$properties = newViews.properties) === null || _newViews$properties === void 0 ? void 0 : _newViews$properties.columns.map(function (column) {
430
- return column.key;
431
- });
432
- var oldColumnKeys = oldViews === null || oldViews === void 0 ? void 0 : (_oldViews$properties = oldViews.properties) === null || _oldViews$properties === void 0 ? void 0 : _oldViews$properties.columns.map(function (column) {
433
- return column.key;
434
- });
435
- var isColumnChange = !isEqual(oldColumnKeys, newColumnKeys);
436
- var isUrlChange = ((_newAdf$attrs = newAdf.attrs) === null || _newAdf$attrs === void 0 ? void 0 : _newAdf$attrs.url) !== ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.url);
437
- if (isColumnChange || isUrlChange) {
438
- tr.setNodeMarkup(from, schemaNodes.blockCard, _objectSpread(_objectSpread({}, node.attrs), newAdf.attrs));
439
- addLinkMetadata(state.selection, tr, {
440
- action: ACTION.UPDATED
419
+ if (newAdf.type === 'blockCard') {
420
+ var _node$attrs, _newAdf$attrs;
421
+ if ((_node$attrs = node.attrs) !== null && _node$attrs !== void 0 && _node$attrs.datasource && (_newAdf$attrs = newAdf.attrs) !== null && _newAdf$attrs !== void 0 && _newAdf$attrs.datasource) {
422
+ var _ref3, _ref6, _newViews$properties, _oldViews$properties, _newAdf$attrs2, _node$attrs2;
423
+ // datasource to datasource
424
+ var _ref = (_ref3 = newAdf.attrs.datasource.views) !== null && _ref3 !== void 0 ? _ref3 : [],
425
+ _ref2 = _slicedToArray(_ref, 1),
426
+ newViews = _ref2[0];
427
+ var _ref4 = (_ref6 = node.attrs.datasource.views) !== null && _ref6 !== void 0 ? _ref6 : [],
428
+ _ref5 = _slicedToArray(_ref4, 1),
429
+ oldViews = _ref5[0];
430
+ var newColumnKeys = newViews === null || newViews === void 0 ? void 0 : (_newViews$properties = newViews.properties) === null || _newViews$properties === void 0 ? void 0 : _newViews$properties.columns.map(function (column) {
431
+ return column.key;
441
432
  });
433
+ var oldColumnKeys = oldViews === null || oldViews === void 0 ? void 0 : (_oldViews$properties = oldViews.properties) === null || _oldViews$properties === void 0 ? void 0 : _oldViews$properties.columns.map(function (column) {
434
+ return column.key;
435
+ });
436
+ var isColumnChange = !isEqual(oldColumnKeys, newColumnKeys);
437
+ var isUrlChange = ((_newAdf$attrs2 = newAdf.attrs) === null || _newAdf$attrs2 === void 0 ? void 0 : _newAdf$attrs2.url) !== ((_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.url);
438
+ if (isColumnChange || isUrlChange) {
439
+ tr.setNodeMarkup(from, schemaNodes.blockCard, _objectSpread(_objectSpread({}, node.attrs), newAdf.attrs));
440
+ addLinkMetadata(state.selection, tr, {
441
+ action: ACTION.UPDATED,
442
+ sourceEvent: sourceEvent
443
+ });
444
+ }
445
+ } else {
446
+ // inline or blockCard to datasource
447
+ tr.setNodeMarkup(from, schemaNodes.blockCard, newAdf.attrs);
442
448
  }
443
449
  } else if (newAdf.type === 'inlineCard') {
444
- // datasource to inline
450
+ // card type to inlineCard
445
451
  tr.setNodeMarkup(from, schemaNodes.inlineCard, newAdf.attrs);
452
+ addLinkMetadata(state.selection, tr, {
453
+ action: ACTION.UPDATED,
454
+ sourceEvent: sourceEvent
455
+ });
446
456
  }
447
457
  hideDatasourceModal(tr);
448
458
  view.dispatch(tr.scrollIntoView());
449
459
  };
450
- export var insertDatasource = function insertDatasource(state, adf, view) {
460
+ export var insertDatasource = function insertDatasource(state, adf, view, sourceEvent) {
451
461
  var tr = state.tr,
452
462
  from = state.selection.from,
453
463
  schemaNodes = state.schema.nodes;
@@ -459,5 +469,9 @@ export var insertDatasource = function insertDatasource(state, adf, view) {
459
469
  // this will allow us to deal with insertions from multiple paths in a more consistent way
460
470
  newNode && tr.insert(from, newNode);
461
471
  hideDatasourceModal(tr);
472
+ addLinkMetadata(state.selection, tr, {
473
+ action: ACTION.INSERTED,
474
+ sourceEvent: sourceEvent
475
+ });
462
476
  view.dispatch(tr.scrollIntoView());
463
477
  };