@atlaskit/editor-plugin-synced-block 5.3.13 → 5.3.15
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 +16 -0
- package/dist/cjs/editor-commands/index.js +7 -5
- package/dist/cjs/pm-plugins/main.js +87 -25
- package/dist/cjs/pm-plugins/utils/handle-bodied-sync-block-creation.js +141 -0
- package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +1 -0
- package/dist/cjs/syncedBlockPlugin.js +4 -2
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/ui/DeleteConfirmationModal.js +18 -1
- package/dist/cjs/ui/Flag.js +5 -1
- package/dist/cjs/ui/floating-toolbar.js +3 -0
- package/dist/es2019/editor-commands/index.js +7 -5
- package/dist/es2019/pm-plugins/main.js +67 -17
- package/dist/es2019/pm-plugins/utils/handle-bodied-sync-block-creation.js +134 -0
- package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +1 -0
- package/dist/es2019/syncedBlockPlugin.js +4 -2
- package/dist/es2019/types/index.js +1 -0
- package/dist/es2019/ui/DeleteConfirmationModal.js +18 -1
- package/dist/es2019/ui/Flag.js +5 -0
- package/dist/es2019/ui/floating-toolbar.js +3 -0
- package/dist/esm/editor-commands/index.js +7 -5
- package/dist/esm/pm-plugins/main.js +87 -25
- package/dist/esm/pm-plugins/utils/handle-bodied-sync-block-creation.js +134 -0
- package/dist/esm/pm-plugins/utils/track-sync-blocks.js +1 -0
- package/dist/esm/syncedBlockPlugin.js +4 -2
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/ui/DeleteConfirmationModal.js +18 -1
- package/dist/esm/ui/Flag.js +5 -1
- package/dist/esm/ui/floating-toolbar.js +3 -0
- package/dist/types/pm-plugins/main.d.ts +2 -1
- package/dist/types/pm-plugins/utils/handle-bodied-sync-block-creation.d.ts +9 -0
- package/dist/types/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +2 -2
- package/dist/types/types/index.d.ts +19 -1
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/utils/handle-bodied-sync-block-creation.d.ts +9 -0
- package/dist/types-ts4.5/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +2 -2
- package/dist/types-ts4.5/types/index.d.ts +19 -1
- package/package.json +4 -1
|
@@ -7,15 +7,39 @@ import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
|
7
7
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
8
8
|
import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
9
9
|
import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
|
|
10
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
11
|
import { lazyBodiedSyncBlockView } from '../nodeviews/bodiedLazySyncedBlock';
|
|
11
12
|
import { SyncBlock as SyncBlockView } from '../nodeviews/syncedBlock';
|
|
12
13
|
import { FLAG_ID } from '../types';
|
|
14
|
+
import { handleBodiedSyncBlockCreation } from './utils/handle-bodied-sync-block-creation';
|
|
13
15
|
import { handleBodiedSyncBlockRemoval } from './utils/handle-bodied-sync-block-removal';
|
|
14
16
|
import { shouldIgnoreDomEvent } from './utils/ignore-dom-event';
|
|
15
17
|
import { calculateDecorations } from './utils/selection-decorations';
|
|
16
18
|
import { hasEditInSyncBlock, trackSyncBlocks } from './utils/track-sync-blocks';
|
|
17
19
|
import { sliceFullyContainsNode } from './utils/utils';
|
|
18
20
|
export const syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
|
|
21
|
+
const mapRetryCreationPosMap = (oldMap, newRetryCreationPos, mapPos) => {
|
|
22
|
+
const resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
|
|
23
|
+
const newMap = new Map(oldMap);
|
|
24
|
+
if (resourceId) {
|
|
25
|
+
const pos = newRetryCreationPos.pos;
|
|
26
|
+
if (!pos) {
|
|
27
|
+
newMap.delete(resourceId);
|
|
28
|
+
} else {
|
|
29
|
+
newMap.set(resourceId, pos);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (newMap.size === 0) {
|
|
33
|
+
return newMap;
|
|
34
|
+
}
|
|
35
|
+
for (const [id, pos] of newMap.entries()) {
|
|
36
|
+
newMap.set(id, {
|
|
37
|
+
from: mapPos(pos.from),
|
|
38
|
+
to: mapPos(pos.to)
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return newMap;
|
|
42
|
+
};
|
|
19
43
|
const showCopiedFlag = api => {
|
|
20
44
|
// Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
|
|
21
45
|
setTimeout(() => {
|
|
@@ -77,7 +101,8 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
77
101
|
return {
|
|
78
102
|
selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
|
|
79
103
|
activeFlag: false,
|
|
80
|
-
syncBlockStore: syncBlockStore
|
|
104
|
+
syncBlockStore: syncBlockStore,
|
|
105
|
+
retryCreationPosMap: new Map()
|
|
81
106
|
};
|
|
82
107
|
},
|
|
83
108
|
apply: (tr, currentPluginState, oldEditorState) => {
|
|
@@ -86,16 +111,23 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
86
111
|
const {
|
|
87
112
|
activeFlag,
|
|
88
113
|
selectionDecorationSet,
|
|
89
|
-
bodiedSyncBlockDeletionStatus
|
|
114
|
+
bodiedSyncBlockDeletionStatus,
|
|
115
|
+
retryCreationPosMap
|
|
90
116
|
} = currentPluginState;
|
|
91
117
|
let newDecorationSet = selectionDecorationSet.map(tr.mapping, tr.doc);
|
|
92
118
|
if (!tr.selection.eq(oldEditorState.selection)) {
|
|
93
119
|
newDecorationSet = calculateDecorations(tr.doc, tr.selection, tr.doc.type.schema);
|
|
94
120
|
}
|
|
121
|
+
let newRetryCreationPosMap = retryCreationPosMap;
|
|
122
|
+
if (fg('platform_synced_block_patch_1')) {
|
|
123
|
+
const newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
124
|
+
newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
125
|
+
}
|
|
95
126
|
return {
|
|
96
127
|
activeFlag: (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag,
|
|
97
128
|
selectionDecorationSet: newDecorationSet,
|
|
98
129
|
syncBlockStore: syncBlockStore,
|
|
130
|
+
retryCreationPosMap: newRetryCreationPosMap,
|
|
99
131
|
bodiedSyncBlockDeletionStatus: (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus
|
|
100
132
|
};
|
|
101
133
|
}
|
|
@@ -125,8 +157,10 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
125
157
|
})
|
|
126
158
|
},
|
|
127
159
|
decorations: state => {
|
|
128
|
-
var
|
|
129
|
-
const
|
|
160
|
+
var _currentPluginState$s, _api$connectivity, _api$connectivity$sha, _api$editorViewMode, _api$editorViewMode$s;
|
|
161
|
+
const currentPluginState = syncedBlockPluginKey.getState(state);
|
|
162
|
+
const selectionDecorationSet = (_currentPluginState$s = currentPluginState === null || currentPluginState === void 0 ? void 0 : currentPluginState.selectionDecorationSet) !== null && _currentPluginState$s !== void 0 ? _currentPluginState$s : DecorationSet.empty;
|
|
163
|
+
const syncBlockStore = currentPluginState === null || currentPluginState === void 0 ? void 0 : currentPluginState.syncBlockStore;
|
|
130
164
|
const {
|
|
131
165
|
doc
|
|
132
166
|
} = state;
|
|
@@ -134,6 +168,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
134
168
|
const isViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : (_api$editorViewMode$s = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode$s === void 0 ? void 0 : _api$editorViewMode$s.mode) === 'view';
|
|
135
169
|
const offlineDecorations = [];
|
|
136
170
|
const viewModeDecorations = [];
|
|
171
|
+
const loadingDecorations = [];
|
|
137
172
|
state.doc.descendants((node, pos) => {
|
|
138
173
|
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
139
174
|
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
@@ -145,8 +180,13 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
145
180
|
class: SyncBlockStateCssClassName.viewModeClassName
|
|
146
181
|
}));
|
|
147
182
|
}
|
|
183
|
+
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId) && fg('platform_synced_block_patch_1')) {
|
|
184
|
+
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
185
|
+
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
148
188
|
});
|
|
149
|
-
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations);
|
|
189
|
+
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations);
|
|
150
190
|
},
|
|
151
191
|
handleClickOn: createSelectionClickHandler(['bodiedSyncBlock'], target => !!target.closest(`.${BodiedSyncBlockSharedCssClassName.prefix}`), {
|
|
152
192
|
useLongPressSelection
|
|
@@ -209,6 +249,12 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
209
249
|
var _api$connectivity2, _api$connectivity2$sh;
|
|
210
250
|
const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity2 = api.connectivity) === null || _api$connectivity2 === void 0 ? void 0 : (_api$connectivity2$sh = _api$connectivity2.sharedState.currentState()) === null || _api$connectivity2$sh === void 0 ? void 0 : _api$connectivity2$sh.mode);
|
|
211
251
|
const isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
|
|
252
|
+
const hasNoPendingRequest = fg('platform_synced_block_patch_1') ? false :
|
|
253
|
+
// requireConfirmationBeforeDelete is always true, so this evaluates to false and hence redundant
|
|
254
|
+
!(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.sourceManager.requireConfirmationBeforeDelete()) && !syncBlockStore.sourceManager.hasPendingCreation();
|
|
255
|
+
const isCommitsCreation = fg('platform_synced_block_patch_1') ? false :
|
|
256
|
+
// For patch 1, we don't intercept the insert transaction, hence it's redundant
|
|
257
|
+
Boolean(tr.getMeta('isCommitSyncBlockCreation'));
|
|
212
258
|
|
|
213
259
|
// Track newly added reference sync blocks before processing the transaction
|
|
214
260
|
if (tr.docChanged && !tr.getMeta('isRemote')) {
|
|
@@ -228,7 +274,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
228
274
|
// or are from remote (collab) or already confirmed sync block deletion
|
|
229
275
|
// We only care about local changes that change the document
|
|
230
276
|
// and are not yet confirmed for sync block deletion
|
|
231
|
-
if (!tr.docChanged ||
|
|
277
|
+
if (!tr.docChanged || hasNoPendingRequest || Boolean(tr.getMeta('isRemote')) || isCommitsCreation || !isOffline && isConfirmedSyncBlockDeletion) {
|
|
232
278
|
return true;
|
|
233
279
|
}
|
|
234
280
|
const {
|
|
@@ -277,18 +323,22 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
277
323
|
// After true is returned here and the node is created, we delete the node in the filterTransaction immediately, which cancels out the creation
|
|
278
324
|
return true;
|
|
279
325
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
326
|
+
if (fg('platform_synced_block_patch_1')) {
|
|
327
|
+
handleBodiedSyncBlockCreation(bodiedSyncBlockAdded, state, api);
|
|
328
|
+
return true;
|
|
329
|
+
} else {
|
|
330
|
+
// If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
|
|
331
|
+
// we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
|
|
332
|
+
// The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
|
|
333
|
+
syncBlockStore.sourceManager.registerCreationCallback(() => {
|
|
334
|
+
var _api$core;
|
|
335
|
+
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(() => {
|
|
336
|
+
return tr.setMeta('isCommitSyncBlockCreation', true);
|
|
337
|
+
});
|
|
338
|
+
api === null || api === void 0 ? void 0 : api.core.actions.focus();
|
|
288
339
|
});
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
return false;
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
292
342
|
}
|
|
293
343
|
} else {
|
|
294
344
|
const {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { FLAG_ID } from '../../types';
|
|
3
|
+
import { syncedBlockPluginKey } from '../main';
|
|
4
|
+
const onRetry = (api, resourceId) => {
|
|
5
|
+
return () => {
|
|
6
|
+
var _api$core, _api$core2;
|
|
7
|
+
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.focus();
|
|
8
|
+
api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(({
|
|
9
|
+
tr
|
|
10
|
+
}) => {
|
|
11
|
+
var _api$syncedBlock, _api$syncedBlock$shar, _api$syncedBlock$shar2, _api$syncedBlock2;
|
|
12
|
+
const pos = api === null || api === void 0 ? void 0 : (_api$syncedBlock = api.syncedBlock) === null || _api$syncedBlock === void 0 ? void 0 : (_api$syncedBlock$shar = _api$syncedBlock.sharedState.currentState()) === null || _api$syncedBlock$shar === void 0 ? void 0 : (_api$syncedBlock$shar2 = _api$syncedBlock$shar.retryCreationPosMap) === null || _api$syncedBlock$shar2 === void 0 ? void 0 : _api$syncedBlock$shar2.get(resourceId);
|
|
13
|
+
const from = pos === null || pos === void 0 ? void 0 : pos.from;
|
|
14
|
+
const to = pos === null || pos === void 0 ? void 0 : pos.to;
|
|
15
|
+
if (from === undefined || to === undefined) {
|
|
16
|
+
return tr;
|
|
17
|
+
}
|
|
18
|
+
tr.setSelection(TextSelection.create(tr.doc, from, to)).setMeta(syncedBlockPluginKey, {
|
|
19
|
+
activeFlag: false
|
|
20
|
+
});
|
|
21
|
+
api === null || api === void 0 ? void 0 : (_api$syncedBlock2 = api.syncedBlock) === null || _api$syncedBlock2 === void 0 ? void 0 : _api$syncedBlock2.commands.insertSyncedBlock()({
|
|
22
|
+
tr
|
|
23
|
+
});
|
|
24
|
+
return tr;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const getRevertCreationPos = (api, doc, resourceId) => {
|
|
29
|
+
var _api$syncedBlock3, _api$syncedBlock3$sha, _api$syncedBlock3$sha2;
|
|
30
|
+
const retryCreationPos = api === null || api === void 0 ? void 0 : (_api$syncedBlock3 = api.syncedBlock) === null || _api$syncedBlock3 === void 0 ? void 0 : (_api$syncedBlock3$sha = _api$syncedBlock3.sharedState.currentState()) === null || _api$syncedBlock3$sha === void 0 ? void 0 : (_api$syncedBlock3$sha2 = _api$syncedBlock3$sha.retryCreationPosMap) === null || _api$syncedBlock3$sha2 === void 0 ? void 0 : _api$syncedBlock3$sha2.get(resourceId);
|
|
31
|
+
if (retryCreationPos) {
|
|
32
|
+
return retryCreationPos;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Fallback to find the positions in case BE call returns before plugin state becomes available
|
|
36
|
+
// which is highly unlikely
|
|
37
|
+
let currentPos;
|
|
38
|
+
doc.descendants((node, pos) => {
|
|
39
|
+
if (currentPos) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (node.type.name === 'bodiedSyncBlock' && resourceId === node.attrs.resourceId) {
|
|
43
|
+
currentPos = {
|
|
44
|
+
from: pos,
|
|
45
|
+
to: pos + node.nodeSize
|
|
46
|
+
};
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return currentPos;
|
|
51
|
+
};
|
|
52
|
+
const buildRevertCreationTr = (tr, pos) => {
|
|
53
|
+
var _tr$doc$nodeAt;
|
|
54
|
+
const content = (_tr$doc$nodeAt = tr.doc.nodeAt(pos.from)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.content;
|
|
55
|
+
if (content) {
|
|
56
|
+
tr.replaceWith(pos.from, pos.to, content);
|
|
57
|
+
const contentFrom = tr.mapping.map(pos.from);
|
|
58
|
+
tr.setSelection(TextSelection.create(tr.doc, contentFrom, contentFrom + content.size));
|
|
59
|
+
} else {
|
|
60
|
+
tr.delete(pos.from, pos.to);
|
|
61
|
+
}
|
|
62
|
+
return tr;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* Save the new bodiedSyncBlock to backend with empty content and handles revert (if failed) and retry flow
|
|
68
|
+
*/
|
|
69
|
+
export const handleBodiedSyncBlockCreation = (bodiedSyncBlockAdded, editorState, api) => {
|
|
70
|
+
const syncBlockStore = syncedBlockPluginKey.getState(editorState).syncBlockStore;
|
|
71
|
+
bodiedSyncBlockAdded.forEach(node => {
|
|
72
|
+
if (node.from === undefined || node.to === undefined) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const retryCreationPos = {
|
|
76
|
+
from: node.from,
|
|
77
|
+
to: node.to
|
|
78
|
+
};
|
|
79
|
+
const resourceId = node.attrs.resourceId;
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
var _api$core3;
|
|
82
|
+
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
|
|
83
|
+
tr
|
|
84
|
+
}) => {
|
|
85
|
+
return tr.setMeta(syncedBlockPluginKey, {
|
|
86
|
+
retryCreationPos: {
|
|
87
|
+
resourceId,
|
|
88
|
+
pos: retryCreationPos
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, success => {
|
|
94
|
+
if (success) {
|
|
95
|
+
var _api$core4, _api$core5;
|
|
96
|
+
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
|
|
97
|
+
tr
|
|
98
|
+
}) => {
|
|
99
|
+
return tr.setMeta(syncedBlockPluginKey, {
|
|
100
|
+
retryCreationPos: {
|
|
101
|
+
resourceId,
|
|
102
|
+
pos: undefined
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.focus();
|
|
107
|
+
} else {
|
|
108
|
+
var _api$core6;
|
|
109
|
+
api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.execute(({
|
|
110
|
+
tr
|
|
111
|
+
}) => {
|
|
112
|
+
const revertCreationPos = getRevertCreationPos(api, tr.doc, resourceId);
|
|
113
|
+
if (!revertCreationPos) {
|
|
114
|
+
return tr;
|
|
115
|
+
}
|
|
116
|
+
const revertTr = buildRevertCreationTr(tr, revertCreationPos);
|
|
117
|
+
return revertTr.setMeta('isConfirmedSyncBlockDeletion', true).setMeta('addToHistory', false).setMeta(syncedBlockPluginKey, {
|
|
118
|
+
activeFlag: {
|
|
119
|
+
id: FLAG_ID.CANNOT_CREATE_SYNC_BLOCK,
|
|
120
|
+
onRetry: onRetry(api, resourceId),
|
|
121
|
+
onDismissed: tr => tr.setMeta(syncedBlockPluginKey, {
|
|
122
|
+
...tr.getMeta(syncedBlockPluginKey),
|
|
123
|
+
retryCreationPos: {
|
|
124
|
+
resourceId,
|
|
125
|
+
pos: undefined
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}, node.node);
|
|
133
|
+
});
|
|
134
|
+
};
|
|
@@ -135,12 +135,14 @@ export const syncedBlockPlugin = ({
|
|
|
135
135
|
const {
|
|
136
136
|
activeFlag,
|
|
137
137
|
syncBlockStore: currentSyncBlockStore,
|
|
138
|
-
bodiedSyncBlockDeletionStatus
|
|
138
|
+
bodiedSyncBlockDeletionStatus,
|
|
139
|
+
retryCreationPosMap
|
|
139
140
|
} = syncedBlockPluginKey.getState(editorState);
|
|
140
141
|
return {
|
|
141
142
|
activeFlag,
|
|
142
143
|
syncBlockStore: currentSyncBlockStore,
|
|
143
|
-
bodiedSyncBlockDeletionStatus
|
|
144
|
+
bodiedSyncBlockDeletionStatus,
|
|
145
|
+
retryCreationPosMap
|
|
144
146
|
};
|
|
145
147
|
}
|
|
146
148
|
};
|
|
@@ -5,6 +5,7 @@ export let FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
|
|
|
5
5
|
FLAG_ID["FAIL_TO_DELETE"] = "fail-to-delete";
|
|
6
6
|
FLAG_ID["SYNC_BLOCK_COPIED"] = "sync-block-copied";
|
|
7
7
|
FLAG_ID["UNPUBLISHED_SYNC_BLOCK_PASTED"] = "unpublished-sync-block-pasted";
|
|
8
|
+
FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
|
|
8
9
|
return FLAG_ID;
|
|
9
10
|
}({});
|
|
10
11
|
export const SYNCED_BLOCK_BUTTON_TEST_ID = {
|
|
@@ -8,6 +8,7 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
|
|
|
8
8
|
import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
9
9
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
10
10
|
import ModalDialog, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
|
|
11
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
12
|
import { Text, Box } from '@atlaskit/primitives/compiled';
|
|
12
13
|
import Spinner from '@atlaskit/spinner';
|
|
13
14
|
import { syncedBlockPluginKey } from '../pm-plugins/main';
|
|
@@ -27,6 +28,22 @@ const modalContentMap = {
|
|
|
27
28
|
confirmButtonLabel: messages.deleteConfirmationModalUnsyncButton
|
|
28
29
|
}
|
|
29
30
|
};
|
|
31
|
+
const modalContentMapNew = {
|
|
32
|
+
'source-block-deleted': {
|
|
33
|
+
titleMultiple: messages.deleteConfirmationModalTitleMultiple,
|
|
34
|
+
titleSingle: messages.deletionConfirmationModalTitleSingle,
|
|
35
|
+
descriptionSingle: messages.deletionConfirmationModalDescriptionNoRef,
|
|
36
|
+
descriptionMultiple: messages.deletionConfirmationModalDescription,
|
|
37
|
+
confirmButtonLabel: messages.deleteConfirmationModalDeleteButton
|
|
38
|
+
},
|
|
39
|
+
'source-block-unsynced': {
|
|
40
|
+
titleMultiple: messages.unsyncConfirmationModalTitle,
|
|
41
|
+
titleSingle: messages.unsyncConfirmationModalTitle,
|
|
42
|
+
descriptionSingle: messages.unsyncConfirmModalDescriptionSingle,
|
|
43
|
+
descriptionMultiple: messages.unsyncConfirmModalDescriptionMultiple,
|
|
44
|
+
confirmButtonLabel: messages.deleteConfirmationModalUnsyncButton
|
|
45
|
+
}
|
|
46
|
+
};
|
|
30
47
|
const styles = {
|
|
31
48
|
spinner: "_1mou1wug _195g1wug"
|
|
32
49
|
};
|
|
@@ -148,7 +165,7 @@ export const DeleteConfirmationModal = ({
|
|
|
148
165
|
}, /*#__PURE__*/React.createElement(Spinner, {
|
|
149
166
|
size: "large"
|
|
150
167
|
})) : /*#__PURE__*/React.createElement(ModalContent, {
|
|
151
|
-
content: modalContentMap[deleteReason],
|
|
168
|
+
content: fg('platform_synced_block_patch_2') ? modalContentMapNew[deleteReason] : modalContentMap[deleteReason],
|
|
152
169
|
referenceCount: referenceCount,
|
|
153
170
|
handleClick: handleClick,
|
|
154
171
|
formatMessage: formatMessage,
|
package/dist/es2019/ui/Flag.js
CHANGED
|
@@ -37,6 +37,11 @@ const flagMap = {
|
|
|
37
37
|
title: messages.unpublishedSyncBlockPastedTitle,
|
|
38
38
|
description: messages.unpublishedSyncBlockPastedDescription,
|
|
39
39
|
type: 'info'
|
|
40
|
+
},
|
|
41
|
+
[FLAG_ID.CANNOT_CREATE_SYNC_BLOCK]: {
|
|
42
|
+
title: messages.cannotCreateSyncBlockTitle,
|
|
43
|
+
description: messages.CannotCreateSyncBlockDescription,
|
|
44
|
+
type: 'error'
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
47
|
export const Flag = ({
|
|
@@ -20,6 +20,9 @@ export const getToolbarConfig = (state, intl, api, syncBlockStore) => {
|
|
|
20
20
|
if (!syncBlockObject) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
+
if (syncBlockStore.sourceManager.isPendingCreation(syncBlockObject.node.attrs.resourceId) && fg('platform_synced_block_patch_1')) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
23
26
|
const syncBlockInstance = syncBlockStore.referenceManager.getFromCache(syncBlockObject.node.attrs.resourceId);
|
|
24
27
|
const isUnsyncedBlock = (syncBlockInstance === null || syncBlockInstance === void 0 ? void 0 : (_syncBlockInstance$er = syncBlockInstance.error) === null || _syncBlockInstance$er === void 0 ? void 0 : _syncBlockInstance$er.type) === SyncBlockError.NotFound;
|
|
25
28
|
const isErroredBlock = syncBlockInstance === null || syncBlockInstance === void 0 ? void 0 : syncBlockInstance.error;
|
|
@@ -38,7 +38,9 @@ export var createSyncedBlock = function createSyncedBlock(_ref) {
|
|
|
38
38
|
|
|
39
39
|
// Save the new node with empty content to backend
|
|
40
40
|
// This is so that the node can be copied and referenced without the source being saved/published
|
|
41
|
-
|
|
41
|
+
if (!fg('platform_synced_block_patch_1')) {
|
|
42
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(attrs, function () {});
|
|
43
|
+
}
|
|
42
44
|
if (typeAheadInsert) {
|
|
43
45
|
tr = typeAheadInsert(newBodiedSyncBlockNode);
|
|
44
46
|
} else {
|
|
@@ -75,15 +77,15 @@ export var createSyncedBlock = function createSyncedBlock(_ref) {
|
|
|
75
77
|
|
|
76
78
|
// Save the new node with empty content to backend
|
|
77
79
|
// This is so that the node can be copied and referenced without the source being saved/published
|
|
78
|
-
|
|
80
|
+
if (!fg('platform_synced_block_patch_1')) {
|
|
81
|
+
// Moved to appendTransaction
|
|
82
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(_attrs, function () {}, _newBodiedSyncBlockNode);
|
|
83
|
+
}
|
|
79
84
|
tr.replaceWith(conversionInfo.from, conversionInfo.to, _newBodiedSyncBlockNode).scrollIntoView();
|
|
80
85
|
|
|
81
86
|
// set selection to the start of the previous selection for the position taken up by the start of the new synced block
|
|
82
87
|
tr.setSelection(TextSelection.create(tr.doc, conversionInfo.from));
|
|
83
88
|
}
|
|
84
|
-
|
|
85
|
-
// This transaction will be intercepted in filterTransaction and dispatched when saving to backend succeeds
|
|
86
|
-
// see filterTransaction for more details
|
|
87
89
|
return tr;
|
|
88
90
|
};
|
|
89
91
|
export var copySyncedBlockReferenceToClipboardEditorCommand = function copySyncedBlockReferenceToClipboardEditorCommand(syncBlockStore, inputMethod, api) {
|