diff --git a/src/search-manager/FilterByPublished.tsx b/src/search-manager/FilterByPublished.tsx index ad9ef662a3..9f369f18f7 100644 --- a/src/search-manager/FilterByPublished.tsx +++ b/src/search-manager/FilterByPublished.tsx @@ -9,19 +9,29 @@ import { import { FilterList } from '@openedx/paragon/icons'; import SearchFilterWidget from './SearchFilterWidget'; import messages from './messages'; -// import { useSearchContext } from './SearchManager'; +import { useSearchContext } from './SearchManager'; +import { PublishStatus } from './data/api'; /** * A button with a dropdown that allows filtering the current search by publish status */ const FilterByPublished: React.FC> = () => { - // const { - // publishedFilter, - // setPublishedFilter, - // } = useSearchContext(); + const { + publishedFilter, + setPublishedFilter, + } = useSearchContext(); const clearFilters = React.useCallback(() => { - // setPublishedFilter(undefined); + setPublishedFilter([]); + }, []); + + const toggleFilterMode = React.useCallback((mode: PublishStatus) => { + setPublishedFilter(oldList => { + if (oldList.includes(mode)) { + return oldList.filter(m => m !== mode); + } + return [...oldList, mode]; + }); }, []); return ( @@ -34,37 +44,37 @@ const FilterByPublished: React.FC> = () => { {}} + value={PublishStatus.Published} + onChange={() => { toggleFilterMode(PublishStatus.Published); }} >
Published - 15 + {' '}15
{}} + value={PublishStatus.Modified} + onChange={() => { toggleFilterMode(PublishStatus.Modified); }} >
Modified since publish - 5 + {' '}5
{}} + value={PublishStatus.NeverPublished} + onChange={() => { toggleFilterMode(PublishStatus.NeverPublished); }} >
Never published - 2 + {' '}2
diff --git a/src/search-manager/SearchManager.ts b/src/search-manager/SearchManager.ts index 413e4ff760..d0b415266e 100644 --- a/src/search-manager/SearchManager.ts +++ b/src/search-manager/SearchManager.ts @@ -10,7 +10,12 @@ import { MeiliSearch, type Filter } from 'meilisearch'; import { union } from 'lodash'; import { - CollectionHit, ContentHit, SearchSortOption, forceArray, OverrideQueries, + CollectionHit, + ContentHit, + SearchSortOption, + forceArray, + OverrideQueries, + type PublishStatus, } from './data/api'; import { useContentSearchConnection, useContentSearchResults } from './data/apiHooks'; @@ -23,6 +28,8 @@ export interface SearchContextData { setBlockTypesFilter: React.Dispatch>; problemTypesFilter: string[]; setProblemTypesFilter: React.Dispatch>; + publishedFilter: PublishStatus[]; + setPublishedFilter: React.Dispatch>; tagsFilter: string[]; setTagsFilter: React.Dispatch>; blockTypes: Record; @@ -100,6 +107,7 @@ export const SearchContextProvider: React.FC<{ const [searchKeywords, setSearchKeywords] = React.useState(''); const [blockTypesFilter, setBlockTypesFilter] = React.useState([]); const [problemTypesFilter, setProblemTypesFilter] = React.useState([]); + const [publishedFilter, setPublishedFilter] = React.useState([]); const [tagsFilter, setTagsFilter] = React.useState([]); let extraFilter: string[] = forceArray(props.extraFilter); @@ -150,6 +158,7 @@ export const SearchContextProvider: React.FC<{ searchKeywords, blockTypesFilter, problemTypesFilter, + publishedFilter, tagsFilter, sort, overrideQueries, @@ -165,6 +174,8 @@ export const SearchContextProvider: React.FC<{ setBlockTypesFilter, problemTypesFilter, setProblemTypesFilter, + publishedFilter, + setPublishedFilter, tagsFilter, setTagsFilter, extraFilter, diff --git a/src/search-manager/data/api.ts b/src/search-manager/data/api.ts index b9ede51d5b..83262ab37e 100644 --- a/src/search-manager/data/api.ts +++ b/src/search-manager/data/api.ts @@ -25,6 +25,12 @@ export enum SearchSortOption { RECENTLY_MODIFIED = 'modified:desc', } +export enum PublishStatus { + Published = 'published', + Modified = 'modified', + NeverPublished = 'never', +} + /** * Get the content search configuration from the CMS. */ @@ -185,6 +191,7 @@ interface FetchSearchParams { searchKeywords: string, blockTypesFilter?: string[], problemTypesFilter?: string[], + publishedFilter?: PublishStatus[], /** The full path of tags that each result MUST have, e.g. ["Difficulty > Hard", "Subject > Math"] */ tagsFilter?: string[], extraFilter?: Filter, @@ -200,6 +207,7 @@ export async function fetchSearchResults({ searchKeywords, blockTypesFilter, problemTypesFilter, + publishedFilter, tagsFilter, extraFilter, sort, @@ -223,6 +231,16 @@ export async function fetchSearchResults({ const problemTypesFilterFormatted = problemTypesFilter?.length ? [problemTypesFilter.map(pt => `content.problem_types = ${pt}`)] : []; + /* eslint-disable */ + const publishStatusFilterFormatted = publishedFilter?.length ? publishedFilter.map(pt => ( + pt === PublishStatus.Published ? 'modified = last_published' : + pt === PublishStatus.Modified ? 'modified > last_published' : + pt === PublishStatus.NeverPublished ? 'last_published IS NULL' : + 'false' + )) : []; + console.log(publishStatusFilterFormatted) + /* eslint-enable */ + const tagsFilterFormatted = formatTagsFilter(tagsFilter); const limit = 20; // How many results to retrieve per page. @@ -246,6 +264,7 @@ export async function fetchSearchResults({ ...typeFilters, ...extraFilterFormatted, ...tagsFilterFormatted, + ...publishStatusFilterFormatted, ], attributesToHighlight: ['display_name', 'content'], highlightPreTag: HIGHLIGHT_PRE_TAG, diff --git a/src/search-manager/data/apiHooks.ts b/src/search-manager/data/apiHooks.ts index cd63bbb344..3e6ce738a5 100644 --- a/src/search-manager/data/apiHooks.ts +++ b/src/search-manager/data/apiHooks.ts @@ -12,6 +12,7 @@ import { fetchDocumentById, fetchBlockTypes, OverrideQueries, + type PublishStatus, } from './api'; /** @@ -55,6 +56,7 @@ export const useContentSearchResults = ({ searchKeywords, blockTypesFilter = [], problemTypesFilter = [], + publishedFilter = [], tagsFilter = [], sort = [], overrideQueries, @@ -71,6 +73,7 @@ export const useContentSearchResults = ({ blockTypesFilter?: string[]; /** Only search for these problem types (e.g. `["choiceresponse", "multiplechoiceresponse"]`) */ problemTypesFilter?: string[]; + publishedFilter?: PublishStatus[]; /** Required tags (all must match), e.g. `["Difficulty > Hard", "Subject > Math"]` */ tagsFilter?: string[]; /** Sort search results using these options */ @@ -90,6 +93,7 @@ export const useContentSearchResults = ({ searchKeywords, blockTypesFilter, problemTypesFilter, + publishedFilter, tagsFilter, sort, overrideQueries, @@ -105,6 +109,7 @@ export const useContentSearchResults = ({ searchKeywords, blockTypesFilter, problemTypesFilter, + publishedFilter, tagsFilter, sort, // For infinite pagination of results, we can retrieve additional pages if requested.