Skip to content

Commit 212a54f

Browse files
authored
[Teak] fix: Inconsistent publish status filter menu placement & fix: Remove never published filter from component picker (#2021)
* fix: Inconsistent publish status filter menu placement (#1966) * fix: Remove never published filter from component picker (#1947) Removes the never-published filter option from the component picker and unit picker.
1 parent 944d131 commit 212a54f

File tree

6 files changed

+118
-36
lines changed

6 files changed

+118
-36
lines changed

src/library-authoring/LibraryAuthoringPage.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
ClearFiltersButton,
3333
FilterByBlockType,
3434
FilterByTags,
35-
FilterByPublished,
3635
SearchContextProvider,
3736
SearchKeywordsField,
3837
SearchSortWidget,
@@ -46,6 +45,7 @@ import { SidebarBodyComponentId, useSidebarContext } from './common/context/Side
4645
import { allLibraryPageTabs, ContentType, useLibraryRoutes } from './routes';
4746

4847
import messages from './messages';
48+
import LibraryFilterByPublished from './generic/filter-by-published';
4949

5050
const HeaderActions = () => {
5151
const intl = useIntl();
@@ -246,6 +246,17 @@ const LibraryAuthoringPage = ({
246246
extraFilter.push(activeTypeFilters[activeKey]);
247247
}
248248

249+
/*
250+
251+
<FilterByPublished key={
252+
// It is necessary to re-render `FilterByPublished` every time `FilterByBlockType`
253+
// appears or disappears, this is because when the menu is opened it is rendered
254+
// in a previous state, causing an inconsistency in its position.
255+
// By changing the key we can re-render the component.
256+
!(insideCollections || insideUnits) ? 'filter-published-1' : 'filter-published-2'
257+
}
258+
*/
259+
249260
// Disable filtering by block/problem type when viewing the Collections tab.
250261
const overrideTypesFilter = (insideCollections || insideUnits) ? new TypesFilterData() : undefined;
251262

@@ -299,7 +310,14 @@ const LibraryAuthoringPage = ({
299310
<SearchKeywordsField className="mr-3" />
300311
<FilterByTags />
301312
{!(insideCollections || insideUnits) && <FilterByBlockType />}
302-
<FilterByPublished />
313+
<LibraryFilterByPublished key={
314+
// It is necessary to re-render `LibraryFilterByPublished` every time `FilterByBlockType`
315+
// appears or disappears, this is because when the menu is opened it is rendered
316+
// in a previous state, causing an inconsistency in its position.
317+
// By changing the key we can re-render the component.
318+
!(insideCollections || insideUnits) ? 'filter-published-1' : 'filter-published-2'
319+
}
320+
/>
303321
<ClearFiltersButton />
304322
<ActionRow.Spacer />
305323
<SearchSortWidget />

src/library-authoring/collections/LibraryCollectionPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import NotFoundAlert from '../../generic/NotFoundAlert';
2222
import {
2323
ClearFiltersButton,
2424
FilterByBlockType,
25-
FilterByPublished,
2625
FilterByTags,
2726
SearchContextProvider,
2827
SearchKeywordsField,
@@ -36,6 +35,7 @@ import { SidebarBodyComponentId, useSidebarContext } from '../common/context/Sid
3635
import messages from './messages';
3736
import { LibrarySidebar } from '../library-sidebar';
3837
import LibraryCollectionComponents from './LibraryCollectionComponents';
38+
import LibraryFilterByPublished from '../generic/filter-by-published';
3939

4040
const HeaderActions = () => {
4141
const intl = useIntl();
@@ -218,7 +218,7 @@ const LibraryCollectionPage = () => {
218218
<SearchKeywordsField className="mr-3" />
219219
<FilterByTags />
220220
<FilterByBlockType />
221-
<FilterByPublished />
221+
<LibraryFilterByPublished />
222222
<ClearFiltersButton />
223223
<ActionRow.Spacer />
224224
<SearchSortWidget />

src/library-authoring/component-picker/ComponentPicker.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,43 @@ describe('<ComponentPicker />', () => {
302302
expect(screen.queryByRole('tab', { name: /collections/i })).not.toBeInTheDocument();
303303
expect(screen.queryByRole('tab', { name: /components/i })).not.toBeInTheDocument();
304304
});
305+
306+
it('should not display never published filter', async () => {
307+
render(<ComponentPicker />);
308+
309+
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
310+
fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i));
311+
312+
// Wait for the content library to load
313+
const filterButton = await screen.findByRole('button', { name: /publish status/i });
314+
fireEvent.click(filterButton);
315+
316+
// Verify the filters. Note: It's hard to verify the `published` filter,
317+
// because there are many components with that text on the screen, but that's not the important thing.
318+
expect(screen.getByText(/modified since publish/i)).toBeInTheDocument();
319+
expect(screen.queryByText(/never published/i)).not.toBeInTheDocument();
320+
});
321+
322+
it('should not display never published filter in collection page', async () => {
323+
render(<ComponentPicker />);
324+
325+
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
326+
fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i));
327+
328+
// Wait for the content library to load
329+
await screen.findByText(/Change Library/i);
330+
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
331+
332+
// Click on the collection card to open the sidebar
333+
fireEvent.click(screen.queryAllByText('Collection 1')[0]);
334+
335+
// Wait for the content library to load
336+
const filterButton = await screen.findByRole('button', { name: /publish status/i });
337+
fireEvent.click(filterButton);
338+
339+
// Verify the filters. Note: It's hard to verify the `published` filter,
340+
// because there are many components with that text on the screen, but that's not the important thing.
341+
expect(screen.getByText(/modified since publish/i)).toBeInTheDocument();
342+
expect(screen.queryByText(/never published/i)).not.toBeInTheDocument();
343+
});
305344
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import { useLibraryContext } from '../../common/context/LibraryContext';
3+
import { FilterByPublished, PublishStatus } from '../../../search-manager';
4+
5+
/**
6+
* When browsing library content for insertion into a course, we only show published
7+
* content. In that case, there is no need for a 'Never Published' filter, which will
8+
* never show results. This component removes that option from FilterByPublished
9+
* when not relevant.
10+
*/
11+
const LibraryFilterByPublished : React.FC<Record<never, never>> = () => {
12+
const { showOnlyPublished } = useLibraryContext();
13+
14+
if (showOnlyPublished) {
15+
return (
16+
<FilterByPublished visibleFilters={
17+
[PublishStatus.Published, PublishStatus.Modified]
18+
}
19+
/>
20+
);
21+
}
22+
23+
return <FilterByPublished />;
24+
};
25+
26+
export default LibraryFilterByPublished;

src/search-manager/FilterByPublished.tsx

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
1010
import messages from './messages';
1111
import SearchFilterWidget from './SearchFilterWidget';
1212
import { useSearchContext } from './SearchManager';
13-
import { PublishStatus } from './data/api';
13+
import { allPublishFilters, PublishStatus } from './data/api';
14+
15+
interface FilterByPublishedProps {
16+
visibleFilters?: PublishStatus[],
17+
}
1418

1519
/**
1620
* A button with a dropdown that allows filtering the current search by publish status
1721
*/
18-
const FilterByPublished: React.FC<Record<never, never>> = () => {
22+
const FilterByPublished = ({
23+
visibleFilters = allPublishFilters,
24+
}: FilterByPublishedProps) => {
1925
const intl = useIntl();
2026
const {
2127
publishStatus,
@@ -42,6 +48,26 @@ const FilterByPublished: React.FC<Record<never, never>> = () => {
4248
};
4349
const appliedFilters = publishStatusFilter.map(mode => ({ label: modeToLabel[mode] }));
4450

51+
const filterLabels = {
52+
[PublishStatus.Published]: intl.formatMessage(messages.publishStatusPublished),
53+
[PublishStatus.Modified]: intl.formatMessage(messages.publishStatusModified),
54+
[PublishStatus.NeverPublished]: intl.formatMessage(messages.publishStatusNeverPublished),
55+
};
56+
57+
const visibleFiltersToRender = visibleFilters.map((filter) => (
58+
<MenuItem
59+
key={filter}
60+
as={Form.Checkbox}
61+
value={filter}
62+
onChange={() => { toggleFilterMode(filter); }}
63+
>
64+
<div>
65+
{filterLabels[filter]}
66+
<Badge variant="light" pill>{publishStatus[filter] ?? 0}</Badge>
67+
</div>
68+
</MenuItem>
69+
));
70+
4571
return (
4672
<SearchFilterWidget
4773
appliedFilters={appliedFilters}
@@ -55,36 +81,7 @@ const FilterByPublished: React.FC<Record<never, never>> = () => {
5581
value={publishStatusFilter}
5682
>
5783
<Menu className="block-type-refinement-menu" style={{ boxShadow: 'none' }}>
58-
<MenuItem
59-
as={Form.Checkbox}
60-
value={PublishStatus.Published}
61-
onChange={() => { toggleFilterMode(PublishStatus.Published); }}
62-
>
63-
<div>
64-
{intl.formatMessage(messages.publishStatusPublished)}
65-
<Badge variant="light" pill>{publishStatus[PublishStatus.Published] ?? 0}</Badge>
66-
</div>
67-
</MenuItem>
68-
<MenuItem
69-
as={Form.Checkbox}
70-
value={PublishStatus.Modified}
71-
onChange={() => { toggleFilterMode(PublishStatus.Modified); }}
72-
>
73-
<div>
74-
{intl.formatMessage(messages.publishStatusModified)}
75-
<Badge variant="light" pill>{publishStatus[PublishStatus.Modified] ?? 0}</Badge>
76-
</div>
77-
</MenuItem>
78-
<MenuItem
79-
as={Form.Checkbox}
80-
value={PublishStatus.NeverPublished}
81-
onChange={() => { toggleFilterMode(PublishStatus.NeverPublished); }}
82-
>
83-
<div>
84-
{intl.formatMessage(messages.publishStatusNeverPublished)}
85-
<Badge variant="light" pill>{publishStatus[PublishStatus.NeverPublished] ?? 0}</Badge>
86-
</div>
87-
</MenuItem>
84+
{visibleFiltersToRender}
8885
</Menu>
8986
</Form.CheckboxSet>
9087
</Form.Group>

src/search-manager/data/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export enum PublishStatus {
3131
NeverPublished = 'never',
3232
}
3333

34+
export const allPublishFilters: PublishStatus[] = Object.values(PublishStatus);
35+
3436
/**
3537
* Get the content search configuration from the CMS.
3638
*/

0 commit comments

Comments
 (0)