@atlaskit/editor-synced-block-provider 2.10.2 → 2.10.4
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 +17 -0
- package/dist/cjs/{providers → clients}/block-service/ari.js +2 -2
- package/dist/cjs/{utils → clients/confluence}/ari.js +5 -5
- package/dist/cjs/{utils → clients/confluence}/contentProperty.js +2 -6
- package/dist/cjs/{utils → clients/confluence}/sourceInfo.js +7 -7
- package/dist/cjs/clients/confluence/utils.js +9 -0
- package/dist/cjs/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/cjs/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/cjs/hooks/useHandleContentChanges.js +1 -1
- package/dist/cjs/index.js +27 -14
- package/dist/cjs/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/cjs/providers/confluence/confluenceContentAPI.js +28 -18
- package/dist/cjs/providers/syncBlockProvider.js +14 -9
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +35 -9
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +52 -10
- package/dist/cjs/store-manager/syncBlockStoreManager.js +14 -158
- package/dist/cjs/utils/utils.js +8 -4
- package/dist/es2019/{providers → clients}/block-service/ari.js +1 -1
- package/dist/es2019/{utils → clients/confluence}/ari.js +4 -4
- package/dist/es2019/{utils → clients/confluence}/contentProperty.js +2 -6
- package/dist/es2019/{utils → clients/confluence}/sourceInfo.js +5 -5
- package/dist/es2019/clients/confluence/utils.js +3 -0
- package/dist/es2019/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/es2019/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/es2019/hooks/useHandleContentChanges.js +1 -1
- package/dist/es2019/index.js +14 -4
- package/dist/es2019/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/es2019/providers/confluence/confluenceContentAPI.js +28 -18
- package/dist/es2019/providers/syncBlockProvider.js +14 -9
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +24 -0
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +39 -1
- package/dist/es2019/store-manager/syncBlockStoreManager.js +12 -119
- package/dist/es2019/utils/utils.js +3 -3
- package/dist/esm/{providers → clients}/block-service/ari.js +1 -1
- package/dist/esm/{utils → clients/confluence}/ari.js +4 -4
- package/dist/esm/{utils → clients/confluence}/contentProperty.js +2 -6
- package/dist/esm/{utils → clients/confluence}/sourceInfo.js +7 -7
- package/dist/esm/clients/confluence/utils.js +3 -0
- package/dist/esm/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/esm/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/esm/hooks/useHandleContentChanges.js +1 -1
- package/dist/esm/index.js +14 -4
- package/dist/esm/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/esm/providers/confluence/confluenceContentAPI.js +28 -18
- package/dist/esm/providers/syncBlockProvider.js +14 -9
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +36 -9
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +52 -10
- package/dist/esm/store-manager/syncBlockStoreManager.js +14 -159
- package/dist/esm/utils/utils.js +7 -3
- package/dist/types/{providers → clients}/block-service/ari.d.ts +1 -1
- package/dist/types/{utils → clients/block-service}/blockService.d.ts +1 -1
- package/dist/types/clients/confluence/ari.d.ts +9 -0
- package/dist/types/{utils → clients/confluence}/contentProperty.d.ts +1 -1
- package/dist/types/clients/confluence/sourceInfo.d.ts +2 -0
- package/dist/types/clients/confluence/utils.d.ts +2 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/providers/confluence/confluenceContentAPI.d.ts +1 -1
- package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +5 -0
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +17 -1
- package/dist/types/store-manager/syncBlockStoreManager.d.ts +4 -59
- package/dist/types/utils/utils.d.ts +1 -2
- package/dist/types-ts4.5/{providers → clients}/block-service/ari.d.ts +1 -1
- package/dist/types-ts4.5/{utils → clients/block-service}/blockService.d.ts +1 -1
- package/dist/types-ts4.5/clients/confluence/ari.d.ts +9 -0
- package/dist/types-ts4.5/{utils → clients/confluence}/contentProperty.d.ts +1 -1
- package/dist/types-ts4.5/clients/confluence/sourceInfo.d.ts +2 -0
- package/dist/types-ts4.5/clients/confluence/utils.d.ts +2 -0
- package/dist/types-ts4.5/index.d.ts +4 -3
- package/dist/types-ts4.5/providers/confluence/confluenceContentAPI.d.ts +1 -1
- package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +5 -0
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +17 -1
- package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +4 -59
- package/dist/types-ts4.5/utils/utils.d.ts +1 -2
- package/package.json +3 -3
- package/dist/types/utils/ari.d.ts +0 -9
- package/dist/types/utils/sourceInfo.d.ts +0 -2
- package/dist/types-ts4.5/utils/ari.d.ts +0 -9
- package/dist/types-ts4.5/utils/sourceInfo.d.ts +0 -2
- /package/dist/cjs/{utils → clients/block-service}/blockService.js +0 -0
- /package/dist/es2019/{utils → clients/block-service}/blockService.js +0 -0
- /package/dist/esm/{utils → clients/block-service}/blockService.js +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { getConfluencePageAri, getPageARIFromContentPropertyResourceId, getLocalIdFromConfluencePageAri, getPageIdAndTypeFromConfluencePageAri, resourceIdFromConfluencePageSourceIdAndLocalId } from '../../clients/confluence/ari';
|
|
4
|
+
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../clients/confluence/contentProperty';
|
|
5
|
+
import { isBlogPageType } from '../../clients/confluence/utils';
|
|
3
6
|
import { SyncBlockError } from '../../common/types';
|
|
4
|
-
import { getConfluencePageAri, getPageARIFromResourceId, getLocalIdFromAri, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
|
|
5
|
-
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../utils/contentProperty';
|
|
6
7
|
import { stringifyError } from '../../utils/errorHandling';
|
|
7
|
-
import { isBlogPageType } from '../../utils/utils';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Configuration for Content API providers
|
|
@@ -51,8 +51,8 @@ class ConfluenceADFFetchProvider {
|
|
|
51
51
|
const {
|
|
52
52
|
id: pageId,
|
|
53
53
|
type: pageType
|
|
54
|
-
} =
|
|
55
|
-
const localId =
|
|
54
|
+
} = getPageIdAndTypeFromConfluencePageAri(resourceId);
|
|
55
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
56
56
|
try {
|
|
57
57
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
58
58
|
const options = {
|
|
@@ -86,8 +86,18 @@ class ConfluenceADFFetchProvider {
|
|
|
86
86
|
return {
|
|
87
87
|
data: {
|
|
88
88
|
content: syncedBlockData.content,
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
// If the block instance ID is not set, use the local ID from the fetch data request
|
|
90
|
+
// This is a fallback for the case where the block instance ID is not set in the synced block data (old data)
|
|
91
|
+
blockInstanceId: syncedBlockData.blockInstanceId || localId,
|
|
92
|
+
// If the resource ID is not set, use the resource ID from the fetch data request
|
|
93
|
+
// This is a fallback for the case where the resource ID is not set in the synced block data (old data)
|
|
94
|
+
resourceId: syncedBlockData.resourceId || resourceId,
|
|
95
|
+
// If the product is not set, use the default product 'confluence-page'
|
|
96
|
+
// This is a fallback for the case where the product is not set in the synced block data (old data)
|
|
97
|
+
product: syncedBlockData.product || 'confluence-page',
|
|
98
|
+
// If the source Ari is not set, use the resource ID as the source Ari
|
|
99
|
+
// This is a fallback for the case where the source Ari is not set in the synced block data (old data)
|
|
100
|
+
sourceAri: syncedBlockData.sourceAri || resourceId
|
|
91
101
|
},
|
|
92
102
|
resourceId
|
|
93
103
|
};
|
|
@@ -99,10 +109,10 @@ class ConfluenceADFFetchProvider {
|
|
|
99
109
|
}
|
|
100
110
|
}
|
|
101
111
|
retrieveSourceInfoFetchData(resourceId) {
|
|
102
|
-
const pageARI =
|
|
112
|
+
const pageARI = getPageARIFromContentPropertyResourceId(resourceId);
|
|
103
113
|
let sourceLocalId;
|
|
104
114
|
try {
|
|
105
|
-
sourceLocalId =
|
|
115
|
+
sourceLocalId = getLocalIdFromConfluencePageAri(resourceId);
|
|
106
116
|
} catch (error) {
|
|
107
117
|
// EDITOR-1921: log analytic here, safe to continue
|
|
108
118
|
}
|
|
@@ -146,13 +156,13 @@ class ConfluenceADFWriteProvider {
|
|
|
146
156
|
});
|
|
147
157
|
this.config = config;
|
|
148
158
|
}
|
|
149
|
-
async writeData(
|
|
159
|
+
async writeData(syncBlockData) {
|
|
150
160
|
let match;
|
|
151
161
|
const {
|
|
152
162
|
resourceId
|
|
153
|
-
} =
|
|
163
|
+
} = syncBlockData;
|
|
154
164
|
try {
|
|
155
|
-
match =
|
|
165
|
+
match = getPageIdAndTypeFromConfluencePageAri(resourceId);
|
|
156
166
|
} catch (error) {
|
|
157
167
|
return {
|
|
158
168
|
error: stringifyError(error)
|
|
@@ -164,11 +174,11 @@ class ConfluenceADFWriteProvider {
|
|
|
164
174
|
} = match;
|
|
165
175
|
try {
|
|
166
176
|
// Update existing content property
|
|
167
|
-
const localId =
|
|
177
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
168
178
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
169
179
|
const sourceAri = getConfluencePageAri(pageId, this.config.cloudId, pageType);
|
|
170
180
|
const syncBlockDataWithSourceDocumentAri = {
|
|
171
|
-
...
|
|
181
|
+
...syncBlockData,
|
|
172
182
|
product: 'confluence-page',
|
|
173
183
|
sourceAri
|
|
174
184
|
};
|
|
@@ -186,7 +196,7 @@ class ConfluenceADFWriteProvider {
|
|
|
186
196
|
resourceId
|
|
187
197
|
};
|
|
188
198
|
} else if (!updateResult) {
|
|
189
|
-
return this.createNewContentProperty(pageId, key,
|
|
199
|
+
return this.createNewContentProperty(pageId, key, syncBlockDataWithSourceDocumentAri, pageType).then(() => {
|
|
190
200
|
return {
|
|
191
201
|
resourceId
|
|
192
202
|
};
|
|
@@ -209,7 +219,7 @@ class ConfluenceADFWriteProvider {
|
|
|
209
219
|
async deleteData(resourceId) {
|
|
210
220
|
let deletePayload, deleteResult, match;
|
|
211
221
|
try {
|
|
212
|
-
match =
|
|
222
|
+
match = getPageIdAndTypeFromConfluencePageAri(resourceId);
|
|
213
223
|
} catch (error) {
|
|
214
224
|
return {
|
|
215
225
|
resourceId,
|
|
@@ -222,7 +232,7 @@ class ConfluenceADFWriteProvider {
|
|
|
222
232
|
type: pageType
|
|
223
233
|
} = match;
|
|
224
234
|
try {
|
|
225
|
-
const localId =
|
|
235
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
226
236
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
227
237
|
const options = {
|
|
228
238
|
pageId,
|
|
@@ -247,7 +257,7 @@ class ConfluenceADFWriteProvider {
|
|
|
247
257
|
};
|
|
248
258
|
}
|
|
249
259
|
generateResourceId(sourceId, localId) {
|
|
250
|
-
return
|
|
260
|
+
return resourceIdFromConfluencePageSourceIdAndLocalId(sourceId, localId);
|
|
251
261
|
}
|
|
252
262
|
}
|
|
253
263
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
|
|
4
|
+
import { fetchConfluenceSourceInfo } from '../clients/confluence/sourceInfo';
|
|
3
5
|
import { SyncBlockError } from '../common/types';
|
|
4
6
|
import { SyncBlockDataProvider } from '../providers/types';
|
|
5
|
-
import { getPageIdAndTypeFromAri } from '../utils/ari';
|
|
6
|
-
import { fetchSourceInfo } from '../utils/sourceInfo';
|
|
7
7
|
export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
8
8
|
// the source document ARI; that the source sync block is on.
|
|
9
9
|
|
|
@@ -155,7 +155,10 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
155
155
|
return Promise.reject(error);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
-
|
|
158
|
+
|
|
159
|
+
// TODO: EDITOR-3312 - based on the source sync block product,
|
|
160
|
+
// execute fetchConfluenceSourceInfo or fetchJiraItemSourceInfo or similar...
|
|
161
|
+
return pageARI ? fetchConfluenceSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
|
|
159
162
|
}
|
|
160
163
|
generateResourceId(sourceId, localId) {
|
|
161
164
|
return this.writeProvider.generateResourceId(sourceId, localId);
|
|
@@ -184,18 +187,20 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
184
187
|
}
|
|
185
188
|
const {
|
|
186
189
|
sourceAri,
|
|
187
|
-
|
|
188
|
-
product: contentProduct
|
|
190
|
+
product
|
|
189
191
|
} = syncBlockInstance.data;
|
|
192
|
+
if (!sourceAri || !product) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
190
195
|
|
|
191
|
-
//
|
|
192
|
-
|
|
196
|
+
// TODO: EDITOR-3312 - based on the source sync block product,
|
|
197
|
+
// execute getPageIdAndTypeFromConfluencePageAri or getJiraItemIdAndTypeFromJiraItemAri or similar...
|
|
193
198
|
const {
|
|
194
199
|
id: contentId
|
|
195
|
-
} =
|
|
200
|
+
} = getPageIdAndTypeFromConfluencePageAri(sourceAri);
|
|
196
201
|
return {
|
|
197
202
|
contentId,
|
|
198
|
-
contentProduct:
|
|
203
|
+
contentProduct: product
|
|
199
204
|
};
|
|
200
205
|
}
|
|
201
206
|
}
|
|
@@ -3,6 +3,12 @@ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
|
3
3
|
import { SyncBlockError } from '../common/types';
|
|
4
4
|
import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
|
|
5
5
|
import { createSyncBlockNode } from '../utils/utils';
|
|
6
|
+
|
|
7
|
+
// A store manager responsible for the lifecycle and state management of reference sync blocks in an editor instance.
|
|
8
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
9
|
+
// Supports fetch, cache, and subscription for sync block data.
|
|
10
|
+
// Handles fetching source URL and title for sync blocks.
|
|
11
|
+
// Can be used in both editor and renderer contexts.
|
|
6
12
|
export class ReferenceSyncBlockStoreManager {
|
|
7
13
|
constructor(dataProvider) {
|
|
8
14
|
_defineProperty(this, "isRefreshingSubscriptions", false);
|
|
@@ -44,6 +50,8 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
44
50
|
return;
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
// TODO: EDITOR-3312 - retrieve the source info based on the source sync block product
|
|
54
|
+
|
|
47
55
|
// if the sync block is a reference block, we need to fetch the URL to the source
|
|
48
56
|
// we could optimise this further by checking if the sync block is on the same page as the source
|
|
49
57
|
if (!this.syncBlockURLRequests.get(resourceId)) {
|
|
@@ -66,7 +74,16 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
66
74
|
});
|
|
67
75
|
}
|
|
68
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Fetch sync block data for a given array of sync block nodes.
|
|
80
|
+
* @param syncBlockNodes - The array of sync block nodes to fetch data for
|
|
81
|
+
* @returns The fetched sync block data results
|
|
82
|
+
*/
|
|
69
83
|
async fetchSyncBlocksData(syncBlockNodes) {
|
|
84
|
+
if (syncBlockNodes.length === 0) {
|
|
85
|
+
return Promise.resolve([]);
|
|
86
|
+
}
|
|
70
87
|
if (!this.dataProvider) {
|
|
71
88
|
throw new Error('Data provider not set');
|
|
72
89
|
}
|
|
@@ -293,9 +310,16 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
293
310
|
}
|
|
294
311
|
}
|
|
295
312
|
destroy() {
|
|
313
|
+
this.dataProvider = undefined;
|
|
296
314
|
this.syncBlockCache.clear();
|
|
297
315
|
this.subscriptions.clear();
|
|
316
|
+
this.titleSubscriptions.clear();
|
|
298
317
|
this.syncBlockURLRequests.clear();
|
|
299
318
|
this.providerFactories.clear();
|
|
319
|
+
this.isRefreshingSubscriptions = false;
|
|
320
|
+
this.providerFactories.forEach(providerFactory => {
|
|
321
|
+
providerFactory.destroy();
|
|
322
|
+
});
|
|
323
|
+
this.providerFactories.clear();
|
|
300
324
|
}
|
|
301
325
|
}
|
|
@@ -3,6 +3,11 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
3
3
|
import uuid from 'uuid';
|
|
4
4
|
import { rebaseTransaction } from '../common/rebase-transaction';
|
|
5
5
|
import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode } from '../utils/utils';
|
|
6
|
+
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
7
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
8
|
+
// Supports create, flush, and delete operations for source sync blocks.
|
|
9
|
+
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
10
|
+
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
6
11
|
export class SourceSyncBlockStoreManager {
|
|
7
12
|
constructor(dataProvider) {
|
|
8
13
|
_defineProperty(this, "setPendingDeletion", (Ids, value) => {
|
|
@@ -14,12 +19,18 @@ export class SourceSyncBlockStoreManager {
|
|
|
14
19
|
this.dataProvider = dataProvider;
|
|
15
20
|
this.syncBlockCache = new Map();
|
|
16
21
|
}
|
|
22
|
+
isSourceBlock(node) {
|
|
23
|
+
return node.type.name === 'bodiedSyncBlock';
|
|
24
|
+
}
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
27
|
* Add/update a sync block node to/from the local cache
|
|
20
28
|
* @param syncBlockNode - The sync block node to update
|
|
21
29
|
*/
|
|
22
30
|
updateSyncBlockData(syncBlockNode) {
|
|
31
|
+
if (!this.isSourceBlock(syncBlockNode)) {
|
|
32
|
+
throw new Error('Invalid sync block node type provided for updateSyncBlockData');
|
|
33
|
+
}
|
|
23
34
|
const {
|
|
24
35
|
localId,
|
|
25
36
|
resourceId
|
|
@@ -37,7 +48,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
37
48
|
*
|
|
38
49
|
* @returns true if saving all nodes successfully, false if fail to save some/all nodes
|
|
39
50
|
*/
|
|
40
|
-
async
|
|
51
|
+
async flush() {
|
|
41
52
|
try {
|
|
42
53
|
if (!this.dataProvider) {
|
|
43
54
|
throw new Error('Data provider not set');
|
|
@@ -73,6 +84,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
73
84
|
registerPendingCreation(resourceId) {
|
|
74
85
|
this.pendingResourceId = resourceId;
|
|
75
86
|
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register callback function (which inserts node, handles focus etc) to be used later when creation to backend succeed
|
|
90
|
+
*/
|
|
76
91
|
registerCreationCallback(callback) {
|
|
77
92
|
this.creationCallback = callback;
|
|
78
93
|
}
|
|
@@ -88,6 +103,11 @@ export class SourceSyncBlockStoreManager {
|
|
|
88
103
|
this.pendingResourceId = undefined;
|
|
89
104
|
this.creationCallback = undefined;
|
|
90
105
|
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @returns true if waiting for the result of saving new bodiedSyncBlock to backend
|
|
110
|
+
*/
|
|
91
111
|
hasPendingCreation() {
|
|
92
112
|
return !!this.pendingResourceId;
|
|
93
113
|
}
|
|
@@ -100,6 +120,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
100
120
|
requireConfirmationBeforeDelete() {
|
|
101
121
|
return !!this.confirmationCallback;
|
|
102
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @returns attributes for a new bodiedSyncBlock node
|
|
126
|
+
*/
|
|
103
127
|
generateBodiedSyncBlockAttrs() {
|
|
104
128
|
var _this$dataProvider;
|
|
105
129
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
@@ -114,6 +138,11 @@ export class SourceSyncBlockStoreManager {
|
|
|
114
138
|
localId
|
|
115
139
|
};
|
|
116
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Create a bodiedSyncBlock node with empty content to backend
|
|
144
|
+
* @param attrs attributes Ids of the node
|
|
145
|
+
*/
|
|
117
146
|
createBodiedSyncBlockNode(attrs) {
|
|
118
147
|
try {
|
|
119
148
|
if (!this.dataProvider) {
|
|
@@ -190,4 +219,13 @@ export class SourceSyncBlockStoreManager {
|
|
|
190
219
|
}
|
|
191
220
|
this.confirmationTransaction = rebaseTransaction(this.confirmationTransaction, incomingTr, state);
|
|
192
221
|
}
|
|
222
|
+
destroy() {
|
|
223
|
+
this.syncBlockCache.clear();
|
|
224
|
+
this.confirmationCallback = undefined;
|
|
225
|
+
this.confirmationTransaction = undefined;
|
|
226
|
+
this.pendingResourceId = undefined;
|
|
227
|
+
this.creationCallback = undefined;
|
|
228
|
+
this.dataProvider = undefined;
|
|
229
|
+
this.editorView = undefined;
|
|
230
|
+
}
|
|
193
231
|
}
|
|
@@ -1,133 +1,26 @@
|
|
|
1
|
-
// eslint-disable-next-line no-restricted-imports
|
|
2
|
-
|
|
3
|
-
import { convertPMNodeToSyncBlockNode } from '../utils/utils';
|
|
4
1
|
import { ReferenceSyncBlockStoreManager } from './referenceSyncBlockStoreManager';
|
|
5
2
|
import { SourceSyncBlockStoreManager } from './sourceSyncBlockStoreManager';
|
|
6
3
|
|
|
7
|
-
// A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
4
|
+
// A parent store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
5
|
+
// Contains two child store managers: ReferenceSyncBlockStoreManager and SourceSyncBlockStoreManager.
|
|
6
|
+
// ReferenceSyncBlockStoreManager is responsible for the lifecycle and state management of reference sync blocks in an editor instance.
|
|
7
|
+
// SourceSyncBlockStoreManager is responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
8
|
+
// Can be used in both editor and renderer contexts.
|
|
12
9
|
export class SyncBlockStoreManager {
|
|
13
10
|
constructor(dataProvider) {
|
|
14
|
-
|
|
11
|
+
// In future, if reference manager needs to reach to source manager and read it's current in memorey cache
|
|
12
|
+
// we can pass the source manager as a parameter to the reference manager constructor
|
|
15
13
|
this.sourceSyncBlockStoreManager = new SourceSyncBlockStoreManager(dataProvider);
|
|
14
|
+
this.referenceSyncBlockStoreManager = new ReferenceSyncBlockStoreManager(dataProvider);
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Fetch sync block data for a given array of sync block nodes.
|
|
20
|
-
* @param nodes - The array of sync block nodes to fetch data for
|
|
21
|
-
* @returns The fetched sync block data results
|
|
22
|
-
*/
|
|
23
|
-
fetchSyncBlocksData(nodes) {
|
|
24
|
-
const syncBlockNodes = nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined) || [];
|
|
25
|
-
if (syncBlockNodes.length === 0) {
|
|
26
|
-
return Promise.resolve([]);
|
|
27
|
-
}
|
|
28
|
-
return this.referenceSyncBlockStoreManager.fetchSyncBlocksData(syncBlockNodes);
|
|
29
|
-
}
|
|
30
|
-
getReferenceSyncBlockStoreManager() {
|
|
16
|
+
get referenceManager() {
|
|
31
17
|
return this.referenceSyncBlockStoreManager;
|
|
32
18
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* Add/update a sync block node to/from the local cache
|
|
36
|
-
* @param syncBlockNode - The sync block node to update
|
|
37
|
-
*/
|
|
38
|
-
updateSyncBlockData(syncBlockNode) {
|
|
39
|
-
if (this.isSourceBlock(syncBlockNode)) {
|
|
40
|
-
return this.sourceSyncBlockStoreManager.updateSyncBlockData(syncBlockNode);
|
|
41
|
-
} else {
|
|
42
|
-
throw new Error('Invalid sync block node type provided for updateSyncBlockData');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Save content of bodiedSyncBlock nodes in local cache to backend
|
|
48
|
-
*
|
|
49
|
-
* @returns true if saving all nodes successfully, false if fail to save some/all nodes
|
|
50
|
-
*/
|
|
51
|
-
flushBodiedSyncBlocks() {
|
|
52
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
53
|
-
return this.sourceSyncBlockStoreManager.flushBodiedSyncBlocks();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get the URL for a sync block.
|
|
58
|
-
* @param resourceId - The resource ID of the sync block to get the URL for
|
|
59
|
-
* @returns
|
|
60
|
-
*/
|
|
61
|
-
getSyncBlockURL(resourceId) {
|
|
62
|
-
// only applicable to reference sync block, for now (will be refactored further)
|
|
63
|
-
return this.referenceSyncBlockStoreManager.getSyncBlockURL(resourceId);
|
|
64
|
-
}
|
|
65
|
-
setEditorView(editorView) {
|
|
66
|
-
this.sourceSyncBlockStoreManager.setEditorView(editorView);
|
|
67
|
-
}
|
|
68
|
-
isSourceBlock(node) {
|
|
69
|
-
return node.type.name === 'bodiedSyncBlock';
|
|
70
|
-
}
|
|
71
|
-
registerConfirmationCallback(callback) {
|
|
72
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
73
|
-
return this.sourceSyncBlockStoreManager.registerConfirmationCallback(callback);
|
|
74
|
-
}
|
|
75
|
-
requireConfirmationBeforeDelete() {
|
|
76
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
77
|
-
return this.sourceSyncBlockStoreManager.requireConfirmationBeforeDelete();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Register callback function (which inserts node, handles focus etc) to be used later when creation to backend succeed
|
|
82
|
-
*/
|
|
83
|
-
registerCreationCallback(callback) {
|
|
84
|
-
this.sourceSyncBlockStoreManager.registerCreationCallback(callback);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
*
|
|
89
|
-
* @returns true if waiting for the result of saving new bodiedSyncBlock to backend
|
|
90
|
-
*/
|
|
91
|
-
hasPendingCreation() {
|
|
92
|
-
return this.sourceSyncBlockStoreManager.hasPendingCreation();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @returns attributes for a new bodiedSyncBlock node
|
|
97
|
-
*/
|
|
98
|
-
generateBodiedSyncBlockAttrs() {
|
|
99
|
-
return this.sourceSyncBlockStoreManager.generateBodiedSyncBlockAttrs();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Save bodiedSyncBlock with empty content to backend
|
|
104
|
-
* @param attrs attributes Ids of the node
|
|
105
|
-
*/
|
|
106
|
-
createBodiedSyncBlockNode(attrs) {
|
|
107
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
108
|
-
return this.sourceSyncBlockStoreManager.createBodiedSyncBlockNode(attrs);
|
|
109
|
-
}
|
|
110
|
-
subscribeToSyncBlockData(node, callback) {
|
|
111
|
-
return this.referenceSyncBlockStoreManager.subscribe(node, callback);
|
|
112
|
-
}
|
|
113
|
-
subscribeToSyncBlockSourceTitle(node, callback) {
|
|
114
|
-
return this.referenceSyncBlockStoreManager.subscribeToSourceTitle(node, callback);
|
|
115
|
-
}
|
|
116
|
-
refreshSubscriptions() {
|
|
117
|
-
this.referenceSyncBlockStoreManager.refreshSubscriptions();
|
|
118
|
-
}
|
|
119
|
-
deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
|
|
120
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
121
|
-
return this.sourceSyncBlockStoreManager.deleteSyncBlocksWithConfirmation(tr, syncBlockIds);
|
|
122
|
-
}
|
|
123
|
-
rebaseTransaction(incomingTr, state) {
|
|
124
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
125
|
-
this.sourceSyncBlockStoreManager.rebaseTransaction(incomingTr, state);
|
|
126
|
-
}
|
|
127
|
-
getReferenceSyncBlockProviderFactory(resourceId) {
|
|
128
|
-
return this.referenceSyncBlockStoreManager.getProviderFactory(resourceId);
|
|
19
|
+
get sourceManager() {
|
|
20
|
+
return this.sourceSyncBlockStoreManager;
|
|
129
21
|
}
|
|
130
22
|
destroy() {
|
|
131
23
|
this.referenceSyncBlockStoreManager.destroy();
|
|
24
|
+
this.sourceSyncBlockStoreManager.destroy();
|
|
132
25
|
}
|
|
133
26
|
}
|
|
@@ -5,9 +5,6 @@ export const convertSyncBlockPMNodeToSyncBlockData = node => {
|
|
|
5
5
|
resourceId: node.attrs.resourceId
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
|
-
export const isBlogPageType = pageType => {
|
|
9
|
-
return pageType === 'blogpost';
|
|
10
|
-
};
|
|
11
8
|
export const createSyncBlockNode = (localId, resourceId) => {
|
|
12
9
|
return {
|
|
13
10
|
type: 'syncBlock',
|
|
@@ -38,4 +35,7 @@ export const convertPMNodeToSyncBlockNode = node => {
|
|
|
38
35
|
return undefined;
|
|
39
36
|
}
|
|
40
37
|
return createSyncBlockNode(node.attrs.localId, node.attrs.resourceId);
|
|
38
|
+
};
|
|
39
|
+
export const convertPMNodesToSyncBlockNodes = nodes => {
|
|
40
|
+
return nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined) || [];
|
|
41
41
|
};
|
|
@@ -19,7 +19,7 @@ export var blockResourceIdFromSourceAndLocalId = function blockResourceIdFromSou
|
|
|
19
19
|
* @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
20
20
|
* @returns the localId of the block node. A randomly generated UUID
|
|
21
21
|
*/
|
|
22
|
-
export var
|
|
22
|
+
export var getLocalIdFromBlockResourceId = function getLocalIdFromBlockResourceId(ari) {
|
|
23
23
|
var match = ari.match(/ari:cloud:blocks:[^:]+:synced-block\/([a-zA-Z0-9-]+)/);
|
|
24
24
|
if (match !== null && match !== void 0 && match[1]) {
|
|
25
25
|
return match[1];
|
|
@@ -6,7 +6,7 @@ export var getConfluencePageAri = function getConfluencePageAri(pageId, cloudId)
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// For extracting from Page ARI and also the content property's version of resourceId
|
|
9
|
-
export var
|
|
9
|
+
export var getPageIdAndTypeFromConfluencePageAri = function getPageIdAndTypeFromConfluencePageAri(ari) {
|
|
10
10
|
var match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/(\d+)/);
|
|
11
11
|
if (match !== null && match !== void 0 && match[2]) {
|
|
12
12
|
return {
|
|
@@ -16,20 +16,20 @@ export var getPageIdAndTypeFromAri = function getPageIdAndTypeFromAri(ari) {
|
|
|
16
16
|
}
|
|
17
17
|
throw new Error("Invalid page ARI: ".concat(ari));
|
|
18
18
|
};
|
|
19
|
-
export var
|
|
19
|
+
export var getLocalIdFromConfluencePageAri = function getLocalIdFromConfluencePageAri(ari) {
|
|
20
20
|
var match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
|
|
21
21
|
if (match !== null && match !== void 0 && match[2]) {
|
|
22
22
|
return match[2];
|
|
23
23
|
}
|
|
24
24
|
throw new Error("Invalid page ARI: ".concat(ari));
|
|
25
25
|
};
|
|
26
|
-
export var
|
|
26
|
+
export var getPageARIFromContentPropertyResourceId = function getPageARIFromContentPropertyResourceId(resourceId) {
|
|
27
27
|
var match = resourceId.match(/(ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+)\/([a-zA-Z0-9-]+)$/);
|
|
28
28
|
if (match !== null && match !== void 0 && match[1]) {
|
|
29
29
|
return match[1];
|
|
30
30
|
}
|
|
31
31
|
throw new Error("Invalid resourceId: ".concat(resourceId));
|
|
32
32
|
};
|
|
33
|
-
export var
|
|
33
|
+
export var resourceIdFromConfluencePageSourceIdAndLocalId = function resourceIdFromConfluencePageSourceIdAndLocalId(sourceId, localId) {
|
|
34
34
|
return sourceId + '/' + localId;
|
|
35
35
|
};
|
|
@@ -133,9 +133,7 @@ export var updateContentProperty = /*#__PURE__*/function () {
|
|
|
133
133
|
pageId: documentARI
|
|
134
134
|
}), {}, {
|
|
135
135
|
key: key,
|
|
136
|
-
value: JSON.stringify(
|
|
137
|
-
content: value.content
|
|
138
|
-
})
|
|
136
|
+
value: JSON.stringify(value)
|
|
139
137
|
}); // Blog content properties don't support the useSameVersion flag at the moment
|
|
140
138
|
if (!isBlog) {
|
|
141
139
|
input = _objectSpread(_objectSpread({}, input), useSameVersion);
|
|
@@ -194,9 +192,7 @@ export var createContentProperty = /*#__PURE__*/function () {
|
|
|
194
192
|
pageId: documentARI
|
|
195
193
|
}), {}, {
|
|
196
194
|
key: key,
|
|
197
|
-
value: JSON.stringify(
|
|
198
|
-
content: value.content
|
|
199
|
-
})
|
|
195
|
+
value: JSON.stringify(value)
|
|
200
196
|
})
|
|
201
197
|
}
|
|
202
198
|
};
|
|
@@ -5,7 +5,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
5
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
6
|
/* eslint-disable require-unicode-regexp */
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { getPageIdAndTypeFromConfluencePageAri } from './ari';
|
|
9
9
|
import { isBlogPageType } from './utils';
|
|
10
10
|
var COMMON_HEADERS = {
|
|
11
11
|
'Content-Type': 'application/json',
|
|
@@ -22,7 +22,7 @@ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
|
|
|
22
22
|
* @returns subType live if livePage, subType null if classic page
|
|
23
23
|
*/
|
|
24
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
|
|
25
|
+
var getConfluenceSourceInfo = /*#__PURE__*/function () {
|
|
26
26
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
|
|
27
27
|
var bodyData, response;
|
|
28
28
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
@@ -59,20 +59,20 @@ var getSourceInfo = /*#__PURE__*/function () {
|
|
|
59
59
|
}
|
|
60
60
|
}, _callee);
|
|
61
61
|
}));
|
|
62
|
-
return function
|
|
62
|
+
return function getConfluenceSourceInfo(_x) {
|
|
63
63
|
return _ref.apply(this, arguments);
|
|
64
64
|
};
|
|
65
65
|
}();
|
|
66
|
-
export var
|
|
66
|
+
export var fetchConfluenceSourceInfo = /*#__PURE__*/function () {
|
|
67
67
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(pageAri, localId) {
|
|
68
68
|
var _response$data, _contentData$space, _getPageIdAndTypeFrom, pageType, response, contentData, title, url, _ref3, base;
|
|
69
69
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
70
70
|
while (1) switch (_context2.prev = _context2.next) {
|
|
71
71
|
case 0:
|
|
72
72
|
_context2.prev = 0;
|
|
73
|
-
_getPageIdAndTypeFrom =
|
|
73
|
+
_getPageIdAndTypeFrom = getPageIdAndTypeFromConfluencePageAri(pageAri), pageType = _getPageIdAndTypeFrom.type;
|
|
74
74
|
_context2.next = 4;
|
|
75
|
-
return
|
|
75
|
+
return getConfluenceSourceInfo(pageAri);
|
|
76
76
|
case 4:
|
|
77
77
|
response = _context2.sent;
|
|
78
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];
|
|
@@ -108,7 +108,7 @@ export var fetchSourceInfo = /*#__PURE__*/function () {
|
|
|
108
108
|
}
|
|
109
109
|
}, _callee2, null, [[0, 15]]);
|
|
110
110
|
}));
|
|
111
|
-
return function
|
|
111
|
+
return function fetchConfluenceSourceInfo(_x2, _x3) {
|
|
112
112
|
return _ref2.apply(this, arguments);
|
|
113
113
|
};
|
|
114
114
|
}();
|
|
@@ -13,7 +13,6 @@ export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resou
|
|
|
13
13
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
14
14
|
isLoading = _useState4[0],
|
|
15
15
|
setIsLoading = _useState4[1];
|
|
16
|
-
var referenceSyncBlockStoreManager = manager.getReferenceSyncBlockStoreManager();
|
|
17
16
|
var reloadData = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
18
17
|
var syncBlockNode;
|
|
19
18
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
@@ -35,7 +34,7 @@ export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resou
|
|
|
35
34
|
setIsLoading(true);
|
|
36
35
|
_context.prev = 6;
|
|
37
36
|
_context.next = 9;
|
|
38
|
-
return
|
|
37
|
+
return manager.referenceManager.fetchSyncBlocksData([syncBlockNode]);
|
|
39
38
|
case 9:
|
|
40
39
|
_context.next = 14;
|
|
41
40
|
break;
|
|
@@ -54,19 +53,19 @@ export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resou
|
|
|
54
53
|
return _context.stop();
|
|
55
54
|
}
|
|
56
55
|
}, _callee, null, [[6, 11]]);
|
|
57
|
-
})), [isLoading, localId,
|
|
56
|
+
})), [isLoading, localId, manager.referenceManager, resourceId]);
|
|
58
57
|
useEffect(function () {
|
|
59
|
-
var unsubscribe =
|
|
58
|
+
var unsubscribe = manager.referenceManager.subscribeToSyncBlock(resourceId || '', localId || '', function (data) {
|
|
60
59
|
setSyncBlockInstance(data);
|
|
61
60
|
setIsLoading(false);
|
|
62
61
|
});
|
|
63
62
|
return function () {
|
|
64
63
|
unsubscribe();
|
|
65
64
|
};
|
|
66
|
-
}, [localId,
|
|
65
|
+
}, [localId, manager.referenceManager, resourceId]);
|
|
67
66
|
return {
|
|
68
67
|
isLoading: isLoading,
|
|
69
|
-
providerFactory:
|
|
68
|
+
providerFactory: manager.referenceManager.getProviderFactory(resourceId || ''),
|
|
70
69
|
reloadData: reloadData,
|
|
71
70
|
syncBlockInstance: syncBlockInstance
|
|
72
71
|
};
|
|
@@ -6,7 +6,7 @@ export var useFetchSyncBlockTitle = function useFetchSyncBlockTitle(manager, syn
|
|
|
6
6
|
sourceTitle = _useState2[0],
|
|
7
7
|
setSourceTitle = _useState2[1];
|
|
8
8
|
useEffect(function () {
|
|
9
|
-
var unsubscribe = manager.
|
|
9
|
+
var unsubscribe = manager.referenceManager.subscribeToSourceTitle(syncBlockNode, function (title) {
|
|
10
10
|
setSourceTitle(title);
|
|
11
11
|
});
|
|
12
12
|
return function () {
|