@atlaskit/editor-plugin-card 14.0.7 → 14.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-card
2
2
 
3
+ ## 14.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`e643f1adf62c9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e643f1adf62c9) -
8
+ Add resolvedInlineSmartLinks to CardPluginState, a generic ordered list of inline smart links that
9
+ have resolved during the editing session. Each entry tracks pos, url, and source, with positions
10
+ remapped on document changes. InlineCardNodeView reads this list and passes isChangeboardTarget to
11
+ SmartLinkDraggable based on the first entry, enabling Product Onboarding spotlight targeting.
12
+ Gated behind cc_dnd_smart_link_changeboard_po_template_gate.
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies
17
+
18
+ ## 14.0.8
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 14.0.7
4
25
 
5
26
  ### Patch Changes
@@ -16,6 +16,7 @@ var _analytics = require("@atlaskit/editor-common/analytics");
16
16
  var _hooks = require("@atlaskit/editor-common/hooks");
17
17
  var _ui = require("@atlaskit/editor-common/ui");
18
18
  var _editorSmartLinkDraggable = require("@atlaskit/editor-smart-link-draggable");
19
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
19
20
  var _smartCard = require("@atlaskit/smart-card");
20
21
  var _ssr = require("@atlaskit/smart-card/ssr");
21
22
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
@@ -165,10 +166,18 @@ var InlineCard = exports.InlineCard = /*#__PURE__*/(0, _react.memo)(function (_r
165
166
  }, card) : data ? card : null;
166
167
  });
167
168
  var WrappedInlineCardWithAwareness = (0, _genericCard.Card)(_inlineCardWithAwareness.InlineCardWithAwareness, _ui.UnsupportedInline);
168
- var selector = function selector(states) {
169
- var _states$editorViewMod;
169
+ var selectorWithCard = function selectorWithCard(states) {
170
+ var _states$editorViewMod, _states$cardState;
170
171
  return {
171
- mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode
172
+ mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode,
173
+ resolvedInlineSmartLinks: (_states$cardState = states.cardState) === null || _states$cardState === void 0 ? void 0 : _states$cardState.resolvedInlineSmartLinks
174
+ };
175
+ };
176
+ var selectorWithoutCard = function selectorWithoutCard(states) {
177
+ var _states$editorViewMod2;
178
+ return {
179
+ mode: (_states$editorViewMod2 = states.editorViewModeState) === null || _states$editorViewMod2 === void 0 ? void 0 : _states$editorViewMod2.mode,
180
+ resolvedInlineSmartLinks: undefined
172
181
  };
173
182
  };
174
183
 
@@ -179,6 +188,7 @@ var selector = function selector(states) {
179
188
  * @example
180
189
  */
181
190
  function InlineCardNodeView(props) {
191
+ var _resolvedInlineSmartL;
182
192
  var useAlternativePreloader = props.useAlternativePreloader,
183
193
  node = props.node,
184
194
  view = props.view,
@@ -192,8 +202,9 @@ function InlineCardNodeView(props) {
192
202
  isPageSSRed = props.isPageSSRed,
193
203
  provider = props.provider,
194
204
  CompetitorPrompt = props.CompetitorPrompt;
195
- var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(pluginInjectionApi, ['editorViewMode'], selector),
196
- mode = _useSharedPluginState.mode;
205
+ var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(pluginInjectionApi, (0, _platformFeatureFlags.fg)('cc_dnd_smart_link_changeboard_po_template_gate') ? ['editorViewMode', 'card'] : ['editorViewMode'], (0, _platformFeatureFlags.fg)('cc_dnd_smart_link_changeboard_po_template_gate') ? selectorWithCard : selectorWithoutCard),
206
+ mode = _useSharedPluginState.mode,
207
+ resolvedInlineSmartLinks = _useSharedPluginState.resolvedInlineSmartLinks;
197
208
  var url = node.attrs.url;
198
209
  var CompetitorPromptComponent = CompetitorPrompt && url ? /*#__PURE__*/_react.default.createElement(CompetitorPrompt, {
199
210
  sourceUrl: url,
@@ -208,6 +219,14 @@ function InlineCardNodeView(props) {
208
219
  });
209
220
  }
210
221
  }, [provider, props.node]);
222
+ var linkPosition = (0, _react.useMemo)(function () {
223
+ if (!getPos || typeof getPos === 'boolean') {
224
+ return undefined;
225
+ }
226
+ var pos = getPos();
227
+ return typeof pos === 'number' ? pos : undefined;
228
+ }, [getPos]);
229
+ var isChangeboardTarget = linkPosition !== undefined && (resolvedInlineSmartLinks === null || resolvedInlineSmartLinks === void 0 || (_resolvedInlineSmartL = resolvedInlineSmartLinks[0]) === null || _resolvedInlineSmartL === void 0 ? void 0 : _resolvedInlineSmartL.pos) === linkPosition;
211
230
  var inlineCardContent = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(WrappedInlineCardWithAwareness, (0, _extends2.default)({
212
231
  node: node,
213
232
  view: view,
@@ -225,7 +244,8 @@ function InlineCardNodeView(props) {
225
244
  return /*#__PURE__*/_react.default.createElement(_editorSmartLinkDraggable.SmartLinkDraggable, {
226
245
  url: url,
227
246
  appearance: _editorSmartLinkDraggable.SMART_LINK_APPEARANCE.INLINE,
228
- source: _editorSmartLinkDraggable.SMART_LINK_DRAG_TYPES.EDITOR
247
+ source: _editorSmartLinkDraggable.SMART_LINK_DRAG_TYPES.EDITOR,
248
+ isChangeboardTarget: isChangeboardTarget
229
249
  }, inlineCardContent);
230
250
  }
231
251
  var inlineCardNodeView = exports.inlineCardNodeView = function inlineCardNodeView(_ref5) {
@@ -14,6 +14,7 @@ var _styles = require("@atlaskit/editor-common/styles");
14
14
  var _state = require("@atlaskit/editor-prosemirror/state");
15
15
  var _utils = require("@atlaskit/editor-prosemirror/utils");
16
16
  var _linkingCommon = require("@atlaskit/linking-common");
17
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
18
  var _inlineCard = require("../nodeviews/inlineCard");
18
19
  var _lazyBlockCard = require("../nodeviews/lazy-block-card");
19
20
  var _lazyEmbedCard = require("../nodeviews/lazy-embed-card");
@@ -30,6 +31,8 @@ var _utils3 = require("./utils");
30
31
  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; }
31
32
  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; }
32
33
  var LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK = 'smart-link-upgrade-pulse';
34
+ // Only the first resolved inline smart link is needed for PO spotlight targeting
35
+ var MAX_RESOLVED_INLINE_SMART_LINKS = 1;
33
36
  var handleAwarenessOverlay = function handleAwarenessOverlay(view) {
34
37
  var currentState = (0, _state2.getPluginState)(view.state);
35
38
  var overlayCandidatePos = currentState === null || currentState === void 0 ? void 0 : currentState.overlayCandidatePosition;
@@ -94,7 +97,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
94
97
  };
95
98
  },
96
99
  apply: function apply(tr, pluginState, prevEditorState) {
97
- var _pluginState$requests;
100
+ var _pluginState$requests, _pluginState$requests2;
98
101
  // Update all the positions of outstanding requests and
99
102
  // cards in the plugin state.
100
103
  var pluginStateWithUpdatedPos = (0, _state2.getPluginStateWithUpdatedPos)(pluginState, tr);
@@ -118,13 +121,31 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pluginI
118
121
  if (!meta) {
119
122
  return pluginStateWithUpdatedPos;
120
123
  }
124
+ var newState = (0, _reducers.default)(pluginStateWithUpdatedPos, meta);
125
+
126
+ // Track the first resolved inline smart link for PO spotlight DOM targeting
127
+ if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length && (0, _platformFeatureFlags.fg)('cc_dnd_smart_link_changeboard_po_template_gate')) {
128
+ var resolvedRequest = pluginState.requests.find(function (req) {
129
+ return req.url === meta.url;
130
+ });
131
+ if ((resolvedRequest === null || resolvedRequest === void 0 ? void 0 : resolvedRequest.appearance) === 'inline') {
132
+ var _newState$resolvedInl, _newState$resolvedInl2;
133
+ if (((_newState$resolvedInl = (_newState$resolvedInl2 = newState.resolvedInlineSmartLinks) === null || _newState$resolvedInl2 === void 0 ? void 0 : _newState$resolvedInl2.length) !== null && _newState$resolvedInl !== void 0 ? _newState$resolvedInl : 0) < MAX_RESOLVED_INLINE_SMART_LINKS) {
134
+ var _newState$resolvedInl3;
135
+ newState.resolvedInlineSmartLinks = [].concat((0, _toConsumableArray2.default)((_newState$resolvedInl3 = newState.resolvedInlineSmartLinks) !== null && _newState$resolvedInl3 !== void 0 ? _newState$resolvedInl3 : []), [{
136
+ pos: resolvedRequest.pos,
137
+ url: resolvedRequest.url,
138
+ source: resolvedRequest.source
139
+ }]);
140
+ }
141
+ }
142
+ }
121
143
  if (!enableInlineUpgradeFeatures) {
122
- return (0, _reducers.default)(pluginStateWithUpdatedPos, meta);
144
+ return newState;
123
145
  }
124
- var newState = (0, _reducers.default)(pluginStateWithUpdatedPos, meta);
125
146
 
126
147
  // the code below is related to the "Inline Switcher" project, for more information pls see EDM-7984
127
- var isSingleInlineLink = (pluginState === null || pluginState === void 0 || (_pluginState$requests = pluginState.requests) === null || _pluginState$requests === void 0 ? void 0 : _pluginState$requests.length) === 1 && pluginState.requests[0].appearance === 'inline';
148
+ var isSingleInlineLink = (pluginState === null || pluginState === void 0 || (_pluginState$requests2 = pluginState.requests) === null || _pluginState$requests2 === void 0 ? void 0 : _pluginState$requests2.length) === 1 && pluginState.requests[0].appearance === 'inline';
128
149
  var isSmartLinkPulseDiscovered = (0, _localStorage.isLocalStorageKeyDiscovered)(LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK);
129
150
  if (meta.type !== 'RESOLVE' || !isSingleInlineLink) {
130
151
  return newState;
@@ -18,6 +18,7 @@ var getPluginState = exports.getPluginState = function getPluginState(editorStat
18
18
  return _pluginKey.pluginKey.getState(editorState);
19
19
  };
20
20
  var getPluginStateWithUpdatedPos = exports.getPluginStateWithUpdatedPos = function getPluginStateWithUpdatedPos(pluginState, tr) {
21
+ var _pluginState$resolved;
21
22
  return _objectSpread(_objectSpread({}, pluginState), {}, {
22
23
  requests: pluginState.requests.map(function (request) {
23
24
  return _objectSpread(_objectSpread({}, request), {}, {
@@ -28,6 +29,11 @@ var getPluginStateWithUpdatedPos = exports.getPluginStateWithUpdatedPos = functi
28
29
  return _objectSpread(_objectSpread({}, card), {}, {
29
30
  pos: tr.mapping.map(card.pos)
30
31
  });
32
+ }),
33
+ resolvedInlineSmartLinks: (_pluginState$resolved = pluginState.resolvedInlineSmartLinks) === null || _pluginState$resolved === void 0 ? void 0 : _pluginState$resolved.map(function (card) {
34
+ return _objectSpread(_objectSpread({}, card), {}, {
35
+ pos: tr.mapping.map(card.pos)
36
+ });
31
37
  })
32
38
  });
33
39
  };
@@ -7,6 +7,7 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
8
  import { UnsupportedInline, findOverflowScrollParent } from '@atlaskit/editor-common/ui';
9
9
  import { SmartLinkDraggable, SMART_LINK_DRAG_TYPES, SMART_LINK_APPEARANCE } from '@atlaskit/editor-smart-link-draggable';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { Card as SmartCard } from '@atlaskit/smart-card';
11
12
  import { CardSSR } from '@atlaskit/smart-card/ssr';
12
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -161,10 +162,18 @@ export const InlineCard = /*#__PURE__*/memo(({
161
162
  }, card) : data ? card : null;
162
163
  });
163
164
  const WrappedInlineCardWithAwareness = Card(InlineCardWithAwareness, UnsupportedInline);
164
- const selector = states => {
165
- var _states$editorViewMod;
165
+ const selectorWithCard = states => {
166
+ var _states$editorViewMod, _states$cardState;
166
167
  return {
167
- mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode
168
+ mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode,
169
+ resolvedInlineSmartLinks: (_states$cardState = states.cardState) === null || _states$cardState === void 0 ? void 0 : _states$cardState.resolvedInlineSmartLinks
170
+ };
171
+ };
172
+ const selectorWithoutCard = states => {
173
+ var _states$editorViewMod2;
174
+ return {
175
+ mode: (_states$editorViewMod2 = states.editorViewModeState) === null || _states$editorViewMod2 === void 0 ? void 0 : _states$editorViewMod2.mode,
176
+ resolvedInlineSmartLinks: undefined
168
177
  };
169
178
  };
170
179
 
@@ -175,6 +184,7 @@ const selector = states => {
175
184
  * @example
176
185
  */
177
186
  export function InlineCardNodeView(props) {
187
+ var _resolvedInlineSmartL;
178
188
  const {
179
189
  useAlternativePreloader,
180
190
  node,
@@ -191,8 +201,9 @@ export function InlineCardNodeView(props) {
191
201
  CompetitorPrompt
192
202
  } = props;
193
203
  const {
194
- mode
195
- } = useSharedPluginStateWithSelector(pluginInjectionApi, ['editorViewMode'], selector);
204
+ mode,
205
+ resolvedInlineSmartLinks
206
+ } = useSharedPluginStateWithSelector(pluginInjectionApi, fg('cc_dnd_smart_link_changeboard_po_template_gate') ? ['editorViewMode', 'card'] : ['editorViewMode'], fg('cc_dnd_smart_link_changeboard_po_template_gate') ? selectorWithCard : selectorWithoutCard);
196
207
  const url = node.attrs.url;
197
208
  const CompetitorPromptComponent = CompetitorPrompt && url ? /*#__PURE__*/React.createElement(CompetitorPrompt, {
198
209
  sourceUrl: url,
@@ -207,6 +218,14 @@ export function InlineCardNodeView(props) {
207
218
  });
208
219
  }
209
220
  }, [provider, props.node]);
221
+ const linkPosition = useMemo(() => {
222
+ if (!getPos || typeof getPos === 'boolean') {
223
+ return undefined;
224
+ }
225
+ const pos = getPos();
226
+ return typeof pos === 'number' ? pos : undefined;
227
+ }, [getPos]);
228
+ const isChangeboardTarget = linkPosition !== undefined && (resolvedInlineSmartLinks === null || resolvedInlineSmartLinks === void 0 ? void 0 : (_resolvedInlineSmartL = resolvedInlineSmartLinks[0]) === null || _resolvedInlineSmartL === void 0 ? void 0 : _resolvedInlineSmartL.pos) === linkPosition;
210
229
  const inlineCardContent = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(WrappedInlineCardWithAwareness, _extends({
211
230
  node: node,
212
231
  view: view,
@@ -224,7 +243,8 @@ export function InlineCardNodeView(props) {
224
243
  return /*#__PURE__*/React.createElement(SmartLinkDraggable, {
225
244
  url: url,
226
245
  appearance: SMART_LINK_APPEARANCE.INLINE,
227
- source: SMART_LINK_DRAG_TYPES.EDITOR
246
+ source: SMART_LINK_DRAG_TYPES.EDITOR,
247
+ isChangeboardTarget: isChangeboardTarget
228
248
  }, inlineCardContent);
229
249
  }
230
250
  export const inlineCardNodeView = ({
@@ -5,6 +5,7 @@ import { DATASOURCE_INNER_CONTAINER_CLASSNAME } from '@atlaskit/editor-common/st
5
5
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
6
6
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
7
7
  import { DATASOURCE_DEFAULT_LAYOUT } from '@atlaskit/linking-common';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { InlineCardNodeView } from '../nodeviews/inlineCard';
9
10
  import { lazyBlockCardView } from '../nodeviews/lazy-block-card';
10
11
  import { lazyEmbedCardView } from '../nodeviews/lazy-embed-card';
@@ -19,6 +20,8 @@ import { handleProvider, resolveWithProvider } from './util/resolve';
19
20
  import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
20
21
  import { isBlockSupportedAtPosition, isEmbedSupportedAtPosition } from './utils';
21
22
  const LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK = 'smart-link-upgrade-pulse';
23
+ // Only the first resolved inline smart link is needed for PO spotlight targeting
24
+ const MAX_RESOLVED_INLINE_SMART_LINKS = 1;
22
25
  const handleAwarenessOverlay = view => {
23
26
  const currentState = getPluginState(view.state);
24
27
  const overlayCandidatePos = currentState === null || currentState === void 0 ? void 0 : currentState.overlayCandidatePosition;
@@ -84,7 +87,7 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
84
87
  };
85
88
  },
86
89
  apply(tr, pluginState, prevEditorState) {
87
- var _pluginState$requests;
90
+ var _pluginState$requests, _pluginState$requests2;
88
91
  // Update all the positions of outstanding requests and
89
92
  // cards in the plugin state.
90
93
  const pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
@@ -109,13 +112,29 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
109
112
  if (!meta) {
110
113
  return pluginStateWithUpdatedPos;
111
114
  }
115
+ const newState = reducer(pluginStateWithUpdatedPos, meta);
116
+
117
+ // Track the first resolved inline smart link for PO spotlight DOM targeting
118
+ if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length && fg('cc_dnd_smart_link_changeboard_po_template_gate')) {
119
+ const resolvedRequest = pluginState.requests.find(req => req.url === meta.url);
120
+ if ((resolvedRequest === null || resolvedRequest === void 0 ? void 0 : resolvedRequest.appearance) === 'inline') {
121
+ var _newState$resolvedInl, _newState$resolvedInl2;
122
+ if (((_newState$resolvedInl = (_newState$resolvedInl2 = newState.resolvedInlineSmartLinks) === null || _newState$resolvedInl2 === void 0 ? void 0 : _newState$resolvedInl2.length) !== null && _newState$resolvedInl !== void 0 ? _newState$resolvedInl : 0) < MAX_RESOLVED_INLINE_SMART_LINKS) {
123
+ var _newState$resolvedInl3;
124
+ newState.resolvedInlineSmartLinks = [...((_newState$resolvedInl3 = newState.resolvedInlineSmartLinks) !== null && _newState$resolvedInl3 !== void 0 ? _newState$resolvedInl3 : []), {
125
+ pos: resolvedRequest.pos,
126
+ url: resolvedRequest.url,
127
+ source: resolvedRequest.source
128
+ }];
129
+ }
130
+ }
131
+ }
112
132
  if (!enableInlineUpgradeFeatures) {
113
- return reducer(pluginStateWithUpdatedPos, meta);
133
+ return newState;
114
134
  }
115
- const newState = reducer(pluginStateWithUpdatedPos, meta);
116
135
 
117
136
  // the code below is related to the "Inline Switcher" project, for more information pls see EDM-7984
118
- const isSingleInlineLink = (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$requests = pluginState.requests) === null || _pluginState$requests === void 0 ? void 0 : _pluginState$requests.length) === 1 && pluginState.requests[0].appearance === 'inline';
137
+ const isSingleInlineLink = (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$requests2 = pluginState.requests) === null || _pluginState$requests2 === void 0 ? void 0 : _pluginState$requests2.length) === 1 && pluginState.requests[0].appearance === 'inline';
119
138
  const isSmartLinkPulseDiscovered = isLocalStorageKeyDiscovered(LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK);
120
139
  if (meta.type !== 'RESOLVE' || !isSingleInlineLink) {
121
140
  return newState;
@@ -6,17 +6,24 @@ import { pluginKey } from '../plugin-key';
6
6
  // Used for interactions with the Card Plugin's state.
7
7
  // ============================================================================ //
8
8
  export const getPluginState = editorState => pluginKey.getState(editorState);
9
- export const getPluginStateWithUpdatedPos = (pluginState, tr) => ({
10
- ...pluginState,
11
- requests: pluginState.requests.map(request => ({
12
- ...request,
13
- pos: tr.mapping.map(request.pos)
14
- })),
15
- cards: pluginState.cards.map(card => ({
16
- ...card,
17
- pos: tr.mapping.map(card.pos)
18
- }))
19
- });
9
+ export const getPluginStateWithUpdatedPos = (pluginState, tr) => {
10
+ var _pluginState$resolved;
11
+ return {
12
+ ...pluginState,
13
+ requests: pluginState.requests.map(request => ({
14
+ ...request,
15
+ pos: tr.mapping.map(request.pos)
16
+ })),
17
+ cards: pluginState.cards.map(card => ({
18
+ ...card,
19
+ pos: tr.mapping.map(card.pos)
20
+ })),
21
+ resolvedInlineSmartLinks: (_pluginState$resolved = pluginState.resolvedInlineSmartLinks) === null || _pluginState$resolved === void 0 ? void 0 : _pluginState$resolved.map(card => ({
22
+ ...card,
23
+ pos: tr.mapping.map(card.pos)
24
+ }))
25
+ };
26
+ };
20
27
  export const getNewRequests = (oldState, currentState) => {
21
28
  if (oldState) {
22
29
  return currentState.requests.filter(req => !oldState.requests.find(oldReq => isSameRequest(oldReq, req)));
@@ -7,6 +7,7 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
8
  import { UnsupportedInline, findOverflowScrollParent } from '@atlaskit/editor-common/ui';
9
9
  import { SmartLinkDraggable, SMART_LINK_DRAG_TYPES, SMART_LINK_APPEARANCE } from '@atlaskit/editor-smart-link-draggable';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { Card as SmartCard } from '@atlaskit/smart-card';
11
12
  import { CardSSR } from '@atlaskit/smart-card/ssr';
12
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -153,10 +154,18 @@ export var InlineCard = /*#__PURE__*/memo(function (_ref) {
153
154
  }, card) : data ? card : null;
154
155
  });
155
156
  var WrappedInlineCardWithAwareness = Card(InlineCardWithAwareness, UnsupportedInline);
156
- var selector = function selector(states) {
157
- var _states$editorViewMod;
157
+ var selectorWithCard = function selectorWithCard(states) {
158
+ var _states$editorViewMod, _states$cardState;
158
159
  return {
159
- mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode
160
+ mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode,
161
+ resolvedInlineSmartLinks: (_states$cardState = states.cardState) === null || _states$cardState === void 0 ? void 0 : _states$cardState.resolvedInlineSmartLinks
162
+ };
163
+ };
164
+ var selectorWithoutCard = function selectorWithoutCard(states) {
165
+ var _states$editorViewMod2;
166
+ return {
167
+ mode: (_states$editorViewMod2 = states.editorViewModeState) === null || _states$editorViewMod2 === void 0 ? void 0 : _states$editorViewMod2.mode,
168
+ resolvedInlineSmartLinks: undefined
160
169
  };
161
170
  };
162
171
 
@@ -167,6 +176,7 @@ var selector = function selector(states) {
167
176
  * @example
168
177
  */
169
178
  export function InlineCardNodeView(props) {
179
+ var _resolvedInlineSmartL;
170
180
  var useAlternativePreloader = props.useAlternativePreloader,
171
181
  node = props.node,
172
182
  view = props.view,
@@ -180,8 +190,9 @@ export function InlineCardNodeView(props) {
180
190
  isPageSSRed = props.isPageSSRed,
181
191
  provider = props.provider,
182
192
  CompetitorPrompt = props.CompetitorPrompt;
183
- var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionApi, ['editorViewMode'], selector),
184
- mode = _useSharedPluginState.mode;
193
+ var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionApi, fg('cc_dnd_smart_link_changeboard_po_template_gate') ? ['editorViewMode', 'card'] : ['editorViewMode'], fg('cc_dnd_smart_link_changeboard_po_template_gate') ? selectorWithCard : selectorWithoutCard),
194
+ mode = _useSharedPluginState.mode,
195
+ resolvedInlineSmartLinks = _useSharedPluginState.resolvedInlineSmartLinks;
185
196
  var url = node.attrs.url;
186
197
  var CompetitorPromptComponent = CompetitorPrompt && url ? /*#__PURE__*/React.createElement(CompetitorPrompt, {
187
198
  sourceUrl: url,
@@ -196,6 +207,14 @@ export function InlineCardNodeView(props) {
196
207
  });
197
208
  }
198
209
  }, [provider, props.node]);
210
+ var linkPosition = useMemo(function () {
211
+ if (!getPos || typeof getPos === 'boolean') {
212
+ return undefined;
213
+ }
214
+ var pos = getPos();
215
+ return typeof pos === 'number' ? pos : undefined;
216
+ }, [getPos]);
217
+ var isChangeboardTarget = linkPosition !== undefined && (resolvedInlineSmartLinks === null || resolvedInlineSmartLinks === void 0 || (_resolvedInlineSmartL = resolvedInlineSmartLinks[0]) === null || _resolvedInlineSmartL === void 0 ? void 0 : _resolvedInlineSmartL.pos) === linkPosition;
199
218
  var inlineCardContent = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(WrappedInlineCardWithAwareness, _extends({
200
219
  node: node,
201
220
  view: view,
@@ -213,7 +232,8 @@ export function InlineCardNodeView(props) {
213
232
  return /*#__PURE__*/React.createElement(SmartLinkDraggable, {
214
233
  url: url,
215
234
  appearance: SMART_LINK_APPEARANCE.INLINE,
216
- source: SMART_LINK_DRAG_TYPES.EDITOR
235
+ source: SMART_LINK_DRAG_TYPES.EDITOR,
236
+ isChangeboardTarget: isChangeboardTarget
217
237
  }, inlineCardContent);
218
238
  }
219
239
  export var inlineCardNodeView = function inlineCardNodeView(_ref5) {
@@ -9,6 +9,7 @@ import { DATASOURCE_INNER_CONTAINER_CLASSNAME } from '@atlaskit/editor-common/st
9
9
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
10
10
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
11
11
  import { DATASOURCE_DEFAULT_LAYOUT } from '@atlaskit/linking-common';
12
+ import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { InlineCardNodeView } from '../nodeviews/inlineCard';
13
14
  import { lazyBlockCardView } from '../nodeviews/lazy-block-card';
14
15
  import { lazyEmbedCardView } from '../nodeviews/lazy-embed-card';
@@ -23,6 +24,8 @@ import { handleProvider, resolveWithProvider } from './util/resolve';
23
24
  import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
24
25
  import { isBlockSupportedAtPosition, isEmbedSupportedAtPosition } from './utils';
25
26
  var LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK = 'smart-link-upgrade-pulse';
27
+ // Only the first resolved inline smart link is needed for PO spotlight targeting
28
+ var MAX_RESOLVED_INLINE_SMART_LINKS = 1;
26
29
  var handleAwarenessOverlay = function handleAwarenessOverlay(view) {
27
30
  var currentState = getPluginState(view.state);
28
31
  var overlayCandidatePos = currentState === null || currentState === void 0 ? void 0 : currentState.overlayCandidatePosition;
@@ -87,7 +90,7 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
87
90
  };
88
91
  },
89
92
  apply: function apply(tr, pluginState, prevEditorState) {
90
- var _pluginState$requests;
93
+ var _pluginState$requests, _pluginState$requests2;
91
94
  // Update all the positions of outstanding requests and
92
95
  // cards in the plugin state.
93
96
  var pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
@@ -111,13 +114,31 @@ export var createPlugin = function createPlugin(options, pluginInjectionApi) {
111
114
  if (!meta) {
112
115
  return pluginStateWithUpdatedPos;
113
116
  }
117
+ var newState = reducer(pluginStateWithUpdatedPos, meta);
118
+
119
+ // Track the first resolved inline smart link for PO spotlight DOM targeting
120
+ if (meta.type === 'RESOLVE' && pluginState !== null && pluginState !== void 0 && (_pluginState$requests = pluginState.requests) !== null && _pluginState$requests !== void 0 && _pluginState$requests.length && fg('cc_dnd_smart_link_changeboard_po_template_gate')) {
121
+ var resolvedRequest = pluginState.requests.find(function (req) {
122
+ return req.url === meta.url;
123
+ });
124
+ if ((resolvedRequest === null || resolvedRequest === void 0 ? void 0 : resolvedRequest.appearance) === 'inline') {
125
+ var _newState$resolvedInl, _newState$resolvedInl2;
126
+ if (((_newState$resolvedInl = (_newState$resolvedInl2 = newState.resolvedInlineSmartLinks) === null || _newState$resolvedInl2 === void 0 ? void 0 : _newState$resolvedInl2.length) !== null && _newState$resolvedInl !== void 0 ? _newState$resolvedInl : 0) < MAX_RESOLVED_INLINE_SMART_LINKS) {
127
+ var _newState$resolvedInl3;
128
+ newState.resolvedInlineSmartLinks = [].concat(_toConsumableArray((_newState$resolvedInl3 = newState.resolvedInlineSmartLinks) !== null && _newState$resolvedInl3 !== void 0 ? _newState$resolvedInl3 : []), [{
129
+ pos: resolvedRequest.pos,
130
+ url: resolvedRequest.url,
131
+ source: resolvedRequest.source
132
+ }]);
133
+ }
134
+ }
135
+ }
114
136
  if (!enableInlineUpgradeFeatures) {
115
- return reducer(pluginStateWithUpdatedPos, meta);
137
+ return newState;
116
138
  }
117
- var newState = reducer(pluginStateWithUpdatedPos, meta);
118
139
 
119
140
  // the code below is related to the "Inline Switcher" project, for more information pls see EDM-7984
120
- var isSingleInlineLink = (pluginState === null || pluginState === void 0 || (_pluginState$requests = pluginState.requests) === null || _pluginState$requests === void 0 ? void 0 : _pluginState$requests.length) === 1 && pluginState.requests[0].appearance === 'inline';
141
+ var isSingleInlineLink = (pluginState === null || pluginState === void 0 || (_pluginState$requests2 = pluginState.requests) === null || _pluginState$requests2 === void 0 ? void 0 : _pluginState$requests2.length) === 1 && pluginState.requests[0].appearance === 'inline';
121
142
  var isSmartLinkPulseDiscovered = isLocalStorageKeyDiscovered(LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK);
122
143
  if (meta.type !== 'RESOLVE' || !isSingleInlineLink) {
123
144
  return newState;
@@ -12,6 +12,7 @@ export var getPluginState = function getPluginState(editorState) {
12
12
  return pluginKey.getState(editorState);
13
13
  };
14
14
  export var getPluginStateWithUpdatedPos = function getPluginStateWithUpdatedPos(pluginState, tr) {
15
+ var _pluginState$resolved;
15
16
  return _objectSpread(_objectSpread({}, pluginState), {}, {
16
17
  requests: pluginState.requests.map(function (request) {
17
18
  return _objectSpread(_objectSpread({}, request), {}, {
@@ -22,6 +23,11 @@ export var getPluginStateWithUpdatedPos = function getPluginStateWithUpdatedPos(
22
23
  return _objectSpread(_objectSpread({}, card), {}, {
23
24
  pos: tr.mapping.map(card.pos)
24
25
  });
26
+ }),
27
+ resolvedInlineSmartLinks: (_pluginState$resolved = pluginState.resolvedInlineSmartLinks) === null || _pluginState$resolved === void 0 ? void 0 : _pluginState$resolved.map(function (card) {
28
+ return _objectSpread(_objectSpread({}, card), {}, {
29
+ pos: tr.mapping.map(card.pos)
30
+ });
25
31
  })
26
32
  });
27
33
  };
@@ -42,6 +42,11 @@ export declare const getPluginStateWithUpdatedPos: (pluginState: CardPluginState
42
42
  sourceEvent?: UIAnalyticsEvent | null | undefined;
43
43
  url: string;
44
44
  }[];
45
+ resolvedInlineSmartLinks?: Array<{
46
+ pos: number;
47
+ source: CardReplacementInputMethod;
48
+ url: string;
49
+ }>;
45
50
  resolvedToolbarAttributesByUrl: Record<string, ToolbarResolvedAttributes>;
46
51
  selectedInlineLinkPosition?: number;
47
52
  showDatasourceModal: boolean;
@@ -101,6 +101,11 @@ export type CardPluginState = {
101
101
  provider: CardProvider | null;
102
102
  removeOverlay?: () => void;
103
103
  requests: Request[];
104
+ resolvedInlineSmartLinks?: Array<{
105
+ pos: number;
106
+ source: CardReplacementInputMethod;
107
+ url: string;
108
+ }>;
104
109
  resolvedToolbarAttributesByUrl: Record<string, ToolbarResolvedAttributes>;
105
110
  selectedInlineLinkPosition?: number;
106
111
  showDatasourceModal: boolean;
@@ -42,6 +42,11 @@ export declare const getPluginStateWithUpdatedPos: (pluginState: CardPluginState
42
42
  sourceEvent?: UIAnalyticsEvent | null | undefined;
43
43
  url: string;
44
44
  }[];
45
+ resolvedInlineSmartLinks?: Array<{
46
+ pos: number;
47
+ source: CardReplacementInputMethod;
48
+ url: string;
49
+ }>;
45
50
  resolvedToolbarAttributesByUrl: Record<string, ToolbarResolvedAttributes>;
46
51
  selectedInlineLinkPosition?: number;
47
52
  showDatasourceModal: boolean;
@@ -101,6 +101,11 @@ export type CardPluginState = {
101
101
  provider: CardProvider | null;
102
102
  removeOverlay?: () => void;
103
103
  requests: Request[];
104
+ resolvedInlineSmartLinks?: Array<{
105
+ pos: number;
106
+ source: CardReplacementInputMethod;
107
+ url: string;
108
+ }>;
104
109
  resolvedToolbarAttributesByUrl: Record<string, ToolbarResolvedAttributes>;
105
110
  selectedInlineLinkPosition?: number;
106
111
  showDatasourceModal: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-card",
3
- "version": "14.0.7",
3
+ "version": "14.1.0",
4
4
  "description": "Card plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -45,7 +45,7 @@
45
45
  "@atlaskit/editor-plugin-width": "^9.0.0",
46
46
  "@atlaskit/editor-prosemirror": "^7.3.0",
47
47
  "@atlaskit/editor-shared-styles": "^3.10.0",
48
- "@atlaskit/editor-smart-link-draggable": "^0.4.0",
48
+ "@atlaskit/editor-smart-link-draggable": "^0.5.0",
49
49
  "@atlaskit/frontend-utilities": "^3.2.0",
50
50
  "@atlaskit/icon": "^34.0.0",
51
51
  "@atlaskit/link": "^3.4.0",
@@ -61,7 +61,7 @@
61
61
  "@atlaskit/primitives": "^19.0.0",
62
62
  "@atlaskit/prosemirror-history": "^0.2.0",
63
63
  "@atlaskit/smart-card": "^44.0.0",
64
- "@atlaskit/tmp-editor-statsig": "^60.2.0",
64
+ "@atlaskit/tmp-editor-statsig": "^61.0.0",
65
65
  "@atlaskit/tokens": "^13.0.0",
66
66
  "@babel/runtime": "^7.0.0",
67
67
  "@emotion/react": "^11.7.1",
@@ -113,6 +113,9 @@
113
113
  "cc_drag_and_drop_smart_link_from_content_to_tree": {
114
114
  "type": "boolean"
115
115
  },
116
+ "cc_dnd_smart_link_changeboard_po_template_gate": {
117
+ "type": "boolean"
118
+ },
116
119
  "confluence-issue-terminology-refresh": {
117
120
  "type": "boolean"
118
121
  },