@atlaskit/editor-plugin-synced-block 5.3.21 → 5.3.22
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 +14 -0
- package/dist/cjs/pm-plugins/main.js +26 -11
- package/dist/cjs/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +45 -13
- package/dist/cjs/ui/SyncedLocationDropdown.js +21 -3
- package/dist/es2019/pm-plugins/main.js +26 -11
- package/dist/es2019/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +57 -24
- package/dist/es2019/ui/SyncedLocationDropdown.js +22 -3
- package/dist/esm/pm-plugins/main.js +26 -11
- package/dist/esm/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/esm/pm-plugins/utils/track-sync-blocks.js +45 -13
- package/dist/esm/ui/SyncedLocationDropdown.js +21 -3
- package/dist/types/syncedBlockPluginType.d.ts +2 -2
- package/dist/types/ui/SyncedLocationDropdown.d.ts +1 -1
- package/dist/types-ts4.5/syncedBlockPluginType.d.ts +2 -2
- package/dist/types-ts4.5/ui/SyncedLocationDropdown.d.ts +1 -1
- package/package.json +2 -2
- package/tsconfig.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 5.3.22
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`8806992b3642c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8806992b3642c) -
|
|
8
|
+
EDITOR-5454 update synced block insert success event to use document inserted event
|
|
9
|
+
- [`2b9f36bb91309`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2b9f36bb91309) -
|
|
10
|
+
Improve robustness
|
|
11
|
+
- [`0f351c68adbac`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0f351c68adbac) -
|
|
12
|
+
Improve robustness
|
|
13
|
+
- [`bf779fa373faa`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bf779fa373faa) -
|
|
14
|
+
[ux] EDITOR-5016 fix synced locations dropdown showing blogpost instead of page
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 5.3.21
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -16,6 +16,7 @@ var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
|
|
|
16
16
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
17
17
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
18
18
|
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
19
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
19
20
|
var _bodiedLazySyncedBlock = require("../nodeviews/bodiedLazySyncedBlock");
|
|
20
21
|
var _syncedBlock = require("../nodeviews/syncedBlock");
|
|
21
22
|
var _types = require("../types");
|
|
@@ -310,17 +311,31 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
310
311
|
});
|
|
311
312
|
});
|
|
312
313
|
syncBlockAdded.forEach(function (syncBlock) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
314
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_3')) {
|
|
315
|
+
var _api$analytics2;
|
|
316
|
+
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
|
|
317
|
+
action: _analytics.ACTION.INSERTED,
|
|
318
|
+
actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
|
|
319
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK,
|
|
320
|
+
attributes: {
|
|
321
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
322
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
323
|
+
},
|
|
324
|
+
eventType: _analytics.EVENT_TYPE.TRACK
|
|
325
|
+
});
|
|
326
|
+
} else {
|
|
327
|
+
var _api$analytics3;
|
|
328
|
+
api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || (_api$analytics3 = _api$analytics3.actions) === null || _api$analytics3 === void 0 || _api$analytics3.fireAnalyticsEvent({
|
|
329
|
+
action: _analytics.ACTION.INSERTED,
|
|
330
|
+
actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
|
|
331
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
|
|
332
|
+
attributes: {
|
|
333
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
334
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
335
|
+
},
|
|
336
|
+
eventType: _analytics.EVENT_TYPE.OPERATIONAL
|
|
337
|
+
});
|
|
338
|
+
}
|
|
324
339
|
});
|
|
325
340
|
if (bodiedSyncBlockRemoved.length > 0) {
|
|
326
341
|
confirmationTransactionRef.current = tr;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.trackSyncBlocks = exports.hasEditInSyncBlock = void 0;
|
|
7
7
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
8
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
9
10
|
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; } } }; }
|
|
10
11
|
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; } }
|
|
11
12
|
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; }
|
|
@@ -28,7 +29,7 @@ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(predica
|
|
|
28
29
|
var hasBodiedSyncBlockChanges = replaceSteps.some(function (step, idx) {
|
|
29
30
|
var from = step.from,
|
|
30
31
|
to = step.to;
|
|
31
|
-
var docAtStep = tr.docs[idx];
|
|
32
|
+
var docAtStep = (0, _platformFeatureFlags.fg)('platform_synced_block_patch_3') ? tr.docs[tr.steps.indexOf(step)] : tr.docs[idx];
|
|
32
33
|
var hasChange = false;
|
|
33
34
|
if (from !== to) {
|
|
34
35
|
step.getMap().forEach(function (oldStart, oldEnd) {
|
|
@@ -108,13 +109,12 @@ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(predica
|
|
|
108
109
|
*/
|
|
109
110
|
var hasEditInSyncBlock = exports.hasEditInSyncBlock = function hasEditInSyncBlock(tr, state) {
|
|
110
111
|
var bodiedSyncBlock = state.schema.nodes.bodiedSyncBlock;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
var step = _step.value;
|
|
112
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_3')) {
|
|
113
|
+
for (var i = 0; i < tr.steps.length; i++) {
|
|
114
|
+
var _tr$docs;
|
|
115
|
+
var step = tr.steps[i];
|
|
116
116
|
var map = step.getMap();
|
|
117
|
-
var
|
|
117
|
+
var docAfterStep = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
|
|
118
118
|
var positions = [];
|
|
119
119
|
|
|
120
120
|
// Extract positions from steps dynamically based on applicable properties
|
|
@@ -131,17 +131,49 @@ var hasEditInSyncBlock = exports.hasEditInSyncBlock = function hasEditInSyncBloc
|
|
|
131
131
|
for (var _i = 0, _positions = positions; _i < _positions.length; _i++) {
|
|
132
132
|
var _pos = _positions[_i];
|
|
133
133
|
var newPos = map.map(_pos);
|
|
134
|
-
if (newPos >= 0 && newPos <=
|
|
135
|
-
if ((0, _utils.findParentNodeOfTypeClosestToPos)(
|
|
134
|
+
if (newPos >= 0 && newPos <= docAfterStep.content.size) {
|
|
135
|
+
if ((0, _utils.findParentNodeOfTypeClosestToPos)(docAfterStep.resolve(newPos), bodiedSyncBlock)) {
|
|
136
136
|
return true;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
}
|
|
142
|
-
_iterator.
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
} else {
|
|
142
|
+
var _iterator = _createForOfIteratorHelper(tr.steps),
|
|
143
|
+
_step;
|
|
144
|
+
try {
|
|
145
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
146
|
+
var _step2 = _step.value;
|
|
147
|
+
var _map = _step2.getMap();
|
|
148
|
+
var doc = tr.doc;
|
|
149
|
+
var _positions2 = [];
|
|
150
|
+
|
|
151
|
+
// Extract positions from steps dynamically based on applicable properties
|
|
152
|
+
if ('from' in _step2 && typeof _step2.from === 'number' && 'to' in _step2 && typeof _step2.to === 'number') {
|
|
153
|
+
var _ref3 = _step2,
|
|
154
|
+
_from = _ref3.from,
|
|
155
|
+
_to = _ref3.to;
|
|
156
|
+
_positions2.push(_from, _to);
|
|
157
|
+
} else if ('pos' in _step2 && typeof _step2.pos === 'number') {
|
|
158
|
+
var _ref4 = _step2,
|
|
159
|
+
_pos2 = _ref4.pos;
|
|
160
|
+
_positions2.push(_pos2);
|
|
161
|
+
}
|
|
162
|
+
for (var _i2 = 0, _positions3 = _positions2; _i2 < _positions3.length; _i2++) {
|
|
163
|
+
var _pos3 = _positions3[_i2];
|
|
164
|
+
var _newPos = _map.map(_pos3);
|
|
165
|
+
if (_newPos >= 0 && _newPos <= doc.content.size) {
|
|
166
|
+
if ((0, _utils.findParentNodeOfTypeClosestToPos)(doc.resolve(_newPos), bodiedSyncBlock)) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
_iterator.e(err);
|
|
174
|
+
} finally {
|
|
175
|
+
_iterator.f();
|
|
176
|
+
}
|
|
145
177
|
}
|
|
146
178
|
return false;
|
|
147
179
|
};
|
|
@@ -21,6 +21,7 @@ var _dropdownMenu = _interopRequireWildcard(require("@atlaskit/dropdown-menu"));
|
|
|
21
21
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
22
22
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
23
23
|
var _ui = require("@atlaskit/editor-common/ui");
|
|
24
|
+
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
24
25
|
var _icon = require("@atlaskit/icon");
|
|
25
26
|
var _pageLiveDoc = _interopRequireDefault(require("@atlaskit/icon-lab/core/page-live-doc"));
|
|
26
27
|
var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/core/chevron-down"));
|
|
@@ -29,6 +30,7 @@ var _quotationMark = _interopRequireDefault(require("@atlaskit/icon/core/quotati
|
|
|
29
30
|
var _statusError = _interopRequireDefault(require("@atlaskit/icon/core/status-error"));
|
|
30
31
|
var _logo = require("@atlaskit/logo");
|
|
31
32
|
var _lozenge = _interopRequireDefault(require("@atlaskit/lozenge"));
|
|
33
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
32
34
|
var _compiled = require("@atlaskit/primitives/compiled");
|
|
33
35
|
var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
|
|
34
36
|
var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
|
|
@@ -90,7 +92,22 @@ var subTypeIconMap = {
|
|
|
90
92
|
page: _page.default,
|
|
91
93
|
blogpost: _quotationMark.default
|
|
92
94
|
};
|
|
93
|
-
var
|
|
95
|
+
var subTypeIconMapNew = {
|
|
96
|
+
live: _pageLiveDoc.default,
|
|
97
|
+
page: _page.default
|
|
98
|
+
};
|
|
99
|
+
var getConfluenceSubTypeIcon = function getConfluenceSubTypeIcon(sourceAri, subType) {
|
|
100
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_3')) {
|
|
101
|
+
var _getPageIdAndTypeFrom = (0, _editorSyncedBlockProvider.getPageIdAndTypeFromConfluencePageAri)({
|
|
102
|
+
ari: sourceAri
|
|
103
|
+
}),
|
|
104
|
+
pageType = _getPageIdAndTypeFrom.type;
|
|
105
|
+
if (pageType === 'blogpost') {
|
|
106
|
+
return _quotationMark.default;
|
|
107
|
+
} else {
|
|
108
|
+
return subType && subType in subTypeIconMapNew ? subTypeIconMapNew[subType] : _page.default;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
94
111
|
return subType && subType in subTypeIconMap ? subTypeIconMap[subType] : _page.default;
|
|
95
112
|
};
|
|
96
113
|
var ProductIcon = function ProductIcon(_ref2) {
|
|
@@ -108,10 +125,11 @@ var ItemIcon = function ItemIcon(_ref3) {
|
|
|
108
125
|
var reference = _ref3.reference;
|
|
109
126
|
var hasAccess = reference.hasAccess,
|
|
110
127
|
subType = reference.subType,
|
|
111
|
-
productType = reference.productType
|
|
128
|
+
productType = reference.productType,
|
|
129
|
+
sourceAri = reference.sourceAri;
|
|
112
130
|
if (productType === 'confluence-page' && hasAccess) {
|
|
113
131
|
return /*#__PURE__*/React.createElement(_icon.IconTile, {
|
|
114
|
-
icon: getConfluenceSubTypeIcon(subType),
|
|
132
|
+
icon: getConfluenceSubTypeIcon(sourceAri, subType),
|
|
115
133
|
label: "",
|
|
116
134
|
appearance: 'gray',
|
|
117
135
|
size: "xsmall"
|
|
@@ -7,6 +7,7 @@ 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';
|
|
@@ -290,17 +291,31 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
290
291
|
});
|
|
291
292
|
});
|
|
292
293
|
syncBlockAdded.forEach(syncBlock => {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
294
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
295
|
+
var _api$analytics2, _api$analytics2$actio;
|
|
296
|
+
api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.fireAnalyticsEvent({
|
|
297
|
+
action: ACTION.INSERTED,
|
|
298
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
299
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
|
|
300
|
+
attributes: {
|
|
301
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
302
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
303
|
+
},
|
|
304
|
+
eventType: EVENT_TYPE.TRACK
|
|
305
|
+
});
|
|
306
|
+
} else {
|
|
307
|
+
var _api$analytics3, _api$analytics3$actio;
|
|
308
|
+
api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : (_api$analytics3$actio = _api$analytics3.actions) === null || _api$analytics3$actio === void 0 ? void 0 : _api$analytics3$actio.fireAnalyticsEvent({
|
|
309
|
+
action: ACTION.INSERTED,
|
|
310
|
+
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
311
|
+
actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
|
|
312
|
+
attributes: {
|
|
313
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
314
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
315
|
+
},
|
|
316
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
317
|
+
});
|
|
318
|
+
}
|
|
304
319
|
});
|
|
305
320
|
if (bodiedSyncBlockRemoved.length > 0) {
|
|
306
321
|
confirmationTransactionRef.current = tr;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
2
|
import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
export const trackSyncBlocks = (predicate, tr, state) => {
|
|
4
5
|
const removed = {};
|
|
5
6
|
const added = {};
|
|
@@ -19,7 +20,7 @@ export const trackSyncBlocks = (predicate, tr, state) => {
|
|
|
19
20
|
from,
|
|
20
21
|
to
|
|
21
22
|
} = step;
|
|
22
|
-
const docAtStep = tr.docs[idx];
|
|
23
|
+
const docAtStep = fg('platform_synced_block_patch_3') ? tr.docs[tr.steps.indexOf(step)] : tr.docs[idx];
|
|
23
24
|
let hasChange = false;
|
|
24
25
|
if (from !== to) {
|
|
25
26
|
step.getMap().forEach((oldStart, oldEnd) => {
|
|
@@ -101,31 +102,63 @@ export const hasEditInSyncBlock = (tr, state) => {
|
|
|
101
102
|
const {
|
|
102
103
|
bodiedSyncBlock
|
|
103
104
|
} = state.schema.nodes;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
106
|
+
for (let i = 0; i < tr.steps.length; i++) {
|
|
107
|
+
var _tr$docs;
|
|
108
|
+
const step = tr.steps[i];
|
|
109
|
+
const map = step.getMap();
|
|
110
|
+
const docAfterStep = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
|
|
111
|
+
const positions = [];
|
|
110
112
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
// Extract positions from steps dynamically based on applicable properties
|
|
114
|
+
if ('from' in step && typeof step.from === 'number' && 'to' in step && typeof step.to === 'number') {
|
|
115
|
+
const {
|
|
116
|
+
from,
|
|
117
|
+
to
|
|
118
|
+
} = step;
|
|
119
|
+
positions.push(from, to);
|
|
120
|
+
} else if ('pos' in step && typeof step.pos === 'number') {
|
|
121
|
+
const {
|
|
122
|
+
pos
|
|
123
|
+
} = step;
|
|
124
|
+
positions.push(pos);
|
|
125
|
+
}
|
|
126
|
+
for (const pos of positions) {
|
|
127
|
+
const newPos = map.map(pos);
|
|
128
|
+
if (newPos >= 0 && newPos <= docAfterStep.content.size) {
|
|
129
|
+
if (findParentNodeOfTypeClosestToPos(docAfterStep.resolve(newPos), bodiedSyncBlock)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
} else {
|
|
136
|
+
for (const step of tr.steps) {
|
|
137
|
+
const map = step.getMap();
|
|
138
|
+
const {
|
|
139
|
+
doc
|
|
140
|
+
} = tr;
|
|
141
|
+
const positions = [];
|
|
142
|
+
|
|
143
|
+
// Extract positions from steps dynamically based on applicable properties
|
|
144
|
+
if ('from' in step && typeof step.from === 'number' && 'to' in step && typeof step.to === 'number') {
|
|
145
|
+
const {
|
|
146
|
+
from,
|
|
147
|
+
to
|
|
148
|
+
} = step;
|
|
149
|
+
positions.push(from, to);
|
|
150
|
+
} else if ('pos' in step && typeof step.pos === 'number') {
|
|
151
|
+
const {
|
|
152
|
+
pos
|
|
153
|
+
} = step;
|
|
154
|
+
positions.push(pos);
|
|
155
|
+
}
|
|
156
|
+
for (const pos of positions) {
|
|
157
|
+
const newPos = map.map(pos);
|
|
158
|
+
if (newPos >= 0 && newPos <= doc.content.size) {
|
|
159
|
+
if (findParentNodeOfTypeClosestToPos(doc.resolve(newPos), bodiedSyncBlock)) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
129
162
|
}
|
|
130
163
|
}
|
|
131
164
|
}
|
|
@@ -9,6 +9,7 @@ import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdow
|
|
|
9
9
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
10
10
|
import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
11
11
|
import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
|
|
12
|
+
import { getPageIdAndTypeFromConfluencePageAri } from '@atlaskit/editor-synced-block-provider';
|
|
12
13
|
import { IconTile } from '@atlaskit/icon';
|
|
13
14
|
import PageLiveDocIcon from '@atlaskit/icon-lab/core/page-live-doc';
|
|
14
15
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
@@ -17,6 +18,7 @@ import QuotationMarkIcon from '@atlaskit/icon/core/quotation-mark';
|
|
|
17
18
|
import StatusErrorIcon from '@atlaskit/icon/core/status-error';
|
|
18
19
|
import { ConfluenceIcon, JiraIcon, AtlassianIcon } from '@atlaskit/logo';
|
|
19
20
|
import Lozenge from '@atlaskit/lozenge';
|
|
21
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
20
22
|
import { Box, Text, Inline, Anchor, Stack } from '@atlaskit/primitives/compiled';
|
|
21
23
|
import Spinner from '@atlaskit/spinner';
|
|
22
24
|
import Tooltip from '@atlaskit/tooltip';
|
|
@@ -74,7 +76,23 @@ const subTypeIconMap = {
|
|
|
74
76
|
page: PageIcon,
|
|
75
77
|
blogpost: QuotationMarkIcon
|
|
76
78
|
};
|
|
77
|
-
const
|
|
79
|
+
const subTypeIconMapNew = {
|
|
80
|
+
live: PageLiveDocIcon,
|
|
81
|
+
page: PageIcon
|
|
82
|
+
};
|
|
83
|
+
const getConfluenceSubTypeIcon = (sourceAri, subType) => {
|
|
84
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
85
|
+
const {
|
|
86
|
+
type: pageType
|
|
87
|
+
} = getPageIdAndTypeFromConfluencePageAri({
|
|
88
|
+
ari: sourceAri
|
|
89
|
+
});
|
|
90
|
+
if (pageType === 'blogpost') {
|
|
91
|
+
return QuotationMarkIcon;
|
|
92
|
+
} else {
|
|
93
|
+
return subType && subType in subTypeIconMapNew ? subTypeIconMapNew[subType] : PageIcon;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
78
96
|
return subType && subType in subTypeIconMap ? subTypeIconMap[subType] : PageIcon;
|
|
79
97
|
};
|
|
80
98
|
const ProductIcon = ({
|
|
@@ -95,11 +113,12 @@ const ItemIcon = ({
|
|
|
95
113
|
const {
|
|
96
114
|
hasAccess,
|
|
97
115
|
subType,
|
|
98
|
-
productType
|
|
116
|
+
productType,
|
|
117
|
+
sourceAri
|
|
99
118
|
} = reference;
|
|
100
119
|
if (productType === 'confluence-page' && hasAccess) {
|
|
101
120
|
return /*#__PURE__*/React.createElement(IconTile, {
|
|
102
|
-
icon: getConfluenceSubTypeIcon(subType),
|
|
121
|
+
icon: getConfluenceSubTypeIcon(sourceAri, subType),
|
|
103
122
|
label: "",
|
|
104
123
|
appearance: 'gray',
|
|
105
124
|
size: "xsmall"
|
|
@@ -14,6 +14,7 @@ import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
|
14
14
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
15
15
|
import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
16
16
|
import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
|
|
17
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
17
18
|
import { lazyBodiedSyncBlockView } from '../nodeviews/bodiedLazySyncedBlock';
|
|
18
19
|
import { SyncBlock as SyncBlockView } from '../nodeviews/syncedBlock';
|
|
19
20
|
import { FLAG_ID } from '../types';
|
|
@@ -303,17 +304,31 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
303
304
|
});
|
|
304
305
|
});
|
|
305
306
|
syncBlockAdded.forEach(function (syncBlock) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
307
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
308
|
+
var _api$analytics2;
|
|
309
|
+
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
|
|
310
|
+
action: ACTION.INSERTED,
|
|
311
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
312
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
|
|
313
|
+
attributes: {
|
|
314
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
315
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
316
|
+
},
|
|
317
|
+
eventType: EVENT_TYPE.TRACK
|
|
318
|
+
});
|
|
319
|
+
} else {
|
|
320
|
+
var _api$analytics3;
|
|
321
|
+
api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || (_api$analytics3 = _api$analytics3.actions) === null || _api$analytics3 === void 0 || _api$analytics3.fireAnalyticsEvent({
|
|
322
|
+
action: ACTION.INSERTED,
|
|
323
|
+
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
324
|
+
actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
|
|
325
|
+
attributes: {
|
|
326
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
327
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
328
|
+
},
|
|
329
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
330
|
+
});
|
|
331
|
+
}
|
|
317
332
|
});
|
|
318
333
|
if (bodiedSyncBlockRemoved.length > 0) {
|
|
319
334
|
confirmationTransactionRef.current = tr;
|
|
@@ -3,6 +3,7 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
3
3
|
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; }
|
|
4
4
|
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
5
|
import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
7
|
export var trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
|
|
7
8
|
var removed = {};
|
|
8
9
|
var added = {};
|
|
@@ -22,7 +23,7 @@ export var trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
|
|
|
22
23
|
var hasBodiedSyncBlockChanges = replaceSteps.some(function (step, idx) {
|
|
23
24
|
var from = step.from,
|
|
24
25
|
to = step.to;
|
|
25
|
-
var docAtStep = tr.docs[idx];
|
|
26
|
+
var docAtStep = fg('platform_synced_block_patch_3') ? tr.docs[tr.steps.indexOf(step)] : tr.docs[idx];
|
|
26
27
|
var hasChange = false;
|
|
27
28
|
if (from !== to) {
|
|
28
29
|
step.getMap().forEach(function (oldStart, oldEnd) {
|
|
@@ -102,13 +103,12 @@ export var trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
|
|
|
102
103
|
*/
|
|
103
104
|
export var hasEditInSyncBlock = function hasEditInSyncBlock(tr, state) {
|
|
104
105
|
var bodiedSyncBlock = state.schema.nodes.bodiedSyncBlock;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var step = _step.value;
|
|
106
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
107
|
+
for (var i = 0; i < tr.steps.length; i++) {
|
|
108
|
+
var _tr$docs;
|
|
109
|
+
var step = tr.steps[i];
|
|
110
110
|
var map = step.getMap();
|
|
111
|
-
var
|
|
111
|
+
var docAfterStep = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
|
|
112
112
|
var positions = [];
|
|
113
113
|
|
|
114
114
|
// Extract positions from steps dynamically based on applicable properties
|
|
@@ -125,17 +125,49 @@ export var hasEditInSyncBlock = function hasEditInSyncBlock(tr, state) {
|
|
|
125
125
|
for (var _i = 0, _positions = positions; _i < _positions.length; _i++) {
|
|
126
126
|
var _pos = _positions[_i];
|
|
127
127
|
var newPos = map.map(_pos);
|
|
128
|
-
if (newPos >= 0 && newPos <=
|
|
129
|
-
if (findParentNodeOfTypeClosestToPos(
|
|
128
|
+
if (newPos >= 0 && newPos <= docAfterStep.content.size) {
|
|
129
|
+
if (findParentNodeOfTypeClosestToPos(docAfterStep.resolve(newPos), bodiedSyncBlock)) {
|
|
130
130
|
return true;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
}
|
|
136
|
-
_iterator.
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
} else {
|
|
136
|
+
var _iterator = _createForOfIteratorHelper(tr.steps),
|
|
137
|
+
_step;
|
|
138
|
+
try {
|
|
139
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
140
|
+
var _step2 = _step.value;
|
|
141
|
+
var _map = _step2.getMap();
|
|
142
|
+
var doc = tr.doc;
|
|
143
|
+
var _positions2 = [];
|
|
144
|
+
|
|
145
|
+
// Extract positions from steps dynamically based on applicable properties
|
|
146
|
+
if ('from' in _step2 && typeof _step2.from === 'number' && 'to' in _step2 && typeof _step2.to === 'number') {
|
|
147
|
+
var _ref3 = _step2,
|
|
148
|
+
_from = _ref3.from,
|
|
149
|
+
_to = _ref3.to;
|
|
150
|
+
_positions2.push(_from, _to);
|
|
151
|
+
} else if ('pos' in _step2 && typeof _step2.pos === 'number') {
|
|
152
|
+
var _ref4 = _step2,
|
|
153
|
+
_pos2 = _ref4.pos;
|
|
154
|
+
_positions2.push(_pos2);
|
|
155
|
+
}
|
|
156
|
+
for (var _i2 = 0, _positions3 = _positions2; _i2 < _positions3.length; _i2++) {
|
|
157
|
+
var _pos3 = _positions3[_i2];
|
|
158
|
+
var _newPos = _map.map(_pos3);
|
|
159
|
+
if (_newPos >= 0 && _newPos <= doc.content.size) {
|
|
160
|
+
if (findParentNodeOfTypeClosestToPos(doc.resolve(_newPos), bodiedSyncBlock)) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (err) {
|
|
167
|
+
_iterator.e(err);
|
|
168
|
+
} finally {
|
|
169
|
+
_iterator.f();
|
|
170
|
+
}
|
|
139
171
|
}
|
|
140
172
|
return false;
|
|
141
173
|
};
|
|
@@ -17,6 +17,7 @@ import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdow
|
|
|
17
17
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
18
18
|
import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
19
19
|
import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
|
|
20
|
+
import { getPageIdAndTypeFromConfluencePageAri } from '@atlaskit/editor-synced-block-provider';
|
|
20
21
|
import { IconTile } from '@atlaskit/icon';
|
|
21
22
|
import PageLiveDocIcon from '@atlaskit/icon-lab/core/page-live-doc';
|
|
22
23
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
@@ -25,6 +26,7 @@ import QuotationMarkIcon from '@atlaskit/icon/core/quotation-mark';
|
|
|
25
26
|
import StatusErrorIcon from '@atlaskit/icon/core/status-error';
|
|
26
27
|
import { ConfluenceIcon, JiraIcon, AtlassianIcon } from '@atlaskit/logo';
|
|
27
28
|
import Lozenge from '@atlaskit/lozenge';
|
|
29
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
28
30
|
import { Box, Text, Inline, Anchor, Stack } from '@atlaskit/primitives/compiled';
|
|
29
31
|
import Spinner from '@atlaskit/spinner';
|
|
30
32
|
import Tooltip from '@atlaskit/tooltip';
|
|
@@ -81,7 +83,22 @@ var subTypeIconMap = {
|
|
|
81
83
|
page: PageIcon,
|
|
82
84
|
blogpost: QuotationMarkIcon
|
|
83
85
|
};
|
|
84
|
-
var
|
|
86
|
+
var subTypeIconMapNew = {
|
|
87
|
+
live: PageLiveDocIcon,
|
|
88
|
+
page: PageIcon
|
|
89
|
+
};
|
|
90
|
+
var getConfluenceSubTypeIcon = function getConfluenceSubTypeIcon(sourceAri, subType) {
|
|
91
|
+
if (fg('platform_synced_block_patch_3')) {
|
|
92
|
+
var _getPageIdAndTypeFrom = getPageIdAndTypeFromConfluencePageAri({
|
|
93
|
+
ari: sourceAri
|
|
94
|
+
}),
|
|
95
|
+
pageType = _getPageIdAndTypeFrom.type;
|
|
96
|
+
if (pageType === 'blogpost') {
|
|
97
|
+
return QuotationMarkIcon;
|
|
98
|
+
} else {
|
|
99
|
+
return subType && subType in subTypeIconMapNew ? subTypeIconMapNew[subType] : PageIcon;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
85
102
|
return subType && subType in subTypeIconMap ? subTypeIconMap[subType] : PageIcon;
|
|
86
103
|
};
|
|
87
104
|
var ProductIcon = function ProductIcon(_ref2) {
|
|
@@ -99,10 +116,11 @@ var ItemIcon = function ItemIcon(_ref3) {
|
|
|
99
116
|
var reference = _ref3.reference;
|
|
100
117
|
var hasAccess = reference.hasAccess,
|
|
101
118
|
subType = reference.subType,
|
|
102
|
-
productType = reference.productType
|
|
119
|
+
productType = reference.productType,
|
|
120
|
+
sourceAri = reference.sourceAri;
|
|
103
121
|
if (productType === 'confluence-page' && hasAccess) {
|
|
104
122
|
return /*#__PURE__*/React.createElement(IconTile, {
|
|
105
|
-
icon: getConfluenceSubTypeIcon(subType),
|
|
123
|
+
icon: getConfluenceSubTypeIcon(sourceAri, subType),
|
|
106
124
|
label: "",
|
|
107
125
|
appearance: 'gray',
|
|
108
126
|
size: "xsmall"
|
|
@@ -12,7 +12,7 @@ import type { FloatingToolbarPlugin } from '@atlaskit/editor-plugin-floating-too
|
|
|
12
12
|
import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
|
|
13
13
|
import type { ToolbarPlugin } from '@atlaskit/editor-plugin-toolbar';
|
|
14
14
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
15
|
-
import type {
|
|
15
|
+
import type { SyncBlockDataProviderInterface, UseFetchSyncBlockDataResult } from '@atlaskit/editor-synced-block-provider';
|
|
16
16
|
import type { SyncedBlockSharedState } from './types';
|
|
17
17
|
export type SyncedBlockEditorProps = {
|
|
18
18
|
defaultDocument: JSONDocNode;
|
|
@@ -42,7 +42,7 @@ export type SyncedBlockRendererProps = {
|
|
|
42
42
|
};
|
|
43
43
|
export interface SyncedBlockPluginOptions extends LongPressSelectionPluginOptions {
|
|
44
44
|
enableSourceCreation?: boolean;
|
|
45
|
-
syncBlockDataProvider:
|
|
45
|
+
syncBlockDataProvider: SyncBlockDataProviderInterface;
|
|
46
46
|
syncedBlockRenderer: (props: SyncedBlockRendererProps) => React.JSX.Element;
|
|
47
47
|
}
|
|
48
48
|
export type SyncedBlockPlugin = NextEditorPlugin<'syncedBlock', {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IntlShape } from 'react-intl-next';
|
|
2
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
-
import type
|
|
3
|
+
import { type SyncBlockSourceInfo, type SyncBlockStoreManager, type ReferencesSourceInfo } from '@atlaskit/editor-synced-block-provider';
|
|
4
4
|
import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
|
|
5
5
|
interface Props {
|
|
6
6
|
api?: ExtractInjectionAPI<SyncedBlockPlugin>;
|
|
@@ -12,7 +12,7 @@ import type { FloatingToolbarPlugin } from '@atlaskit/editor-plugin-floating-too
|
|
|
12
12
|
import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
|
|
13
13
|
import type { ToolbarPlugin } from '@atlaskit/editor-plugin-toolbar';
|
|
14
14
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
15
|
-
import type {
|
|
15
|
+
import type { SyncBlockDataProviderInterface, UseFetchSyncBlockDataResult } from '@atlaskit/editor-synced-block-provider';
|
|
16
16
|
import type { SyncedBlockSharedState } from './types';
|
|
17
17
|
export type SyncedBlockEditorProps = {
|
|
18
18
|
defaultDocument: JSONDocNode;
|
|
@@ -42,7 +42,7 @@ export type SyncedBlockRendererProps = {
|
|
|
42
42
|
};
|
|
43
43
|
export interface SyncedBlockPluginOptions extends LongPressSelectionPluginOptions {
|
|
44
44
|
enableSourceCreation?: boolean;
|
|
45
|
-
syncBlockDataProvider:
|
|
45
|
+
syncBlockDataProvider: SyncBlockDataProviderInterface;
|
|
46
46
|
syncedBlockRenderer: (props: SyncedBlockRendererProps) => React.JSX.Element;
|
|
47
47
|
}
|
|
48
48
|
export type SyncedBlockPlugin = NextEditorPlugin<'syncedBlock', {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IntlShape } from 'react-intl-next';
|
|
2
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
-
import type
|
|
3
|
+
import { type SyncBlockSourceInfo, type SyncBlockStoreManager, type ReferencesSourceInfo } from '@atlaskit/editor-synced-block-provider';
|
|
4
4
|
import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
|
|
5
5
|
interface Props {
|
|
6
6
|
api?: ExtractInjectionAPI<SyncedBlockPlugin>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.22",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@atlaskit/editor-common": "^111.
|
|
64
|
+
"@atlaskit/editor-common": "^111.14.0",
|
|
65
65
|
"react": "^18.2.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|