From 7b65dd64927071bb5e3342cabd9a45c0986e0225 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Tue, 13 May 2025 19:21:44 -0500 Subject: [PATCH 1/4] fix: Remove never published filter from component picker --- .../LibraryAuthoringPage.tsx | 8 ++- .../component-picker/ComponentPicker.test.tsx | 16 +++++ src/search-manager/FilterByPublished.tsx | 60 +++++++++---------- src/search-manager/data/api.ts | 2 + 4 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/library-authoring/LibraryAuthoringPage.tsx b/src/library-authoring/LibraryAuthoringPage.tsx index 95172f8d01..17e0006bf2 100644 --- a/src/library-authoring/LibraryAuthoringPage.tsx +++ b/src/library-authoring/LibraryAuthoringPage.tsx @@ -37,6 +37,7 @@ import { SearchKeywordsField, SearchSortWidget, TypesFilterData, + PublishStatus, } from '../search-manager'; import LibraryContent from './LibraryContent'; import { LibrarySidebar } from './library-sidebar'; @@ -259,6 +260,11 @@ const LibraryAuthoringPage = ({ )); + const publishedFilters = [PublishStatus.Published, PublishStatus.Modified]; + if (!showOnlyPublished) { + publishedFilters.push(PublishStatus.NeverPublished); + } + return (
@@ -299,7 +305,7 @@ const LibraryAuthoringPage = ({ {!(insideCollections || insideUnits) && } - + diff --git a/src/library-authoring/component-picker/ComponentPicker.test.tsx b/src/library-authoring/component-picker/ComponentPicker.test.tsx index 8e9fbbaf9d..2c743a2fed 100644 --- a/src/library-authoring/component-picker/ComponentPicker.test.tsx +++ b/src/library-authoring/component-picker/ComponentPicker.test.tsx @@ -302,4 +302,20 @@ 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(); + }); }); diff --git a/src/search-manager/FilterByPublished.tsx b/src/search-manager/FilterByPublished.tsx index f8ede2a956..66690e7575 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,25 @@ 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 e1a6aeaa33..d829b8a527 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. */ From f768f29900ef5c7f3782742b803c8a5ae241336b Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Wed, 14 May 2025 12:12:28 -0500 Subject: [PATCH 2/4] refactor: LibraryFilterByPublished created with library context --- .../LibraryAuthoringPage.tsx | 10 ++------ .../collections/LibraryCollectionPage.tsx | 4 ++-- .../component-picker/ComponentPicker.test.tsx | 23 +++++++++++++++++++ .../generic/filter-by-published/index.tsx | 17 ++++++++++++++ 4 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 src/library-authoring/generic/filter-by-published/index.tsx diff --git a/src/library-authoring/LibraryAuthoringPage.tsx b/src/library-authoring/LibraryAuthoringPage.tsx index 17e0006bf2..e57c7cbe5b 100644 --- a/src/library-authoring/LibraryAuthoringPage.tsx +++ b/src/library-authoring/LibraryAuthoringPage.tsx @@ -32,12 +32,10 @@ import { ClearFiltersButton, FilterByBlockType, FilterByTags, - FilterByPublished, SearchContextProvider, SearchKeywordsField, SearchSortWidget, TypesFilterData, - PublishStatus, } from '../search-manager'; import LibraryContent from './LibraryContent'; import { LibrarySidebar } from './library-sidebar'; @@ -47,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(); @@ -260,11 +259,6 @@ const LibraryAuthoringPage = ({ )); - const publishedFilters = [PublishStatus.Published, PublishStatus.Modified]; - if (!showOnlyPublished) { - publishedFilters.push(PublishStatus.NeverPublished); - } - return (
@@ -305,7 +299,7 @@ const LibraryAuthoringPage = ({ {!(insideCollections || insideUnits) && } - + diff --git a/src/library-authoring/collections/LibraryCollectionPage.tsx b/src/library-authoring/collections/LibraryCollectionPage.tsx index de3c7ce234..943664788d 100644 --- a/src/library-authoring/collections/LibraryCollectionPage.tsx +++ b/src/library-authoring/collections/LibraryCollectionPage.tsx @@ -22,7 +22,6 @@ import NotFoundAlert from '../../generic/NotFoundAlert'; import { ClearFiltersButton, FilterByBlockType, - FilterByPublished, FilterByTags, SearchContextProvider, SearchKeywordsField, @@ -36,6 +35,7 @@ import { SidebarBodyComponentId, useSidebarContext } from '../common/context/Sid import messages from './messages'; import { LibrarySidebar } from '../library-sidebar'; import LibraryCollectionComponents from './LibraryCollectionComponents'; +import LibraryFilterByPublished from '../generic/filter-by-published'; const HeaderActions = () => { 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 2c743a2fed..2d492adf65 100644 --- a/src/library-authoring/component-picker/ComponentPicker.test.tsx +++ b/src/library-authoring/component-picker/ComponentPicker.test.tsx @@ -318,4 +318,27 @@ describe('', () => { 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 0000000000..0dc52ff85a --- /dev/null +++ b/src/library-authoring/generic/filter-by-published/index.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { useLibraryContext } from '../../common/context/LibraryContext'; +import { FilterByPublished, PublishStatus } from '../../../search-manager'; + +const LibraryFilterByPublished : React.FC> = () => { + const { showOnlyPublished } = useLibraryContext(); + const publishedFilters = [PublishStatus.Published, PublishStatus.Modified]; + if (!showOnlyPublished) { + publishedFilters.push(PublishStatus.NeverPublished); + } + + return ( + + ); +}; + +export default LibraryFilterByPublished; From dd81baf98e2075feb20ee609f96e147131584298 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Wed, 14 May 2025 13:49:35 -0500 Subject: [PATCH 3/4] style: Fix broken coverage --- .../generic/filter-by-published/index.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/library-authoring/generic/filter-by-published/index.tsx b/src/library-authoring/generic/filter-by-published/index.tsx index 0dc52ff85a..c446f957c9 100644 --- a/src/library-authoring/generic/filter-by-published/index.tsx +++ b/src/library-authoring/generic/filter-by-published/index.tsx @@ -4,14 +4,17 @@ import { FilterByPublished, PublishStatus } from '../../../search-manager'; const LibraryFilterByPublished : React.FC> = () => { const { showOnlyPublished } = useLibraryContext(); - const publishedFilters = [PublishStatus.Published, PublishStatus.Modified]; - if (!showOnlyPublished) { - publishedFilters.push(PublishStatus.NeverPublished); + + if (showOnlyPublished) { + return ( + + ); } - return ( - - ); + return ; }; export default LibraryFilterByPublished; From df819d36c76c7d05059efb4538b470729f96cd59 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Wed, 21 May 2025 19:28:23 -0500 Subject: [PATCH 4/4] style: Nits on the code --- src/library-authoring/generic/filter-by-published/index.tsx | 6 ++++++ src/search-manager/FilterByPublished.tsx | 1 + 2 files changed, 7 insertions(+) diff --git a/src/library-authoring/generic/filter-by-published/index.tsx b/src/library-authoring/generic/filter-by-published/index.tsx index c446f957c9..825ac56f4d 100644 --- a/src/library-authoring/generic/filter-by-published/index.tsx +++ b/src/library-authoring/generic/filter-by-published/index.tsx @@ -2,6 +2,12 @@ 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(); diff --git a/src/search-manager/FilterByPublished.tsx b/src/search-manager/FilterByPublished.tsx index 66690e7575..079c6d43ee 100644 --- a/src/search-manager/FilterByPublished.tsx +++ b/src/search-manager/FilterByPublished.tsx @@ -56,6 +56,7 @@ const FilterByPublished = ({ const visibleFiltersToRender = visibleFilters.map((filter) => ( { toggleFilterMode(filter); }}