@atlaskit/editor-synced-block-provider 6.2.6 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/providers/block-service/blockServiceAPI.js +10 -7
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +159 -19
- package/dist/es2019/providers/block-service/blockServiceAPI.js +8 -4
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +95 -2
- package/dist/esm/providers/block-service/blockServiceAPI.js +10 -7
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +159 -19
- package/dist/types/providers/types.d.ts +2 -1
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +15 -0
- package/dist/types-ts4.5/providers/types.d.ts +2 -1
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +15 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 6.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`943c90327ad3b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/943c90327ad3b) -
|
|
8
|
+
Add discardUnpublishedSyncBlocks action to clean up orphaned synced blocks when user cancels
|
|
9
|
+
editing. Fetches block statuses from the backend on editor init and deletes all blocks with
|
|
10
|
+
'unpublished' status on cancel.
|
|
11
|
+
|
|
3
12
|
## 6.2.6
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -54,7 +54,7 @@ var mapErrorResponseCode = function mapErrorResponseCode(errorCode) {
|
|
|
54
54
|
case 'NOT_FOUND':
|
|
55
55
|
return _types.SyncBlockError.NotFound;
|
|
56
56
|
case 'EntityNotFound':
|
|
57
|
-
return (0, _platformFeatureFlags.fg)('
|
|
57
|
+
return (0, _platformFeatureFlags.fg)('platform_synced_block_patch_10') ? _types.SyncBlockError.EntityNotFound : _types.SyncBlockError.Errored;
|
|
58
58
|
case 'INVALID_REQUEST':
|
|
59
59
|
return _types.SyncBlockError.InvalidRequest;
|
|
60
60
|
case 'CONFLICT':
|
|
@@ -1271,7 +1271,7 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
1271
1271
|
value: function () {
|
|
1272
1272
|
var _writeDataBatch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data) {
|
|
1273
1273
|
var _this3 = this;
|
|
1274
|
-
var stepVersion, blockAriToResourceIdMap, blocks, response, results,
|
|
1274
|
+
var stepVersion, blockAriToResourceIdMap, blocks, response, results, successBlocks, _iterator6, _step6, block, successBlock, errorResourceIds, _iterator7, _step7, _loop2;
|
|
1275
1275
|
return _regenerator.default.wrap(function _callee10$(_context12) {
|
|
1276
1276
|
while (1) switch (_context12.prev = _context12.next) {
|
|
1277
1277
|
case 0:
|
|
@@ -1321,17 +1321,20 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
1321
1321
|
response = _context12.sent;
|
|
1322
1322
|
results = []; // Process successful updates
|
|
1323
1323
|
if (response.success) {
|
|
1324
|
-
|
|
1325
|
-
return blockAriToResourceIdMap.get(block.blockAri);
|
|
1324
|
+
successBlocks = new Map(response.success.map(function (block) {
|
|
1325
|
+
return [blockAriToResourceIdMap.get(block.blockAri), block];
|
|
1326
1326
|
}));
|
|
1327
1327
|
_iterator6 = _createForOfIteratorHelper(data);
|
|
1328
1328
|
try {
|
|
1329
1329
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1330
1330
|
block = _step6.value;
|
|
1331
|
-
|
|
1332
|
-
|
|
1331
|
+
successBlock = successBlocks.get(block.resourceId);
|
|
1332
|
+
if (successBlock) {
|
|
1333
|
+
results.push(_objectSpread({
|
|
1333
1334
|
resourceId: block.resourceId
|
|
1334
|
-
})
|
|
1335
|
+
}, (0, _platformFeatureFlags.fg)('platform_synced_block_patch_10') && {
|
|
1336
|
+
status: successBlock.status
|
|
1337
|
+
}));
|
|
1335
1338
|
}
|
|
1336
1339
|
}
|
|
1337
1340
|
} catch (err) {
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.SourceSyncBlockStoreManager = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
10
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
12
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
@@ -18,6 +19,9 @@ var _types = require("../common/types");
|
|
|
18
19
|
var _errorHandling = require("../utils/errorHandling");
|
|
19
20
|
var _experienceTracking = require("../utils/experienceTracking");
|
|
20
21
|
var _utils = require("../utils/utils");
|
|
22
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
23
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
24
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
21
25
|
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; }
|
|
22
26
|
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; }
|
|
23
27
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
@@ -108,6 +112,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
108
112
|
isDirty: isDirty,
|
|
109
113
|
// if the change is from remote, it's not dirty
|
|
110
114
|
contentFragment: syncBlockNode.content
|
|
115
|
+
}, (0, _platformFeatureFlags.fg)('platform_synced_block_patch_10') && {
|
|
116
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
111
117
|
}));
|
|
112
118
|
} else {
|
|
113
119
|
var _syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
|
|
@@ -116,6 +122,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
116
122
|
}
|
|
117
123
|
this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, _syncBlockData), {}, {
|
|
118
124
|
isDirty: true
|
|
125
|
+
}, (0, _platformFeatureFlags.fg)('platform_synced_block_patch_10') && {
|
|
126
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
119
127
|
}));
|
|
120
128
|
}
|
|
121
129
|
return true;
|
|
@@ -214,6 +222,13 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
214
222
|
writeResults.forEach(function (result) {
|
|
215
223
|
if (result.resourceId && !result.error) {
|
|
216
224
|
var _this2$fireAnalyticsE;
|
|
225
|
+
// Update cache with the status returned from the backend
|
|
226
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_10')) {
|
|
227
|
+
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
228
|
+
if (cachedData && result.status) {
|
|
229
|
+
cachedData.status = result.status;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
217
232
|
(_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, (0, _errorHandling.updateSuccessPayload)(result.resourceId, false));
|
|
218
233
|
}
|
|
219
234
|
});
|
|
@@ -367,6 +382,14 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
367
382
|
if ((0, _platformFeatureFlags.fg)('platform_synced_block_update_refactor')) {
|
|
368
383
|
// add the node to the cache
|
|
369
384
|
this.updateSyncBlockData(node, false);
|
|
385
|
+
|
|
386
|
+
// Mark the block as unpublished in the cache so it can be cleaned up on cancel
|
|
387
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_10')) {
|
|
388
|
+
var cached = this.syncBlockCache.get(resourceId);
|
|
389
|
+
if (cached) {
|
|
390
|
+
cached.status = 'unpublished';
|
|
391
|
+
}
|
|
392
|
+
}
|
|
370
393
|
}
|
|
371
394
|
this.creationCompletionCallbacks.set(resourceId, onCompletion);
|
|
372
395
|
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 || _this$createExperienc.start({});
|
|
@@ -550,6 +573,123 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
550
573
|
}
|
|
551
574
|
|
|
552
575
|
/**
|
|
576
|
+
* Fetches the current status of all source sync blocks in the cache from the backend
|
|
577
|
+
* and updates the cache entries with the fetched status.
|
|
578
|
+
* This is called on editor init so we know which blocks are 'unpublished' vs 'active'.
|
|
579
|
+
*/
|
|
580
|
+
}, {
|
|
581
|
+
key: "fetchAndCacheStatuses",
|
|
582
|
+
value: (function () {
|
|
583
|
+
var _fetchAndCacheStatuses = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
584
|
+
var _this6 = this;
|
|
585
|
+
var sourceToReferenceMap, syncBlockNodes, results, _iterator, _step, _sourceToReferenceMap, _result$data, result, sourceResourceId, cached;
|
|
586
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
587
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
588
|
+
case 0:
|
|
589
|
+
if (!(!(0, _platformFeatureFlags.fg)('platform_synced_block_patch_10') || !this.dataProvider || this.syncBlockCache.size === 0)) {
|
|
590
|
+
_context4.next = 2;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
return _context4.abrupt("return");
|
|
594
|
+
case 2:
|
|
595
|
+
// Source blocks have plain UUID resourceIds, but fetchNodesData internally uses
|
|
596
|
+
// generateBlockAriFromReference which expects reference-format resourceIds
|
|
597
|
+
// (e.g. "confluence-page/pageId/uuid"). We convert source resourceIds to reference
|
|
598
|
+
// format before fetching, and maintain a mapping back to original resourceIds
|
|
599
|
+
// so we can update the correct cache entries.
|
|
600
|
+
sourceToReferenceMap = new Map();
|
|
601
|
+
syncBlockNodes = Array.from(this.syncBlockCache.entries()).map(function (_ref) {
|
|
602
|
+
var _this6$dataProvider$g, _this6$dataProvider;
|
|
603
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
604
|
+
resourceId = _ref2[0],
|
|
605
|
+
data = _ref2[1];
|
|
606
|
+
var referenceResourceId = (_this6$dataProvider$g = (_this6$dataProvider = _this6.dataProvider) === null || _this6$dataProvider === void 0 ? void 0 : _this6$dataProvider.generateResourceIdForReference(resourceId)) !== null && _this6$dataProvider$g !== void 0 ? _this6$dataProvider$g : resourceId;
|
|
607
|
+
sourceToReferenceMap.set(referenceResourceId, resourceId);
|
|
608
|
+
return {
|
|
609
|
+
type: 'bodiedSyncBlock',
|
|
610
|
+
attrs: {
|
|
611
|
+
localId: data.blockInstanceId,
|
|
612
|
+
resourceId: referenceResourceId
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
});
|
|
616
|
+
_context4.prev = 4;
|
|
617
|
+
_context4.next = 7;
|
|
618
|
+
return this.dataProvider.fetchNodesData(syncBlockNodes);
|
|
619
|
+
case 7:
|
|
620
|
+
results = _context4.sent;
|
|
621
|
+
_iterator = _createForOfIteratorHelper(results);
|
|
622
|
+
try {
|
|
623
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
624
|
+
result = _step.value;
|
|
625
|
+
// Map the reference resourceId back to the source resourceId
|
|
626
|
+
sourceResourceId = (_sourceToReferenceMap = sourceToReferenceMap.get(result.resourceId)) !== null && _sourceToReferenceMap !== void 0 ? _sourceToReferenceMap : result.resourceId;
|
|
627
|
+
cached = this.syncBlockCache.get(sourceResourceId);
|
|
628
|
+
if (cached && (_result$data = result.data) !== null && _result$data !== void 0 && _result$data.status) {
|
|
629
|
+
cached.status = result.data.status;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
} catch (err) {
|
|
633
|
+
_iterator.e(err);
|
|
634
|
+
} finally {
|
|
635
|
+
_iterator.f();
|
|
636
|
+
}
|
|
637
|
+
_context4.next = 14;
|
|
638
|
+
break;
|
|
639
|
+
case 12:
|
|
640
|
+
_context4.prev = 12;
|
|
641
|
+
_context4.t0 = _context4["catch"](4);
|
|
642
|
+
case 14:
|
|
643
|
+
case "end":
|
|
644
|
+
return _context4.stop();
|
|
645
|
+
}
|
|
646
|
+
}, _callee4, this, [[4, 12]]);
|
|
647
|
+
}));
|
|
648
|
+
function fetchAndCacheStatuses() {
|
|
649
|
+
return _fetchAndCacheStatuses.apply(this, arguments);
|
|
650
|
+
}
|
|
651
|
+
return fetchAndCacheStatuses;
|
|
652
|
+
}()
|
|
653
|
+
/**
|
|
654
|
+
* Deletes all source sync blocks that have 'unpublished' status.
|
|
655
|
+
* Used to clean up orphaned blocks when a user cancels editing without saving.
|
|
656
|
+
* Blocks that were already saved (status 'active') are not affected.
|
|
657
|
+
*
|
|
658
|
+
* @returns true if all deletions succeeded, false otherwise
|
|
659
|
+
*/
|
|
660
|
+
)
|
|
661
|
+
}, {
|
|
662
|
+
key: "discardUnpublishedBlocks",
|
|
663
|
+
value: function discardUnpublishedBlocks() {
|
|
664
|
+
if (!(0, _platformFeatureFlags.fg)('platform_synced_block_patch_10')) {
|
|
665
|
+
return Promise.resolve(true);
|
|
666
|
+
}
|
|
667
|
+
var unpublishedBlockIds = Array.from(this.syncBlockCache.entries()).filter(function (_ref3) {
|
|
668
|
+
var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
|
|
669
|
+
_ = _ref4[0],
|
|
670
|
+
data = _ref4[1];
|
|
671
|
+
return data.status === 'unpublished' && !data.pendingDeletion;
|
|
672
|
+
}).map(function (_ref5) {
|
|
673
|
+
var _ref6 = (0, _slicedToArray2.default)(_ref5, 2),
|
|
674
|
+
resourceId = _ref6[0],
|
|
675
|
+
data = _ref6[1];
|
|
676
|
+
return {
|
|
677
|
+
resourceId: resourceId,
|
|
678
|
+
localId: data.blockInstanceId
|
|
679
|
+
};
|
|
680
|
+
});
|
|
681
|
+
if (unpublishedBlockIds.length === 0) {
|
|
682
|
+
return Promise.resolve(true);
|
|
683
|
+
}
|
|
684
|
+
return this.delete(unpublishedBlockIds, function () {},
|
|
685
|
+
// onDelete: no-op, document is being discarded
|
|
686
|
+
function () {},
|
|
687
|
+
// onDeleteCompleted: no-op
|
|
688
|
+
'source-block-unpublished');
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Deletes sync blocks with confirmation from the backend
|
|
553
693
|
*
|
|
554
694
|
* @param syncBlockIds - The sync block ids to delete
|
|
555
695
|
* @param onDelete - The callback to delete sync block node from document
|
|
@@ -559,33 +699,33 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
559
699
|
}, {
|
|
560
700
|
key: "deleteSyncBlocksWithConfirmation",
|
|
561
701
|
value: (function () {
|
|
562
|
-
var _deleteSyncBlocksWithConfirmation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
702
|
+
var _deleteSyncBlocksWithConfirmation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(syncBlockIds, deletionReason, onDelete, onDeleteCompleted, destroyCallback) {
|
|
563
703
|
var confirmed, isDeleteSuccessful;
|
|
564
|
-
return _regenerator.default.wrap(function
|
|
565
|
-
while (1) switch (
|
|
704
|
+
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
705
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
566
706
|
case 0:
|
|
567
707
|
if (!(this.viewMode === 'view' && (0, _platformFeatureFlags.fg)('platform_synced_block_patch_8'))) {
|
|
568
|
-
|
|
708
|
+
_context5.next = 2;
|
|
569
709
|
break;
|
|
570
710
|
}
|
|
571
|
-
return
|
|
711
|
+
return _context5.abrupt("return", Promise.resolve());
|
|
572
712
|
case 2:
|
|
573
713
|
if (!this.confirmationCallback) {
|
|
574
|
-
|
|
714
|
+
_context5.next = 14;
|
|
575
715
|
break;
|
|
576
716
|
}
|
|
577
|
-
|
|
717
|
+
_context5.next = 5;
|
|
578
718
|
return this.confirmationCallback(syncBlockIds, deletionReason);
|
|
579
719
|
case 5:
|
|
580
|
-
confirmed =
|
|
720
|
+
confirmed = _context5.sent;
|
|
581
721
|
if (!confirmed) {
|
|
582
|
-
|
|
722
|
+
_context5.next = 13;
|
|
583
723
|
break;
|
|
584
724
|
}
|
|
585
|
-
|
|
725
|
+
_context5.next = 9;
|
|
586
726
|
return this.delete(syncBlockIds, onDelete, onDeleteCompleted, deletionReason);
|
|
587
727
|
case 9:
|
|
588
|
-
isDeleteSuccessful =
|
|
728
|
+
isDeleteSuccessful = _context5.sent;
|
|
589
729
|
if (!isDeleteSuccessful) {
|
|
590
730
|
// If deletion failed, save deletion info for potential retry
|
|
591
731
|
this.deletionRetryInfo = {
|
|
@@ -598,15 +738,15 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
598
738
|
} else {
|
|
599
739
|
destroyCallback();
|
|
600
740
|
}
|
|
601
|
-
|
|
741
|
+
_context5.next = 14;
|
|
602
742
|
break;
|
|
603
743
|
case 13:
|
|
604
744
|
destroyCallback();
|
|
605
745
|
case 14:
|
|
606
746
|
case "end":
|
|
607
|
-
return
|
|
747
|
+
return _context5.stop();
|
|
608
748
|
}
|
|
609
|
-
},
|
|
749
|
+
}, _callee5, this);
|
|
610
750
|
}));
|
|
611
751
|
function deleteSyncBlocksWithConfirmation(_x5, _x6, _x7, _x8, _x9) {
|
|
612
752
|
return _deleteSyncBlocksWithConfirmation.apply(this, arguments);
|
|
@@ -616,7 +756,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
616
756
|
}, {
|
|
617
757
|
key: "getSyncBlockSourceInfo",
|
|
618
758
|
value: function getSyncBlockSourceInfo(localId) {
|
|
619
|
-
var
|
|
759
|
+
var _this7 = this;
|
|
620
760
|
try {
|
|
621
761
|
var _this$fetchSourceInfo;
|
|
622
762
|
if (!this.dataProvider) {
|
|
@@ -625,13 +765,13 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
625
765
|
(_this$fetchSourceInfo = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo === void 0 || _this$fetchSourceInfo.start();
|
|
626
766
|
return this.dataProvider.fetchSyncBlockSourceInfo(localId, undefined, undefined).then(function (sourceInfo) {
|
|
627
767
|
if (!sourceInfo) {
|
|
628
|
-
var
|
|
629
|
-
(
|
|
768
|
+
var _this7$fetchSourceInf;
|
|
769
|
+
(_this7$fetchSourceInf = _this7.fetchSourceInfoExperience) === null || _this7$fetchSourceInf === void 0 || _this7$fetchSourceInf.failure({
|
|
630
770
|
reason: 'No source info returned'
|
|
631
771
|
});
|
|
632
772
|
} else {
|
|
633
|
-
var
|
|
634
|
-
(
|
|
773
|
+
var _this7$fetchSourceInf2;
|
|
774
|
+
(_this7$fetchSourceInf2 = _this7.fetchSourceInfoExperience) === null || _this7$fetchSourceInf2 === void 0 || _this7$fetchSourceInf2.success();
|
|
635
775
|
}
|
|
636
776
|
return sourceInfo;
|
|
637
777
|
});
|
|
@@ -37,7 +37,7 @@ const mapErrorResponseCode = errorCode => {
|
|
|
37
37
|
case 'NOT_FOUND':
|
|
38
38
|
return SyncBlockError.NotFound;
|
|
39
39
|
case 'EntityNotFound':
|
|
40
|
-
return fg('
|
|
40
|
+
return fg('platform_synced_block_patch_10') ? SyncBlockError.EntityNotFound : SyncBlockError.Errored;
|
|
41
41
|
case 'INVALID_REQUEST':
|
|
42
42
|
return SyncBlockError.InvalidRequest;
|
|
43
43
|
case 'CONFLICT':
|
|
@@ -861,11 +861,15 @@ class BlockServiceADFWriteProvider {
|
|
|
861
861
|
|
|
862
862
|
// Process successful updates
|
|
863
863
|
if (response.success) {
|
|
864
|
-
const
|
|
864
|
+
const successBlocks = new Map(response.success.map(block => [blockAriToResourceIdMap.get(block.blockAri), block]));
|
|
865
865
|
for (const block of data) {
|
|
866
|
-
|
|
866
|
+
const successBlock = successBlocks.get(block.resourceId);
|
|
867
|
+
if (successBlock) {
|
|
867
868
|
results.push({
|
|
868
|
-
resourceId: block.resourceId
|
|
869
|
+
resourceId: block.resourceId,
|
|
870
|
+
...(fg('platform_synced_block_patch_10') && {
|
|
871
|
+
status: successBlock.status
|
|
872
|
+
})
|
|
869
873
|
});
|
|
870
874
|
}
|
|
871
875
|
}
|
|
@@ -86,7 +86,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
86
86
|
...syncBlockData,
|
|
87
87
|
isDirty: isDirty,
|
|
88
88
|
// if the change is from remote, it's not dirty
|
|
89
|
-
contentFragment: syncBlockNode.content
|
|
89
|
+
contentFragment: syncBlockNode.content,
|
|
90
|
+
...(fg('platform_synced_block_patch_10') && {
|
|
91
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
92
|
+
})
|
|
90
93
|
});
|
|
91
94
|
} else {
|
|
92
95
|
const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
|
|
@@ -95,7 +98,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
95
98
|
}
|
|
96
99
|
this.syncBlockCache.set(resourceId, {
|
|
97
100
|
...syncBlockData,
|
|
98
|
-
isDirty: true
|
|
101
|
+
isDirty: true,
|
|
102
|
+
...(fg('platform_synced_block_patch_10') && {
|
|
103
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
104
|
+
})
|
|
99
105
|
});
|
|
100
106
|
}
|
|
101
107
|
return true;
|
|
@@ -172,6 +178,13 @@ export class SourceSyncBlockStoreManager {
|
|
|
172
178
|
writeResults.forEach(result => {
|
|
173
179
|
if (result.resourceId && !result.error) {
|
|
174
180
|
var _this$fireAnalyticsEv2;
|
|
181
|
+
// Update cache with the status returned from the backend
|
|
182
|
+
if (fg('platform_synced_block_patch_10')) {
|
|
183
|
+
const cachedData = this.syncBlockCache.get(result.resourceId);
|
|
184
|
+
if (cachedData && result.status) {
|
|
185
|
+
cachedData.status = result.status;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
175
188
|
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 ? void 0 : _this$fireAnalyticsEv2.call(this, updateSuccessPayload(result.resourceId, false));
|
|
176
189
|
}
|
|
177
190
|
});
|
|
@@ -296,6 +309,14 @@ export class SourceSyncBlockStoreManager {
|
|
|
296
309
|
if (fg('platform_synced_block_update_refactor')) {
|
|
297
310
|
// add the node to the cache
|
|
298
311
|
this.updateSyncBlockData(node, false);
|
|
312
|
+
|
|
313
|
+
// Mark the block as unpublished in the cache so it can be cleaned up on cancel
|
|
314
|
+
if (fg('platform_synced_block_patch_10')) {
|
|
315
|
+
const cached = this.syncBlockCache.get(resourceId);
|
|
316
|
+
if (cached) {
|
|
317
|
+
cached.status = 'unpublished';
|
|
318
|
+
}
|
|
319
|
+
}
|
|
299
320
|
}
|
|
300
321
|
this.creationCompletionCallbacks.set(resourceId, onCompletion);
|
|
301
322
|
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 ? void 0 : _this$createExperienc.start({});
|
|
@@ -424,6 +445,78 @@ export class SourceSyncBlockStoreManager {
|
|
|
424
445
|
}
|
|
425
446
|
|
|
426
447
|
/**
|
|
448
|
+
* Fetches the current status of all source sync blocks in the cache from the backend
|
|
449
|
+
* and updates the cache entries with the fetched status.
|
|
450
|
+
* This is called on editor init so we know which blocks are 'unpublished' vs 'active'.
|
|
451
|
+
*/
|
|
452
|
+
async fetchAndCacheStatuses() {
|
|
453
|
+
if (!fg('platform_synced_block_patch_10') || !this.dataProvider || this.syncBlockCache.size === 0) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Source blocks have plain UUID resourceIds, but fetchNodesData internally uses
|
|
458
|
+
// generateBlockAriFromReference which expects reference-format resourceIds
|
|
459
|
+
// (e.g. "confluence-page/pageId/uuid"). We convert source resourceIds to reference
|
|
460
|
+
// format before fetching, and maintain a mapping back to original resourceIds
|
|
461
|
+
// so we can update the correct cache entries.
|
|
462
|
+
const sourceToReferenceMap = new Map();
|
|
463
|
+
const syncBlockNodes = Array.from(this.syncBlockCache.entries()).map(([resourceId, data]) => {
|
|
464
|
+
var _this$dataProvider$ge, _this$dataProvider;
|
|
465
|
+
const referenceResourceId = (_this$dataProvider$ge = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.generateResourceIdForReference(resourceId)) !== null && _this$dataProvider$ge !== void 0 ? _this$dataProvider$ge : resourceId;
|
|
466
|
+
sourceToReferenceMap.set(referenceResourceId, resourceId);
|
|
467
|
+
return {
|
|
468
|
+
type: 'bodiedSyncBlock',
|
|
469
|
+
attrs: {
|
|
470
|
+
localId: data.blockInstanceId,
|
|
471
|
+
resourceId: referenceResourceId
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
});
|
|
475
|
+
try {
|
|
476
|
+
const results = await this.dataProvider.fetchNodesData(syncBlockNodes);
|
|
477
|
+
for (const result of results) {
|
|
478
|
+
var _sourceToReferenceMap, _result$data;
|
|
479
|
+
// Map the reference resourceId back to the source resourceId
|
|
480
|
+
const sourceResourceId = (_sourceToReferenceMap = sourceToReferenceMap.get(result.resourceId)) !== null && _sourceToReferenceMap !== void 0 ? _sourceToReferenceMap : result.resourceId;
|
|
481
|
+
const cached = this.syncBlockCache.get(sourceResourceId);
|
|
482
|
+
if (cached && (_result$data = result.data) !== null && _result$data !== void 0 && _result$data.status) {
|
|
483
|
+
cached.status = result.data.status;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
} catch {
|
|
487
|
+
// If the fetch fails, statuses remain undefined.
|
|
488
|
+
// This is acceptable — on cancel, blocks without a known status
|
|
489
|
+
// will not be deleted (safe default).
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Deletes all source sync blocks that have 'unpublished' status.
|
|
495
|
+
* Used to clean up orphaned blocks when a user cancels editing without saving.
|
|
496
|
+
* Blocks that were already saved (status 'active') are not affected.
|
|
497
|
+
*
|
|
498
|
+
* @returns true if all deletions succeeded, false otherwise
|
|
499
|
+
*/
|
|
500
|
+
discardUnpublishedBlocks() {
|
|
501
|
+
if (!fg('platform_synced_block_patch_10')) {
|
|
502
|
+
return Promise.resolve(true);
|
|
503
|
+
}
|
|
504
|
+
const unpublishedBlockIds = Array.from(this.syncBlockCache.entries()).filter(([_, data]) => data.status === 'unpublished' && !data.pendingDeletion).map(([resourceId, data]) => ({
|
|
505
|
+
resourceId,
|
|
506
|
+
localId: data.blockInstanceId
|
|
507
|
+
}));
|
|
508
|
+
if (unpublishedBlockIds.length === 0) {
|
|
509
|
+
return Promise.resolve(true);
|
|
510
|
+
}
|
|
511
|
+
return this.delete(unpublishedBlockIds, () => {},
|
|
512
|
+
// onDelete: no-op, document is being discarded
|
|
513
|
+
() => {},
|
|
514
|
+
// onDeleteCompleted: no-op
|
|
515
|
+
'source-block-unpublished');
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Deletes sync blocks with confirmation from the backend
|
|
427
520
|
*
|
|
428
521
|
* @param syncBlockIds - The sync block ids to delete
|
|
429
522
|
* @param onDelete - The callback to delete sync block node from document
|
|
@@ -48,7 +48,7 @@ var mapErrorResponseCode = function mapErrorResponseCode(errorCode) {
|
|
|
48
48
|
case 'NOT_FOUND':
|
|
49
49
|
return SyncBlockError.NotFound;
|
|
50
50
|
case 'EntityNotFound':
|
|
51
|
-
return fg('
|
|
51
|
+
return fg('platform_synced_block_patch_10') ? SyncBlockError.EntityNotFound : SyncBlockError.Errored;
|
|
52
52
|
case 'INVALID_REQUEST':
|
|
53
53
|
return SyncBlockError.InvalidRequest;
|
|
54
54
|
case 'CONFLICT':
|
|
@@ -1266,7 +1266,7 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
1266
1266
|
value: function () {
|
|
1267
1267
|
var _writeDataBatch = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10(data) {
|
|
1268
1268
|
var _this3 = this;
|
|
1269
|
-
var stepVersion, blockAriToResourceIdMap, blocks, response, results,
|
|
1269
|
+
var stepVersion, blockAriToResourceIdMap, blocks, response, results, successBlocks, _iterator6, _step6, block, successBlock, errorResourceIds, _iterator7, _step7, _loop2;
|
|
1270
1270
|
return _regeneratorRuntime.wrap(function _callee10$(_context12) {
|
|
1271
1271
|
while (1) switch (_context12.prev = _context12.next) {
|
|
1272
1272
|
case 0:
|
|
@@ -1316,17 +1316,20 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
1316
1316
|
response = _context12.sent;
|
|
1317
1317
|
results = []; // Process successful updates
|
|
1318
1318
|
if (response.success) {
|
|
1319
|
-
|
|
1320
|
-
return blockAriToResourceIdMap.get(block.blockAri);
|
|
1319
|
+
successBlocks = new Map(response.success.map(function (block) {
|
|
1320
|
+
return [blockAriToResourceIdMap.get(block.blockAri), block];
|
|
1321
1321
|
}));
|
|
1322
1322
|
_iterator6 = _createForOfIteratorHelper(data);
|
|
1323
1323
|
try {
|
|
1324
1324
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1325
1325
|
block = _step6.value;
|
|
1326
|
-
|
|
1327
|
-
|
|
1326
|
+
successBlock = successBlocks.get(block.resourceId);
|
|
1327
|
+
if (successBlock) {
|
|
1328
|
+
results.push(_objectSpread({
|
|
1328
1329
|
resourceId: block.resourceId
|
|
1329
|
-
})
|
|
1330
|
+
}, fg('platform_synced_block_patch_10') && {
|
|
1331
|
+
status: successBlock.status
|
|
1332
|
+
}));
|
|
1330
1333
|
}
|
|
1331
1334
|
}
|
|
1332
1335
|
} catch (err) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
3
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
4
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
5
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
6
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
7
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
8
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
9
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
6
10
|
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; }
|
|
7
11
|
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; }
|
|
@@ -101,6 +105,8 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
101
105
|
isDirty: isDirty,
|
|
102
106
|
// if the change is from remote, it's not dirty
|
|
103
107
|
contentFragment: syncBlockNode.content
|
|
108
|
+
}, fg('platform_synced_block_patch_10') && {
|
|
109
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
104
110
|
}));
|
|
105
111
|
} else {
|
|
106
112
|
var _syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
|
|
@@ -109,6 +115,8 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
109
115
|
}
|
|
110
116
|
this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, _syncBlockData), {}, {
|
|
111
117
|
isDirty: true
|
|
118
|
+
}, fg('platform_synced_block_patch_10') && {
|
|
119
|
+
status: cachedBlock === null || cachedBlock === void 0 ? void 0 : cachedBlock.status
|
|
112
120
|
}));
|
|
113
121
|
}
|
|
114
122
|
return true;
|
|
@@ -207,6 +215,13 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
207
215
|
writeResults.forEach(function (result) {
|
|
208
216
|
if (result.resourceId && !result.error) {
|
|
209
217
|
var _this2$fireAnalyticsE;
|
|
218
|
+
// Update cache with the status returned from the backend
|
|
219
|
+
if (fg('platform_synced_block_patch_10')) {
|
|
220
|
+
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
221
|
+
if (cachedData && result.status) {
|
|
222
|
+
cachedData.status = result.status;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
210
225
|
(_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, updateSuccessPayload(result.resourceId, false));
|
|
211
226
|
}
|
|
212
227
|
});
|
|
@@ -360,6 +375,14 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
360
375
|
if (fg('platform_synced_block_update_refactor')) {
|
|
361
376
|
// add the node to the cache
|
|
362
377
|
this.updateSyncBlockData(node, false);
|
|
378
|
+
|
|
379
|
+
// Mark the block as unpublished in the cache so it can be cleaned up on cancel
|
|
380
|
+
if (fg('platform_synced_block_patch_10')) {
|
|
381
|
+
var cached = this.syncBlockCache.get(resourceId);
|
|
382
|
+
if (cached) {
|
|
383
|
+
cached.status = 'unpublished';
|
|
384
|
+
}
|
|
385
|
+
}
|
|
363
386
|
}
|
|
364
387
|
this.creationCompletionCallbacks.set(resourceId, onCompletion);
|
|
365
388
|
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 || _this$createExperienc.start({});
|
|
@@ -543,6 +566,123 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
543
566
|
}
|
|
544
567
|
|
|
545
568
|
/**
|
|
569
|
+
* Fetches the current status of all source sync blocks in the cache from the backend
|
|
570
|
+
* and updates the cache entries with the fetched status.
|
|
571
|
+
* This is called on editor init so we know which blocks are 'unpublished' vs 'active'.
|
|
572
|
+
*/
|
|
573
|
+
}, {
|
|
574
|
+
key: "fetchAndCacheStatuses",
|
|
575
|
+
value: (function () {
|
|
576
|
+
var _fetchAndCacheStatuses = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
577
|
+
var _this6 = this;
|
|
578
|
+
var sourceToReferenceMap, syncBlockNodes, results, _iterator, _step, _sourceToReferenceMap, _result$data, result, sourceResourceId, cached;
|
|
579
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
580
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
581
|
+
case 0:
|
|
582
|
+
if (!(!fg('platform_synced_block_patch_10') || !this.dataProvider || this.syncBlockCache.size === 0)) {
|
|
583
|
+
_context4.next = 2;
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
return _context4.abrupt("return");
|
|
587
|
+
case 2:
|
|
588
|
+
// Source blocks have plain UUID resourceIds, but fetchNodesData internally uses
|
|
589
|
+
// generateBlockAriFromReference which expects reference-format resourceIds
|
|
590
|
+
// (e.g. "confluence-page/pageId/uuid"). We convert source resourceIds to reference
|
|
591
|
+
// format before fetching, and maintain a mapping back to original resourceIds
|
|
592
|
+
// so we can update the correct cache entries.
|
|
593
|
+
sourceToReferenceMap = new Map();
|
|
594
|
+
syncBlockNodes = Array.from(this.syncBlockCache.entries()).map(function (_ref) {
|
|
595
|
+
var _this6$dataProvider$g, _this6$dataProvider;
|
|
596
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
597
|
+
resourceId = _ref2[0],
|
|
598
|
+
data = _ref2[1];
|
|
599
|
+
var referenceResourceId = (_this6$dataProvider$g = (_this6$dataProvider = _this6.dataProvider) === null || _this6$dataProvider === void 0 ? void 0 : _this6$dataProvider.generateResourceIdForReference(resourceId)) !== null && _this6$dataProvider$g !== void 0 ? _this6$dataProvider$g : resourceId;
|
|
600
|
+
sourceToReferenceMap.set(referenceResourceId, resourceId);
|
|
601
|
+
return {
|
|
602
|
+
type: 'bodiedSyncBlock',
|
|
603
|
+
attrs: {
|
|
604
|
+
localId: data.blockInstanceId,
|
|
605
|
+
resourceId: referenceResourceId
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
});
|
|
609
|
+
_context4.prev = 4;
|
|
610
|
+
_context4.next = 7;
|
|
611
|
+
return this.dataProvider.fetchNodesData(syncBlockNodes);
|
|
612
|
+
case 7:
|
|
613
|
+
results = _context4.sent;
|
|
614
|
+
_iterator = _createForOfIteratorHelper(results);
|
|
615
|
+
try {
|
|
616
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
617
|
+
result = _step.value;
|
|
618
|
+
// Map the reference resourceId back to the source resourceId
|
|
619
|
+
sourceResourceId = (_sourceToReferenceMap = sourceToReferenceMap.get(result.resourceId)) !== null && _sourceToReferenceMap !== void 0 ? _sourceToReferenceMap : result.resourceId;
|
|
620
|
+
cached = this.syncBlockCache.get(sourceResourceId);
|
|
621
|
+
if (cached && (_result$data = result.data) !== null && _result$data !== void 0 && _result$data.status) {
|
|
622
|
+
cached.status = result.data.status;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
} catch (err) {
|
|
626
|
+
_iterator.e(err);
|
|
627
|
+
} finally {
|
|
628
|
+
_iterator.f();
|
|
629
|
+
}
|
|
630
|
+
_context4.next = 14;
|
|
631
|
+
break;
|
|
632
|
+
case 12:
|
|
633
|
+
_context4.prev = 12;
|
|
634
|
+
_context4.t0 = _context4["catch"](4);
|
|
635
|
+
case 14:
|
|
636
|
+
case "end":
|
|
637
|
+
return _context4.stop();
|
|
638
|
+
}
|
|
639
|
+
}, _callee4, this, [[4, 12]]);
|
|
640
|
+
}));
|
|
641
|
+
function fetchAndCacheStatuses() {
|
|
642
|
+
return _fetchAndCacheStatuses.apply(this, arguments);
|
|
643
|
+
}
|
|
644
|
+
return fetchAndCacheStatuses;
|
|
645
|
+
}()
|
|
646
|
+
/**
|
|
647
|
+
* Deletes all source sync blocks that have 'unpublished' status.
|
|
648
|
+
* Used to clean up orphaned blocks when a user cancels editing without saving.
|
|
649
|
+
* Blocks that were already saved (status 'active') are not affected.
|
|
650
|
+
*
|
|
651
|
+
* @returns true if all deletions succeeded, false otherwise
|
|
652
|
+
*/
|
|
653
|
+
)
|
|
654
|
+
}, {
|
|
655
|
+
key: "discardUnpublishedBlocks",
|
|
656
|
+
value: function discardUnpublishedBlocks() {
|
|
657
|
+
if (!fg('platform_synced_block_patch_10')) {
|
|
658
|
+
return Promise.resolve(true);
|
|
659
|
+
}
|
|
660
|
+
var unpublishedBlockIds = Array.from(this.syncBlockCache.entries()).filter(function (_ref3) {
|
|
661
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
662
|
+
_ = _ref4[0],
|
|
663
|
+
data = _ref4[1];
|
|
664
|
+
return data.status === 'unpublished' && !data.pendingDeletion;
|
|
665
|
+
}).map(function (_ref5) {
|
|
666
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
667
|
+
resourceId = _ref6[0],
|
|
668
|
+
data = _ref6[1];
|
|
669
|
+
return {
|
|
670
|
+
resourceId: resourceId,
|
|
671
|
+
localId: data.blockInstanceId
|
|
672
|
+
};
|
|
673
|
+
});
|
|
674
|
+
if (unpublishedBlockIds.length === 0) {
|
|
675
|
+
return Promise.resolve(true);
|
|
676
|
+
}
|
|
677
|
+
return this.delete(unpublishedBlockIds, function () {},
|
|
678
|
+
// onDelete: no-op, document is being discarded
|
|
679
|
+
function () {},
|
|
680
|
+
// onDeleteCompleted: no-op
|
|
681
|
+
'source-block-unpublished');
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Deletes sync blocks with confirmation from the backend
|
|
546
686
|
*
|
|
547
687
|
* @param syncBlockIds - The sync block ids to delete
|
|
548
688
|
* @param onDelete - The callback to delete sync block node from document
|
|
@@ -552,33 +692,33 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
552
692
|
}, {
|
|
553
693
|
key: "deleteSyncBlocksWithConfirmation",
|
|
554
694
|
value: (function () {
|
|
555
|
-
var _deleteSyncBlocksWithConfirmation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
695
|
+
var _deleteSyncBlocksWithConfirmation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(syncBlockIds, deletionReason, onDelete, onDeleteCompleted, destroyCallback) {
|
|
556
696
|
var confirmed, isDeleteSuccessful;
|
|
557
|
-
return _regeneratorRuntime.wrap(function
|
|
558
|
-
while (1) switch (
|
|
697
|
+
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
698
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
559
699
|
case 0:
|
|
560
700
|
if (!(this.viewMode === 'view' && fg('platform_synced_block_patch_8'))) {
|
|
561
|
-
|
|
701
|
+
_context5.next = 2;
|
|
562
702
|
break;
|
|
563
703
|
}
|
|
564
|
-
return
|
|
704
|
+
return _context5.abrupt("return", Promise.resolve());
|
|
565
705
|
case 2:
|
|
566
706
|
if (!this.confirmationCallback) {
|
|
567
|
-
|
|
707
|
+
_context5.next = 14;
|
|
568
708
|
break;
|
|
569
709
|
}
|
|
570
|
-
|
|
710
|
+
_context5.next = 5;
|
|
571
711
|
return this.confirmationCallback(syncBlockIds, deletionReason);
|
|
572
712
|
case 5:
|
|
573
|
-
confirmed =
|
|
713
|
+
confirmed = _context5.sent;
|
|
574
714
|
if (!confirmed) {
|
|
575
|
-
|
|
715
|
+
_context5.next = 13;
|
|
576
716
|
break;
|
|
577
717
|
}
|
|
578
|
-
|
|
718
|
+
_context5.next = 9;
|
|
579
719
|
return this.delete(syncBlockIds, onDelete, onDeleteCompleted, deletionReason);
|
|
580
720
|
case 9:
|
|
581
|
-
isDeleteSuccessful =
|
|
721
|
+
isDeleteSuccessful = _context5.sent;
|
|
582
722
|
if (!isDeleteSuccessful) {
|
|
583
723
|
// If deletion failed, save deletion info for potential retry
|
|
584
724
|
this.deletionRetryInfo = {
|
|
@@ -591,15 +731,15 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
591
731
|
} else {
|
|
592
732
|
destroyCallback();
|
|
593
733
|
}
|
|
594
|
-
|
|
734
|
+
_context5.next = 14;
|
|
595
735
|
break;
|
|
596
736
|
case 13:
|
|
597
737
|
destroyCallback();
|
|
598
738
|
case 14:
|
|
599
739
|
case "end":
|
|
600
|
-
return
|
|
740
|
+
return _context5.stop();
|
|
601
741
|
}
|
|
602
|
-
},
|
|
742
|
+
}, _callee5, this);
|
|
603
743
|
}));
|
|
604
744
|
function deleteSyncBlocksWithConfirmation(_x5, _x6, _x7, _x8, _x9) {
|
|
605
745
|
return _deleteSyncBlocksWithConfirmation.apply(this, arguments);
|
|
@@ -609,7 +749,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
609
749
|
}, {
|
|
610
750
|
key: "getSyncBlockSourceInfo",
|
|
611
751
|
value: function getSyncBlockSourceInfo(localId) {
|
|
612
|
-
var
|
|
752
|
+
var _this7 = this;
|
|
613
753
|
try {
|
|
614
754
|
var _this$fetchSourceInfo;
|
|
615
755
|
if (!this.dataProvider) {
|
|
@@ -618,13 +758,13 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
618
758
|
(_this$fetchSourceInfo = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo === void 0 || _this$fetchSourceInfo.start();
|
|
619
759
|
return this.dataProvider.fetchSyncBlockSourceInfo(localId, undefined, undefined).then(function (sourceInfo) {
|
|
620
760
|
if (!sourceInfo) {
|
|
621
|
-
var
|
|
622
|
-
(
|
|
761
|
+
var _this7$fetchSourceInf;
|
|
762
|
+
(_this7$fetchSourceInf = _this7.fetchSourceInfoExperience) === null || _this7$fetchSourceInf === void 0 || _this7$fetchSourceInf.failure({
|
|
623
763
|
reason: 'No source info returned'
|
|
624
764
|
});
|
|
625
765
|
} else {
|
|
626
|
-
var
|
|
627
|
-
(
|
|
766
|
+
var _this7$fetchSourceInf2;
|
|
767
|
+
(_this7$fetchSourceInf2 = _this7.fetchSourceInfoExperience) === null || _this7$fetchSourceInf2 === void 0 || _this7$fetchSourceInf2.success();
|
|
628
768
|
}
|
|
629
769
|
return sourceInfo;
|
|
630
770
|
});
|
|
@@ -3,7 +3,7 @@ import type { EmojiProvider } from '@atlaskit/emoji';
|
|
|
3
3
|
import type { MentionProvider } from '@atlaskit/mention/types';
|
|
4
4
|
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
5
5
|
import type { TaskDecisionProvider } from '@atlaskit/task-decision/types';
|
|
6
|
-
import type { SyncBlockData, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId, SyncBlockAttrs, ReferenceSyncBlockData, DeletionReason } from '../common/types';
|
|
6
|
+
import type { SyncBlockData, SyncBlockStatus, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId, SyncBlockAttrs, ReferenceSyncBlockData, DeletionReason } from '../common/types';
|
|
7
7
|
type SyncBlockErrorInfo = {
|
|
8
8
|
reason?: string;
|
|
9
9
|
sourceAri?: string;
|
|
@@ -48,6 +48,7 @@ export type SyncBlockParentInfo = {
|
|
|
48
48
|
export type WriteSyncBlockResult = {
|
|
49
49
|
error?: string;
|
|
50
50
|
resourceId?: ResourceId;
|
|
51
|
+
status?: SyncBlockStatus;
|
|
51
52
|
};
|
|
52
53
|
export type SourceInfoFetchData = {
|
|
53
54
|
pageARI: string;
|
|
@@ -68,6 +68,21 @@ export declare class SourceSyncBlockStoreManager {
|
|
|
68
68
|
retryDeletion(): Promise<void>;
|
|
69
69
|
clearPendingDeletion(): void;
|
|
70
70
|
/**
|
|
71
|
+
* Fetches the current status of all source sync blocks in the cache from the backend
|
|
72
|
+
* and updates the cache entries with the fetched status.
|
|
73
|
+
* This is called on editor init so we know which blocks are 'unpublished' vs 'active'.
|
|
74
|
+
*/
|
|
75
|
+
fetchAndCacheStatuses(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Deletes all source sync blocks that have 'unpublished' status.
|
|
78
|
+
* Used to clean up orphaned blocks when a user cancels editing without saving.
|
|
79
|
+
* Blocks that were already saved (status 'active') are not affected.
|
|
80
|
+
*
|
|
81
|
+
* @returns true if all deletions succeeded, false otherwise
|
|
82
|
+
*/
|
|
83
|
+
discardUnpublishedBlocks(): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Deletes sync blocks with confirmation from the backend
|
|
71
86
|
*
|
|
72
87
|
* @param syncBlockIds - The sync block ids to delete
|
|
73
88
|
* @param onDelete - The callback to delete sync block node from document
|
|
@@ -3,7 +3,7 @@ import type { EmojiProvider } from '@atlaskit/emoji';
|
|
|
3
3
|
import type { MentionProvider } from '@atlaskit/mention/types';
|
|
4
4
|
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
5
5
|
import type { TaskDecisionProvider } from '@atlaskit/task-decision/types';
|
|
6
|
-
import type { SyncBlockData, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId, SyncBlockAttrs, ReferenceSyncBlockData, DeletionReason } from '../common/types';
|
|
6
|
+
import type { SyncBlockData, SyncBlockStatus, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId, SyncBlockAttrs, ReferenceSyncBlockData, DeletionReason } from '../common/types';
|
|
7
7
|
type SyncBlockErrorInfo = {
|
|
8
8
|
reason?: string;
|
|
9
9
|
sourceAri?: string;
|
|
@@ -48,6 +48,7 @@ export type SyncBlockParentInfo = {
|
|
|
48
48
|
export type WriteSyncBlockResult = {
|
|
49
49
|
error?: string;
|
|
50
50
|
resourceId?: ResourceId;
|
|
51
|
+
status?: SyncBlockStatus;
|
|
51
52
|
};
|
|
52
53
|
export type SourceInfoFetchData = {
|
|
53
54
|
pageARI: string;
|
|
@@ -68,6 +68,21 @@ export declare class SourceSyncBlockStoreManager {
|
|
|
68
68
|
retryDeletion(): Promise<void>;
|
|
69
69
|
clearPendingDeletion(): void;
|
|
70
70
|
/**
|
|
71
|
+
* Fetches the current status of all source sync blocks in the cache from the backend
|
|
72
|
+
* and updates the cache entries with the fetched status.
|
|
73
|
+
* This is called on editor init so we know which blocks are 'unpublished' vs 'active'.
|
|
74
|
+
*/
|
|
75
|
+
fetchAndCacheStatuses(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Deletes all source sync blocks that have 'unpublished' status.
|
|
78
|
+
* Used to clean up orphaned blocks when a user cancels editing without saving.
|
|
79
|
+
* Blocks that were already saved (status 'active') are not affected.
|
|
80
|
+
*
|
|
81
|
+
* @returns true if all deletions succeeded, false otherwise
|
|
82
|
+
*/
|
|
83
|
+
discardUnpublishedBlocks(): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Deletes sync blocks with confirmation from the backend
|
|
71
86
|
*
|
|
72
87
|
* @param syncBlockIds - The sync block ids to delete
|
|
73
88
|
* @param onDelete - The callback to delete sync block node from document
|
package/package.json
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
30
30
|
"@atlaskit/node-data-provider": "^11.0.0",
|
|
31
31
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
32
|
-
"@atlaskit/tmp-editor-statsig": "^72.
|
|
32
|
+
"@atlaskit/tmp-editor-statsig": "^72.2.0",
|
|
33
33
|
"@babel/runtime": "^7.0.0",
|
|
34
34
|
"@compiled/react": "^0.20.0",
|
|
35
35
|
"graphql-ws": "^5.14.2",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"name": "@atlaskit/editor-synced-block-provider",
|
|
84
|
-
"version": "6.
|
|
84
|
+
"version": "6.3.0",
|
|
85
85
|
"description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
|
|
86
86
|
"author": "Atlassian Pty Ltd",
|
|
87
87
|
"license": "Apache-2.0",
|
|
@@ -98,6 +98,9 @@
|
|
|
98
98
|
"platform_synced_block_patch_9": {
|
|
99
99
|
"type": "boolean"
|
|
100
100
|
},
|
|
101
|
+
"platform_synced_block_patch_10": {
|
|
102
|
+
"type": "boolean"
|
|
103
|
+
},
|
|
101
104
|
"platform_synced_block_add_info_web_socket_error": {
|
|
102
105
|
"type": "boolean"
|
|
103
106
|
}
|