@atlaskit/editor-plugin-quick-insert 30.0.1 → 30.0.3

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.
Files changed (28) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/quickInsertPlugin.js +6 -2
  3. package/dist/cjs/ui/getQuickInsertComponents.js +8 -53
  4. package/dist/cjs/ui/getRecommendedComponents.js +19 -38
  5. package/dist/cjs/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  6. package/dist/cjs/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  7. package/dist/cjs/ui/registered-menu/get-quick-insert-menu-model.js +175 -88
  8. package/dist/es2019/quickInsertPlugin.js +6 -2
  9. package/dist/es2019/ui/getQuickInsertComponents.js +6 -43
  10. package/dist/es2019/ui/getRecommendedComponents.js +17 -37
  11. package/dist/es2019/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  12. package/dist/es2019/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  13. package/dist/es2019/ui/registered-menu/get-quick-insert-menu-model.js +128 -55
  14. package/dist/esm/quickInsertPlugin.js +6 -2
  15. package/dist/esm/ui/getQuickInsertComponents.js +8 -53
  16. package/dist/esm/ui/getRecommendedComponents.js +18 -37
  17. package/dist/esm/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  18. package/dist/esm/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  19. package/dist/esm/ui/registered-menu/get-quick-insert-menu-model.js +176 -89
  20. package/dist/types/ui/getQuickInsertComponents.d.ts +3 -4
  21. package/dist/types/ui/getRecommendedComponents.d.ts +8 -13
  22. package/dist/types/ui/registered-menu/QuickInsertMenuRoot.d.ts +3 -1
  23. package/dist/types/ui/registered-menu/get-quick-insert-menu-model.d.ts +12 -2
  24. package/package.json +5 -6
  25. package/dist/cjs/ui/QuickInsertRecommendedSlot.js +0 -23
  26. package/dist/es2019/ui/QuickInsertRecommendedSlot.js +0 -18
  27. package/dist/esm/ui/QuickInsertRecommendedSlot.js +0 -16
  28. package/dist/types/ui/QuickInsertRecommendedSlot.d.ts +0 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-quick-insert
2
2
 
3
+ ## 30.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`9e0f075939161`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9e0f075939161) -
8
+ Deduplicate registered Quick Insert items across recommended, search, and browse views, while
9
+ preserving selection identity and registration context when `platform_editor_slash_command` is
10
+ enabled.
11
+ - Updated dependencies
12
+
13
+ ## 30.0.2
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+
3
19
  ## 30.0.1
4
20
 
5
21
  ### Patch Changes
@@ -28,6 +28,7 @@ var _pluginKey = require("./pm-plugins/plugin-key");
28
28
  var _blockControlQuickInsert = require("./ui/block-control-quick-insert");
29
29
  var _getLegacyCompatibleComponents = require("./ui/getLegacyCompatibleComponents");
30
30
  var _getQuickInsertComponents = require("./ui/getQuickInsertComponents");
31
+ var _getRecommendedComponents = require("./ui/getRecommendedComponents");
31
32
  var _ModalElementBrowser = _interopRequireDefault(require("./ui/ModalElementBrowser"));
32
33
  var _RegistryElementBrowser = require("./ui/RegistryElementBrowser");
33
34
  var _search = require("./ui/search");
@@ -43,6 +44,10 @@ var quickInsertPlugin = exports.quickInsertPlugin = function quickInsertPlugin(_
43
44
  };
44
45
  var typeAheadPrioritySortingFn = (0, _search.withLayoutQuickInsertPrioritySorting)(options === null || options === void 0 ? void 0 : options.prioritySortingFn);
45
46
  var getItemRank = (0, _quickInsertRank.createQuickInsertRankResolver)(options === null || options === void 0 ? void 0 : options.getItemRank);
47
+ var getRecommendedItems = (0, _getRecommendedComponents.createRecommendedItemsResolver)({
48
+ isRecommendedItem: options === null || options === void 0 ? void 0 : options.isRecommendedItem,
49
+ maxRecommendedItems: options === null || options === void 0 ? void 0 : options.maxRecommendedItems
50
+ });
46
51
  var typeAhead = {
47
52
  id: _typeAhead.TypeAheadAvailableNodes.QUICK_INSERT,
48
53
  registeredMenuKey: (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_slash_command') ? _keys.MENU.key : undefined,
@@ -91,8 +96,7 @@ var quickInsertPlugin = exports.quickInsertPlugin = function quickInsertPlugin(_
91
96
  api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register((0, _getQuickInsertComponents.getQuickInsertComponents)({
92
97
  api: api,
93
98
  getItemRank: getItemRank,
94
- isRecommendedItem: options === null || options === void 0 ? void 0 : options.isRecommendedItem,
95
- maxRecommendedItems: options === null || options === void 0 ? void 0 : options.maxRecommendedItems,
99
+ getRecommendedItems: getRecommendedItems,
96
100
  emptyStateHandler: options === null || options === void 0 ? void 0 : options.emptyStateHandler,
97
101
  fireAnalyticsEvent: api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent,
98
102
  includeElementBrowserItems: (options === null || options === void 0 ? void 0 : options.enableElementBrowser) === true
@@ -13,9 +13,7 @@ var _messages = require("@atlaskit/editor-common/quick-insert/messages");
13
13
  var _rank = require("@atlaskit/editor-common/quick-insert/rank");
14
14
  var _typeAheadGetMenuFooterSectionKey = require("@atlaskit/editor-common/type-ahead-get-menu-footer-section-key");
15
15
  var _typeAheadGetSectionOverflowItemKey = require("@atlaskit/editor-common/type-ahead-get-section-overflow-item-key");
16
- var _getRecommendedComponents = require("./getRecommendedComponents");
17
16
  var _QuickInsertMenuFooterItem = require("./QuickInsertMenuFooterItem");
18
- var _QuickInsertRecommendedSlot = require("./QuickInsertRecommendedSlot");
19
17
  var _QuickInsertSectionOverflowMenuItem = require("./QuickInsertSectionOverflowMenuItem");
20
18
  var _QuickInsertMenuRoot = _interopRequireDefault(require("./registered-menu/QuickInsertMenuRoot"));
21
19
  var _QuickInsertMenuSection = require("./registered-menu/QuickInsertMenuSection");
@@ -64,62 +62,24 @@ var createSectionComponent = function createSectionComponent(message) {
64
62
  var getQuickInsertComponents = exports.getQuickInsertComponents = function getQuickInsertComponents(_ref2) {
65
63
  var api = _ref2.api,
66
64
  includeElementBrowserItems = _ref2.includeElementBrowserItems,
67
- isRecommendedItem = _ref2.isRecommendedItem,
68
- maxRecommendedItems = _ref2.maxRecommendedItems,
69
65
  getItemRank = _ref2.getItemRank,
66
+ getRecommendedItems = _ref2.getRecommendedItems,
70
67
  emptyStateHandler = _ref2.emptyStateHandler,
71
68
  fireAnalyticsEvent = _ref2.fireAnalyticsEvent;
72
- var recommendedSnapshot = (0, _getRecommendedComponents.createRecommendedSnapshotCache)({
73
- api: api,
74
- isRecommendedItem: isRecommendedItem,
75
- maxRecommendedItems: maxRecommendedItems
76
- });
77
- var recommendedSlots = Array.from({
78
- length: _getRecommendedComponents.MAX_RECOMMENDED_ITEMS
79
- }, function (_, index) {
80
- return {
81
- key: "".concat(_getRecommendedComponents.RECOMMENDED_SLOT_KEY_PREFIX).concat(index),
82
- type: 'menu-item',
83
- parents: [{
84
- key: _keys.RECOMMENDED_SECTION.key,
85
- type: _keys.RECOMMENDED_SECTION.type,
86
- rank: index
87
- }],
88
- match: function match() {
89
- return null;
90
- },
91
- isHidden: function isHidden() {
92
- var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
93
- surfaceContext = _ref3.surfaceContext;
94
- return !recommendedSnapshot.getSnapshot(surfaceContext)[index];
95
- },
96
- component: function component(_ref4) {
97
- var children = _ref4.children,
98
- parents = _ref4.parents,
99
- surfaceContext = _ref4.surfaceContext;
100
- return /*#__PURE__*/_react.default.createElement(_QuickInsertRecommendedSlot.QuickInsertRecommendedSlot, {
101
- parents: parents,
102
- surfaceContext: surfaceContext,
103
- index: index,
104
- getSnapshot: recommendedSnapshot.getSnapshot
105
- }, children);
106
- }
107
- };
108
- });
109
69
  return [{
110
70
  key: _keys.MENU.key,
111
71
  type: _keys.MENU.type,
112
- component: function component(_ref5) {
113
- var children = _ref5.children;
72
+ component: function component() {
114
73
  return /*#__PURE__*/_react.default.createElement(_QuickInsertMenuRoot.default, {
115
74
  getItemRank: getItemRank,
75
+ getRecommendedItems: getRecommendedItems,
116
76
  emptyStateHandler: emptyStateHandler,
117
77
  fireAnalyticsEvent: fireAnalyticsEvent
118
- }, children);
78
+ });
119
79
  }
120
- }].concat(recommendedSlots, (0, _toConsumableArray2.default)(categories.flatMap(function (_ref6) {
121
- var message = _ref6.message,
122
- section = _ref6.section;
80
+ }].concat((0, _toConsumableArray2.default)(categories.flatMap(function (_ref3) {
81
+ var message = _ref3.message,
82
+ section = _ref3.section;
123
83
  return [{
124
84
  key: section.key,
125
85
  type: section.type,
@@ -128,12 +88,7 @@ var getQuickInsertComponents = exports.getQuickInsertComponents = function getQu
128
88
  type: _keys.MENU.type,
129
89
  rank: _rank.QUICK_INSERT_MENU_RANK[section.key]
130
90
  }],
131
- component: createSectionComponent(message),
132
- isHidden: section.key === _keys.RECOMMENDED_SECTION.key ? function () {
133
- var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
134
- surfaceContext = _ref7.surfaceContext;
135
- return recommendedSnapshot.getSnapshot(surfaceContext).length === 0;
136
- } : undefined
91
+ component: createSectionComponent(message)
137
92
  }].concat((0, _toConsumableArray2.default)(includeElementBrowserItems && section.key !== _keys.RECOMMENDED_SECTION.key ? [{
138
93
  key: (0, _typeAheadGetSectionOverflowItemKey.getSectionOverflowItemKey)(section.key),
139
94
  type: 'menu-item',
@@ -3,32 +3,26 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.resolveMaxRecommendedItems = exports.isRecommendedSlotKey = exports.getRecommendedComponents = exports.createRecommendedSnapshotCache = exports.RECOMMENDED_SLOT_KEY_PREFIX = exports.MAX_RECOMMENDED_ITEMS = void 0;
6
+ exports.resolveMaxRecommendedItems = exports.getRecommendedComponents = exports.createRecommendedItemsResolver = exports.MAX_RECOMMENDED_ITEMS = void 0;
7
7
  var _error = require("@atlaskit/editor-common/monitoring/error");
8
8
  var _getProviderMenuItemKey = require("@atlaskit/editor-common/quick-insert/get-provider-menu-item-key");
9
9
  var _isRecommendedItem = require("@atlaskit/editor-common/quick-insert/is-recommended-item");
10
- var _keys = require("@atlaskit/editor-common/quick-insert/keys");
11
- var _surfaceContext = require("@atlaskit/editor-common/registered-menu/surface-context");
12
10
  var _typeAheadIsMenuFooterSectionKey = require("@atlaskit/editor-common/type-ahead-is-menu-footer-section-key");
13
11
  var _typeAheadIsSectionOverflowItemKey = require("@atlaskit/editor-common/type-ahead-is-section-overflow-item-key");
14
12
  var MAX_RECOMMENDED_ITEMS = exports.MAX_RECOMMENDED_ITEMS = 5;
15
- var RECOMMENDED_SLOT_KEY_PREFIX = exports.RECOMMENDED_SLOT_KEY_PREFIX = 'quick-insert-recommended-slot-';
16
- var isRecommendedSlotKey = exports.isRecommendedSlotKey = function isRecommendedSlotKey(key) {
17
- return key.startsWith(RECOMMENDED_SLOT_KEY_PREFIX);
18
- };
19
13
  var isRecommendationCandidate = function isRecommendationCandidate(component) {
20
- return component.type === 'menu-item' && !isRecommendedSlotKey(component.key) && !(0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(component.key) && !component.parents.some(function (parent) {
14
+ return component.type === 'menu-item' && !(0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(component.key) && !component.parents.some(function (parent) {
21
15
  return (0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(parent.key);
22
16
  });
23
17
  };
24
18
 
25
- /** Normalises a consumer-supplied limit to the number of available recommended slots. */
19
+ /** Normalises a consumer-supplied limit to the supported number of recommended items. */
26
20
  var resolveMaxRecommendedItems = exports.resolveMaxRecommendedItems = function resolveMaxRecommendedItems(maxRecommendedItems) {
27
21
  if (maxRecommendedItems === undefined || !Number.isFinite(maxRecommendedItems)) {
28
22
  return MAX_RECOMMENDED_ITEMS;
29
23
  }
30
24
  if (maxRecommendedItems > MAX_RECOMMENDED_ITEMS) {
31
- void (0, _error.logException)(new Error('Quick Insert maxRecommendedItems exceeds the available slots'), {
25
+ void (0, _error.logException)(new Error('Quick Insert maxRecommendedItems exceeds the supported maximum'), {
32
26
  location: 'editor-plugin-quick-insert/getRecommendedComponents'
33
27
  });
34
28
  }
@@ -73,34 +67,21 @@ var getRecommendedComponents = exports.getRecommendedComponents = function getRe
73
67
  });
74
68
  };
75
69
 
76
- /** Keeps only the current menu-open recommendation snapshot. */
77
-
78
- var createRecommendedSnapshotCache = exports.createRecommendedSnapshotCache = function createRecommendedSnapshotCache(_ref3) {
79
- var api = _ref3.api,
80
- isRecommendedItem = _ref3.isRecommendedItem,
70
+ /**
71
+ * Resolves the Recommended section for a browse-mode menu. Callers memoise per components array,
72
+ * so the resolver itself keeps no state.
73
+ */
74
+ var createRecommendedItemsResolver = exports.createRecommendedItemsResolver = function createRecommendedItemsResolver(_ref3) {
75
+ var isRecommendedItem = _ref3.isRecommendedItem,
81
76
  maxRecommendedItems = _ref3.maxRecommendedItems;
82
- var snapshot;
83
- var getSnapshot = function getSnapshot(surfaceContext) {
84
- var _surfaceContext$get, _snapshot;
85
- var menuOpenId = surfaceContext === null || surfaceContext === void 0 || (_surfaceContext$get = surfaceContext.get(_surfaceContext.REGISTERED_MENU_SURFACE_CONTEXT)) === null || _surfaceContext$get === void 0 ? void 0 : _surfaceContext$get.menuOpenId;
86
- if (!surfaceContext || !menuOpenId) {
87
- return [];
88
- }
89
- if (((_snapshot = snapshot) === null || _snapshot === void 0 ? void 0 : _snapshot.id) !== menuOpenId) {
90
- var _api$uiControlRegistr, _api$uiControlRegistr2;
91
- snapshot = {
92
- id: menuOpenId,
93
- items: getRecommendedComponents({
94
- components: (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(_keys.MENU.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [],
95
- context: surfaceContext,
96
- isRecommendedItem: isRecommendedItem,
97
- maxRecommendedItems: maxRecommendedItems
98
- })
99
- };
100
- }
101
- return snapshot.items;
102
- };
103
- return {
104
- getSnapshot: getSnapshot
77
+ return function (_ref4) {
78
+ var components = _ref4.components,
79
+ surfaceContext = _ref4.surfaceContext;
80
+ return surfaceContext ? getRecommendedComponents({
81
+ components: components,
82
+ context: surfaceContext,
83
+ isRecommendedItem: isRecommendedItem,
84
+ maxRecommendedItems: maxRecommendedItems
85
+ }) : [];
105
86
  };
106
87
  };
@@ -38,7 +38,8 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
38
38
  var _surfaceContext$get, _registeredMenu$maxHe;
39
39
  var emptyStateHandler = _ref.emptyStateHandler,
40
40
  fireAnalyticsEvent = _ref.fireAnalyticsEvent,
41
- getItemRank = _ref.getItemRank;
41
+ getItemRank = _ref.getItemRank,
42
+ getRecommendedItems = _ref.getRecommendedItems;
42
43
  var registeredMenu = (0, _context.useRegisteredMenuContext)();
43
44
  var _registeredMenu$query = registeredMenu.query,
44
45
  query = _registeredMenu$query === void 0 ? '' : _registeredMenu$query,
@@ -58,6 +59,7 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
58
59
  components: components,
59
60
  formatMessage: formatMessage,
60
61
  getItemRank: runtimeItemRank !== null && runtimeItemRank !== void 0 ? runtimeItemRank : getItemRank,
62
+ getRecommendedItems: getRecommendedItems,
61
63
  query: query,
62
64
  rootComponent: rootComponent,
63
65
  selectCategoryItems: components.some(function (_ref2) {
@@ -66,7 +68,7 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
66
68
  }) ? _selectQuickInsertCategoryItems.selectQuickInsertCategoryItems : undefined,
67
69
  surfaceContext: surfaceContext
68
70
  });
69
- }, [components, formatMessage, getItemRank, query, rootComponent, runtimeItemRank, surfaceContext]);
71
+ }, [components, formatMessage, getItemRank, getRecommendedItems, query, rootComponent, runtimeItemRank, surfaceContext]);
70
72
  var resultCount = (0, _react.useMemo)(function () {
71
73
  return model.sections.reduce(function (count, _ref3) {
72
74
  var _ref4 = (0, _toArray2.default)(_ref3),
@@ -10,7 +10,6 @@ var _provider = require("@atlaskit/editor-common/quick-insert/provider");
10
10
  var _useQuickInsertContext = require("@atlaskit/editor-common/quick-insert/use-quick-insert-context");
11
11
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
12
12
  var RegisteredQuickInsertMenuItem = exports.RegisteredQuickInsertMenuItem = function RegisteredQuickInsertMenuItem(_ref) {
13
- var _registration$compone;
14
13
  var id = _ref.id,
15
14
  isSelected = _ref.isSelected,
16
15
  isActive = _ref.isActive,
@@ -35,8 +34,11 @@ var RegisteredQuickInsertMenuItem = exports.RegisteredQuickInsertMenuItem = func
35
34
  surfaceContext: surfaceContext
36
35
  };
37
36
  }, [editorView, isOffline, popupsMountPoint, select, surfaceContext, isActive, id, isSelected]);
38
- var Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : _react.default.Fragment;
37
+ var Component = registration.component;
39
38
  return /*#__PURE__*/_react.default.createElement(_provider.QuickInsertProvider, {
40
39
  value: value
41
- }, /*#__PURE__*/_react.default.createElement(Component, null, null));
40
+ }, Component ? /*#__PURE__*/_react.default.createElement(Component, {
41
+ parents: registration.parents,
42
+ surfaceContext: surfaceContext
43
+ }, null) : null);
42
44
  };
@@ -51,48 +51,70 @@ var getSearchResults = function getSearchResults(matches) {
51
51
  var identity = _ref.identity;
52
52
  return identity;
53
53
  }));
54
- var tailMatches = matches.filter(function (_ref2) {
54
+ return [].concat((0, _toConsumableArray2.default)(topMatches), (0, _toConsumableArray2.default)(matches.filter(function (_ref2) {
55
55
  var identity = _ref2.identity;
56
56
  return !topMatchIdentities.has(identity);
57
- });
58
- return [].concat((0, _toConsumableArray2.default)(topMatches), (0, _toConsumableArray2.default)(tailMatches)).map(function (_ref3) {
59
- var item = _ref3.item;
60
- return item;
61
- });
62
- };
63
- var getRenderedMenuItems = function getRenderedMenuItems(section, childrenMap, surfaceContext) {
64
- var _childrenMap$get;
65
- return ((_childrenMap$get = childrenMap.get((0, _surfaceRenderer.getComponentIdentity)(section))) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : []).filter(function (child) {
66
- return child.type === 'menu-item' && (0, _surfaceRenderer.willComponentRender)(child, childrenMap, surfaceContext);
67
- });
57
+ })));
68
58
  };
69
- var buildBrowseSections = function buildBrowseSections(_ref4) {
70
- var childrenMap = _ref4.childrenMap,
71
- contentSections = _ref4.contentSections,
72
- selectCategoryItems = _ref4.selectCategoryItems,
73
- surfaceContext = _ref4.surfaceContext;
74
- var sections = [];
75
- var _iterator = _createForOfIteratorHelper(contentSections),
59
+
60
+ /** Recommended uses resolved items rather than registered children. */
61
+ var readMenuSections = function readMenuSections(_ref3) {
62
+ var childrenMap = _ref3.childrenMap,
63
+ _ref3$recommendedItem = _ref3.recommendedItems,
64
+ recommendedItems = _ref3$recommendedItem === void 0 ? [] : _ref3$recommendedItem,
65
+ sections = _ref3.sections,
66
+ surfaceContext = _ref3.surfaceContext;
67
+ var renderedSections = [];
68
+ var _iterator = _createForOfIteratorHelper(sections),
76
69
  _step;
77
70
  try {
78
71
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
72
+ var _section$isHidden, _section$isHidden2, _childrenMap$get;
79
73
  var section = _step.value;
80
- var children = getRenderedMenuItems(section, childrenMap, surfaceContext);
81
- var overflowItems = children.filter(function (child) {
82
- return (0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(child.key);
83
- });
84
- var viewMoreItem = overflowItems[overflowItems.length - 1];
85
- var items = children.filter(function (child) {
86
- return !(0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(child.key);
87
- });
88
- if (items.length === 0) {
74
+ if (section.type !== 'menu-section') {
89
75
  continue;
90
76
  }
91
- var selectedItems = viewMoreItem !== undefined && selectCategoryItems !== undefined ? selectCategoryItems(items) : items;
92
- if (selectedItems.length < items.length && viewMoreItem !== undefined) {
93
- sections.push([section].concat((0, _toConsumableArray2.default)(selectedItems), [viewMoreItem]));
94
- } else {
95
- sections.push([section].concat((0, _toConsumableArray2.default)(selectedItems)));
77
+ if (surfaceContext ? (_section$isHidden = section.isHidden) === null || _section$isHidden === void 0 ? void 0 : _section$isHidden.call(section, {
78
+ surfaceContext: surfaceContext
79
+ }) : (_section$isHidden2 = section.isHidden) === null || _section$isHidden2 === void 0 ? void 0 : _section$isHidden2.call(section)) {
80
+ continue;
81
+ }
82
+ if (section.key === _keys.RECOMMENDED_SECTION.key) {
83
+ renderedSections.push({
84
+ section: section,
85
+ items: recommendedItems
86
+ });
87
+ continue;
88
+ }
89
+ var children = (_childrenMap$get = childrenMap.get((0, _surfaceRenderer.getComponentIdentity)(section))) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : [];
90
+ var items = [];
91
+ var viewMoreItem = void 0;
92
+ var _iterator2 = _createForOfIteratorHelper(children),
93
+ _step2;
94
+ try {
95
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
96
+ var child = _step2.value;
97
+ if (child.type !== 'menu-item' || !(0, _surfaceRenderer.willComponentRender)(child, childrenMap, surfaceContext)) {
98
+ continue;
99
+ }
100
+ if ((0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(child.key)) {
101
+ viewMoreItem !== null && viewMoreItem !== void 0 ? viewMoreItem : viewMoreItem = child;
102
+ } else {
103
+ items.push(child);
104
+ }
105
+ }
106
+ // Empty registrations are visible leaves; containers need a visible child.
107
+ } catch (err) {
108
+ _iterator2.e(err);
109
+ } finally {
110
+ _iterator2.f();
111
+ }
112
+ if (children.length === 0 || items.length > 0 || viewMoreItem) {
113
+ renderedSections.push({
114
+ section: section,
115
+ items: items,
116
+ viewMoreItem: viewMoreItem
117
+ });
96
118
  }
97
119
  }
98
120
  } catch (err) {
@@ -100,53 +122,92 @@ var buildBrowseSections = function buildBrowseSections(_ref4) {
100
122
  } finally {
101
123
  _iterator.f();
102
124
  }
125
+ return renderedSections;
126
+ };
127
+ var getOwnerSectionKey = function getOwnerSectionKey(item, isRecommendedItem) {
128
+ var _item$parents$;
129
+ return isRecommendedItem(item) ? _keys.RECOMMENDED_SECTION.key : (_item$parents$ = item.parents[0]) === null || _item$parents$ === void 0 ? void 0 : _item$parents$.key;
130
+ };
131
+ var buildBrowseSections = function buildBrowseSections(_ref4) {
132
+ var contentSections = _ref4.contentSections,
133
+ isRecommendedItem = _ref4.isRecommendedItem,
134
+ selectCategoryItems = _ref4.selectCategoryItems;
135
+ var sections = [];
136
+ var _iterator3 = _createForOfIteratorHelper(contentSections),
137
+ _step3;
138
+ try {
139
+ var _loop = function _loop() {
140
+ var _step3$value = _step3.value,
141
+ items = _step3$value.items,
142
+ section = _step3$value.section,
143
+ viewMoreItem = _step3$value.viewMoreItem;
144
+ var ownedItems = items.filter(function (item) {
145
+ return getOwnerSectionKey(item, isRecommendedItem) === section.key;
146
+ });
147
+ if (ownedItems.length === 0) {
148
+ return 1; // continue
149
+ }
150
+ var selectedItems = viewMoreItem && selectCategoryItems ? selectCategoryItems(ownedItems) : ownedItems;
151
+ sections.push([section].concat((0, _toConsumableArray2.default)(selectedItems), (0, _toConsumableArray2.default)(viewMoreItem && selectedItems.length < ownedItems.length ? [viewMoreItem] : [])));
152
+ };
153
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
154
+ if (_loop()) continue;
155
+ }
156
+ } catch (err) {
157
+ _iterator3.e(err);
158
+ } finally {
159
+ _iterator3.f();
160
+ }
103
161
  return {
104
162
  fallbackItems: [],
105
163
  sections: sections
106
164
  };
107
165
  };
108
166
  var buildSearchSections = function buildSearchSections(_ref5) {
109
- var childrenMap = _ref5.childrenMap,
110
- components = _ref5.components,
167
+ var components = _ref5.components,
111
168
  contentSections = _ref5.contentSections,
112
169
  formatMessage = _ref5.formatMessage,
170
+ isRecommendedItem = _ref5.isRecommendedItem,
113
171
  query = _ref5.query,
114
- root = _ref5.root,
115
- surfaceContext = _ref5.surfaceContext;
116
- var matches = new Map();
172
+ root = _ref5.root;
117
173
  var sourceIndexByComponent = new Map(components.map(function (component, index) {
118
174
  return [component, index];
119
175
  }));
120
- var _iterator2 = _createForOfIteratorHelper(contentSections),
121
- _step2;
176
+ var matches = new Map();
177
+ var fallbackItem;
178
+ var _iterator4 = _createForOfIteratorHelper(contentSections),
179
+ _step4;
122
180
  try {
123
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
124
- var section = _step2.value;
125
- var _iterator3 = _createForOfIteratorHelper(getRenderedMenuItems(section, childrenMap, surfaceContext)),
126
- _step3;
181
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
182
+ var _step4$value = _step4.value,
183
+ items = _step4$value.items,
184
+ section = _step4$value.section;
185
+ var sectionRank = getParentRank(section, root.key);
186
+ var _iterator5 = _createForOfIteratorHelper(items),
187
+ _step5;
127
188
  try {
128
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
189
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
129
190
  var _item$match, _match$score, _sourceIndexByCompone;
130
- var item = _step3.value;
131
- if ((0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(item.key)) {
132
- continue;
191
+ var item = _step5.value;
192
+ if (item.key === _keys.ASK_ROVO_MENU_ITEM.key) {
193
+ fallbackItem !== null && fallbackItem !== void 0 ? fallbackItem : fallbackItem = item;
133
194
  }
134
195
  var match = (_item$match = item.match) === null || _item$match === void 0 ? void 0 : _item$match.call(item, {
135
196
  formatMessage: formatMessage,
136
197
  itemKey: item.key,
137
198
  query: query
138
199
  });
139
- if (item.match && match === null) {
200
+ if (item.match && match === null || getOwnerSectionKey(item, isRecommendedItem) !== section.key) {
140
201
  continue;
141
202
  }
142
203
  var candidate = {
143
- identity: "".concat(item.type, ":").concat(item.key),
204
+ identity: (0, _surfaceRenderer.getComponentIdentity)(item),
144
205
  item: item,
145
206
  itemRank: getParentRank(item, section.key),
146
207
  priorityGroup: (match === null || match === void 0 ? void 0 : match.priorityGroup) !== undefined && Number.isFinite(match.priorityGroup) ? match.priorityGroup : undefined,
147
208
  score: Math.min(1, Math.max(0, (_match$score = match === null || match === void 0 ? void 0 : match.score) !== null && _match$score !== void 0 ? _match$score : 0)),
148
- sourceIndex: (_sourceIndexByCompone = sourceIndexByComponent.get(item)) !== null && _sourceIndexByCompone !== void 0 ? _sourceIndexByCompone : Number.MAX_SAFE_INTEGER,
149
- sectionRank: getParentRank(section, root.key)
209
+ sectionRank: sectionRank,
210
+ sourceIndex: (_sourceIndexByCompone = sourceIndexByComponent.get(item)) !== null && _sourceIndexByCompone !== void 0 ? _sourceIndexByCompone : Number.MAX_SAFE_INTEGER
150
211
  };
151
212
  var existing = matches.get(candidate.identity);
152
213
  if (!existing || compareMatchedItems(candidate, existing) < 0) {
@@ -154,15 +215,15 @@ var buildSearchSections = function buildSearchSections(_ref5) {
154
215
  }
155
216
  }
156
217
  } catch (err) {
157
- _iterator3.e(err);
218
+ _iterator5.e(err);
158
219
  } finally {
159
- _iterator3.f();
220
+ _iterator5.f();
160
221
  }
161
222
  }
162
223
  } catch (err) {
163
- _iterator2.e(err);
224
+ _iterator4.e(err);
164
225
  } finally {
165
- _iterator2.f();
226
+ _iterator4.f();
166
227
  }
167
228
  var uniqueMatches = Array.from(matches.values()).sort(compareMatchedItems);
168
229
  var prioritizedMatches = uniqueMatches.filter(function (_ref6) {
@@ -176,44 +237,50 @@ var buildSearchSections = function buildSearchSections(_ref5) {
176
237
  var orderedSearchResults = [].concat((0, _toConsumableArray2.default)(prioritizedMatches.sort(comparePrioritizedSearchResults).map(function (_ref8) {
177
238
  var item = _ref8.item;
178
239
  return item;
179
- })), (0, _toConsumableArray2.default)(getSearchResults(unprioritizedMatches)));
240
+ })), (0, _toConsumableArray2.default)(getSearchResults(unprioritizedMatches).map(function (_ref9) {
241
+ var item = _ref9.item;
242
+ return item;
243
+ })));
180
244
  if (orderedSearchResults.length > 0) {
181
245
  return {
182
246
  fallbackItems: [],
183
247
  sections: [[SEARCH_RESULTS_HEADING].concat((0, _toConsumableArray2.default)(orderedSearchResults))]
184
248
  };
185
249
  }
186
- var fallbackItem = contentSections.flatMap(function (section) {
187
- var _childrenMap$get2;
188
- return (_childrenMap$get2 = childrenMap.get((0, _surfaceRenderer.getComponentIdentity)(section))) !== null && _childrenMap$get2 !== void 0 ? _childrenMap$get2 : [];
189
- }).find(function (component) {
190
- return component.type === _keys.ASK_ROVO_MENU_ITEM.type && component.key === _keys.ASK_ROVO_MENU_ITEM.key && (0, _surfaceRenderer.willComponentRender)(component, childrenMap, surfaceContext);
191
- });
192
250
  return {
193
251
  fallbackItems: fallbackItem ? [fallbackItem] : [],
194
252
  sections: []
195
253
  };
196
254
  };
197
255
 
256
+ /**
257
+ * Resolves the Recommended items for a browse. Receives the unranked components so a resolver
258
+ * can look recommendations up by their registered keys.
259
+ */
260
+
198
261
  /**
199
262
  * Builds the registered quick-insert menu model. An empty query browses every
200
263
  * category; a non-empty query returns ranked matches. The footer is shared by both.
201
264
  */
202
- var getQuickInsertMenuModel = exports.getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref9) {
203
- var components = _ref9.components,
204
- formatMessage = _ref9.formatMessage,
205
- getItemRank = _ref9.getItemRank,
206
- query = _ref9.query,
207
- rootComponent = _ref9.rootComponent,
208
- selectCategoryItems = _ref9.selectCategoryItems,
209
- surfaceContext = _ref9.surfaceContext;
265
+ var getQuickInsertMenuModel = exports.getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref0) {
266
+ var _root$isHidden, _root$isHidden2, _contentSections$find;
267
+ var components = _ref0.components,
268
+ formatMessage = _ref0.formatMessage,
269
+ getItemRank = _ref0.getItemRank,
270
+ getRecommendedItems = _ref0.getRecommendedItems,
271
+ query = _ref0.query,
272
+ rootComponent = _ref0.rootComponent,
273
+ selectCategoryItems = _ref0.selectCategoryItems,
274
+ surfaceContext = _ref0.surfaceContext;
210
275
  var rankedComponents = (0, _itemRank.applyRegisteredItemRanks)(components, getItemRank);
211
276
  var _resolveSurface = (0, _surfaceRenderer.resolveSurface)(rankedComponents, rootComponent),
212
277
  childrenMap = _resolveSurface.childrenMap,
213
278
  root = _resolveSurface.root,
214
279
  _resolveSurface$topLe = _resolveSurface.topLevelChildren,
215
280
  topLevelChildren = _resolveSurface$topLe === void 0 ? [] : _resolveSurface$topLe;
216
- if (!root || !(0, _surfaceRenderer.willComponentRender)(root, childrenMap, surfaceContext)) {
281
+ if (!root || (surfaceContext ? (_root$isHidden = root.isHidden) === null || _root$isHidden === void 0 ? void 0 : _root$isHidden.call(root, {
282
+ surfaceContext: surfaceContext
283
+ }) : (_root$isHidden2 = root.isHidden) === null || _root$isHidden2 === void 0 ? void 0 : _root$isHidden2.call(root))) {
217
284
  return {
218
285
  fallbackItems: [],
219
286
  footer: undefined,
@@ -221,32 +288,52 @@ var getQuickInsertMenuModel = exports.getQuickInsertMenuModel = function getQuic
221
288
  sections: []
222
289
  };
223
290
  }
224
- var renderedSections = topLevelChildren.filter(function (section) {
225
- return section.type === 'menu-section' && (0, _surfaceRenderer.willComponentRender)(section, childrenMap, surfaceContext);
291
+ var isBrowse = query === '';
292
+ var renderedSections = readMenuSections({
293
+ sections: topLevelChildren,
294
+ childrenMap: childrenMap,
295
+ surfaceContext: surfaceContext,
296
+ recommendedItems: isBrowse ? getRecommendedItems === null || getRecommendedItems === void 0 ? void 0 : getRecommendedItems({
297
+ components: components,
298
+ surfaceContext: surfaceContext
299
+ }) : undefined
226
300
  });
227
- var footerSection = renderedSections.find(function (_ref0) {
228
- var key = _ref0.key;
229
- return (0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(key);
301
+ if (topLevelChildren.length > 0 && renderedSections.length === 0) {
302
+ return {
303
+ fallbackItems: [],
304
+ footer: undefined,
305
+ root: undefined,
306
+ sections: []
307
+ };
308
+ }
309
+ var footerSection = renderedSections.find(function (_ref1) {
310
+ var section = _ref1.section;
311
+ return (0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(section.key);
230
312
  });
231
- var contentSections = renderedSections.filter(function (_ref1) {
232
- var key = _ref1.key;
233
- return !(0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(key);
313
+ var contentSections = renderedSections.filter(function (_ref10) {
314
+ var section = _ref10.section;
315
+ return !(0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(section.key) && (isBrowse || section.key !== _keys.RECOMMENDED_SECTION.key);
234
316
  });
235
- var content = query === '' ? buildBrowseSections({
236
- childrenMap: childrenMap,
317
+ var recommendedIdentities = new Set((_contentSections$find = contentSections.find(function (_ref11) {
318
+ var section = _ref11.section;
319
+ return section.key === _keys.RECOMMENDED_SECTION.key;
320
+ })) === null || _contentSections$find === void 0 ? void 0 : _contentSections$find.items.map(_surfaceRenderer.getComponentIdentity));
321
+ var isRecommendedItem = function isRecommendedItem(item) {
322
+ return recommendedIdentities.has((0, _surfaceRenderer.getComponentIdentity)(item));
323
+ };
324
+ var content = isBrowse ? buildBrowseSections({
237
325
  contentSections: contentSections,
238
- selectCategoryItems: selectCategoryItems,
239
- surfaceContext: surfaceContext
326
+ isRecommendedItem: isRecommendedItem,
327
+ selectCategoryItems: selectCategoryItems
240
328
  }) : buildSearchSections({
241
- childrenMap: childrenMap,
242
329
  components: rankedComponents,
243
330
  contentSections: contentSections,
244
331
  formatMessage: formatMessage,
332
+ isRecommendedItem: isRecommendedItem,
245
333
  query: query,
246
- root: root,
247
- surfaceContext: surfaceContext
334
+ root: root
248
335
  });
249
- var footer = footerSection ? getRenderedMenuItems(footerSection, childrenMap, surfaceContext)[0] : undefined;
336
+ var footer = footerSection === null || footerSection === void 0 ? void 0 : footerSection.items[0];
250
337
  return _objectSpread(_objectSpread({}, content), {}, {
251
338
  footer: footer,
252
339
  root: root