@atlaskit/editor-synced-block-provider 2.7.0 → 2.7.2

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,20 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 2.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`7bb84f91500cf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7bb84f91500cf) -
8
+ [ux] EDITOR-2442 update warning modal on source sync block deletion
9
+
10
+ ## 2.7.1
11
+
12
+ ### Patch Changes
13
+
14
+ - [`23f6c637ea176`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/23f6c637ea176) -
15
+ [ux] EDITOR-2629 redirect to source edit page instead of view page on edit source url click in
16
+ sync block
17
+
3
18
  ## 2.7.0
4
19
 
5
20
  ### Minor Changes
@@ -18,6 +18,7 @@ var _react = require("react");
18
18
  var _types = require("../common/types");
19
19
  var _types2 = require("../providers/types");
20
20
  var _ari = require("../utils/ari");
21
+ var _sourceInfo = require("../utils/sourceInfo");
21
22
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
22
23
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
23
24
  var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
@@ -157,8 +158,8 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
157
158
  return this.sourceId;
158
159
  }
159
160
  }, {
160
- key: "retrieveSyncBlockSourceUrlAndTitle",
161
- value: function retrieveSyncBlockSourceUrlAndTitle(node) {
161
+ key: "retrieveSyncBlockSourceInfo",
162
+ value: function retrieveSyncBlockSourceInfo(node) {
162
163
  var resourceId = node.attrs.resourceId;
163
164
  var pageARI;
164
165
  var sourceLocalId;
@@ -174,7 +175,7 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
174
175
  // EDITOR-1921: log analytic here, safe to continue
175
176
  }
176
177
  }
177
- return pageARI ? fetchURLandTitlefromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
178
+ return pageARI ? (0, _sourceInfo.fetchSourceInfo)(pageARI, sourceLocalId) : Promise.resolve(undefined);
178
179
  }
179
180
  }]);
180
181
  }(_types2.SyncBlockDataProvider);
@@ -182,52 +183,4 @@ var useMemoizedSyncedBlockProvider = exports.useMemoizedSyncedBlockProvider = fu
182
183
  return (0, _react.useMemo)(function () {
183
184
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
184
185
  }, [fetchProvider, writeProvider, sourceId]);
185
- };
186
- var fetchURLandTitlefromARI = /*#__PURE__*/function () {
187
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(ari, sourceLocalId) {
188
- var response, _payload$data, _payload$data2, payload, url, title;
189
- return _regenerator.default.wrap(function _callee3$(_context3) {
190
- while (1) switch (_context3.prev = _context3.next) {
191
- case 0:
192
- _context3.next = 2;
193
- return fetch('/gateway/api/object-resolver/resolve/ari', {
194
- method: 'POST',
195
- headers: {
196
- 'Content-Type': 'application/json',
197
- Accept: 'application/json'
198
- },
199
- body: JSON.stringify({
200
- ari: ari
201
- })
202
- });
203
- case 2:
204
- response = _context3.sent;
205
- if (!response.ok) {
206
- _context3.next = 12;
207
- break;
208
- }
209
- _context3.next = 6;
210
- return response.json();
211
- case 6:
212
- payload = _context3.sent;
213
- url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
214
- title = payload === null || payload === void 0 || (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
215
- return _context3.abrupt("return", {
216
- url: typeof url === 'string' ? sourceLocalId ? url + "?block=".concat(sourceLocalId) : url : undefined,
217
- title: typeof title === 'string' ? title : undefined
218
- });
219
- case 12:
220
- //eslint-disable-next-line no-console
221
- console.error('Failed to fetch URL and title from ARI', response.statusText);
222
- case 13:
223
- return _context3.abrupt("return", undefined);
224
- case 14:
225
- case "end":
226
- return _context3.stop();
227
- }
228
- }, _callee3);
229
- }));
230
- return function fetchURLandTitlefromARI(_x4, _x5) {
231
- return _ref.apply(this, arguments);
232
- };
233
- }();
186
+ };
@@ -113,8 +113,8 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
113
113
  return refreshSubscriptions;
114
114
  }())
115
115
  }, {
116
- key: "fetchSyncBlockSourceURLAndTitle",
117
- value: function fetchSyncBlockSourceURLAndTitle(resourceId) {
116
+ key: "retrieveSyncBlockSourceInfo",
117
+ value: function retrieveSyncBlockSourceInfo(resourceId) {
118
118
  var _this = this;
119
119
  if (!resourceId || !this.dataProvider) {
120
120
  return;
@@ -124,7 +124,7 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
124
124
  // we could optimise this further by checking if the sync block is on the same page as the source
125
125
  if (!this.syncBlockURLRequests.get(resourceId)) {
126
126
  this.syncBlockURLRequests.set(resourceId, true);
127
- this.dataProvider.retrieveSyncBlockSourceUrlAndTitle((0, _utils.createSyncBlockNode)('', resourceId)).then(function (sourceInfo) {
127
+ this.dataProvider.retrieveSyncBlockSourceInfo((0, _utils.createSyncBlockNode)('', resourceId)).then(function (sourceInfo) {
128
128
  var existingSyncBlock = _this.getFromCache(resourceId);
129
129
  if (existingSyncBlock && existingSyncBlock.data) {
130
130
  existingSyncBlock.data = _objectSpread(_objectSpread({}, existingSyncBlock.data), {}, {
@@ -179,7 +179,7 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
179
179
 
180
180
  // fetch source URL and title if not already present
181
181
  if ((!((_resolvedSyncBlockIns = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns !== void 0 && _resolvedSyncBlockIns.sourceURL) || !((_resolvedSyncBlockIns2 = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns2 !== void 0 && _resolvedSyncBlockIns2.sourceTitle)) && resolvedSyncBlockInstance.resourceId) {
182
- _this2.fetchSyncBlockSourceURLAndTitle(resolvedSyncBlockInstance.resourceId);
182
+ _this2.retrieveSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
183
183
  }
184
184
  });
185
185
  return _context3.abrupt("return", resolvedData);
@@ -214,7 +214,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
214
214
  }
215
215
  this.confirmationTransaction = tr;
216
216
  _context2.next = 4;
217
- return this.confirmationCallback();
217
+ return this.confirmationCallback(syncBlockIds.length);
218
218
  case 4:
219
219
  confirmed = _context2.sent;
220
220
  if (!confirmed) {
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.fetchSourceInfo = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
+ var _ari = require("./ari");
12
+ var _utils = require("./utils");
13
+ 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; }
14
+ 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; } /* eslint-disable require-unicode-regexp */
15
+ var COMMON_HEADERS = {
16
+ 'Content-Type': 'application/json',
17
+ Accept: 'application/json'
18
+ };
19
+ var AGG_HEADERS = {
20
+ 'X-ExperimentalApi': 'confluence-agg-beta'
21
+ };
22
+ var GRAPHQL_ENDPOINT = '/gateway/api/graphql';
23
+ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
24
+ /**
25
+ * Query to get the page subtype by id (i.e. live or classic)
26
+ * @param documentARI
27
+ * @returns subType live if livePage, subType null if classic page
28
+ */
29
+ var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n\tcontent (id: $id) {\n\t\tnodes {\n\t\t\tid\n\t\t\tlinks {\n\t\t\t\tbase\n\t\t\t}\n\t\t\tspace {\n\t\t\t\tkey\n\t\t\t}\n\t\t\tsubType\n\t\t\ttitle\n\t\t}\n\t}\n}");
30
+ var getSourceInfo = /*#__PURE__*/function () {
31
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(ari) {
32
+ var bodyData, response;
33
+ return _regenerator.default.wrap(function _callee$(_context) {
34
+ while (1) switch (_context.prev = _context.next) {
35
+ case 0:
36
+ bodyData = {
37
+ query: GET_SOURCE_INFO_QUERY,
38
+ operationName: GET_SOURCE_INFO_OPERATION_NAME,
39
+ variables: {
40
+ id: ari
41
+ }
42
+ };
43
+ _context.next = 3;
44
+ return fetch(GRAPHQL_ENDPOINT, {
45
+ method: 'POST',
46
+ headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
47
+ body: JSON.stringify(bodyData)
48
+ });
49
+ case 3:
50
+ response = _context.sent;
51
+ if (response.ok) {
52
+ _context.next = 6;
53
+ break;
54
+ }
55
+ throw new Error("Failed to get url: ".concat(response.statusText));
56
+ case 6:
57
+ _context.next = 8;
58
+ return response.json();
59
+ case 8:
60
+ return _context.abrupt("return", _context.sent);
61
+ case 9:
62
+ case "end":
63
+ return _context.stop();
64
+ }
65
+ }, _callee);
66
+ }));
67
+ return function getSourceInfo(_x) {
68
+ return _ref.apply(this, arguments);
69
+ };
70
+ }();
71
+ var fetchSourceInfo = exports.fetchSourceInfo = /*#__PURE__*/function () {
72
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(ari, localId) {
73
+ var _response$data, _contentData$space, _getPageIdAndTypeFrom, pageType, response, contentData, title, url, _ref3, base;
74
+ return _regenerator.default.wrap(function _callee2$(_context2) {
75
+ while (1) switch (_context2.prev = _context2.next) {
76
+ case 0:
77
+ _context2.prev = 0;
78
+ _getPageIdAndTypeFrom = (0, _ari.getPageIdAndTypeFromAri)(ari), pageType = _getPageIdAndTypeFrom.type;
79
+ _context2.next = 4;
80
+ return getSourceInfo(ari);
81
+ case 4:
82
+ response = _context2.sent;
83
+ contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.content) === null || _response$data === void 0 || (_response$data = _response$data.nodes) === null || _response$data === void 0 ? void 0 : _response$data[0];
84
+ if (contentData) {
85
+ _context2.next = 8;
86
+ break;
87
+ }
88
+ throw new Error("Failed to get content data");
89
+ case 8:
90
+ title = contentData.title;
91
+ _ref3 = contentData.links || {}, base = _ref3.base;
92
+ if (base && (_contentData$space = contentData.space) !== null && _contentData$space !== void 0 && _contentData$space.key && contentData.id) {
93
+ if ((0, _utils.isBlogPageType)(pageType)) {
94
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/blog/edit-v2/").concat(contentData.id);
95
+ } else if (contentData.subType === 'live') {
96
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/pages/").concat(contentData.id);
97
+ } else {
98
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/pages/edit-v2/").concat(contentData.id);
99
+ }
100
+ }
101
+ url = url && localId ? "".concat(url, "#block-").concat(localId) : url;
102
+ return _context2.abrupt("return", Promise.resolve({
103
+ title: title,
104
+ url: url
105
+ }));
106
+ case 15:
107
+ _context2.prev = 15;
108
+ _context2.t0 = _context2["catch"](0);
109
+ return _context2.abrupt("return", Promise.resolve(undefined));
110
+ case 18:
111
+ case "end":
112
+ return _context2.stop();
113
+ }
114
+ }, _callee2, null, [[0, 15]]);
115
+ }));
116
+ return function fetchSourceInfo(_x2, _x3) {
117
+ return _ref2.apply(this, arguments);
118
+ };
119
+ }();
@@ -3,6 +3,7 @@ import { useMemo } from 'react';
3
3
  import { SyncBlockError } from '../common/types';
4
4
  import { SyncBlockDataProvider } from '../providers/types';
5
5
  import { getLocalIdFromAri, getPageARIFromResourceId } from '../utils/ari';
6
+ import { fetchSourceInfo } from '../utils/sourceInfo';
6
7
  export class SyncBlockProvider extends SyncBlockDataProvider {
7
8
  constructor(fetchProvider, writeProvider, sourceId) {
8
9
  super();
@@ -78,7 +79,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
78
79
  getSourceId() {
79
80
  return this.sourceId;
80
81
  }
81
- retrieveSyncBlockSourceUrlAndTitle(node) {
82
+ retrieveSyncBlockSourceInfo(node) {
82
83
  const {
83
84
  resourceId
84
85
  } = node.attrs;
@@ -96,37 +97,11 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
96
97
  // EDITOR-1921: log analytic here, safe to continue
97
98
  }
98
99
  }
99
- return pageARI ? fetchURLandTitlefromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
100
+ return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
100
101
  }
101
102
  }
102
103
  export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId) => {
103
104
  return useMemo(() => {
104
105
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
105
106
  }, [fetchProvider, writeProvider, sourceId]);
106
- };
107
- const fetchURLandTitlefromARI = async (ari, sourceLocalId) => {
108
- const response = await fetch('/gateway/api/object-resolver/resolve/ari', {
109
- method: 'POST',
110
- headers: {
111
- 'Content-Type': 'application/json',
112
- Accept: 'application/json'
113
- },
114
- body: JSON.stringify({
115
- ari
116
- })
117
- });
118
- if (response.ok) {
119
- var _payload$data, _payload$data2;
120
- const payload = await response.json();
121
- const url = payload === null || payload === void 0 ? void 0 : (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
122
- const title = payload === null || payload === void 0 ? void 0 : (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
123
- return {
124
- url: typeof url === 'string' ? sourceLocalId ? url + `?block=${sourceLocalId}` : url : undefined,
125
- title: typeof title === 'string' ? title : undefined
126
- };
127
- } else {
128
- //eslint-disable-next-line no-console
129
- console.error('Failed to fetch URL and title from ARI', response.statusText);
130
- }
131
- return undefined;
132
107
  };
@@ -36,7 +36,7 @@ export class ReferenceSyncBlockStoreManager {
36
36
  this.isRefreshingSubscriptions = false;
37
37
  }
38
38
  }
39
- fetchSyncBlockSourceURLAndTitle(resourceId) {
39
+ retrieveSyncBlockSourceInfo(resourceId) {
40
40
  if (!resourceId || !this.dataProvider) {
41
41
  return;
42
42
  }
@@ -45,7 +45,7 @@ export class ReferenceSyncBlockStoreManager {
45
45
  // we could optimise this further by checking if the sync block is on the same page as the source
46
46
  if (!this.syncBlockURLRequests.get(resourceId)) {
47
47
  this.syncBlockURLRequests.set(resourceId, true);
48
- this.dataProvider.retrieveSyncBlockSourceUrlAndTitle(createSyncBlockNode('', resourceId)).then(sourceInfo => {
48
+ this.dataProvider.retrieveSyncBlockSourceInfo(createSyncBlockNode('', resourceId)).then(sourceInfo => {
49
49
  const existingSyncBlock = this.getFromCache(resourceId);
50
50
  if (existingSyncBlock && existingSyncBlock.data) {
51
51
  existingSyncBlock.data = {
@@ -84,7 +84,7 @@ export class ReferenceSyncBlockStoreManager {
84
84
 
85
85
  // fetch source URL and title if not already present
86
86
  if ((!((_resolvedSyncBlockIns = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns !== void 0 && _resolvedSyncBlockIns.sourceURL) || !((_resolvedSyncBlockIns2 = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns2 !== void 0 && _resolvedSyncBlockIns2.sourceTitle)) && resolvedSyncBlockInstance.resourceId) {
87
- this.fetchSyncBlockSourceURLAndTitle(resolvedSyncBlockInstance.resourceId);
87
+ this.retrieveSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
88
88
  }
89
89
  });
90
90
  return resolvedData;
@@ -143,7 +143,7 @@ export class SourceSyncBlockStoreManager {
143
143
  async deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
144
144
  if (this.confirmationCallback) {
145
145
  this.confirmationTransaction = tr;
146
- const confirmed = await this.confirmationCallback();
146
+ const confirmed = await this.confirmationCallback(syncBlockIds.length);
147
147
  if (confirmed) {
148
148
  var _this$editorView;
149
149
  (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.dispatch(this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true));
@@ -0,0 +1,89 @@
1
+ /* eslint-disable require-unicode-regexp */
2
+
3
+ import { getPageIdAndTypeFromAri } from "./ari";
4
+ import { isBlogPageType } from "./utils";
5
+ const COMMON_HEADERS = {
6
+ 'Content-Type': 'application/json',
7
+ Accept: 'application/json'
8
+ };
9
+ const AGG_HEADERS = {
10
+ 'X-ExperimentalApi': 'confluence-agg-beta'
11
+ };
12
+ const GRAPHQL_ENDPOINT = '/gateway/api/graphql';
13
+ const GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
14
+ /**
15
+ * Query to get the page subtype by id (i.e. live or classic)
16
+ * @param documentARI
17
+ * @returns subType live if livePage, subType null if classic page
18
+ */
19
+ const GET_SOURCE_INFO_QUERY = `query ${GET_SOURCE_INFO_OPERATION_NAME} ($id: ID!) {
20
+ content (id: $id) {
21
+ nodes {
22
+ id
23
+ links {
24
+ base
25
+ }
26
+ space {
27
+ key
28
+ }
29
+ subType
30
+ title
31
+ }
32
+ }
33
+ }`;
34
+ const getSourceInfo = async ari => {
35
+ const bodyData = {
36
+ query: GET_SOURCE_INFO_QUERY,
37
+ operationName: GET_SOURCE_INFO_OPERATION_NAME,
38
+ variables: {
39
+ id: ari
40
+ }
41
+ };
42
+ const response = await fetch(GRAPHQL_ENDPOINT, {
43
+ method: 'POST',
44
+ headers: {
45
+ ...COMMON_HEADERS,
46
+ ...AGG_HEADERS
47
+ },
48
+ body: JSON.stringify(bodyData)
49
+ });
50
+ if (!response.ok) {
51
+ throw new Error(`Failed to get url: ${response.statusText}`);
52
+ }
53
+ return await response.json();
54
+ };
55
+ export const fetchSourceInfo = async (ari, localId) => {
56
+ try {
57
+ var _response$data, _response$data$conten, _response$data$conten2, _contentData$space;
58
+ const {
59
+ type: pageType
60
+ } = getPageIdAndTypeFromAri(ari);
61
+ const response = await getSourceInfo(ari);
62
+ const contentData = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$conten = _response$data.content) === null || _response$data$conten === void 0 ? void 0 : (_response$data$conten2 = _response$data$conten.nodes) === null || _response$data$conten2 === void 0 ? void 0 : _response$data$conten2[0];
63
+ if (!contentData) {
64
+ throw new Error(`Failed to get content data`);
65
+ }
66
+ const title = contentData.title;
67
+ let url;
68
+ const {
69
+ base
70
+ } = contentData.links || {};
71
+ if (base && (_contentData$space = contentData.space) !== null && _contentData$space !== void 0 && _contentData$space.key && contentData.id) {
72
+ if (isBlogPageType(pageType)) {
73
+ url = `${base}/spaces/${contentData.space.key}/blog/edit-v2/${contentData.id}`;
74
+ } else if (contentData.subType === 'live') {
75
+ url = `${base}/spaces/${contentData.space.key}/pages/${contentData.id}`;
76
+ } else {
77
+ url = `${base}/spaces/${contentData.space.key}/pages/edit-v2/${contentData.id}`;
78
+ }
79
+ }
80
+ url = url && localId ? `${url}#block-${localId}` : url;
81
+ return Promise.resolve({
82
+ title,
83
+ url
84
+ });
85
+ } catch (error) {
86
+ // TODO: EDITOR-1921 - add error analytics
87
+ return Promise.resolve(undefined);
88
+ }
89
+ };
@@ -13,6 +13,7 @@ import { useMemo } from 'react';
13
13
  import { SyncBlockError } from '../common/types';
14
14
  import { SyncBlockDataProvider } from '../providers/types';
15
15
  import { getLocalIdFromAri, getPageARIFromResourceId } from '../utils/ari';
16
+ import { fetchSourceInfo } from '../utils/sourceInfo';
16
17
  export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
17
18
  function SyncBlockProvider(fetchProvider, writeProvider, sourceId) {
18
19
  var _this;
@@ -150,8 +151,8 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
150
151
  return this.sourceId;
151
152
  }
152
153
  }, {
153
- key: "retrieveSyncBlockSourceUrlAndTitle",
154
- value: function retrieveSyncBlockSourceUrlAndTitle(node) {
154
+ key: "retrieveSyncBlockSourceInfo",
155
+ value: function retrieveSyncBlockSourceInfo(node) {
155
156
  var resourceId = node.attrs.resourceId;
156
157
  var pageARI;
157
158
  var sourceLocalId;
@@ -167,7 +168,7 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
167
168
  // EDITOR-1921: log analytic here, safe to continue
168
169
  }
169
170
  }
170
- return pageARI ? fetchURLandTitlefromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
171
+ return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
171
172
  }
172
173
  }]);
173
174
  }(SyncBlockDataProvider);
@@ -175,52 +176,4 @@ export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvi
175
176
  return useMemo(function () {
176
177
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
177
178
  }, [fetchProvider, writeProvider, sourceId]);
178
- };
179
- var fetchURLandTitlefromARI = /*#__PURE__*/function () {
180
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(ari, sourceLocalId) {
181
- var response, _payload$data, _payload$data2, payload, url, title;
182
- return _regeneratorRuntime.wrap(function _callee3$(_context3) {
183
- while (1) switch (_context3.prev = _context3.next) {
184
- case 0:
185
- _context3.next = 2;
186
- return fetch('/gateway/api/object-resolver/resolve/ari', {
187
- method: 'POST',
188
- headers: {
189
- 'Content-Type': 'application/json',
190
- Accept: 'application/json'
191
- },
192
- body: JSON.stringify({
193
- ari: ari
194
- })
195
- });
196
- case 2:
197
- response = _context3.sent;
198
- if (!response.ok) {
199
- _context3.next = 12;
200
- break;
201
- }
202
- _context3.next = 6;
203
- return response.json();
204
- case 6:
205
- payload = _context3.sent;
206
- url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
207
- title = payload === null || payload === void 0 || (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
208
- return _context3.abrupt("return", {
209
- url: typeof url === 'string' ? sourceLocalId ? url + "?block=".concat(sourceLocalId) : url : undefined,
210
- title: typeof title === 'string' ? title : undefined
211
- });
212
- case 12:
213
- //eslint-disable-next-line no-console
214
- console.error('Failed to fetch URL and title from ARI', response.statusText);
215
- case 13:
216
- return _context3.abrupt("return", undefined);
217
- case 14:
218
- case "end":
219
- return _context3.stop();
220
- }
221
- }, _callee3);
222
- }));
223
- return function fetchURLandTitlefromARI(_x4, _x5) {
224
- return _ref.apply(this, arguments);
225
- };
226
- }();
179
+ };
@@ -106,8 +106,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
106
106
  return refreshSubscriptions;
107
107
  }())
108
108
  }, {
109
- key: "fetchSyncBlockSourceURLAndTitle",
110
- value: function fetchSyncBlockSourceURLAndTitle(resourceId) {
109
+ key: "retrieveSyncBlockSourceInfo",
110
+ value: function retrieveSyncBlockSourceInfo(resourceId) {
111
111
  var _this = this;
112
112
  if (!resourceId || !this.dataProvider) {
113
113
  return;
@@ -117,7 +117,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
117
117
  // we could optimise this further by checking if the sync block is on the same page as the source
118
118
  if (!this.syncBlockURLRequests.get(resourceId)) {
119
119
  this.syncBlockURLRequests.set(resourceId, true);
120
- this.dataProvider.retrieveSyncBlockSourceUrlAndTitle(createSyncBlockNode('', resourceId)).then(function (sourceInfo) {
120
+ this.dataProvider.retrieveSyncBlockSourceInfo(createSyncBlockNode('', resourceId)).then(function (sourceInfo) {
121
121
  var existingSyncBlock = _this.getFromCache(resourceId);
122
122
  if (existingSyncBlock && existingSyncBlock.data) {
123
123
  existingSyncBlock.data = _objectSpread(_objectSpread({}, existingSyncBlock.data), {}, {
@@ -172,7 +172,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
172
172
 
173
173
  // fetch source URL and title if not already present
174
174
  if ((!((_resolvedSyncBlockIns = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns !== void 0 && _resolvedSyncBlockIns.sourceURL) || !((_resolvedSyncBlockIns2 = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns2 !== void 0 && _resolvedSyncBlockIns2.sourceTitle)) && resolvedSyncBlockInstance.resourceId) {
175
- _this2.fetchSyncBlockSourceURLAndTitle(resolvedSyncBlockInstance.resourceId);
175
+ _this2.retrieveSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
176
176
  }
177
177
  });
178
178
  return _context3.abrupt("return", resolvedData);
@@ -207,7 +207,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
207
207
  }
208
208
  this.confirmationTransaction = tr;
209
209
  _context2.next = 4;
210
- return this.confirmationCallback();
210
+ return this.confirmationCallback(syncBlockIds.length);
211
211
  case 4:
212
212
  confirmed = _context2.sent;
213
213
  if (!confirmed) {
@@ -0,0 +1,114 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
+ 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; }
5
+ 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) { _defineProperty(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; }
6
+ /* eslint-disable require-unicode-regexp */
7
+
8
+ import { getPageIdAndTypeFromAri } from "./ari";
9
+ import { isBlogPageType } from "./utils";
10
+ var COMMON_HEADERS = {
11
+ 'Content-Type': 'application/json',
12
+ Accept: 'application/json'
13
+ };
14
+ var AGG_HEADERS = {
15
+ 'X-ExperimentalApi': 'confluence-agg-beta'
16
+ };
17
+ var GRAPHQL_ENDPOINT = '/gateway/api/graphql';
18
+ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
19
+ /**
20
+ * Query to get the page subtype by id (i.e. live or classic)
21
+ * @param documentARI
22
+ * @returns subType live if livePage, subType null if classic page
23
+ */
24
+ var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n\tcontent (id: $id) {\n\t\tnodes {\n\t\t\tid\n\t\t\tlinks {\n\t\t\t\tbase\n\t\t\t}\n\t\t\tspace {\n\t\t\t\tkey\n\t\t\t}\n\t\t\tsubType\n\t\t\ttitle\n\t\t}\n\t}\n}");
25
+ var getSourceInfo = /*#__PURE__*/function () {
26
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
27
+ var bodyData, response;
28
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
29
+ while (1) switch (_context.prev = _context.next) {
30
+ case 0:
31
+ bodyData = {
32
+ query: GET_SOURCE_INFO_QUERY,
33
+ operationName: GET_SOURCE_INFO_OPERATION_NAME,
34
+ variables: {
35
+ id: ari
36
+ }
37
+ };
38
+ _context.next = 3;
39
+ return fetch(GRAPHQL_ENDPOINT, {
40
+ method: 'POST',
41
+ headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
42
+ body: JSON.stringify(bodyData)
43
+ });
44
+ case 3:
45
+ response = _context.sent;
46
+ if (response.ok) {
47
+ _context.next = 6;
48
+ break;
49
+ }
50
+ throw new Error("Failed to get url: ".concat(response.statusText));
51
+ case 6:
52
+ _context.next = 8;
53
+ return response.json();
54
+ case 8:
55
+ return _context.abrupt("return", _context.sent);
56
+ case 9:
57
+ case "end":
58
+ return _context.stop();
59
+ }
60
+ }, _callee);
61
+ }));
62
+ return function getSourceInfo(_x) {
63
+ return _ref.apply(this, arguments);
64
+ };
65
+ }();
66
+ export var fetchSourceInfo = /*#__PURE__*/function () {
67
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(ari, localId) {
68
+ var _response$data, _contentData$space, _getPageIdAndTypeFrom, pageType, response, contentData, title, url, _ref3, base;
69
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
70
+ while (1) switch (_context2.prev = _context2.next) {
71
+ case 0:
72
+ _context2.prev = 0;
73
+ _getPageIdAndTypeFrom = getPageIdAndTypeFromAri(ari), pageType = _getPageIdAndTypeFrom.type;
74
+ _context2.next = 4;
75
+ return getSourceInfo(ari);
76
+ case 4:
77
+ response = _context2.sent;
78
+ contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.content) === null || _response$data === void 0 || (_response$data = _response$data.nodes) === null || _response$data === void 0 ? void 0 : _response$data[0];
79
+ if (contentData) {
80
+ _context2.next = 8;
81
+ break;
82
+ }
83
+ throw new Error("Failed to get content data");
84
+ case 8:
85
+ title = contentData.title;
86
+ _ref3 = contentData.links || {}, base = _ref3.base;
87
+ if (base && (_contentData$space = contentData.space) !== null && _contentData$space !== void 0 && _contentData$space.key && contentData.id) {
88
+ if (isBlogPageType(pageType)) {
89
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/blog/edit-v2/").concat(contentData.id);
90
+ } else if (contentData.subType === 'live') {
91
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/pages/").concat(contentData.id);
92
+ } else {
93
+ url = "".concat(base, "/spaces/").concat(contentData.space.key, "/pages/edit-v2/").concat(contentData.id);
94
+ }
95
+ }
96
+ url = url && localId ? "".concat(url, "#block-").concat(localId) : url;
97
+ return _context2.abrupt("return", Promise.resolve({
98
+ title: title,
99
+ url: url
100
+ }));
101
+ case 15:
102
+ _context2.prev = 15;
103
+ _context2.t0 = _context2["catch"](0);
104
+ return _context2.abrupt("return", Promise.resolve(undefined));
105
+ case 18:
106
+ case "end":
107
+ return _context2.stop();
108
+ }
109
+ }, _callee2, null, [[0, 15]]);
110
+ }));
111
+ return function fetchSourceInfo(_x2, _x3) {
112
+ return _ref2.apply(this, arguments);
113
+ };
114
+ }();
@@ -21,6 +21,6 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
21
21
  writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<WriteSyncBlockResult>>;
22
22
  deleteNodesData(resourceIds: string[]): Promise<Array<DeleteSyncBlockResult>>;
23
23
  getSourceId(): string;
24
- retrieveSyncBlockSourceUrlAndTitle(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
24
+ retrieveSyncBlockSourceInfo(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
25
25
  }
26
26
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
@@ -34,7 +34,7 @@ export declare abstract class SyncBlockDataProvider extends NodeDataProvider<Syn
34
34
  abstract writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<WriteSyncBlockResult>>;
35
35
  abstract deleteNodesData(resourceIds: string[]): Promise<Array<DeleteSyncBlockResult>>;
36
36
  abstract getSourceId(): ResourceId;
37
- abstract retrieveSyncBlockSourceUrlAndTitle(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
37
+ abstract retrieveSyncBlockSourceInfo(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
38
38
  }
39
39
  export type SubscriptionCallback = (data: SyncBlockInstance) => void;
40
40
  export type TitleSubscriptionCallback = (title: string) => void;
@@ -14,7 +14,7 @@ export declare class ReferenceSyncBlockStoreManager {
14
14
  * @returns {Promise<void>}
15
15
  */
16
16
  refreshSubscriptions(): Promise<void>;
17
- private fetchSyncBlockSourceURLAndTitle;
17
+ private retrieveSyncBlockSourceInfo;
18
18
  fetchSyncBlocksData(syncBlockNodes: SyncBlockNode[]): Promise<SyncBlockInstance[]>;
19
19
  private updateCache;
20
20
  private updateSourceTitleSubscriptions;
@@ -3,7 +3,7 @@ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/stat
3
3
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
4
  import type { ResourceId, SyncBlockAttrs } from '../common/types';
5
5
  import type { SyncBlockDataProvider } from '../providers/types';
6
- export type ConfirmationCallback = () => Promise<boolean>;
6
+ export type ConfirmationCallback = (syncBlockCount: number) => Promise<boolean>;
7
7
  export type CreationCallback = () => void;
8
8
  export declare class SourceSyncBlockStoreManager {
9
9
  private dataProvider?;
@@ -0,0 +1,2 @@
1
+ import type { SyncBlockSourceInfo } from "../providers/types";
2
+ export declare const fetchSourceInfo: (ari: string, localId?: string) => Promise<SyncBlockSourceInfo | undefined>;
@@ -21,6 +21,6 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
21
21
  writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<WriteSyncBlockResult>>;
22
22
  deleteNodesData(resourceIds: string[]): Promise<Array<DeleteSyncBlockResult>>;
23
23
  getSourceId(): string;
24
- retrieveSyncBlockSourceUrlAndTitle(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
24
+ retrieveSyncBlockSourceInfo(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
25
25
  }
26
26
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
@@ -34,7 +34,7 @@ export declare abstract class SyncBlockDataProvider extends NodeDataProvider<Syn
34
34
  abstract writeNodesData(nodes: SyncBlockNode[], data: SyncBlockData[]): Promise<Array<WriteSyncBlockResult>>;
35
35
  abstract deleteNodesData(resourceIds: string[]): Promise<Array<DeleteSyncBlockResult>>;
36
36
  abstract getSourceId(): ResourceId;
37
- abstract retrieveSyncBlockSourceUrlAndTitle(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
37
+ abstract retrieveSyncBlockSourceInfo(node: SyncBlockNode): Promise<SyncBlockSourceInfo | undefined>;
38
38
  }
39
39
  export type SubscriptionCallback = (data: SyncBlockInstance) => void;
40
40
  export type TitleSubscriptionCallback = (title: string) => void;
@@ -14,7 +14,7 @@ export declare class ReferenceSyncBlockStoreManager {
14
14
  * @returns {Promise<void>}
15
15
  */
16
16
  refreshSubscriptions(): Promise<void>;
17
- private fetchSyncBlockSourceURLAndTitle;
17
+ private retrieveSyncBlockSourceInfo;
18
18
  fetchSyncBlocksData(syncBlockNodes: SyncBlockNode[]): Promise<SyncBlockInstance[]>;
19
19
  private updateCache;
20
20
  private updateSourceTitleSubscriptions;
@@ -3,7 +3,7 @@ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/stat
3
3
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
4
  import type { ResourceId, SyncBlockAttrs } from '../common/types';
5
5
  import type { SyncBlockDataProvider } from '../providers/types';
6
- export type ConfirmationCallback = () => Promise<boolean>;
6
+ export type ConfirmationCallback = (syncBlockCount: number) => Promise<boolean>;
7
7
  export type CreationCallback = () => void;
8
8
  export declare class SourceSyncBlockStoreManager {
9
9
  private dataProvider?;
@@ -0,0 +1,2 @@
1
+ import type { SyncBlockSourceInfo } from "../providers/types";
2
+ export declare const fetchSourceInfo: (ari: string, localId?: string) => Promise<SyncBlockSourceInfo | undefined>;
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  }
83
83
  },
84
84
  "name": "@atlaskit/editor-synced-block-provider",
85
- "version": "2.7.0",
85
+ "version": "2.7.2",
86
86
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
87
87
  "author": "Atlassian Pty Ltd",
88
88
  "license": "Apache-2.0",