@atlaskit/editor-core 239.0.3 → 240.0.1
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 +32 -0
- package/dist/cjs/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/cjs/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/cjs/ui/EditorContentContainer/EditorContentContainer-compiled.js +1 -1
- package/dist/cjs/ui/quick-insert/ExtensionQuickInsertMenuItem.js +22 -2
- package/dist/cjs/ui/quick-insert/app-vendor/AppVendorRequestError.js +31 -0
- package/dist/cjs/ui/quick-insert/app-vendor/appVendorCache.js +14 -0
- package/dist/cjs/ui/quick-insert/app-vendor/fetchAppVendors.js +112 -0
- package/dist/cjs/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +101 -0
- package/dist/cjs/ui/quick-insert/app-vendor/getAppVendorLookup.js +33 -0
- package/dist/cjs/ui/quick-insert/app-vendor/prefetchAppVendors.js +129 -0
- package/dist/cjs/ui/quick-insert/app-vendor/useAppVendorName.js +26 -0
- package/dist/cjs/ui/quick-insert/getExtensionQuickInsertComponents.js +13 -2
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/es2019/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/es2019/ui/EditorContentContainer/EditorContentContainer-compiled.js +1 -1
- package/dist/es2019/ui/quick-insert/ExtensionQuickInsertMenuItem.js +20 -3
- package/dist/es2019/ui/quick-insert/app-vendor/AppVendorRequestError.js +11 -0
- package/dist/es2019/ui/quick-insert/app-vendor/appVendorCache.js +8 -0
- package/dist/es2019/ui/quick-insert/app-vendor/fetchAppVendors.js +69 -0
- package/dist/es2019/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +51 -0
- package/dist/es2019/ui/quick-insert/app-vendor/getAppVendorLookup.js +28 -0
- package/dist/es2019/ui/quick-insert/app-vendor/prefetchAppVendors.js +109 -0
- package/dist/es2019/ui/quick-insert/app-vendor/useAppVendorName.js +18 -0
- package/dist/es2019/ui/quick-insert/getExtensionQuickInsertComponents.js +17 -10
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/esm/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/esm/ui/EditorContentContainer/EditorContentContainer-compiled.js +1 -1
- package/dist/esm/ui/quick-insert/ExtensionQuickInsertMenuItem.js +22 -3
- package/dist/esm/ui/quick-insert/app-vendor/AppVendorRequestError.js +24 -0
- package/dist/esm/ui/quick-insert/app-vendor/appVendorCache.js +8 -0
- package/dist/esm/ui/quick-insert/app-vendor/fetchAppVendors.js +105 -0
- package/dist/esm/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +94 -0
- package/dist/esm/ui/quick-insert/app-vendor/getAppVendorLookup.js +27 -0
- package/dist/esm/ui/quick-insert/app-vendor/prefetchAppVendors.js +119 -0
- package/dist/esm/ui/quick-insert/app-vendor/useAppVendorName.js +20 -0
- package/dist/esm/ui/quick-insert/getExtensionQuickInsertComponents.js +13 -2
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/editor-appearances/ChromelessEditor.d.ts +1 -1
- package/dist/types/editor-appearances/CommentEditor.d.ts +1 -1
- package/dist/types/editor-appearances/FullPageEditor.d.ts +1 -1
- package/dist/types/editor-appearances/FullWidthEditor.d.ts +1 -1
- package/dist/types/types/editor-props.d.ts +1 -13
- package/dist/types/ui/quick-insert/ExtensionQuickInsertMenuItem.d.ts +3 -1
- package/dist/types/ui/quick-insert/app-vendor/AppVendorRequestError.d.ts +5 -0
- package/dist/types/ui/quick-insert/app-vendor/appVendorCache.d.ts +17 -0
- package/dist/types/ui/quick-insert/app-vendor/fetchAppVendors.d.ts +8 -0
- package/dist/types/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.d.ts +23 -0
- package/dist/types/ui/quick-insert/app-vendor/getAppVendorLookup.d.ts +11 -0
- package/dist/types/ui/quick-insert/app-vendor/prefetchAppVendors.d.ts +7 -0
- package/dist/types/ui/quick-insert/app-vendor/useAppVendorName.d.ts +2 -0
- package/package.json +12 -12
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
4
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
5
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
6
|
+
import _wrapNativeSuper from "@babel/runtime/helpers/wrapNativeSuper";
|
|
7
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
8
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
9
|
+
/** Statuses where retrying cannot succeed, or would add load to a throttled gateway. */
|
|
10
|
+
var BLOCKING_STATUSES = new Set([401, 403, 429]);
|
|
11
|
+
export var AppVendorRequestError = /*#__PURE__*/function (_Error) {
|
|
12
|
+
/** Whether every remaining lookup should stop rather than retry. */
|
|
13
|
+
|
|
14
|
+
function AppVendorRequestError(message, status) {
|
|
15
|
+
var _this;
|
|
16
|
+
_classCallCheck(this, AppVendorRequestError);
|
|
17
|
+
_this = _callSuper(this, AppVendorRequestError, [message]);
|
|
18
|
+
_this.name = 'AppVendorRequestError';
|
|
19
|
+
_this.isBlocking = status !== undefined && BLOCKING_STATUSES.has(status);
|
|
20
|
+
return _this;
|
|
21
|
+
}
|
|
22
|
+
_inherits(AppVendorRequestError, _Error);
|
|
23
|
+
return _createClass(AppVendorRequestError);
|
|
24
|
+
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendor names keyed by lookup id, plus the subscribers to notify when they change.
|
|
3
|
+
* Module scope so names survive editor and provider rebuilds for the rest of the page load.
|
|
4
|
+
*/
|
|
5
|
+
export var appVendorCache = {
|
|
6
|
+
entries: new Map(),
|
|
7
|
+
listeners: new Set()
|
|
8
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
+
import { AppVendorRequestError } from './AppVendorRequestError';
|
|
4
|
+
var AGG_PATH = '/gateway/api/graphql';
|
|
5
|
+
var OPERATION_NAME = 'QuickInsertAppVendorsQuery';
|
|
6
|
+
var getField = function getField(_ref, variable) {
|
|
7
|
+
var kind = _ref.kind;
|
|
8
|
+
return kind === 'forge' ? "marketplaceAppByCloudAppId(cloudAppId: $".concat(variable, ")") : "marketplaceAppByKey(appKey: $".concat(variable, ")");
|
|
9
|
+
};
|
|
10
|
+
var getVariableType = function getVariableType(_ref2) {
|
|
11
|
+
var kind = _ref2.kind;
|
|
12
|
+
return kind === 'forge' ? 'ID!' : 'String!';
|
|
13
|
+
};
|
|
14
|
+
var buildQuery = function buildQuery(lookups) {
|
|
15
|
+
var variables = lookups.map(function (lookup, index) {
|
|
16
|
+
return "$a".concat(index, ": ").concat(getVariableType(lookup));
|
|
17
|
+
});
|
|
18
|
+
var fields = lookups.map(function (lookup, index) {
|
|
19
|
+
return "a".concat(index, ": ").concat(getField(lookup, "a".concat(index)), " { partner { name } }");
|
|
20
|
+
});
|
|
21
|
+
return "query ".concat(OPERATION_NAME, "(").concat(variables.join(', '), ") { ").concat(fields.join(' '), " }");
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** A request that never settles would otherwise leave its lookups pending for the page load. */
|
|
25
|
+
var REQUEST_TIMEOUT_MS = 10000;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fetches Marketplace partner names for at most one batch of lookups.
|
|
29
|
+
* Resolves `null` for apps without a listed partner and omits lookups whose field errored, so they
|
|
30
|
+
* can be retried; rejects with `AppVendorRequestError` when the request itself fails, or with an
|
|
31
|
+
* `AbortError` when it takes longer than `REQUEST_TIMEOUT_MS`.
|
|
32
|
+
*/
|
|
33
|
+
export var fetchAppVendors = /*#__PURE__*/function () {
|
|
34
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(lookups) {
|
|
35
|
+
var controller, timeout, response, _yield$response$json, data, errors, erroredAliases;
|
|
36
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
37
|
+
while (1) switch (_context.prev = _context.next) {
|
|
38
|
+
case 0:
|
|
39
|
+
controller = new AbortController();
|
|
40
|
+
timeout = setTimeout(function () {
|
|
41
|
+
return controller.abort();
|
|
42
|
+
}, REQUEST_TIMEOUT_MS);
|
|
43
|
+
_context.prev = 1;
|
|
44
|
+
_context.next = 2;
|
|
45
|
+
return fetch(AGG_PATH, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json'
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
operationName: OPERATION_NAME,
|
|
52
|
+
query: buildQuery(lookups),
|
|
53
|
+
variables: Object.fromEntries(lookups.map(function (_ref4, index) {
|
|
54
|
+
var value = _ref4.value;
|
|
55
|
+
return ["a".concat(index), value];
|
|
56
|
+
}))
|
|
57
|
+
}),
|
|
58
|
+
// Also aborts reading the body, so a slow response cannot hang either.
|
|
59
|
+
signal: controller.signal
|
|
60
|
+
});
|
|
61
|
+
case 2:
|
|
62
|
+
response = _context.sent;
|
|
63
|
+
if (response.ok) {
|
|
64
|
+
_context.next = 3;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
throw new AppVendorRequestError("App vendor request failed: ".concat(response.status), response.status);
|
|
68
|
+
case 3:
|
|
69
|
+
_context.next = 4;
|
|
70
|
+
return response.json();
|
|
71
|
+
case 4:
|
|
72
|
+
_yield$response$json = _context.sent;
|
|
73
|
+
data = _yield$response$json.data;
|
|
74
|
+
errors = _yield$response$json.errors;
|
|
75
|
+
if (data) {
|
|
76
|
+
_context.next = 5;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
throw new AppVendorRequestError('App vendor request returned no data');
|
|
80
|
+
case 5:
|
|
81
|
+
// A field that errored or timed out also returns null, which must not be cached as unlisted.
|
|
82
|
+
erroredAliases = new Set(errors === null || errors === void 0 ? void 0 : errors.map(function (_ref5) {
|
|
83
|
+
var path = _ref5.path;
|
|
84
|
+
return path === null || path === void 0 ? void 0 : path[0];
|
|
85
|
+
}));
|
|
86
|
+
return _context.abrupt("return", new Map(lookups.flatMap(function (_ref6, index) {
|
|
87
|
+
var _data$alias;
|
|
88
|
+
var id = _ref6.id;
|
|
89
|
+
var alias = "a".concat(index);
|
|
90
|
+
return erroredAliases.has(alias) ? [] : [[id, ((_data$alias = data[alias]) === null || _data$alias === void 0 || (_data$alias = _data$alias.partner) === null || _data$alias === void 0 ? void 0 : _data$alias.name) || null]];
|
|
91
|
+
})));
|
|
92
|
+
case 6:
|
|
93
|
+
_context.prev = 6;
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
return _context.finish(6);
|
|
96
|
+
case 7:
|
|
97
|
+
case "end":
|
|
98
|
+
return _context.stop();
|
|
99
|
+
}
|
|
100
|
+
}, _callee, null, [[1,, 6, 7]]);
|
|
101
|
+
}));
|
|
102
|
+
return function fetchAppVendors(_x) {
|
|
103
|
+
return _ref3.apply(this, arguments);
|
|
104
|
+
};
|
|
105
|
+
}();
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
+
import { AppVendorRequestError } from './AppVendorRequestError';
|
|
4
|
+
import { fetchAppVendors } from './fetchAppVendors';
|
|
5
|
+
/** Marketplace has no bulk lookup; larger aliased requests time out. */
|
|
6
|
+
var BATCH_SIZE = 15;
|
|
7
|
+
var MAX_CONCURRENT_BATCHES = 3;
|
|
8
|
+
/**
|
|
9
|
+
* Fetches lookups in batches, at most `MAX_CONCURRENT_BATCHES` at a time, reporting each batch as it
|
|
10
|
+
* settles. Batches that have not started when `shouldContinue` returns false are reported as skipped.
|
|
11
|
+
* Loaded on demand so editors without ecosystem apps never download the fetching code.
|
|
12
|
+
*/
|
|
13
|
+
export var fetchAppVendorsInBatches = /*#__PURE__*/function () {
|
|
14
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(lookups, _ref) {
|
|
15
|
+
var onBatch, shouldContinue, batches, start, nextBatch, runWorker;
|
|
16
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
17
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
18
|
+
case 0:
|
|
19
|
+
onBatch = _ref.onBatch, shouldContinue = _ref.shouldContinue;
|
|
20
|
+
batches = [];
|
|
21
|
+
for (start = 0; start < lookups.length; start += BATCH_SIZE) {
|
|
22
|
+
batches.push(lookups.slice(start, start + BATCH_SIZE));
|
|
23
|
+
}
|
|
24
|
+
nextBatch = 0;
|
|
25
|
+
runWorker = /*#__PURE__*/function () {
|
|
26
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
27
|
+
var batch, names, isBlocking, _t;
|
|
28
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
29
|
+
while (1) switch (_context.prev = _context.next) {
|
|
30
|
+
case 0:
|
|
31
|
+
if (!(nextBatch < batches.length)) {
|
|
32
|
+
_context.next = 6;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
batch = batches[nextBatch++];
|
|
36
|
+
if (shouldContinue()) {
|
|
37
|
+
_context.next = 1;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
onBatch(batch, {
|
|
41
|
+
status: 'skipped'
|
|
42
|
+
});
|
|
43
|
+
return _context.abrupt("continue", 0);
|
|
44
|
+
case 1:
|
|
45
|
+
// Only the request is caught, so a batch is never reported twice.
|
|
46
|
+
names = void 0;
|
|
47
|
+
_context.prev = 2;
|
|
48
|
+
_context.next = 3;
|
|
49
|
+
return fetchAppVendors(batch);
|
|
50
|
+
case 3:
|
|
51
|
+
names = _context.sent;
|
|
52
|
+
_context.next = 5;
|
|
53
|
+
break;
|
|
54
|
+
case 4:
|
|
55
|
+
_context.prev = 4;
|
|
56
|
+
_t = _context["catch"](2);
|
|
57
|
+
isBlocking = _t instanceof AppVendorRequestError && _t.isBlocking;
|
|
58
|
+
onBatch(batch, {
|
|
59
|
+
error: _t,
|
|
60
|
+
isBlocking: isBlocking,
|
|
61
|
+
status: 'rejected'
|
|
62
|
+
});
|
|
63
|
+
return _context.abrupt("continue", 0);
|
|
64
|
+
case 5:
|
|
65
|
+
onBatch(batch, {
|
|
66
|
+
names: names,
|
|
67
|
+
status: 'fulfilled'
|
|
68
|
+
});
|
|
69
|
+
_context.next = 0;
|
|
70
|
+
break;
|
|
71
|
+
case 6:
|
|
72
|
+
case "end":
|
|
73
|
+
return _context.stop();
|
|
74
|
+
}
|
|
75
|
+
}, _callee, null, [[2, 4]]);
|
|
76
|
+
}));
|
|
77
|
+
return function runWorker() {
|
|
78
|
+
return _ref3.apply(this, arguments);
|
|
79
|
+
};
|
|
80
|
+
}();
|
|
81
|
+
_context2.next = 1;
|
|
82
|
+
return Promise.all(Array.from({
|
|
83
|
+
length: Math.min(MAX_CONCURRENT_BATCHES, batches.length)
|
|
84
|
+
}, runWorker));
|
|
85
|
+
case 1:
|
|
86
|
+
case "end":
|
|
87
|
+
return _context2.stop();
|
|
88
|
+
}
|
|
89
|
+
}, _callee2);
|
|
90
|
+
}));
|
|
91
|
+
return function fetchAppVendorsInBatches(_x, _x2) {
|
|
92
|
+
return _ref2.apply(this, arguments);
|
|
93
|
+
};
|
|
94
|
+
}();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FORGE_EXTENSION_TYPE } from '@atlaskit/editor-common/extensions/manifest-helpers';
|
|
2
|
+
var FORGE_APP_ARI_PREFIX = 'ari:cloud:ecosystem::app/';
|
|
3
|
+
|
|
4
|
+
/** How to look up the Marketplace partner of the app that contributes an extension item. */
|
|
5
|
+
|
|
6
|
+
/** Returns a lookup only for ecosystem apps; Atlassian-owned items have no Marketplace partner. */
|
|
7
|
+
export var getAppVendorLookup = function getAppVendorLookup(_ref) {
|
|
8
|
+
var app = _ref.app,
|
|
9
|
+
extensionType = _ref.extensionType;
|
|
10
|
+
if ((app === null || app === void 0 ? void 0 : app.source) !== 'ecosystem' || !app.key) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
if (extensionType === FORGE_EXTENSION_TYPE) {
|
|
14
|
+
// Marketplace returns null for a bare Forge app UUID, so always send the full ARI.
|
|
15
|
+
var value = app.key.startsWith(FORGE_APP_ARI_PREFIX) ? app.key : "".concat(FORGE_APP_ARI_PREFIX).concat(app.key);
|
|
16
|
+
return {
|
|
17
|
+
id: "forge:".concat(value),
|
|
18
|
+
kind: 'forge',
|
|
19
|
+
value: value
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
id: "connect:".concat(app.key),
|
|
24
|
+
kind: 'connect',
|
|
25
|
+
value: app.key
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import { logException } from '@atlaskit/editor-common/monitoring/error';
|
|
5
|
+
import { appVendorCache } from './appVendorCache';
|
|
6
|
+
import { getAppVendorLookup } from './getAppVendorLookup';
|
|
7
|
+
|
|
8
|
+
/** Failed lookups are retried on later menu opens, up to this many attempts per page load. */
|
|
9
|
+
var MAX_ATTEMPTS = 3;
|
|
10
|
+
var LOG_LOCATION = 'editor-core/quick-insert/prefetchAppVendors';
|
|
11
|
+
var entries = appVendorCache.entries,
|
|
12
|
+
listeners = appVendorCache.listeners;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Set once any batch fails with 401, 403, or 429. Those mean the session cannot read Marketplace
|
|
16
|
+
* data or the gateway is throttling, which applies to every editor on the page, so all further
|
|
17
|
+
* lookups stop until the page reloads.
|
|
18
|
+
*/
|
|
19
|
+
var isBlocked = false;
|
|
20
|
+
var shouldFetch = function shouldFetch(entry) {
|
|
21
|
+
return !entry || entry.status === 'failed' && entry.attempts < MAX_ATTEMPTS;
|
|
22
|
+
};
|
|
23
|
+
var getAttempts = function getAttempts(entry) {
|
|
24
|
+
return (entry === null || entry === void 0 ? void 0 : entry.status) === 'failed' ? entry.attempts : 0;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// A throwing subscriber must not stop the others or abort the batch that is being settled.
|
|
28
|
+
var notify = function notify() {
|
|
29
|
+
return listeners.forEach(function (listener) {
|
|
30
|
+
try {
|
|
31
|
+
listener();
|
|
32
|
+
} catch (error) {
|
|
33
|
+
logException(error, {
|
|
34
|
+
location: LOG_LOCATION
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
var markFailed = function markFailed(_ref) {
|
|
40
|
+
var attempts = _ref.attempts,
|
|
41
|
+
id = _ref.id;
|
|
42
|
+
return entries.set(id, {
|
|
43
|
+
attempts: attempts,
|
|
44
|
+
status: 'failed'
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
var settleBatch = function settleBatch(batch, result) {
|
|
48
|
+
if (result.status !== 'fulfilled') {
|
|
49
|
+
if (result.status === 'rejected') {
|
|
50
|
+
isBlocked || (isBlocked = result.isBlocking);
|
|
51
|
+
logException(result.error, {
|
|
52
|
+
location: LOG_LOCATION
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
batch.forEach(markFailed);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Lookups missing from the result errored individually and stay retryable.
|
|
60
|
+
batch.forEach(function (lookup) {
|
|
61
|
+
var name = result.names.get(lookup.id);
|
|
62
|
+
if (name === undefined) {
|
|
63
|
+
markFailed(lookup);
|
|
64
|
+
} else {
|
|
65
|
+
entries.set(lookup.id, {
|
|
66
|
+
name: name,
|
|
67
|
+
status: 'resolved'
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
notify();
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Starts fetching Marketplace partner names for every ecosystem app among `items`.
|
|
76
|
+
* Safe to call repeatedly: cached, in-flight, and exhausted lookups are skipped. The fetching code
|
|
77
|
+
* is loaded only once a lookup is queued.
|
|
78
|
+
*/
|
|
79
|
+
export var prefetchAppVendors = function prefetchAppVendors(items) {
|
|
80
|
+
if (isBlocked) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
var lookups = [];
|
|
84
|
+
items.forEach(function (item) {
|
|
85
|
+
var lookup = getAppVendorLookup(item);
|
|
86
|
+
var entry = lookup && entries.get(lookup.id);
|
|
87
|
+
if (lookup && shouldFetch(entry)) {
|
|
88
|
+
lookups.push(_objectSpread(_objectSpread({}, lookup), {}, {
|
|
89
|
+
attempts: getAttempts(entry) + 1
|
|
90
|
+
}));
|
|
91
|
+
entries.set(lookup.id, {
|
|
92
|
+
status: 'pending'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
if (lookups.length === 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
void import( /* webpackChunkName: "@atlaskit-internal_editor-core-quick-insert-app-vendor" */'./fetchAppVendorsInBatches').then(function (_ref2) {
|
|
100
|
+
var fetchAppVendorsInBatches = _ref2.fetchAppVendorsInBatches;
|
|
101
|
+
return fetchAppVendorsInBatches(lookups, {
|
|
102
|
+
onBatch: settleBatch,
|
|
103
|
+
shouldContinue: function shouldContinue() {
|
|
104
|
+
return !isBlocked;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}, function (error) {
|
|
108
|
+
// The chunk failed to load; nothing was requested, so every queued lookup can retry.
|
|
109
|
+
lookups.forEach(markFailed);
|
|
110
|
+
logException(error, {
|
|
111
|
+
location: LOG_LOCATION
|
|
112
|
+
});
|
|
113
|
+
}).catch(function (error) {
|
|
114
|
+
// Fetch errors are reported per batch; this only catches an unexpected throw while settling.
|
|
115
|
+
logException(error, {
|
|
116
|
+
location: LOG_LOCATION
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
import { appVendorCache } from './appVendorCache';
|
|
3
|
+
var subscribe = function subscribe(listener) {
|
|
4
|
+
appVendorCache.listeners.add(listener);
|
|
5
|
+
return function () {
|
|
6
|
+
appVendorCache.listeners.delete(listener);
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
var getServerSnapshot = function getServerSnapshot() {
|
|
10
|
+
return undefined;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Returns the partner name, `null` for unlisted apps, or `undefined` while unknown. */
|
|
14
|
+
export var useAppVendorName = function useAppVendorName(id) {
|
|
15
|
+
var getSnapshot = function getSnapshot() {
|
|
16
|
+
var entry = id ? appVendorCache.entries.get(id) : undefined;
|
|
17
|
+
return (entry === null || entry === void 0 ? void 0 : entry.status) === 'resolved' ? entry.name : undefined;
|
|
18
|
+
};
|
|
19
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
20
|
+
};
|
|
@@ -6,6 +6,7 @@ import { createQuickInsertMatcher } from '@atlaskit/editor-common/quick-insert/c
|
|
|
6
6
|
import { getQuickInsertMenuItemParents } from '@atlaskit/editor-common/quick-insert/get-menu-item-parents';
|
|
7
7
|
import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, STRUCTURE_SECTION, TABS_MENU_ITEM } from '@atlaskit/editor-common/quick-insert/keys';
|
|
8
8
|
import { CREATE_SECTION_RANK, EXTENSION_ITEM_RANK, MEDIA_SECTION_RANK } from '@atlaskit/editor-common/quick-insert/rank';
|
|
9
|
+
import { prefetchAppVendors } from './app-vendor/prefetchAppVendors';
|
|
9
10
|
import { ExtensionQuickInsertMenuItem } from './ExtensionQuickInsertMenuItem';
|
|
10
11
|
import { QuickInsertSkillMenuItem } from './QuickInsertSkillMenuItem';
|
|
11
12
|
var structureExtensionItemKeyRanks = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
|
|
@@ -82,6 +83,10 @@ export var getExtensionQuickInsertComponents = function getExtensionQuickInsertC
|
|
|
82
83
|
editorActions = _ref4.editorActions,
|
|
83
84
|
items = _ref4.items;
|
|
84
85
|
var getExtensionItemRank = createExtensionItemRanker(items);
|
|
86
|
+
// Every row prefetches all items so the first row to mount fetches vendors in one batch.
|
|
87
|
+
var prefetchVendors = function prefetchVendors() {
|
|
88
|
+
return prefetchAppVendors(items);
|
|
89
|
+
};
|
|
85
90
|
return items.map(function (item, index) {
|
|
86
91
|
var structureRank = getStructureExtensionItemRank(item);
|
|
87
92
|
var isStructureItem = structureRank !== undefined;
|
|
@@ -116,13 +121,19 @@ export var getExtensionQuickInsertComponents = function getExtensionQuickInsertC
|
|
|
116
121
|
};
|
|
117
122
|
}),
|
|
118
123
|
component: function component(props) {
|
|
119
|
-
|
|
120
|
-
return /*#__PURE__*/React.createElement(Component, {
|
|
124
|
+
return item.extensionType === 'com.atlassian.rovo.skill' ? /*#__PURE__*/React.createElement(QuickInsertSkillMenuItem, {
|
|
121
125
|
apiRef: apiRef,
|
|
122
126
|
createAnalyticsEvent: createAnalyticsEvent,
|
|
123
127
|
editorActions: editorActions,
|
|
124
128
|
item: item,
|
|
125
129
|
onInsert: props.onInsert
|
|
130
|
+
}) : /*#__PURE__*/React.createElement(ExtensionQuickInsertMenuItem, {
|
|
131
|
+
apiRef: apiRef,
|
|
132
|
+
createAnalyticsEvent: createAnalyticsEvent,
|
|
133
|
+
editorActions: editorActions,
|
|
134
|
+
item: item,
|
|
135
|
+
onInsert: props.onInsert,
|
|
136
|
+
prefetchVendors: prefetchVendors
|
|
126
137
|
});
|
|
127
138
|
}
|
|
128
139
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { EditorNextProps } from '../types/editor-props';
|
|
3
|
-
export type ChromelessEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'assistiveLabel' | 'disabled' | 'shouldFocus' | 'quickInsert' | '
|
|
3
|
+
export type ChromelessEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'assistiveLabel' | 'disabled' | 'shouldFocus' | 'quickInsert' | 'secondaryToolbarComponents' | 'featureFlags' | 'onChange' | 'onDestroy' | 'onEditorReady' | 'onSave' | 'onCancel' | 'mentionProvider' | 'contextIdentifierProvider' | 'searchProvider' | 'extensionProviders' | 'popupsMountPoint' | 'popupsBoundariesElement' | 'popupsScrollableElement'>;
|
|
4
4
|
/**
|
|
5
5
|
* Editor component based on `ComposableEditor` which sets the `appearance` to "chromeless".
|
|
6
6
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { EditorNextProps } from '../types/editor-props';
|
|
3
|
-
export type CommentEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'assistiveLabel' | 'disabled' | 'shouldFocus' | 'quickInsert' | '
|
|
3
|
+
export type CommentEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'assistiveLabel' | 'disabled' | 'shouldFocus' | 'quickInsert' | 'secondaryToolbarComponents' | 'featureFlags' | 'onChange' | 'onDestroy' | 'onEditorReady' | 'onSave' | 'onCancel' | 'mentionProvider' | 'contextIdentifierProvider' | 'searchProvider' | 'extensionProviders'>;
|
|
4
4
|
/**
|
|
5
5
|
* Editor component based on `ComposableEditor` which sets the `appearance` to "comment".
|
|
6
6
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type EditorActions from '../actions';
|
|
3
3
|
import type { EditorNextProps } from '../types/editor-props';
|
|
4
|
-
export type FullPageEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'disabled' | 'mentionProvider' | '
|
|
4
|
+
export type FullPageEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'disabled' | 'mentionProvider' | 'contextIdentifierProvider' | 'searchProvider' | 'activityProvider' | 'annotationProviders' | 'collabEditProvider' | 'collabEdit' | 'contentMode' | 'taskDecisionProvider' | 'extensionProviders' | 'shouldFocus' | 'quickInsert' | 'secondaryToolbarComponents' | 'featureFlags' | 'primaryToolbarComponents' | 'contextPanel' | 'contentComponents' | 'primaryToolbarIconBefore' | 'sanitizePrivateContent' | '__livePage'> & {
|
|
5
5
|
appearance: 'full-page' | 'full-width' | 'max';
|
|
6
6
|
onChange?: () => void;
|
|
7
7
|
onEditorReady?: (editorActions: EditorActions) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { EditorNextProps } from '../types/editor-props';
|
|
3
|
-
export type FullWidthEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'disabled' | 'mentionProvider' | '
|
|
3
|
+
export type FullWidthEditorProps = Pick<EditorNextProps, 'preset' | 'defaultValue' | 'disabled' | 'mentionProvider' | 'contextIdentifierProvider' | 'searchProvider' | 'annotationProviders' | 'collabEditProvider' | 'collabEdit' | 'taskDecisionProvider' | 'extensionProviders' | 'shouldFocus' | 'quickInsert' | 'secondaryToolbarComponents' | 'featureFlags' | 'primaryToolbarComponents' | 'contextPanel' | 'contentComponents' | 'primaryToolbarIconBefore' | 'sanitizePrivateContent'> & {
|
|
4
4
|
onChange?: () => void;
|
|
5
5
|
onEditorReady?: () => void;
|
|
6
6
|
};
|
|
@@ -15,7 +15,6 @@ import type { EmptyStateHandler } from '@atlaskit/editor-common/types/empty-stat
|
|
|
15
15
|
import type { FeedbackInfo } from '@atlaskit/editor-common/types/feedback-dialog';
|
|
16
16
|
import type { LinkingOptions } from '@atlaskit/editor-common/types/hyperlink';
|
|
17
17
|
import type { Transformer } from '@atlaskit/editor-common/types/next-editor-plugin';
|
|
18
|
-
import type { PerformanceTracking } from '@atlaskit/editor-common/types/performance-tracking';
|
|
19
18
|
import type { QuickInsertOptions } from '@atlaskit/editor-common/types/quick-insert';
|
|
20
19
|
import type { MenuItem } from '@atlaskit/editor-common/ui-menu/DropdownMenu/types';
|
|
21
20
|
import type { UseStickyToolbarType } from '@atlaskit/editor-common/ui-toolbar';
|
|
@@ -83,7 +82,7 @@ interface EditorBaseProps {
|
|
|
83
82
|
contentMode?: 'standard' | 'compact' | undefined;
|
|
84
83
|
contentTransformerProvider?: (schema: Schema) => Transformer<string>;
|
|
85
84
|
contextPanel?: ReactComponents;
|
|
86
|
-
defaultValue?: Node | string |
|
|
85
|
+
defaultValue?: Node | string | object;
|
|
87
86
|
disabled?: boolean;
|
|
88
87
|
editorActions?: EditorActions;
|
|
89
88
|
errorReporterHandler?: ErrorReportingHandler;
|
|
@@ -119,12 +118,6 @@ interface EditorBaseProps {
|
|
|
119
118
|
featureFlags?: {
|
|
120
119
|
[featureFlag: string]: string | boolean;
|
|
121
120
|
};
|
|
122
|
-
/**
|
|
123
|
-
* @deprecated do not use, value is hardcoded. Can be mocked for tests. Config exists here: platform/packages/editor/editor-plugin-base/src/pm-plugins/utils/inputTrackingConfig.ts
|
|
124
|
-
* @description The nth keystroke after which an input time taken event is sent, 0 to disable it
|
|
125
|
-
* @default 100
|
|
126
|
-
*/
|
|
127
|
-
inputSamplingLimit?: number;
|
|
128
121
|
isEditorModernisationEnabled?: boolean;
|
|
129
122
|
maxHeight?: number;
|
|
130
123
|
minHeight?: number;
|
|
@@ -189,11 +182,6 @@ export interface EditorSharedPropsWithPlugins {
|
|
|
189
182
|
allowUndoRedoButtons?: boolean;
|
|
190
183
|
collabEdit?: CollabEditOptions;
|
|
191
184
|
onSave?: (editorView: EditorView) => void;
|
|
192
|
-
/**
|
|
193
|
-
* @deprecated do not use, value is hardcoded. Can be mocked for tests. Config exists here: platform/packages/editor/editor-plugin-base/src/pm-plugins/utils/inputTrackingConfig.ts
|
|
194
|
-
* @description Control performance metric measurements and tracking
|
|
195
|
-
*/
|
|
196
|
-
performanceTracking?: PerformanceTracking;
|
|
197
185
|
primaryToolbarComponents?: PrimaryToolbarComponents;
|
|
198
186
|
sanitizePrivateContent?: boolean;
|
|
199
187
|
}
|
|
@@ -4,10 +4,12 @@ import type { MenuItem } from '@atlaskit/editor-common/extensions/types/utils';
|
|
|
4
4
|
import type { PublicPluginAPI } from '@atlaskit/editor-common/types/next-editor-plugin';
|
|
5
5
|
import type { ExtensionPlugin } from '@atlaskit/editor-plugin-extension/extensionPluginType';
|
|
6
6
|
import type EditorActions from '../../actions';
|
|
7
|
-
export declare const ExtensionQuickInsertMenuItem: ({ apiRef, createAnalyticsEvent, editorActions, item, onInsert, }: {
|
|
7
|
+
export declare const ExtensionQuickInsertMenuItem: ({ apiRef, createAnalyticsEvent, editorActions, item, onInsert, prefetchVendors, }: {
|
|
8
8
|
apiRef: React.MutableRefObject<PublicPluginAPI<[ExtensionPlugin]> | undefined>;
|
|
9
9
|
createAnalyticsEvent?: CreateUIAnalyticsEvent;
|
|
10
10
|
editorActions: EditorActions;
|
|
11
11
|
item: MenuItem;
|
|
12
12
|
onInsert?: () => void;
|
|
13
|
+
/** Starts fetching vendor names for every extension item in the menu. */
|
|
14
|
+
prefetchVendors?: () => void;
|
|
13
15
|
}) => React.JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type AppVendorEntry = {
|
|
2
|
+
status: 'pending';
|
|
3
|
+
} | {
|
|
4
|
+
name: string | null;
|
|
5
|
+
status: 'resolved';
|
|
6
|
+
} | {
|
|
7
|
+
attempts: number;
|
|
8
|
+
status: 'failed';
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Vendor names keyed by lookup id, plus the subscribers to notify when they change.
|
|
12
|
+
* Module scope so names survive editor and provider rebuilds for the rest of the page load.
|
|
13
|
+
*/
|
|
14
|
+
export declare const appVendorCache: {
|
|
15
|
+
entries: Map<string, AppVendorEntry>;
|
|
16
|
+
listeners: Set<() => void>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AppVendorLookup } from './getAppVendorLookup';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches Marketplace partner names for at most one batch of lookups.
|
|
4
|
+
* Resolves `null` for apps without a listed partner and omits lookups whose field errored, so they
|
|
5
|
+
* can be retried; rejects with `AppVendorRequestError` when the request itself fails, or with an
|
|
6
|
+
* `AbortError` when it takes longer than `REQUEST_TIMEOUT_MS`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const fetchAppVendors: (lookups: AppVendorLookup[]) => Promise<Map<string, string | null>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AppVendorLookup } from './getAppVendorLookup';
|
|
2
|
+
export type QueuedLookup = AppVendorLookup & {
|
|
3
|
+
attempts: number;
|
|
4
|
+
};
|
|
5
|
+
export type AppVendorBatchResult = {
|
|
6
|
+
names: Map<string, string | null>;
|
|
7
|
+
status: 'fulfilled';
|
|
8
|
+
} | {
|
|
9
|
+
error: unknown;
|
|
10
|
+
isBlocking: boolean;
|
|
11
|
+
status: 'rejected';
|
|
12
|
+
} | {
|
|
13
|
+
status: 'skipped';
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Fetches lookups in batches, at most `MAX_CONCURRENT_BATCHES` at a time, reporting each batch as it
|
|
17
|
+
* settles. Batches that have not started when `shouldContinue` returns false are reported as skipped.
|
|
18
|
+
* Loaded on demand so editors without ecosystem apps never download the fetching code.
|
|
19
|
+
*/
|
|
20
|
+
export declare const fetchAppVendorsInBatches: (lookups: QueuedLookup[], { onBatch, shouldContinue, }: {
|
|
21
|
+
onBatch: (batch: QueuedLookup[], result: AppVendorBatchResult) => void;
|
|
22
|
+
shouldContinue: () => boolean;
|
|
23
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MenuItem } from '@atlaskit/editor-common/extensions/types/utils';
|
|
2
|
+
/** How to look up the Marketplace partner of the app that contributes an extension item. */
|
|
3
|
+
export type AppVendorLookup = {
|
|
4
|
+
/** Stable cache key shared by every item from the same app. */
|
|
5
|
+
id: string;
|
|
6
|
+
kind: 'forge' | 'connect';
|
|
7
|
+
/** Forge app ARI or Connect app key. */
|
|
8
|
+
value: string;
|
|
9
|
+
};
|
|
10
|
+
/** Returns a lookup only for ecosystem apps; Atlassian-owned items have no Marketplace partner. */
|
|
11
|
+
export declare const getAppVendorLookup: ({ app, extensionType, }: Pick<MenuItem, 'app' | 'extensionType'>) => AppVendorLookup | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MenuItem } from '@atlaskit/editor-common/extensions/types/utils';
|
|
2
|
+
/**
|
|
3
|
+
* Starts fetching Marketplace partner names for every ecosystem app among `items`.
|
|
4
|
+
* Safe to call repeatedly: cached, in-flight, and exhausted lookups are skipped. The fetching code
|
|
5
|
+
* is loaded only once a lookup is queued.
|
|
6
|
+
*/
|
|
7
|
+
export declare const prefetchAppVendors: (items: Pick<MenuItem, 'app' | 'extensionType'>[]) => void;
|