diff --git a/src/library-authoring/LibraryAuthoringPage.tsx b/src/library-authoring/LibraryAuthoringPage.tsx index 6e6100329..9d42611c1 100644 --- a/src/library-authoring/LibraryAuthoringPage.tsx +++ b/src/library-authoring/LibraryAuthoringPage.tsx @@ -32,7 +32,6 @@ import { ClearFiltersButton, FilterByBlockType, FilterByTags, - FilterByPublished, SearchContextProvider, SearchKeywordsField, SearchSortWidget, @@ -46,6 +45,7 @@ import { SidebarBodyComponentId, useSidebarContext } from './common/context/Side import { allLibraryPageTabs, ContentType, useLibraryRoutes } from './routes'; import messages from './messages'; +import LibraryFilterByPublished from './generic/filter-by-published'; const HeaderActions = () => { const intl = useIntl(); @@ -246,6 +246,17 @@ const LibraryAuthoringPage = ({ extraFilter.push(activeTypeFilters[activeKey]); } + /* + + {!(insideCollections || insideUnits) && } - { const intl = useIntl(); @@ -218,7 +218,7 @@ const LibraryCollectionPage = () => { - + diff --git a/src/library-authoring/component-picker/ComponentPicker.test.tsx b/src/library-authoring/component-picker/ComponentPicker.test.tsx index 8e9fbbaf9..2d492adf6 100644 --- a/src/library-authoring/component-picker/ComponentPicker.test.tsx +++ b/src/library-authoring/component-picker/ComponentPicker.test.tsx @@ -302,4 +302,43 @@ describe('', () => { expect(screen.queryByRole('tab', { name: /collections/i })).not.toBeInTheDocument(); expect(screen.queryByRole('tab', { name: /components/i })).not.toBeInTheDocument(); }); + + it('should not display never published filter', async () => { + render(); + + expect(await screen.findByText('Test Library 1')).toBeInTheDocument(); + fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i)); + + // Wait for the content library to load + const filterButton = await screen.findByRole('button', { name: /publish status/i }); + fireEvent.click(filterButton); + + // Verify the filters. Note: It's hard to verify the `published` filter, + // because there are many components with that text on the screen, but that's not the important thing. + expect(screen.getByText(/modified since publish/i)).toBeInTheDocument(); + expect(screen.queryByText(/never published/i)).not.toBeInTheDocument(); + }); + + it('should not display never published filter in collection page', async () => { + render(); + + expect(await screen.findByText('Test Library 1')).toBeInTheDocument(); + fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i)); + + // Wait for the content library to load + await screen.findByText(/Change Library/i); + expect(await screen.findByText('Test Library 1')).toBeInTheDocument(); + + // Click on the collection card to open the sidebar + fireEvent.click(screen.queryAllByText('Collection 1')[0]); + + // Wait for the content library to load + const filterButton = await screen.findByRole('button', { name: /publish status/i }); + fireEvent.click(filterButton); + + // Verify the filters. Note: It's hard to verify the `published` filter, + // because there are many components with that text on the screen, but that's not the important thing. + expect(screen.getByText(/modified since publish/i)).toBeInTheDocument(); + expect(screen.queryByText(/never published/i)).not.toBeInTheDocument(); + }); }); diff --git a/src/library-authoring/generic/filter-by-published/index.tsx b/src/library-authoring/generic/filter-by-published/index.tsx new file mode 100644 index 000000000..825ac56f4 --- /dev/null +++ b/src/library-authoring/generic/filter-by-published/index.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { useLibraryContext } from '../../common/context/LibraryContext'; +import { FilterByPublished, PublishStatus } from '../../../search-manager'; + +/** + * When browsing library content for insertion into a course, we only show published + * content. In that case, there is no need for a 'Never Published' filter, which will + * never show results. This component removes that option from FilterByPublished + * when not relevant. + */ +const LibraryFilterByPublished : React.FC> = () => { + const { showOnlyPublished } = useLibraryContext(); + + if (showOnlyPublished) { + return ( + + ); + } + + return ; +}; + +export default LibraryFilterByPublished; diff --git a/src/search-manager/FilterByPublished.tsx b/src/search-manager/FilterByPublished.tsx index f8ede2a95..079c6d43e 100644 --- a/src/search-manager/FilterByPublished.tsx +++ b/src/search-manager/FilterByPublished.tsx @@ -10,12 +10,18 @@ import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import messages from './messages'; import SearchFilterWidget from './SearchFilterWidget'; import { useSearchContext } from './SearchManager'; -import { PublishStatus } from './data/api'; +import { allPublishFilters, PublishStatus } from './data/api'; + +interface FilterByPublishedProps { + visibleFilters?: PublishStatus[], +} /** * A button with a dropdown that allows filtering the current search by publish status */ -const FilterByPublished: React.FC> = () => { +const FilterByPublished = ({ + visibleFilters = allPublishFilters, +}: FilterByPublishedProps) => { const intl = useIntl(); const { publishStatus, @@ -42,6 +48,26 @@ const FilterByPublished: React.FC> = () => { }; const appliedFilters = publishStatusFilter.map(mode => ({ label: modeToLabel[mode] })); + const filterLabels = { + [PublishStatus.Published]: intl.formatMessage(messages.publishStatusPublished), + [PublishStatus.Modified]: intl.formatMessage(messages.publishStatusModified), + [PublishStatus.NeverPublished]: intl.formatMessage(messages.publishStatusNeverPublished), + }; + + const visibleFiltersToRender = visibleFilters.map((filter) => ( + { toggleFilterMode(filter); }} + > +
+ {filterLabels[filter]} + {publishStatus[filter] ?? 0} +
+
+ )); + return ( > = () => { value={publishStatusFilter} > - { toggleFilterMode(PublishStatus.Published); }} - > -
- {intl.formatMessage(messages.publishStatusPublished)} - {publishStatus[PublishStatus.Published] ?? 0} -
-
- { toggleFilterMode(PublishStatus.Modified); }} - > -
- {intl.formatMessage(messages.publishStatusModified)} - {publishStatus[PublishStatus.Modified] ?? 0} -
-
- { toggleFilterMode(PublishStatus.NeverPublished); }} - > -
- {intl.formatMessage(messages.publishStatusNeverPublished)} - {publishStatus[PublishStatus.NeverPublished] ?? 0} -
-
+ {visibleFiltersToRender}
diff --git a/src/search-manager/data/api.ts b/src/search-manager/data/api.ts index 01811883c..aa7ec2f61 100644 --- a/src/search-manager/data/api.ts +++ b/src/search-manager/data/api.ts @@ -31,6 +31,8 @@ export enum PublishStatus { NeverPublished = 'never', } +export const allPublishFilters: PublishStatus[] = Object.values(PublishStatus); + /** * Get the content search configuration from the CMS. */