Skip to content

Commit

Permalink
refator: remove SearchContext from sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Sep 26, 2024
1 parent f9fa28e commit 7ef8f14
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 40 deletions.
28 changes: 21 additions & 7 deletions src/library-authoring/collections/CollectionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 }))
Expand All @@ -51,7 +60,12 @@ const CollectionStatsWidget = () => {

if (totalBlocksCount === 0) {
return (
<div className="text-center text-muted">
<div
className="text-center text-muted align-content-center"
style={{
height: '72px', // same height as the BlockCount component
}}
>
<FormattedMessage {...messages.detailsTabStatsNoComponents} />
</div>
);
Expand Down Expand Up @@ -135,7 +149,7 @@ const CollectionDetails = ({ library, collection }: CollectionDetailsProps) => {
<h3 className="h5">
{intl.formatMessage(messages.detailsTabStatsTitle)}
</h3>
<CollectionStatsWidget />
<CollectionStatsWidget collection={collection} />
</div>
<hr className="w-100" />
<div>
Expand Down
47 changes: 15 additions & 32 deletions src/library-authoring/library-sidebar/LibrarySidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 (
<SearchContextProvider
extraFilter={[
`context_key = "${library.id}"`,
...(currentCollectionHit ? [`collections.key = "${currentCollectionHit.blockId}"`] : []),
]}
overrideQueries={{ ...(collectionQuery ? { collections: collectionQuery } : {}) }}
>
<Stack gap={4} className="p-3 text-primary-700">
<Stack direction="horizontal" className="d-flex justify-content-between">
{buildHeader()}
<IconButton
className="mt-1"
src={Close}
iconAs={Icon}
alt={intl.formatMessage(messages.closeButtonAlt)}
onClick={closeLibrarySidebar}
size="inline"
/>
</Stack>
<div>
{buildBody()}
</div>
<Stack gap={4} className="p-3 text-primary-700">
<Stack direction="horizontal" className="d-flex justify-content-between">
{buildHeader()}
<IconButton
className="mt-1"
src={Close}
iconAs={Icon}
alt={intl.formatMessage(messages.closeButtonAlt)}
onClick={closeLibrarySidebar}
size="inline"
/>
</Stack>
</SearchContextProvider>
<div>
{buildBody()}
</div>
</Stack>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/search-manager/SearchManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const SearchContextProvider: React.FC<{
searchSortOrder,
setSearchSortOrder,
defaultSearchSortOrder,
closeSearchModal: props.closeSearchModal ?? (() => {}),
closeSearchModal: props.closeSearchModal ?? (() => { }),
hasError: hasConnectionError || result.isError,
...result,
},
Expand Down
23 changes: 23 additions & 0 deletions src/search-manager/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Record<string, number>> => {
// 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;
Expand Down
17 changes: 17 additions & 0 deletions src/search-manager/data/apiHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
fetchTagsThatMatchKeyword,
getContentSearchConfig,
fetchDocumentById,
fetchBlockTypes,
OverrideQueries,
} from './api';

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/search-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

0 comments on commit 7ef8f14

Please sign in to comment.