diff --git a/src/library-authoring/collections/CollectionDetails.tsx b/src/library-authoring/collections/CollectionDetails.tsx
index 07076c334d..650fcd4af9 100644
--- a/src/library-authoring/collections/CollectionDetails.tsx
+++ b/src/library-authoring/collections/CollectionDetails.tsx
@@ -5,7 +5,7 @@ import classNames from 'classnames';
import { getItemIcon } from '../../generic/block-type-utils';
import { ToastContext } from '../../generic/toast-context';
-import { BlockTypeLabel, type CollectionHit, useSearchContext } from '../../search-manager';
+import { BlockTypeLabel, type CollectionHit, useGetBlockTypes } from '../../search-manager';
import type { ContentLibrary } from '../data/api';
import { useUpdateCollection } from '../data/apiHooks';
import HistoryWidget from '../generic/history-widget';
@@ -36,10 +36,19 @@ const BlockCount = ({
);
};
-const CollectionStatsWidget = () => {
- const {
- blockTypes,
- } = useSearchContext();
+interface CollectionStatsWidgetProps {
+ collection: CollectionHit,
+}
+
+const CollectionStatsWidget = ({ collection }: CollectionStatsWidgetProps) => {
+ const { data: blockTypes } = useGetBlockTypes([
+ `context_key = "${collection.contextKey}"`,
+ `collections.key = "${collection.blockId}"`,
+ ]);
+
+ if (!blockTypes) {
+ return null;
+ }
const blockTypesArray = Object.entries(blockTypes)
.map(([blockType, count]) => ({ blockType, count }))
@@ -51,7 +60,12 @@ const CollectionStatsWidget = () => {
if (totalBlocksCount === 0) {
return (
-
+
);
@@ -135,7 +149,7 @@ const CollectionDetails = ({ library, collection }: CollectionDetailsProps) => {
{intl.formatMessage(messages.detailsTabStatsTitle)}
-
+
diff --git a/src/library-authoring/library-sidebar/LibrarySidebar.tsx b/src/library-authoring/library-sidebar/LibrarySidebar.tsx
index 0d521e6b6f..d4466ef408 100644
--- a/src/library-authoring/library-sidebar/LibrarySidebar.tsx
+++ b/src/library-authoring/library-sidebar/LibrarySidebar.tsx
@@ -6,11 +6,7 @@ import {
} from '@openedx/paragon';
import { Close } from '@openedx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';
-import { SearchParams } from 'meilisearch';
-import {
- SearchContextProvider,
-} from '../../search-manager';
import { AddContentContainer, AddContentHeader } from '../add-content';
import { CollectionInfo, CollectionInfoHeader } from '../collections';
import { ContentLibrary } from '../data/api';
@@ -68,36 +64,23 @@ const LibrarySidebar = ({ library }: LibrarySidebarProps) => {
const buildBody = () : React.ReactNode => bodyComponentMap[sidebarBodyComponent || 'unknown'];
const buildHeader = (): React.ReactNode => headerComponentMap[sidebarBodyComponent || 'unknown'];
- const collectionQuery: SearchParams | undefined = currentCollectionHit ? {
- filter: ['type = "collection"', `context_key = "${library.id}"`, `block_id = "${currentCollectionHit.blockId}"`],
- limit: 1,
- } : undefined;
-
return (
-
-
-
- {buildHeader()}
-
-
-
- {buildBody()}
-
+
+
+ {buildHeader()}
+
-
+
+ {buildBody()}
+
+
);
};
diff --git a/src/search-manager/SearchManager.ts b/src/search-manager/SearchManager.ts
index bcce0779e7..cb1314b6b3 100644
--- a/src/search-manager/SearchManager.ts
+++ b/src/search-manager/SearchManager.ts
@@ -166,7 +166,7 @@ export const SearchContextProvider: React.FC<{
searchSortOrder,
setSearchSortOrder,
defaultSearchSortOrder,
- closeSearchModal: props.closeSearchModal ?? (() => {}),
+ closeSearchModal: props.closeSearchModal ?? (() => { }),
hasError: hasConnectionError || result.isError,
...result,
},
diff --git a/src/search-manager/data/api.ts b/src/search-manager/data/api.ts
index d343a7cdaa..5ae417a233 100644
--- a/src/search-manager/data/api.ts
+++ b/src/search-manager/data/api.ts
@@ -303,6 +303,29 @@ export async function fetchSearchResults({
};
}
+/**
+ * Fetch the block types facet distribution for the search results.
+ */
+export const fetchBlockTypes = async (
+ client: MeiliSearch,
+ indexName: string,
+ extraFilter?: Filter,
+): Promise
> => {
+ // Convert 'extraFilter' into an array
+ const extraFilterFormatted = forceArray(extraFilter);
+
+ const { results } = await client.multiSearch({
+ queries: [{
+ indexUid: indexName,
+ facets: ['block_type', 'content.problem_types'],
+ filter: extraFilterFormatted,
+ limit: 0, // We don't need any "hits" for this - just the facetDistribution
+ }],
+ });
+
+ return results[0].facetDistribution?.block_type ?? {};
+};
+
/** Information about a single tag in the tag tree, as returned by fetchAvailableTagOptions() */
export interface TagEntry {
tagName: string;
diff --git a/src/search-manager/data/apiHooks.ts b/src/search-manager/data/apiHooks.ts
index c2a330c1e0..c22a004269 100644
--- a/src/search-manager/data/apiHooks.ts
+++ b/src/search-manager/data/apiHooks.ts
@@ -10,6 +10,7 @@ import {
fetchTagsThatMatchKeyword,
getContentSearchConfig,
fetchDocumentById,
+ fetchBlockTypes,
OverrideQueries,
} from './api';
@@ -243,6 +244,22 @@ export const useTagFilterOptions = (args: {
return { ...mainQuery, data };
};
+export const useGetBlockTypes = (extraFilters: Filter) => {
+ const { client, indexName } = useContentSearchConnection();
+ return useQuery({
+ enabled: client !== undefined && indexName !== undefined,
+ queryKey: [
+ 'content_search',
+ client?.config.apiKey,
+ client?.config.host,
+ indexName,
+ extraFilters,
+ 'block_types',
+ ],
+ queryFn: () => fetchBlockTypes(client!, indexName!, extraFilters),
+ });
+};
+
/* istanbul ignore next */
export const useGetSingleDocument = ({ client, indexName, id }: {
client?: MeiliSearch;
diff --git a/src/search-manager/index.ts b/src/search-manager/index.ts
index 00117f6dcd..e2d4188be1 100644
--- a/src/search-manager/index.ts
+++ b/src/search-manager/index.ts
@@ -8,5 +8,6 @@ export { default as SearchKeywordsField } from './SearchKeywordsField';
export { default as SearchSortWidget } from './SearchSortWidget';
export { default as Stats } from './Stats';
export { HIGHLIGHT_PRE_TAG, HIGHLIGHT_POST_TAG } from './data/api';
+export { useGetBlockTypes } from './data/apiHooks';
export type { CollectionHit, ContentHit, ContentHitTags } from './data/api';