@atlaskit/editor-plugin-synced-block 8.3.2 → 8.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -2
- package/CHANGELOG.md +26 -0
- package/dist/cjs/nodeviews/bodiedSyncedBlock.js +7 -25
- package/dist/cjs/nodeviews/syncedBlock.js +1 -4
- package/dist/cjs/pm-plugins/main.js +54 -60
- package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +10 -19
- package/dist/cjs/pm-plugins/utils/utils.js +3 -10
- package/dist/cjs/syncedBlockPlugin.js +1 -7
- package/dist/cjs/ui/CreateSyncedBlockDropdownItem.js +23 -13
- package/dist/cjs/ui/DeleteConfirmationModal.js +29 -93
- package/dist/cjs/ui/SyncBlockLabel.js +1 -4
- package/dist/cjs/ui/SyncedLocationDropdown.js +2 -2
- package/dist/cjs/ui/floating-toolbar.js +1 -2
- package/dist/cjs/ui/quick-insert.js +2 -3
- package/dist/es2019/nodeviews/bodiedSyncedBlock.js +7 -23
- package/dist/es2019/nodeviews/syncedBlock.js +1 -4
- package/dist/es2019/pm-plugins/main.js +42 -48
- package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +7 -19
- package/dist/es2019/pm-plugins/utils/utils.js +3 -11
- package/dist/es2019/syncedBlockPlugin.js +1 -7
- package/dist/es2019/ui/CreateSyncedBlockDropdownItem.js +15 -6
- package/dist/es2019/ui/DeleteConfirmationModal.js +36 -77
- package/dist/es2019/ui/SyncBlockLabel.js +1 -4
- package/dist/es2019/ui/SyncedLocationDropdown.js +2 -2
- package/dist/es2019/ui/floating-toolbar.js +1 -2
- package/dist/es2019/ui/quick-insert.js +2 -2
- package/dist/esm/nodeviews/bodiedSyncedBlock.js +7 -25
- package/dist/esm/nodeviews/syncedBlock.js +1 -4
- package/dist/esm/pm-plugins/main.js +54 -60
- package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +10 -19
- package/dist/esm/pm-plugins/utils/utils.js +3 -11
- package/dist/esm/syncedBlockPlugin.js +1 -7
- package/dist/esm/ui/CreateSyncedBlockDropdownItem.js +23 -13
- package/dist/esm/ui/DeleteConfirmationModal.js +29 -93
- package/dist/esm/ui/SyncBlockLabel.js +1 -4
- package/dist/esm/ui/SyncedLocationDropdown.js +2 -2
- package/dist/esm/ui/floating-toolbar.js +1 -2
- package/dist/esm/ui/quick-insert.js +2 -3
- package/dist/types/nodeviews/bodiedSyncedBlock.d.ts +1 -3
- package/dist/types-ts4.5/nodeviews/bodiedSyncedBlock.d.ts +1 -3
- package/docs/0-intro.tsx +1 -1
- package/package.json +8 -20
- package/dist/cjs/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -35
- package/dist/es2019/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -27
- package/dist/esm/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -28
- package/dist/types/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.d.ts +0 -6
- package/dist/types-ts4.5/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.d.ts +0 -6
|
@@ -4,10 +4,8 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
|
|
|
4
4
|
import { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
5
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
6
|
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
7
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
8
7
|
import { flushBodiedSyncBlocks, flushSyncBlocks, discardUnpublishedSyncBlocks } from './editor-actions';
|
|
9
8
|
import { copySyncedBlockReferenceToClipboardEditorCommand, createSyncedBlock } from './editor-commands';
|
|
10
|
-
import { bodiedSyncBlockNodeWithToDOMFixed } from './nodeviews/bodiedSyncBlockNodeWithToDOMFixed';
|
|
11
9
|
import { createPlugin, syncedBlockPluginKey } from './pm-plugins/main';
|
|
12
10
|
import { getMenuAndToolbarExperiencesPlugin } from './pm-plugins/menu-and-toolbar-experiences';
|
|
13
11
|
import { getBlockMenuComponents } from './ui/block-menu-components';
|
|
@@ -78,11 +76,7 @@ export const syncedBlockPlugin = ({
|
|
|
78
76
|
node: syncBlock
|
|
79
77
|
}, {
|
|
80
78
|
name: 'bodiedSyncBlock',
|
|
81
|
-
node:
|
|
82
|
-
exposure: true
|
|
83
|
-
}) ?
|
|
84
|
-
// delete bodiedSyncBlockNodeWithToDOMFixed when cleaning up platform_synced_block_patch_6
|
|
85
|
-
bodiedSyncBlockNodeWithToDOMFixed() : bodiedSyncBlock
|
|
79
|
+
node: bodiedSyncBlock
|
|
86
80
|
}];
|
|
87
81
|
},
|
|
88
82
|
pmPlugins() {
|
|
@@ -9,6 +9,11 @@ import Lozenge from '@atlaskit/lozenge';
|
|
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
10
|
import { canBeConvertedToSyncBlock } from '../pm-plugins/utils/utils';
|
|
11
11
|
import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
|
|
12
|
+
const SyncedBlockNewLozenge = ({
|
|
13
|
+
label
|
|
14
|
+
}) => /*#__PURE__*/React.createElement(Lozenge, {
|
|
15
|
+
appearance: fg('confluence_fronend_labels_categorization_migration') ? 'discovery' : 'new'
|
|
16
|
+
}, label);
|
|
12
17
|
const CreateSyncedBlockDropdownItem = ({
|
|
13
18
|
api
|
|
14
19
|
}) => {
|
|
@@ -40,6 +45,9 @@ const CreateSyncedBlockDropdownItem = ({
|
|
|
40
45
|
}));
|
|
41
46
|
};
|
|
42
47
|
const isOffline = isOfflineMode(mode);
|
|
48
|
+
const lozenge = /*#__PURE__*/React.createElement(SyncedBlockNewLozenge, {
|
|
49
|
+
label: formatMessage(blockMenuMessages.newLozenge)
|
|
50
|
+
});
|
|
43
51
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
|
|
44
52
|
elemBefore: /*#__PURE__*/React.createElement(SyncBlocksIcon, {
|
|
45
53
|
label: "",
|
|
@@ -48,9 +56,8 @@ const CreateSyncedBlockDropdownItem = ({
|
|
|
48
56
|
onClick: onClick,
|
|
49
57
|
isDisabled: isOffline,
|
|
50
58
|
testId: SYNCED_BLOCK_BUTTON_TEST_ID.blockMenuCreate,
|
|
51
|
-
elemAfter:
|
|
52
|
-
|
|
53
|
-
}, formatMessage(blockMenuMessages.newLozenge))
|
|
59
|
+
elemAfter: fg('platform_synced_block_patch_12') ? undefined : lozenge,
|
|
60
|
+
elemAfterText: fg('platform_synced_block_patch_12') ? lozenge : undefined
|
|
54
61
|
}, formatMessage(blockMenuMessages.syncBlock));
|
|
55
62
|
};
|
|
56
63
|
const CopySyncedBlockDropdownItem = ({
|
|
@@ -74,6 +81,9 @@ const CopySyncedBlockDropdownItem = ({
|
|
|
74
81
|
closeMenu: true
|
|
75
82
|
}));
|
|
76
83
|
};
|
|
84
|
+
const lozenge = /*#__PURE__*/React.createElement(SyncedBlockNewLozenge, {
|
|
85
|
+
label: formatMessage(blockMenuMessages.newLozenge)
|
|
86
|
+
});
|
|
77
87
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
|
|
78
88
|
elemBefore: /*#__PURE__*/React.createElement(SyncBlocksIcon, {
|
|
79
89
|
label: "",
|
|
@@ -81,9 +91,8 @@ const CopySyncedBlockDropdownItem = ({
|
|
|
81
91
|
}),
|
|
82
92
|
onClick: onClick,
|
|
83
93
|
isDisabled: isOfflineMode(mode),
|
|
84
|
-
elemAfter:
|
|
85
|
-
|
|
86
|
-
}, formatMessage(blockMenuMessages.newLozenge))
|
|
94
|
+
elemAfter: fg('platform_synced_block_patch_12') ? undefined : lozenge,
|
|
95
|
+
elemAfterText: fg('platform_synced_block_patch_12') ? lozenge : undefined
|
|
87
96
|
}, formatMessage(blockMenuMessages.copySyncedBlock));
|
|
88
97
|
};
|
|
89
98
|
export const CreateOrCopySyncedBlockDropdownItem = ({
|
|
@@ -8,33 +8,9 @@ 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';
|
|
12
11
|
import { Text, Box } from '@atlaskit/primitives/compiled';
|
|
13
12
|
import Spinner from '@atlaskit/spinner';
|
|
14
13
|
import { syncedBlockPluginKey } from '../pm-plugins/main';
|
|
15
|
-
const modalContentMapOld = {
|
|
16
|
-
'source-block-deleted': {
|
|
17
|
-
titleMultiple: messages.deleteConfirmationModalTitleMultiple,
|
|
18
|
-
titleSingle: messages.deletionConfirmationModalTitleSingle,
|
|
19
|
-
descriptionSingle: messages.deletionConfirmationModalDescriptionNoRef,
|
|
20
|
-
descriptionMultiple: messages.deletionConfirmationModalDescription,
|
|
21
|
-
confirmButtonLabel: messages.deleteConfirmationModalDeleteButton
|
|
22
|
-
},
|
|
23
|
-
'source-block-unpublished': {
|
|
24
|
-
titleMultiple: messages.deleteConfirmationModalTitleMultiple,
|
|
25
|
-
titleSingle: messages.deletionConfirmationModalTitleSingle,
|
|
26
|
-
descriptionSingle: messages.deletionConfirmationModalDescriptionNoRef,
|
|
27
|
-
descriptionMultiple: messages.deletionConfirmationModalDescription,
|
|
28
|
-
confirmButtonLabel: messages.deleteConfirmationModalDeleteButton
|
|
29
|
-
},
|
|
30
|
-
'source-block-unsynced': {
|
|
31
|
-
titleMultiple: messages.unsyncConfirmationModalTitle,
|
|
32
|
-
titleSingle: messages.unsyncConfirmationModalTitle,
|
|
33
|
-
descriptionSingle: messages.unsyncConfirmModalDescriptionSingle,
|
|
34
|
-
descriptionMultiple: messages.unsyncConfirmModalDescriptionMultiple,
|
|
35
|
-
confirmButtonLabel: messages.deleteConfirmationModalUnsyncButton
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
14
|
const modalContentMap = {
|
|
39
15
|
'source-block-deleted': {
|
|
40
16
|
titleMultiple: messages.deleteConfirmationModalTitleMultiple,
|
|
@@ -87,10 +63,9 @@ export const DeleteConfirmationModal = ({
|
|
|
87
63
|
} = useIntl();
|
|
88
64
|
const resolverRef = React.useRef(undefined);
|
|
89
65
|
|
|
90
|
-
// When
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
// close the modal (which was never open).
|
|
66
|
+
// When a source block with no references is deleted, the modal is never shown but
|
|
67
|
+
// onDeleteCompleted still sets bodiedSyncBlockDeletionStatus to 'completed'. This ref signals
|
|
68
|
+
// the useEffect to silently reset the status without trying to close the modal (which was never open).
|
|
94
69
|
const skipModalOnCompletedRef = React.useRef(false);
|
|
95
70
|
const handleClick = useCallback(confirm => () => {
|
|
96
71
|
var _api$core;
|
|
@@ -137,38 +112,36 @@ export const DeleteConfirmationModal = ({
|
|
|
137
112
|
return references.reduce((sum, count) => sum + count, 0);
|
|
138
113
|
};
|
|
139
114
|
const confirmationCallback = useCallback(async (syncBlockIds, deleteReason) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
} : {})
|
|
166
|
-
});
|
|
115
|
+
// Fetch references before opening the modal. If none exist, skip the modal
|
|
116
|
+
// entirely and auto-confirm the deletion. On fetch error, default to showing
|
|
117
|
+
// the modal to avoid accidental data loss.
|
|
118
|
+
let count;
|
|
119
|
+
try {
|
|
120
|
+
count = await fetchReferenceCountRef.current(syncBlockIds);
|
|
121
|
+
} catch {
|
|
122
|
+
count = 1;
|
|
123
|
+
}
|
|
124
|
+
if (count === 0) {
|
|
125
|
+
var _api$core3;
|
|
126
|
+
// No references — auto-confirm without showing the modal.
|
|
127
|
+
// Clear activeFlag to avoid issues with subsequent deletion attempts.
|
|
128
|
+
// We do NOT reset bodiedSyncBlockDeletionStatus here because onDeleteCompleted
|
|
129
|
+
// will set it to 'completed' after the delete call returns. Instead we use a
|
|
130
|
+
// ref to signal that the next 'completed' status should be silently reset
|
|
131
|
+
// without trying to close the modal.
|
|
132
|
+
skipModalOnCompletedRef.current = true;
|
|
133
|
+
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(({
|
|
134
|
+
tr
|
|
135
|
+
}) => {
|
|
136
|
+
return tr.setMeta(syncedBlockPluginKey, {
|
|
137
|
+
...(activeFlagRef.current ? {
|
|
138
|
+
activeFlag: false
|
|
139
|
+
} : {})
|
|
167
140
|
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
setReferenceCount(count);
|
|
141
|
+
});
|
|
142
|
+
return true;
|
|
171
143
|
}
|
|
144
|
+
setReferenceCount(count);
|
|
172
145
|
setIsOpen(true);
|
|
173
146
|
setSyncBlockIds(syncBlockIds);
|
|
174
147
|
if (deleteReason) {
|
|
@@ -201,7 +174,7 @@ export const DeleteConfirmationModal = ({
|
|
|
201
174
|
};
|
|
202
175
|
}, [syncBlockStoreManager, confirmationCallback]);
|
|
203
176
|
useEffect(() => {
|
|
204
|
-
if (skipModalOnCompletedRef.current
|
|
177
|
+
if (skipModalOnCompletedRef.current) {
|
|
205
178
|
if (bodiedSyncBlockDeletionStatus === 'completed') {
|
|
206
179
|
var _api$core6;
|
|
207
180
|
// Deletion was auto-confirmed without showing the modal (no references).
|
|
@@ -238,24 +211,10 @@ export const DeleteConfirmationModal = ({
|
|
|
238
211
|
});
|
|
239
212
|
}
|
|
240
213
|
}, [api === null || api === void 0 ? void 0 : (_api$core8 = api.core) === null || _api$core8 === void 0 ? void 0 : _api$core8.actions, bodiedSyncBlockDeletionStatus, isOpen]);
|
|
241
|
-
useEffect(() => {
|
|
242
|
-
// When the flag is off, fetch references after the modal opens (original behaviour).
|
|
243
|
-
// When the flag is on, references are fetched and set before the modal opens in
|
|
244
|
-
// confirmationCallback, so this useEffect is skipped to avoid a duplicate fetch.
|
|
245
|
-
if (isOpen && syncBlockIds !== undefined && !fg('platform_synced_block_patch_9')) {
|
|
246
|
-
const fetchReferences = async () => {
|
|
247
|
-
try {
|
|
248
|
-
const totalCount = await fetchReferenceCountRef.current(syncBlockIds);
|
|
249
|
-
setReferenceCount(totalCount);
|
|
250
|
-
} catch {
|
|
251
|
-
setReferenceCount(0);
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
214
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}, [isOpen, syncBlockIds]);
|
|
215
|
+
// References are fetched and set before the modal opens in
|
|
216
|
+
// confirmationCallback, so no additional fetch is needed here.
|
|
217
|
+
|
|
259
218
|
return /*#__PURE__*/React.createElement(ModalTransition, null, isOpen && /*#__PURE__*/React.createElement(ModalDialog, {
|
|
260
219
|
onClose: handleClick(false),
|
|
261
220
|
testId: "sync-block-delete-confirmation",
|
|
@@ -265,7 +224,7 @@ export const DeleteConfirmationModal = ({
|
|
|
265
224
|
}, /*#__PURE__*/React.createElement(Spinner, {
|
|
266
225
|
size: "large"
|
|
267
226
|
})) : /*#__PURE__*/React.createElement(ModalContent, {
|
|
268
|
-
content:
|
|
227
|
+
content: modalContentMap[deleteReason],
|
|
269
228
|
referenceCount: referenceCount,
|
|
270
229
|
handleClick: handleClick,
|
|
271
230
|
formatMessage: formatMessage,
|
|
@@ -4,7 +4,6 @@ import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages'
|
|
|
4
4
|
import { SyncBlockLabelSharedCssClassName } from '@atlaskit/editor-common/sync-block';
|
|
5
5
|
import BlockSyncedIcon from '@atlaskit/icon-lab/core/block-synced';
|
|
6
6
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
7
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
8
7
|
import Tooltip from '@atlaskit/tooltip';
|
|
9
8
|
import VisuallyHidden from '@atlaskit/visually-hidden';
|
|
10
9
|
import { formatElapsedTime } from './utils/time';
|
|
@@ -70,9 +69,7 @@ const SyncBlockLabelComponent = ({
|
|
|
70
69
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
|
|
71
70
|
,
|
|
72
71
|
className: SyncBlockLabelSharedCssClassName.labelClassName,
|
|
73
|
-
"aria-describedby":
|
|
74
|
-
exposure: true
|
|
75
|
-
}) ? undefined : ariaDescribedById
|
|
72
|
+
"aria-describedby": isSource || isUnsyncedBlock ? undefined : ariaDescribedById
|
|
76
73
|
}, /*#__PURE__*/React.createElement(BlockSyncedIcon, {
|
|
77
74
|
color: "var(--ds-icon-subtle, #505258)",
|
|
78
75
|
size: "small",
|
|
@@ -262,7 +262,7 @@ export const processReferenceData = (referenceData, intl) => {
|
|
|
262
262
|
});
|
|
263
263
|
for (const references of sourceInfoMap.values()) {
|
|
264
264
|
if (references.length > 1) {
|
|
265
|
-
references.forEach((reference, index) => reference.title = `${reference.title === '' && reference.hasAccess
|
|
265
|
+
references.forEach((reference, index) => reference.title = `${reference.title === '' && reference.hasAccess ? formatMessage(messages.syncedLocationDropdownUntitledPage) : reference.title}: ${formatMessage(messages.syncedLocationDropdownTitleBlockIndex, {
|
|
266
266
|
index: index + 1
|
|
267
267
|
})}`);
|
|
268
268
|
}
|
|
@@ -381,7 +381,7 @@ const DropdownContent = ({
|
|
|
381
381
|
count: `${referenceData.length > 99 ? '99+' : referenceData.length}`
|
|
382
382
|
})
|
|
383
383
|
}, referenceData.map(reference => {
|
|
384
|
-
const title = reference.title === '' && reference.hasAccess
|
|
384
|
+
const title = reference.title === '' && reference.hasAccess ? formatMessage(messages.syncedLocationDropdownUntitledPage) : reference.title || reference.url || '';
|
|
385
385
|
return /*#__PURE__*/React.createElement("div", {
|
|
386
386
|
key: reference.title,
|
|
387
387
|
className: ax(["_2ll012x7"])
|
|
@@ -9,7 +9,6 @@ import CopyIcon from '@atlaskit/icon/core/copy';
|
|
|
9
9
|
import DeleteIcon from '@atlaskit/icon/core/delete';
|
|
10
10
|
import EditIcon from '@atlaskit/icon/core/edit';
|
|
11
11
|
import LinkBrokenIcon from '@atlaskit/icon/core/link-broken';
|
|
12
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
13
12
|
import { copySyncedBlockReferenceToClipboard, editSyncedBlockSource, removeSyncedBlock, unsync } from '../editor-commands';
|
|
14
13
|
import { findSyncBlockOrBodiedSyncBlock, isBodiedSyncBlockNode } from '../pm-plugins/utils/utils';
|
|
15
14
|
import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
|
|
@@ -83,7 +82,7 @@ export const getToolbarConfig = (state, intl, api, syncBlockStore) => {
|
|
|
83
82
|
var _syncBlockInstance$da;
|
|
84
83
|
return /*#__PURE__*/React.createElement(Button, {
|
|
85
84
|
areAnyNewToolbarFlagsEnabled: true,
|
|
86
|
-
disabled:
|
|
85
|
+
disabled: (syncBlockInstance === null || syncBlockInstance === void 0 ? void 0 : (_syncBlockInstance$da = syncBlockInstance.data) === null || _syncBlockInstance$da === void 0 ? void 0 : _syncBlockInstance$da.status) === 'unpublished',
|
|
87
86
|
icon: /*#__PURE__*/React.createElement(LinkBrokenIcon, {
|
|
88
87
|
label: ""
|
|
89
88
|
}),
|
|
@@ -20,8 +20,8 @@ export const getQuickInsertConfig = (config, api, syncBlockStore) => {
|
|
|
20
20
|
id: 'syncBlock',
|
|
21
21
|
title: formatMessage(blockTypeMessages.syncedBlock),
|
|
22
22
|
description: formatMessage(blockTypeMessages.syncedBlockDescription),
|
|
23
|
-
priority:
|
|
24
|
-
keywords: ['synced', 'block', 'synced-block', 'sync', 'sync-block', 'auto', 'update', 'excerpt', 'connect',
|
|
23
|
+
priority: 400,
|
|
24
|
+
keywords: ['synced', 'block', 'synced-block', 'sync', 'sync-block', 'auto', 'update', 'excerpt', 'connect', 'create'],
|
|
25
25
|
isDisabledOffline: true,
|
|
26
26
|
keyshortcut: '',
|
|
27
27
|
lozenge: /*#__PURE__*/React.createElement("span", {
|
|
@@ -12,7 +12,6 @@ import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
|
12
12
|
import { BodiedSyncBlockSharedCssClassName } from '@atlaskit/editor-common/sync-block';
|
|
13
13
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
14
14
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
15
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
16
15
|
import { BodiedSyncBlockWrapper } from '../ui/BodiedSyncBlockWrapper';
|
|
17
16
|
import { SyncBlockLabel } from '../ui/SyncBlockLabel';
|
|
18
17
|
var toDOMOld = function toDOMOld() {
|
|
@@ -165,14 +164,13 @@ var toDOM = function toDOM(node) {
|
|
|
165
164
|
}, 0]];
|
|
166
165
|
};
|
|
167
166
|
export var BodiedSyncBlock = /*#__PURE__*/function () {
|
|
168
|
-
function BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI
|
|
167
|
+
function BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI) {
|
|
169
168
|
var _this4 = this;
|
|
170
169
|
_classCallCheck(this, BodiedSyncBlock);
|
|
171
170
|
this.node = node;
|
|
172
171
|
this.view = view;
|
|
173
172
|
this.getPos = getPos;
|
|
174
173
|
this.api = api;
|
|
175
|
-
this.syncBlockStore = syncBlockStore;
|
|
176
174
|
this.nodeViewPortalProviderAPI = nodeViewPortalProviderAPI;
|
|
177
175
|
var _DOMSerializer$render2 = DOMSerializer.renderSpec(document, toDOM(this.node)),
|
|
178
176
|
dom = _DOMSerializer$render2.dom,
|
|
@@ -198,12 +196,8 @@ export var BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
198
196
|
this.handleConnectivityModeChange();
|
|
199
197
|
this.handleViewModeChange();
|
|
200
198
|
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
if (!fg('platform_synced_block_update_refactor')) {
|
|
204
|
-
var _this$syncedBlockStor;
|
|
205
|
-
(_this$syncedBlockStor = this.syncedBlockStore) === null || _this$syncedBlockStor === void 0 || _this$syncedBlockStor.sourceManager.updateSyncBlockData(node, false);
|
|
206
|
-
}
|
|
199
|
+
// Cache is populated in state.init() and updated in appendTransaction,
|
|
200
|
+
// so no additional updateSyncBlockData call is needed here.
|
|
207
201
|
}
|
|
208
202
|
return _createClass(BodiedSyncBlock, [{
|
|
209
203
|
key: "updateContentEditable",
|
|
@@ -246,26 +240,15 @@ export var BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
246
240
|
});
|
|
247
241
|
}
|
|
248
242
|
}
|
|
249
|
-
}, {
|
|
250
|
-
key: "syncedBlockStore",
|
|
251
|
-
get: function get() {
|
|
252
|
-
var _this$api$syncedBlock2, _this$api1;
|
|
253
|
-
return (_this$api$syncedBlock2 = (_this$api1 = this.api) === null || _this$api1 === void 0 || (_this$api1 = _this$api1.syncedBlock.sharedState) === null || _this$api1 === void 0 || (_this$api1 = _this$api1.currentState()) === null || _this$api1 === void 0 ? void 0 : _this$api1.syncBlockStore) !== null && _this$api$syncedBlock2 !== void 0 ? _this$api$syncedBlock2 : this.syncBlockStore;
|
|
254
|
-
}
|
|
255
243
|
}, {
|
|
256
244
|
key: "update",
|
|
257
245
|
value: function update(node) {
|
|
258
246
|
if (this.node.type !== node.type) {
|
|
259
247
|
return false;
|
|
260
248
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (!fg('platform_synced_block_update_refactor')) {
|
|
265
|
-
var _this$syncedBlockStor2;
|
|
266
|
-
(_this$syncedBlockStor2 = this.syncedBlockStore) === null || _this$syncedBlockStor2 === void 0 || _this$syncedBlockStor2.sourceManager.updateSyncBlockData(node, false);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
249
|
+
|
|
250
|
+
// Cache updates are handled in appendTransaction where we can
|
|
251
|
+
// filter out non-user changes (remote collab, table auto-scale, etc.)
|
|
269
252
|
this.node = node;
|
|
270
253
|
return true;
|
|
271
254
|
}
|
|
@@ -289,9 +272,8 @@ export var BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
289
272
|
}();
|
|
290
273
|
export var bodiedSyncBlockNodeView = function bodiedSyncBlockNodeView(props) {
|
|
291
274
|
var api = props.api,
|
|
292
|
-
syncBlockStore = props.syncBlockStore,
|
|
293
275
|
nodeViewPortalProviderAPI = props.pmPluginFactoryParams.nodeViewPortalProviderAPI;
|
|
294
276
|
return function (node, view, getPos) {
|
|
295
|
-
return new BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI
|
|
277
|
+
return new BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI);
|
|
296
278
|
};
|
|
297
279
|
};
|
|
@@ -14,7 +14,6 @@ import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
|
|
|
14
14
|
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
15
15
|
import { SyncBlockSharedCssClassName, SyncBlockActionsProvider } from '@atlaskit/editor-common/sync-block';
|
|
16
16
|
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
17
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
18
17
|
import { removeSyncedBlockAtPos } from '../editor-commands';
|
|
19
18
|
import { SyncBlockRendererWrapper } from '../ui/SyncBlockRendererWrapper';
|
|
20
19
|
export var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
@@ -61,9 +60,7 @@ export var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
61
60
|
}, {
|
|
62
61
|
key: "update",
|
|
63
62
|
value: function update(node, decorations, innerDecorations) {
|
|
64
|
-
return _superPropGet(SyncBlock, "update", this, 3)([node, decorations, innerDecorations,
|
|
65
|
-
exposure: true
|
|
66
|
-
}) ? this.validUpdate : undefined]);
|
|
63
|
+
return _superPropGet(SyncBlock, "update", this, 3)([node, decorations, innerDecorations, this.validUpdate]);
|
|
67
64
|
}
|
|
68
65
|
}, {
|
|
69
66
|
key: "render",
|
|
@@ -362,18 +362,14 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
362
362
|
|
|
363
363
|
// Populate source sync block cache from initial document
|
|
364
364
|
// When fg is ON, this replaces the constructor call in the nodeview
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
// Fetch statuses from the backend so we can identify unpublished blocks on cancel
|
|
373
|
-
if (fg('platform_synced_block_patch_10')) {
|
|
374
|
-
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
365
|
+
instance.doc.forEach(function (node) {
|
|
366
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
367
|
+
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
375
368
|
}
|
|
376
|
-
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Fetch statuses from the backend so we can identify unpublished blocks on cancel
|
|
372
|
+
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
377
373
|
}
|
|
378
374
|
|
|
379
375
|
// Read initial shared-state signals for status decorations
|
|
@@ -686,7 +682,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
686
682
|
}
|
|
687
683
|
}
|
|
688
684
|
var viewMode = api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode;
|
|
689
|
-
if (viewMode === 'view'
|
|
685
|
+
if (viewMode === 'view') {
|
|
690
686
|
return true;
|
|
691
687
|
}
|
|
692
688
|
var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
|
|
@@ -703,40 +699,39 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
703
699
|
}
|
|
704
700
|
});
|
|
705
701
|
}
|
|
706
|
-
if (fg('platform_synced_block_update_refactor')) {
|
|
707
|
-
// if doc changed and it's a remote transaction, check if any synced block were added,
|
|
708
|
-
// and if so, for source synced blocks, ensure we update the cache with them
|
|
709
|
-
// and for reference synced blocks, ensure we fetch the data from the server
|
|
710
|
-
if (tr.docChanged && tr.getMeta('isRemote')) {
|
|
711
|
-
var _trackSyncBlocks4 = trackSyncBlocks(function (node) {
|
|
712
|
-
return syncBlockStore.isSyncBlock(node);
|
|
713
|
-
}, tr, state),
|
|
714
|
-
_added = _trackSyncBlocks4.added;
|
|
715
|
-
var sourceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
716
|
-
return nodeInfo.node && syncBlockStore.sourceManager.isSourceBlock(nodeInfo.node);
|
|
717
|
-
});
|
|
718
|
-
var referenceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
719
|
-
return nodeInfo.node && syncBlockStore.referenceManager.isReferenceBlock(nodeInfo.node);
|
|
720
|
-
});
|
|
721
|
-
sourceSyncBlockNodes.forEach(function (nodeInfo) {
|
|
722
|
-
var _nodeInfo$attrs2;
|
|
723
|
-
if ((_nodeInfo$attrs2 = nodeInfo.attrs) !== null && _nodeInfo$attrs2 !== void 0 && _nodeInfo$attrs2.resourceId && nodeInfo.node) {
|
|
724
|
-
syncBlockStore.sourceManager.updateSyncBlockData(nodeInfo.node, tr.getMeta('isRemote'));
|
|
725
|
-
}
|
|
726
|
-
});
|
|
727
702
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
703
|
+
// if doc changed and it's a remote transaction, check if any synced block were added,
|
|
704
|
+
// and if so, for source synced blocks, ensure we update the cache with them
|
|
705
|
+
// and for reference synced blocks, ensure we fetch the data from the server
|
|
706
|
+
if (tr.docChanged && tr.getMeta('isRemote')) {
|
|
707
|
+
var _trackSyncBlocks4 = trackSyncBlocks(function (node) {
|
|
708
|
+
return syncBlockStore.isSyncBlock(node);
|
|
709
|
+
}, tr, state),
|
|
710
|
+
_added = _trackSyncBlocks4.added;
|
|
711
|
+
var sourceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
712
|
+
return nodeInfo.node && syncBlockStore.sourceManager.isSourceBlock(nodeInfo.node);
|
|
713
|
+
});
|
|
714
|
+
var referenceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
715
|
+
return nodeInfo.node && syncBlockStore.referenceManager.isReferenceBlock(nodeInfo.node);
|
|
716
|
+
});
|
|
717
|
+
sourceSyncBlockNodes.forEach(function (nodeInfo) {
|
|
718
|
+
var _nodeInfo$attrs2;
|
|
719
|
+
if ((_nodeInfo$attrs2 = nodeInfo.attrs) !== null && _nodeInfo$attrs2 !== void 0 && _nodeInfo$attrs2.resourceId && nodeInfo.node) {
|
|
720
|
+
syncBlockStore.sourceManager.updateSyncBlockData(nodeInfo.node, tr.getMeta('isRemote'));
|
|
732
721
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
syncBlockStore.
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// Fetch statuses for remotely-added source sync blocks
|
|
725
|
+
// so we can identify unpublished blocks on cancel
|
|
726
|
+
if (sourceSyncBlockNodes.length > 0) {
|
|
727
|
+
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
739
728
|
}
|
|
729
|
+
var syncBlockNodes = referenceSyncBlockNodes.map(function (nodeInfo) {
|
|
730
|
+
return nodeInfo.node;
|
|
731
|
+
}).filter(function (node) {
|
|
732
|
+
return node !== undefined;
|
|
733
|
+
});
|
|
734
|
+
syncBlockStore.referenceManager.fetchSyncBlocksData(convertPMNodesToSyncBlockNodes(syncBlockNodes));
|
|
740
735
|
}
|
|
741
736
|
if (!tr.docChanged || Boolean(tr.getMeta('isRemote')) || !isOffline && isConfirmedSyncBlockDeletion) {
|
|
742
737
|
return true;
|
|
@@ -778,26 +773,25 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
778
773
|
}
|
|
779
774
|
}
|
|
780
775
|
var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
|
|
781
|
-
if (viewMode === 'view'
|
|
776
|
+
if (viewMode === 'view') {
|
|
782
777
|
return null;
|
|
783
778
|
}
|
|
784
779
|
|
|
785
|
-
// Update source sync block cache for user-initiated changes only
|
|
786
|
-
//
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
780
|
+
// Update source sync block cache for user-initiated changes only.
|
|
781
|
+
// Cache updates are handled here instead of in the nodeview update() so we
|
|
782
|
+
// can filter out non-user changes (remote collab, dirty programmatic txns).
|
|
783
|
+
var isUserChange = function isUserChange(tr) {
|
|
784
|
+
return tr.docChanged && !isDirtyTransaction(tr) && !tr.getMeta('isRemote');
|
|
785
|
+
};
|
|
786
|
+
var hasSourceBlockEdit = trs.some(function (tr) {
|
|
787
|
+
return isUserChange(tr) && hasEditInSyncBlock(tr, oldState);
|
|
788
|
+
});
|
|
789
|
+
if (hasSourceBlockEdit) {
|
|
790
|
+
newState.doc.forEach(function (node) {
|
|
791
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
792
|
+
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
793
|
+
}
|
|
793
794
|
});
|
|
794
|
-
if (hasSourceBlockEdit) {
|
|
795
|
-
newState.doc.forEach(function (node) {
|
|
796
|
-
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
797
|
-
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
}
|
|
801
795
|
}
|
|
802
796
|
trs.filter(function (tr) {
|
|
803
797
|
return tr.docChanged;
|
|
@@ -848,7 +842,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
848
842
|
}
|
|
849
843
|
if (trs.some(function (tr) {
|
|
850
844
|
return tr.docChanged && !tr.getMeta('isRemote');
|
|
851
|
-
})
|
|
845
|
+
})) {
|
|
852
846
|
// Quick check: only walk the full document when at least one
|
|
853
847
|
// transaction inserted a source synced block. This avoids an
|
|
854
848
|
// expensive descendants() traversal on every local edit.
|