@atlaskit/editor-synced-block-provider 6.5.2 → 6.5.3
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 +9 -0
- package/dist/cjs/clients/jira/sourceInfo.js +63 -10
- package/dist/cjs/hooks/useFetchSyncBlockData.js +1 -1
- package/dist/cjs/providers/types.js +6 -0
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +24 -12
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +18 -15
- package/dist/cjs/store-manager/syncBlockBatchFetcher.js +1 -1
- package/dist/cjs/store-manager/syncBlockProviderFactoryManager.js +6 -4
- package/dist/cjs/store-manager/syncBlockStoreManager.js +2 -1
- package/dist/cjs/store-manager/syncBlockSubscriptionManager.js +9 -5
- package/dist/cjs/utils/errorHandling.js +41 -26
- package/dist/cjs/utils/resolveSyncBlockInstance.js +11 -10
- package/dist/cjs/utils/utils.js +30 -2
- package/dist/es2019/clients/jira/sourceInfo.js +64 -4
- package/dist/es2019/hooks/useFetchSyncBlockData.js +2 -2
- package/dist/es2019/providers/syncBlockProvider.js +4 -2
- package/dist/es2019/providers/types.js +7 -0
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +25 -13
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +19 -16
- package/dist/es2019/store-manager/syncBlockBatchFetcher.js +2 -2
- package/dist/es2019/store-manager/syncBlockProviderFactoryManager.js +6 -4
- package/dist/es2019/store-manager/syncBlockStoreManager.js +2 -1
- package/dist/es2019/store-manager/syncBlockSubscriptionManager.js +9 -5
- package/dist/es2019/utils/errorHandling.js +33 -14
- package/dist/es2019/utils/resolveSyncBlockInstance.js +11 -10
- package/dist/es2019/utils/utils.js +26 -0
- package/dist/esm/clients/jira/sourceInfo.js +63 -11
- package/dist/esm/hooks/useFetchSyncBlockData.js +2 -2
- package/dist/esm/providers/types.js +7 -0
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +25 -13
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +19 -16
- package/dist/esm/store-manager/syncBlockBatchFetcher.js +2 -2
- package/dist/esm/store-manager/syncBlockProviderFactoryManager.js +6 -4
- package/dist/esm/store-manager/syncBlockStoreManager.js +2 -1
- package/dist/esm/store-manager/syncBlockSubscriptionManager.js +9 -5
- package/dist/esm/utils/errorHandling.js +41 -26
- package/dist/esm/utils/resolveSyncBlockInstance.js +11 -10
- package/dist/esm/utils/utils.js +29 -1
- package/dist/types/clients/jira/sourceInfo.d.ts +20 -0
- package/dist/types/common/types.d.ts +2 -1
- package/dist/types/providers/types.d.ts +17 -0
- package/dist/types/utils/errorHandling.d.ts +13 -12
- package/dist/types/utils/utils.d.ts +3 -1
- package/dist/types-ts4.5/clients/jira/sourceInfo.d.ts +20 -0
- package/dist/types-ts4.5/common/types.d.ts +2 -1
- package/dist/types-ts4.5/providers/types.d.ts +17 -0
- package/dist/types-ts4.5/utils/errorHandling.d.ts +13 -12
- package/dist/types-ts4.5/utils/utils.d.ts +3 -1
- package/package.json +6 -3
- package/types/package.json +17 -0
- package/utils/package.json +17 -0
|
@@ -6,7 +6,7 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
|
6
6
|
import { SyncBlockError } from '../common/types';
|
|
7
7
|
import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload, getSourceInfoErrorPayload, updateSuccessPayload, createSuccessPayload, deleteSuccessPayload, fetchReferencesErrorPayload } from '../utils/errorHandling';
|
|
8
8
|
import { getCreateSourceExperience, getDeleteSourceExperience, getSaveSourceExperience, getFetchSourceInfoExperience } from '../utils/experienceTracking';
|
|
9
|
-
import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
|
|
9
|
+
import { convertSyncBlockPMNodeToSyncBlockData, productAttrIfGateOn } from '../utils/utils';
|
|
10
10
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
11
11
|
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
12
12
|
// Supports create, flush, and delete operations for source sync blocks.
|
|
@@ -106,11 +106,13 @@ export class SourceSyncBlockStoreManager {
|
|
|
106
106
|
}
|
|
107
107
|
return true;
|
|
108
108
|
} catch (error) {
|
|
109
|
-
var _this$fireAnalyticsEv;
|
|
109
|
+
var _this$fireAnalyticsEv, _syncBlockNode$attrs, _syncBlockNode$attrs2;
|
|
110
110
|
logException(error, {
|
|
111
111
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
112
112
|
});
|
|
113
|
-
|
|
113
|
+
// We can derive the product from `syncBlockNode.attrs.resourceId` even though
|
|
114
|
+
// the variable wasn't destructured (the destructuring step itself may have thrown).
|
|
115
|
+
(_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 ? void 0 : _this$fireAnalyticsEv.call(this, updateCacheErrorPayload(error.message, syncBlockNode === null || syncBlockNode === void 0 ? void 0 : (_syncBlockNode$attrs = syncBlockNode.attrs) === null || _syncBlockNode$attrs === void 0 ? void 0 : _syncBlockNode$attrs.resourceId, productAttrIfGateOn(syncBlockNode === null || syncBlockNode === void 0 ? void 0 : (_syncBlockNode$attrs2 = syncBlockNode.attrs) === null || _syncBlockNode$attrs2 === void 0 ? void 0 : _syncBlockNode$attrs2.resourceId)));
|
|
114
116
|
return false;
|
|
115
117
|
}
|
|
116
118
|
}
|
|
@@ -185,7 +187,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
185
187
|
cachedData.status = result.status;
|
|
186
188
|
}
|
|
187
189
|
}
|
|
188
|
-
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 ? void 0 : _this$fireAnalyticsEv2.call(this, updateSuccessPayload(result.resourceId, false));
|
|
190
|
+
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 ? void 0 : _this$fireAnalyticsEv2.call(this, updateSuccessPayload(result.resourceId, false, productAttrIfGateOn(result.resourceId)));
|
|
189
191
|
}
|
|
190
192
|
});
|
|
191
193
|
return true;
|
|
@@ -194,7 +196,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
194
196
|
(_this$saveExperience3 = this.saveExperience) === null || _this$saveExperience3 === void 0 ? void 0 : _this$saveExperience3.failure();
|
|
195
197
|
writeResults.filter(result => !result.resourceId || result.error).forEach(result => {
|
|
196
198
|
var _this$fireAnalyticsEv3;
|
|
197
|
-
(_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 ? void 0 : _this$fireAnalyticsEv3.call(this, updateErrorPayload(result.error || 'Failed to write data', result.resourceId));
|
|
199
|
+
(_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 ? void 0 : _this$fireAnalyticsEv3.call(this, updateErrorPayload(result.error || 'Failed to write data', result.resourceId, productAttrIfGateOn(result.resourceId)));
|
|
198
200
|
});
|
|
199
201
|
return false;
|
|
200
202
|
}
|
|
@@ -203,6 +205,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
203
205
|
logException(error, {
|
|
204
206
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
205
207
|
});
|
|
208
|
+
// Top-level flush failure is not tied to a single resourceId.
|
|
206
209
|
(_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 ? void 0 : _this$fireAnalyticsEv4.call(this, updateErrorPayload(error.message));
|
|
207
210
|
return false;
|
|
208
211
|
} finally {
|
|
@@ -258,16 +261,16 @@ export class SourceSyncBlockStoreManager {
|
|
|
258
261
|
}
|
|
259
262
|
} else {
|
|
260
263
|
var _this$fireAnalyticsEv5;
|
|
261
|
-
(_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 ? void 0 : _this$fireAnalyticsEv5.call(this, createErrorPayload('creation complete callback missing', resourceId));
|
|
264
|
+
(_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 ? void 0 : _this$fireAnalyticsEv5.call(this, createErrorPayload('creation complete callback missing', resourceId, productAttrIfGateOn(resourceId)));
|
|
262
265
|
}
|
|
263
266
|
if (success) {
|
|
264
267
|
var _this$fireAnalyticsEv6;
|
|
265
|
-
(_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 ? void 0 : _this$fireAnalyticsEv6.call(this, createSuccessPayload(resourceId || ''));
|
|
268
|
+
(_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 ? void 0 : _this$fireAnalyticsEv6.call(this, createSuccessPayload(resourceId || '', productAttrIfGateOn(resourceId)));
|
|
266
269
|
} else {
|
|
267
270
|
var _this$fireAnalyticsEv7;
|
|
268
271
|
// Delete the node from cache if fail to create so it's not flushed to BE
|
|
269
272
|
this.syncBlockCache.delete(resourceId || '');
|
|
270
|
-
(_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 ? void 0 : _this$fireAnalyticsEv7.call(this, createErrorPayload('Fail to create bodied sync block', resourceId));
|
|
273
|
+
(_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 ? void 0 : _this$fireAnalyticsEv7.call(this, createErrorPayload('Fail to create bodied sync block', resourceId, productAttrIfGateOn(resourceId)));
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
276
|
registerConfirmationCallback(callback) {
|
|
@@ -346,7 +349,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
346
349
|
(_this$createExperienc3 = this.createExperience) === null || _this$createExperienc3 === void 0 ? void 0 : _this$createExperienc3.failure({
|
|
347
350
|
reason: result.error || 'Failed to create bodied sync block'
|
|
348
351
|
});
|
|
349
|
-
(_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 ? void 0 : _this$fireAnalyticsEv8.call(this, createErrorPayload(result.error || 'Failed to create bodied sync block', resourceId));
|
|
352
|
+
(_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 ? void 0 : _this$fireAnalyticsEv8.call(this, createErrorPayload(result.error || 'Failed to create bodied sync block', resourceId, productAttrIfGateOn(resourceId)));
|
|
350
353
|
}
|
|
351
354
|
}).catch(error => {
|
|
352
355
|
var _this$createExperienc4, _this$fireAnalyticsEv9;
|
|
@@ -357,7 +360,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
357
360
|
(_this$createExperienc4 = this.createExperience) === null || _this$createExperienc4 === void 0 ? void 0 : _this$createExperienc4.failure({
|
|
358
361
|
reason: error.message
|
|
359
362
|
});
|
|
360
|
-
(_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 ? void 0 : _this$fireAnalyticsEv9.call(this, createErrorPayload(error.message, resourceId));
|
|
363
|
+
(_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 ? void 0 : _this$fireAnalyticsEv9.call(this, createErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
361
364
|
});
|
|
362
365
|
} catch (error) {
|
|
363
366
|
var _this$fireAnalyticsEv0;
|
|
@@ -367,7 +370,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
367
370
|
logException(error, {
|
|
368
371
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
369
372
|
});
|
|
370
|
-
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 ? void 0 : _this$fireAnalyticsEv0.call(this, createErrorPayload(error.message));
|
|
373
|
+
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 ? void 0 : _this$fireAnalyticsEv0.call(this, createErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
371
374
|
}
|
|
372
375
|
}
|
|
373
376
|
async delete(syncBlockIds, onDelete, onDeleteCompleted, reason) {
|
|
@@ -395,7 +398,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
395
398
|
(_this$deleteExperienc2 = this.deleteExperience) === null || _this$deleteExperienc2 === void 0 ? void 0 : _this$deleteExperienc2.success();
|
|
396
399
|
results.forEach(result => {
|
|
397
400
|
var _this$fireAnalyticsEv1;
|
|
398
|
-
(_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 ? void 0 : _this$fireAnalyticsEv1.call(this, deleteSuccessPayload(result.resourceId));
|
|
401
|
+
(_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 ? void 0 : _this$fireAnalyticsEv1.call(this, deleteSuccessPayload(result.resourceId, productAttrIfGateOn(result.resourceId)));
|
|
399
402
|
});
|
|
400
403
|
} else {
|
|
401
404
|
var _this$deleteExperienc3;
|
|
@@ -406,10 +409,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
406
409
|
results.forEach(result => {
|
|
407
410
|
if (result.success) {
|
|
408
411
|
var _this$fireAnalyticsEv10;
|
|
409
|
-
(_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 ? void 0 : _this$fireAnalyticsEv10.call(this, deleteSuccessPayload(result.resourceId));
|
|
412
|
+
(_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 ? void 0 : _this$fireAnalyticsEv10.call(this, deleteSuccessPayload(result.resourceId, productAttrIfGateOn(result.resourceId)));
|
|
410
413
|
} else {
|
|
411
414
|
var _this$fireAnalyticsEv11;
|
|
412
|
-
(_this$fireAnalyticsEv11 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv11 === void 0 ? void 0 : _this$fireAnalyticsEv11.call(this, deleteErrorPayload(result.error || 'Failed to delete synced block', result.resourceId));
|
|
415
|
+
(_this$fireAnalyticsEv11 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv11 === void 0 ? void 0 : _this$fireAnalyticsEv11.call(this, deleteErrorPayload(result.error || 'Failed to delete synced block', result.resourceId, productAttrIfGateOn(result.resourceId)));
|
|
413
416
|
}
|
|
414
417
|
});
|
|
415
418
|
}
|
|
@@ -419,7 +422,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
419
422
|
syncBlockIds.forEach(Ids => {
|
|
420
423
|
var _this$fireAnalyticsEv12;
|
|
421
424
|
this.setPendingDeletion(Ids, false);
|
|
422
|
-
(_this$fireAnalyticsEv12 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv12 === void 0 ? void 0 : _this$fireAnalyticsEv12.call(this, deleteErrorPayload(error.message, Ids.resourceId));
|
|
425
|
+
(_this$fireAnalyticsEv12 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv12 === void 0 ? void 0 : _this$fireAnalyticsEv12.call(this, deleteErrorPayload(error.message, Ids.resourceId, productAttrIfGateOn(Ids.resourceId)));
|
|
423
426
|
});
|
|
424
427
|
logException(error, {
|
|
425
428
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
@@ -597,7 +600,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
597
600
|
logException(error, {
|
|
598
601
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
599
602
|
});
|
|
600
|
-
(_this$fireAnalyticsEv14 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv14 === void 0 ? void 0 : _this$fireAnalyticsEv14.call(this, fetchReferencesErrorPayload(error.message));
|
|
603
|
+
(_this$fireAnalyticsEv14 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv14 === void 0 ? void 0 : _this$fireAnalyticsEv14.call(this, fetchReferencesErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
601
604
|
return Promise.resolve({
|
|
602
605
|
error: SyncBlockError.Errored
|
|
603
606
|
});
|
|
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
import rafSchedule from 'raf-schd';
|
|
3
3
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
4
4
|
import { fetchErrorPayload } from '../utils/errorHandling';
|
|
5
|
-
import { createSyncBlockNode } from '../utils/utils';
|
|
5
|
+
import { createSyncBlockNode, productAttrIfGateOn } from '../utils/utils';
|
|
6
6
|
/**
|
|
7
7
|
* Handles debounced batch-fetching of sync block data via `raf-schd`.
|
|
8
8
|
* Accumulates resource IDs and flushes them in a single fetch per
|
|
@@ -29,7 +29,7 @@ export class SyncBlockBatchFetcher {
|
|
|
29
29
|
});
|
|
30
30
|
resourceIds.forEach(resId => {
|
|
31
31
|
var _this$deps$getFireAna;
|
|
32
|
-
(_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 ? void 0 : _this$deps$getFireAna(fetchErrorPayload(error.message, resId));
|
|
32
|
+
(_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 ? void 0 : _this$deps$getFireAna(fetchErrorPayload(error.message, resId, productAttrIfGateOn(resId)));
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
});
|
|
@@ -3,6 +3,7 @@ import { logException } from '@atlaskit/editor-common/monitoring';
|
|
|
3
3
|
import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
4
4
|
import { fetchErrorPayload } from '../utils/errorHandling';
|
|
5
5
|
import { parseResourceId } from '../utils/resourceId';
|
|
6
|
+
import { productAttrIfGateOn } from '../utils/utils';
|
|
6
7
|
/**
|
|
7
8
|
* Manages creation and caching of ProviderFactory instances used to
|
|
8
9
|
* render synced block content (media, emoji, smart links, etc.).
|
|
@@ -20,7 +21,7 @@ export class SyncBlockProviderFactoryManager {
|
|
|
20
21
|
logException(error, {
|
|
21
22
|
location: 'editor-synced-block-provider/syncBlockProviderFactoryManager'
|
|
22
23
|
});
|
|
23
|
-
(_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 ? void 0 : _this$deps$getFireAna(fetchErrorPayload(error.message));
|
|
24
|
+
(_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 ? void 0 : _this$deps$getFireAna(fetchErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
24
25
|
return undefined;
|
|
25
26
|
}
|
|
26
27
|
const {
|
|
@@ -54,7 +55,7 @@ export class SyncBlockProviderFactoryManager {
|
|
|
54
55
|
logException(error, {
|
|
55
56
|
location: 'editor-synced-block-provider/syncBlockProviderFactoryManager'
|
|
56
57
|
});
|
|
57
|
-
(_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 ? void 0 : _this$deps$getFireAna2(fetchErrorPayload(error.message, resourceId));
|
|
58
|
+
(_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 ? void 0 : _this$deps$getFireAna2(fetchErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
return providerFactory;
|
|
@@ -130,8 +131,9 @@ export class SyncBlockProviderFactoryManager {
|
|
|
130
131
|
return;
|
|
131
132
|
}
|
|
132
133
|
if (!syncBlock.data.sourceAri || !syncBlock.data.product) {
|
|
133
|
-
var _this$deps$getFireAna3;
|
|
134
|
-
(_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 ? void 0 : _this$deps$getFireAna3(fetchErrorPayload('Sync block source ari or product not found'
|
|
134
|
+
var _this$deps$getFireAna3, _syncBlock$data$produ;
|
|
135
|
+
(_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 ? void 0 : _this$deps$getFireAna3(fetchErrorPayload('Sync block source ari or product not found', resourceId, // Prefer cached product when available; fall back to parsing resourceId.
|
|
136
|
+
(_syncBlock$data$produ = syncBlock.data.product) !== null && _syncBlock$data$produ !== void 0 ? _syncBlock$data$produ : productAttrIfGateOn(resourceId)));
|
|
135
137
|
return;
|
|
136
138
|
}
|
|
137
139
|
const parentInfo = dataProvider.retrieveSyncBlockParentInfo(syncBlock.data.sourceAri, syncBlock.data.product);
|
|
@@ -5,6 +5,7 @@ import { getProductFromSourceAri } from '../clients/block-service/ari';
|
|
|
5
5
|
import { SyncBlockError } from '../common/types';
|
|
6
6
|
import { fetchReferencesErrorPayload } from '../utils/errorHandling';
|
|
7
7
|
import { getFetchReferencesExperience, getFetchSourceInfoExperience } from '../utils/experienceTracking';
|
|
8
|
+
import { productAttrIfGateOn } from '../utils/utils';
|
|
8
9
|
import { ReferenceSyncBlockStoreManager } from './referenceSyncBlockStoreManager';
|
|
9
10
|
import { SourceSyncBlockStoreManager } from './sourceSyncBlockStoreManager';
|
|
10
11
|
|
|
@@ -102,7 +103,7 @@ export class SyncBlockStoreManager {
|
|
|
102
103
|
logException(error, {
|
|
103
104
|
location: 'editor-synced-block-provider/syncBlockStoreManager'
|
|
104
105
|
});
|
|
105
|
-
(_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 ? void 0 : _this$fireAnalyticsEv.call(this, fetchReferencesErrorPayload(error.message));
|
|
106
|
+
(_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 ? void 0 : _this$fireAnalyticsEv.call(this, fetchReferencesErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
106
107
|
return {
|
|
107
108
|
error: SyncBlockError.Errored
|
|
108
109
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
import { fetchErrorPayload, fetchSuccessPayload } from '../utils/errorHandling';
|
|
4
5
|
import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
|
|
6
|
+
import { getSourceProductFromResourceIdSafe, productAttrIfGateOn } from '../utils/utils';
|
|
5
7
|
/**
|
|
6
8
|
* Manages the lifecycle of GraphQL WebSocket subscriptions for sync block
|
|
7
9
|
* real-time updates, owns the subscriptions and titleSubscriptions maps,
|
|
@@ -219,7 +221,7 @@ export class SyncBlockSubscriptionManager {
|
|
|
219
221
|
logException(error, {
|
|
220
222
|
location: 'editor-synced-block-provider/syncBlockSubscriptionManager/graphql-subscription'
|
|
221
223
|
});
|
|
222
|
-
(_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 ? void 0 : _this$deps$getFireAna2(fetchErrorPayload(error.message));
|
|
224
|
+
(_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 ? void 0 : _this$deps$getFireAna2(fetchErrorPayload(error.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
223
225
|
});
|
|
224
226
|
if (unsubscribe) {
|
|
225
227
|
this.graphqlSubscriptions.set(resourceId, unsubscribe);
|
|
@@ -270,14 +272,16 @@ export class SyncBlockSubscriptionManager {
|
|
|
270
272
|
const callbacks = this.subscriptions.get(syncBlockInstance.resourceId);
|
|
271
273
|
const localIds = callbacks ? Object.keys(callbacks) : [];
|
|
272
274
|
localIds.forEach(localId => {
|
|
273
|
-
var _this$deps$getFireAna3, _syncBlockInstance$da;
|
|
274
|
-
(_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 ? void 0 : _this$deps$getFireAna3(fetchSuccessPayload(syncBlockInstance.resourceId, localId,
|
|
275
|
+
var _this$deps$getFireAna3, _syncBlockInstance$da, _syncBlockInstance$da2;
|
|
276
|
+
(_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 ? void 0 : _this$deps$getFireAna3(fetchSuccessPayload(syncBlockInstance.resourceId, localId,
|
|
277
|
+
// Prefer cached product when available; fall back to parsing the resourceId.
|
|
278
|
+
fg('platform_synced_block_patch_11') ? (_syncBlockInstance$da = (_syncBlockInstance$da2 = syncBlockInstance.data) === null || _syncBlockInstance$da2 === void 0 ? void 0 : _syncBlockInstance$da2.product) !== null && _syncBlockInstance$da !== void 0 ? _syncBlockInstance$da : getSourceProductFromResourceIdSafe(syncBlockInstance.resourceId) : undefined));
|
|
275
279
|
});
|
|
276
280
|
this.deps.fetchSyncBlockSourceInfo(resolved.resourceId);
|
|
277
281
|
} else {
|
|
278
|
-
var _syncBlockInstance$er, _syncBlockInstance$er2, _this$deps$getFireAna4;
|
|
282
|
+
var _syncBlockInstance$er, _syncBlockInstance$er2, _this$deps$getFireAna4, _syncBlockInstance$da3, _syncBlockInstance$da4;
|
|
279
283
|
const errorMessage = ((_syncBlockInstance$er = syncBlockInstance.error) === null || _syncBlockInstance$er === void 0 ? void 0 : _syncBlockInstance$er.reason) || ((_syncBlockInstance$er2 = syncBlockInstance.error) === null || _syncBlockInstance$er2 === void 0 ? void 0 : _syncBlockInstance$er2.type);
|
|
280
|
-
(_this$deps$getFireAna4 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna4 === void 0 ? void 0 : _this$deps$getFireAna4(fetchErrorPayload(errorMessage, syncBlockInstance.resourceId));
|
|
284
|
+
(_this$deps$getFireAna4 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna4 === void 0 ? void 0 : _this$deps$getFireAna4(fetchErrorPayload(errorMessage, syncBlockInstance.resourceId, fg('platform_synced_block_patch_11') ? (_syncBlockInstance$da3 = (_syncBlockInstance$da4 = syncBlockInstance.data) === null || _syncBlockInstance$da4 === void 0 ? void 0 : _syncBlockInstance$da4.product) !== null && _syncBlockInstance$da3 !== void 0 ? _syncBlockInstance$da3 : getSourceProductFromResourceIdSafe(syncBlockInstance.resourceId) : undefined));
|
|
281
285
|
}
|
|
282
286
|
}
|
|
283
287
|
}
|
|
@@ -6,7 +6,14 @@ export const stringifyError = error => {
|
|
|
6
6
|
return undefined;
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
// `sourceProduct` is threaded through every helper so analytics
|
|
11
|
+
// events can be attributed to the source product (`confluence-page` vs `jira-work-item`).
|
|
12
|
+
// All helpers accept it as an optional trailing argument; the spread-only-when-truthy
|
|
13
|
+
// pattern below ensures we never emit `sourceProduct: undefined` (which would dirty the
|
|
14
|
+
// event schema with empty keys).
|
|
15
|
+
|
|
16
|
+
export const getErrorPayload = (actionSubjectId, error, resourceId, sourceProduct) => ({
|
|
10
17
|
action: ACTION.ERROR,
|
|
11
18
|
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
12
19
|
actionSubjectId,
|
|
@@ -15,17 +22,20 @@ export const getErrorPayload = (actionSubjectId, error, resourceId) => ({
|
|
|
15
22
|
error,
|
|
16
23
|
...(resourceId && {
|
|
17
24
|
resourceId
|
|
25
|
+
}),
|
|
26
|
+
...(sourceProduct && {
|
|
27
|
+
sourceProduct
|
|
18
28
|
})
|
|
19
29
|
}
|
|
20
30
|
});
|
|
21
|
-
export const fetchErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId);
|
|
22
|
-
export const getSourceInfoErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error, resourceId);
|
|
23
|
-
export const updateErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error, resourceId);
|
|
24
|
-
export const updateReferenceErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error, resourceId);
|
|
25
|
-
export const createErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error, resourceId);
|
|
26
|
-
export const deleteErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE, error, resourceId);
|
|
27
|
-
export const updateCacheErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE_CACHE, error, resourceId);
|
|
28
|
-
export const fetchReferencesErrorPayload = (error, resourceId) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH_REFERENCES, error, resourceId);
|
|
31
|
+
export const fetchErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId, sourceProduct);
|
|
32
|
+
export const getSourceInfoErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error, resourceId, sourceProduct);
|
|
33
|
+
export const updateErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error, resourceId, sourceProduct);
|
|
34
|
+
export const updateReferenceErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error, resourceId, sourceProduct);
|
|
35
|
+
export const createErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error, resourceId, sourceProduct);
|
|
36
|
+
export const deleteErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE, error, resourceId, sourceProduct);
|
|
37
|
+
export const updateCacheErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE_CACHE, error, resourceId, sourceProduct);
|
|
38
|
+
export const fetchReferencesErrorPayload = (error, resourceId, sourceProduct) => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH_REFERENCES, error, resourceId, sourceProduct);
|
|
29
39
|
|
|
30
40
|
// Success payloads
|
|
31
41
|
export const fetchSuccessPayload = (resourceId, blockInstanceId, sourceProduct) => ({
|
|
@@ -41,14 +51,17 @@ export const fetchSuccessPayload = (resourceId, blockInstanceId, sourceProduct)
|
|
|
41
51
|
})
|
|
42
52
|
}
|
|
43
53
|
});
|
|
44
|
-
export const createSuccessPayload = resourceId => {
|
|
54
|
+
export const createSuccessPayload = (resourceId, sourceProduct) => {
|
|
45
55
|
return {
|
|
46
56
|
action: ACTION.INSERTED,
|
|
47
57
|
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
48
58
|
actionSubjectId: ACTION_SUBJECT_ID.BODIED_SYNCED_BLOCK,
|
|
49
59
|
eventType: EVENT_TYPE.TRACK,
|
|
50
60
|
attributes: {
|
|
51
|
-
resourceId
|
|
61
|
+
resourceId,
|
|
62
|
+
...(sourceProduct && {
|
|
63
|
+
sourceProduct
|
|
64
|
+
})
|
|
52
65
|
}
|
|
53
66
|
};
|
|
54
67
|
};
|
|
@@ -61,7 +74,7 @@ export const createSuccessPayloadNew = resourceId => ({
|
|
|
61
74
|
resourceId
|
|
62
75
|
}
|
|
63
76
|
});
|
|
64
|
-
export const updateSuccessPayload = (resourceId, hasReference) => ({
|
|
77
|
+
export const updateSuccessPayload = (resourceId, hasReference, sourceProduct) => ({
|
|
65
78
|
action: ACTION.UPDATED,
|
|
66
79
|
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
67
80
|
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE,
|
|
@@ -70,15 +83,21 @@ export const updateSuccessPayload = (resourceId, hasReference) => ({
|
|
|
70
83
|
resourceId,
|
|
71
84
|
...(hasReference !== undefined && {
|
|
72
85
|
hasReference
|
|
86
|
+
}),
|
|
87
|
+
...(sourceProduct && {
|
|
88
|
+
sourceProduct
|
|
73
89
|
})
|
|
74
90
|
}
|
|
75
91
|
});
|
|
76
|
-
export const deleteSuccessPayload = resourceId => ({
|
|
92
|
+
export const deleteSuccessPayload = (resourceId, sourceProduct) => ({
|
|
77
93
|
action: ACTION.DELETED,
|
|
78
94
|
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
79
95
|
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE,
|
|
80
96
|
eventType: EVENT_TYPE.OPERATIONAL,
|
|
81
97
|
attributes: {
|
|
82
|
-
resourceId
|
|
98
|
+
resourceId,
|
|
99
|
+
...(sourceProduct && {
|
|
100
|
+
sourceProduct
|
|
101
|
+
})
|
|
83
102
|
}
|
|
84
103
|
});
|
|
@@ -12,7 +12,7 @@ import { SyncBlockError } from '../common/types';
|
|
|
12
12
|
* @returns A merged SyncBlockInstance object.
|
|
13
13
|
*/
|
|
14
14
|
export const resolveSyncBlockInstance = (oldResult, newResult) => {
|
|
15
|
-
var _newResult$data, _oldResult$data, _newResult$data2, _oldResult$data2, _newResult$data3, _oldResult$data3;
|
|
15
|
+
var _newResult$data, _oldResult$data, _newResult$data2, _oldResult$data2, _newResult$data3, _oldResult$data3, _newResult$data4, _oldResult$data4;
|
|
16
16
|
// if the old result has no data, we simply return the new result
|
|
17
17
|
if (!oldResult.data) {
|
|
18
18
|
return newResult;
|
|
@@ -34,30 +34,31 @@ export const resolveSyncBlockInstance = (oldResult, newResult) => {
|
|
|
34
34
|
sourceURL: ((_newResult$data = newResult.data) === null || _newResult$data === void 0 ? void 0 : _newResult$data.sourceURL) || ((_oldResult$data = oldResult.data) === null || _oldResult$data === void 0 ? void 0 : _oldResult$data.sourceURL) || undefined,
|
|
35
35
|
sourceTitle: ((_newResult$data2 = newResult.data) === null || _newResult$data2 === void 0 ? void 0 : _newResult$data2.sourceTitle) || ((_oldResult$data2 = oldResult.data) === null || _oldResult$data2 === void 0 ? void 0 : _oldResult$data2.sourceTitle) || undefined,
|
|
36
36
|
sourceSubType: mergeSubType(oldResult, newResult),
|
|
37
|
-
onSameDocument: ((_newResult$data3 = newResult.data) === null || _newResult$data3 === void 0 ? void 0 : _newResult$data3.onSameDocument) || ((_oldResult$data3 = oldResult.data) === null || _oldResult$data3 === void 0 ? void 0 : _oldResult$data3.onSameDocument) || undefined
|
|
37
|
+
onSameDocument: ((_newResult$data3 = newResult.data) === null || _newResult$data3 === void 0 ? void 0 : _newResult$data3.onSameDocument) || ((_oldResult$data3 = oldResult.data) === null || _oldResult$data3 === void 0 ? void 0 : _oldResult$data3.onSameDocument) || undefined,
|
|
38
|
+
issueType: ((_newResult$data4 = newResult.data) === null || _newResult$data4 === void 0 ? void 0 : _newResult$data4.issueType) || ((_oldResult$data4 = oldResult.data) === null || _oldResult$data4 === void 0 ? void 0 : _oldResult$data4.issueType) || undefined
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
};
|
|
41
42
|
const mergeSubType = (oldResult, newResult) => {
|
|
42
|
-
var _newResult$
|
|
43
|
+
var _newResult$data5, _newResult$data6, _oldResult$data5;
|
|
43
44
|
// for classic pages, subType is 'null'
|
|
44
|
-
if (((_newResult$
|
|
45
|
+
if (((_newResult$data5 = newResult.data) === null || _newResult$data5 === void 0 ? void 0 : _newResult$data5.sourceSubType) !== undefined) {
|
|
45
46
|
return newResult.data.sourceSubType;
|
|
46
47
|
}
|
|
47
|
-
if ((_newResult$
|
|
48
|
+
if ((_newResult$data6 = newResult.data) !== null && _newResult$data6 !== void 0 && _newResult$data6.sourceAri) {
|
|
48
49
|
// for blogposts, subType is always undefined
|
|
49
50
|
try {
|
|
50
|
-
var _newResult$
|
|
51
|
+
var _newResult$data7;
|
|
51
52
|
const {
|
|
52
53
|
type: pageType
|
|
53
54
|
} = getPageIdAndTypeFromConfluencePageAri({
|
|
54
|
-
ari: (_newResult$
|
|
55
|
+
ari: (_newResult$data7 = newResult.data) === null || _newResult$data7 === void 0 ? void 0 : _newResult$data7.sourceAri
|
|
55
56
|
});
|
|
56
57
|
if (pageType === 'blogpost') {
|
|
57
|
-
var _newResult$
|
|
58
|
-
return (_newResult$
|
|
58
|
+
var _newResult$data8;
|
|
59
|
+
return (_newResult$data8 = newResult.data) === null || _newResult$data8 === void 0 ? void 0 : _newResult$data8.sourceSubType;
|
|
59
60
|
}
|
|
60
61
|
} catch {}
|
|
61
62
|
}
|
|
62
|
-
return (_oldResult$
|
|
63
|
+
return (_oldResult$data5 = oldResult.data) === null || _oldResult$data5 === void 0 ? void 0 : _oldResult$data5.sourceSubType;
|
|
63
64
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable require-unicode-regexp */
|
|
2
2
|
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
export const convertSyncBlockPMNodeToSyncBlockData = node => {
|
|
4
5
|
return {
|
|
5
6
|
blockInstanceId: node.attrs.localId,
|
|
@@ -48,6 +49,31 @@ export const getContentIdAndProductFromResourceId = resourceId => {
|
|
|
48
49
|
}
|
|
49
50
|
throw new Error(`Invalid resourceId: ${resourceId}`);
|
|
50
51
|
};
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Safe variant of `getContentIdAndProductFromResourceId` for analytics call-sites.
|
|
55
|
+
* Returns `undefined` instead of throwing when the resourceId is missing or malformed,
|
|
56
|
+
* so a bad value can never break the analytics pipeline.
|
|
57
|
+
*/
|
|
58
|
+
export const getSourceProductFromResourceIdSafe = resourceId => {
|
|
59
|
+
if (!resourceId) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
return getContentIdAndProductFromResourceId(resourceId).sourceProduct;
|
|
64
|
+
} catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* Convenience wrapper around `getSourceProductFromResourceIdSafe` that returns
|
|
71
|
+
* `undefined` whenever the `platform_synced_block_patch_11` rollout flag is off.
|
|
72
|
+
* Centralised so that the flag name lives in exactly one place — when the flag is
|
|
73
|
+
* cleaned up, this function should be deleted in its entirety and call-sites should
|
|
74
|
+
* fall back to calling `getSourceProductFromResourceIdSafe` directly.
|
|
75
|
+
*/
|
|
76
|
+
export const productAttrIfGateOn = resourceId => fg('platform_synced_block_patch_11') ? getSourceProductFromResourceIdSafe(resourceId) : undefined;
|
|
51
77
|
export const convertContentUpdatedAt = contentUpdatedAt => {
|
|
52
78
|
if (typeof contentUpdatedAt === 'number') {
|
|
53
79
|
try {
|
|
@@ -4,7 +4,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
4
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
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
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
8
|
import { fetchWithRetry } from '../../utils/retry';
|
|
9
9
|
var COMMON_HEADERS = {
|
|
10
10
|
'Content-Type': 'application/json',
|
|
@@ -20,7 +20,11 @@ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
|
|
|
20
20
|
* @param id - the ID of the work item
|
|
21
21
|
* @returns url of the work item
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
// `issueType` is requested unconditionally because GraphQL field selection cannot be
|
|
24
|
+
// gated at the network layer without a separate operation; AGG ignores unknown
|
|
25
|
+
// front-end gating. The runtime mapping into `SyncBlockSourceInfo.issueType` is gated
|
|
26
|
+
// by `platform_synced_block_patch_11` below.
|
|
27
|
+
var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n jira {\n issueById(id: $id) {\n id\n webUrl\n summary\n issueType {\n name\n avatar {\n xsmall\n }\n }\n }\n }}");
|
|
24
28
|
var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
|
|
25
29
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
|
|
26
30
|
var bodyData, response;
|
|
@@ -108,34 +112,82 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
|
|
|
108
112
|
return _ref2.apply(this, arguments);
|
|
109
113
|
};
|
|
110
114
|
}();
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Fetch source-info metadata for a Jira work item used by reference sync blocks.
|
|
118
|
+
*
|
|
119
|
+
* Parity notes vs the Confluence equivalent (`fetchConfluencePageInfo`):
|
|
120
|
+
*
|
|
121
|
+
* - **Archived / draft URL variants** are intentionally omitted. Confluence pages can be
|
|
122
|
+
* "unpublished" (draft, archived, in-trash) and need REST fallbacks plus alternate URL
|
|
123
|
+
* shapes. Jira work items have no equivalent lifecycle — an issue either exists in AGG
|
|
124
|
+
* or it does not — so a single `webUrl` is sufficient.
|
|
125
|
+
*
|
|
126
|
+
* - **`#block-{localId}` deep-link anchor** is intentionally not appended. The current
|
|
127
|
+
* Jira issue view does not implement scroll-to-anchor for unknown fragments, so the
|
|
128
|
+
* anchor would be dead weight on the URL. The dispatching code in
|
|
129
|
+
* `syncBlockProvider.fetchSyncBlockSourceInfo` deliberately does not pass `localId`
|
|
130
|
+
* here for the same reason. If/when Jira issue view supports anchor scrolling for
|
|
131
|
+
* sync-block local IDs, accept `localId?: string` here and append `#block-{localId}`.
|
|
132
|
+
*
|
|
133
|
+
* - **`subType` / page-type variants** are not modeled — Jira issue type is exposed via
|
|
134
|
+
* the separate `issueType` field returned alongside `summary` / `webUrl`.
|
|
135
|
+
*/
|
|
111
136
|
export var fetchJiraWorkItemInfo = /*#__PURE__*/function () {
|
|
112
137
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(workItemAri, hasAccess) {
|
|
113
|
-
var _response$data, response, contentData, webUrl, summary;
|
|
138
|
+
var _response$data, _contentData$webUrl, _contentData$summary, response, contentData, _rawIssueType$avatar, _webUrl, _summary, rawIssueType, issueTypeName, issueType, webUrl, summary;
|
|
114
139
|
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
115
140
|
while (1) switch (_context3.prev = _context3.next) {
|
|
116
141
|
case 0:
|
|
117
142
|
if (!hasAccess) {
|
|
118
|
-
_context3.next =
|
|
143
|
+
_context3.next = 17;
|
|
119
144
|
break;
|
|
120
145
|
}
|
|
121
146
|
_context3.next = 3;
|
|
122
147
|
return getJiraWorkItemSourceInfo(workItemAri);
|
|
123
148
|
case 3:
|
|
124
149
|
response = _context3.sent;
|
|
125
|
-
contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.jira) === null || _response$data === void 0 ? void 0 : _response$data.issueById;
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.jira) === null || _response$data === void 0 ? void 0 : _response$data.issueById; // Defensive narrowing (gated by `platform_synced_block_patch_11`):
|
|
151
|
+
// AGG may return `null` (not just omit the field) for `webUrl` / `summary` on
|
|
152
|
+
// partially indexed issues. Without these guards, downstream consumers that
|
|
153
|
+
// expect `string | undefined` would receive `null` and either crash or render
|
|
154
|
+
// the literal string "null". The pre-gate path preserves the legacy behaviour
|
|
155
|
+
// so this can be dialled off independently.
|
|
156
|
+
if (!fg('platform_synced_block_patch_11')) {
|
|
157
|
+
_context3.next = 12;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
_webUrl = typeof (contentData === null || contentData === void 0 ? void 0 : contentData.webUrl) === 'string' ? contentData.webUrl : undefined;
|
|
161
|
+
_summary = typeof (contentData === null || contentData === void 0 ? void 0 : contentData.summary) === 'string' ? contentData.summary : undefined; // Surface issue-type metadata so consumers can render the correct ADS issue-type
|
|
162
|
+
// icon. Defensive narrowing mirrors the webUrl/summary treatment above: only
|
|
163
|
+
// surfaced when `name` is a non-empty string; AGG values like `{ name: null }`
|
|
164
|
+
// collapse back to `undefined`.
|
|
165
|
+
rawIssueType = contentData === null || contentData === void 0 ? void 0 : contentData.issueType;
|
|
166
|
+
issueTypeName = typeof (rawIssueType === null || rawIssueType === void 0 ? void 0 : rawIssueType.name) === 'string' && rawIssueType.name.length > 0 ? rawIssueType.name : undefined;
|
|
167
|
+
issueType = issueTypeName ? {
|
|
168
|
+
name: issueTypeName,
|
|
169
|
+
iconUrl: typeof (rawIssueType === null || rawIssueType === void 0 || (_rawIssueType$avatar = rawIssueType.avatar) === null || _rawIssueType$avatar === void 0 ? void 0 : _rawIssueType$avatar.xsmall) === 'string' ? rawIssueType.avatar.xsmall : undefined
|
|
170
|
+
} : undefined;
|
|
171
|
+
return _context3.abrupt("return", Promise.resolve({
|
|
172
|
+
url: _webUrl,
|
|
173
|
+
sourceAri: workItemAri,
|
|
174
|
+
title: _summary,
|
|
175
|
+
issueType: issueType
|
|
176
|
+
}));
|
|
177
|
+
case 12:
|
|
178
|
+
webUrl = (_contentData$webUrl = contentData === null || contentData === void 0 ? void 0 : contentData.webUrl) !== null && _contentData$webUrl !== void 0 ? _contentData$webUrl : undefined;
|
|
179
|
+
summary = (_contentData$summary = contentData === null || contentData === void 0 ? void 0 : contentData.summary) !== null && _contentData$summary !== void 0 ? _contentData$summary : undefined;
|
|
128
180
|
return _context3.abrupt("return", Promise.resolve({
|
|
129
181
|
url: webUrl,
|
|
130
182
|
sourceAri: workItemAri,
|
|
131
183
|
title: summary
|
|
132
184
|
}));
|
|
133
|
-
case
|
|
134
|
-
_context3.next =
|
|
185
|
+
case 17:
|
|
186
|
+
_context3.next = 19;
|
|
135
187
|
return resolveNoAccessWorkItemInfo(workItemAri);
|
|
136
|
-
case
|
|
188
|
+
case 19:
|
|
137
189
|
return _context3.abrupt("return", _context3.sent);
|
|
138
|
-
case
|
|
190
|
+
case 20:
|
|
139
191
|
case "end":
|
|
140
192
|
return _context3.stop();
|
|
141
193
|
}
|
|
@@ -9,7 +9,7 @@ import { isSSR } from '@atlaskit/editor-common/core-utils';
|
|
|
9
9
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
10
10
|
import { SyncBlockError } from '../common/types';
|
|
11
11
|
import { fetchErrorPayload } from '../utils/errorHandling';
|
|
12
|
-
import { createSyncBlockNode } from '../utils/utils';
|
|
12
|
+
import { createSyncBlockNode, productAttrIfGateOn } from '../utils/utils';
|
|
13
13
|
export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resourceId, localId, fireAnalyticsEvent) {
|
|
14
14
|
// Initialize both states from a single cache lookup to avoid race conditions.
|
|
15
15
|
// When a block is moved/remounted, the old component's cleanup may clear the cache
|
|
@@ -71,7 +71,7 @@ export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resou
|
|
|
71
71
|
logException(_context.t0, {
|
|
72
72
|
location: 'editor-synced-block-provider/useFetchSyncBlockData'
|
|
73
73
|
});
|
|
74
|
-
fireAnalyticsEvent === null || fireAnalyticsEvent === void 0 || fireAnalyticsEvent(fetchErrorPayload(_context.t0.message));
|
|
74
|
+
fireAnalyticsEvent === null || fireAnalyticsEvent === void 0 || fireAnalyticsEvent(fetchErrorPayload(_context.t0.message, resourceId, productAttrIfGateOn(resourceId)));
|
|
75
75
|
|
|
76
76
|
// Set error state if fetching fails
|
|
77
77
|
setFetchState({
|
|
@@ -13,6 +13,13 @@ import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
|
13
13
|
* This will be used in both data processing and rendering contexts.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Lightweight metadata for a Jira issue's type, surfaced so consumers can render the
|
|
18
|
+
* correct ADS issue-type icon (Task / Bug / Story / Epic / Subtask) or fall back to the
|
|
19
|
+
* AGG-provided `iconUrl` for custom types. Optional throughout — Confluence references
|
|
20
|
+
* leave it `undefined`.
|
|
21
|
+
*/
|
|
22
|
+
|
|
16
23
|
/**
|
|
17
24
|
* Configuration options for batch fetch operations
|
|
18
25
|
*/
|