Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rpenido/bkp/fal 3764 before squash #54

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
4191ecb
feat: Add lib v2/legacy tabs in studio home
yusuf-musleh May 27, 2024
15c678b
feat: Add `LIBRARY_MODE` config variable
yusuf-musleh May 28, 2024
14b8b3a
feat: Add url paths/navigation for each tab
yusuf-musleh May 28, 2024
515cc71
feat: LibraryV2 redirect to lib mfe or placeholder
yusuf-musleh May 30, 2024
9c6e1e6
feat: Add pagination support for lib v2s
yusuf-musleh May 30, 2024
da189c1
fix: Redirect to placeholder create lib in v2/mixed disabled mfe
yusuf-musleh Jun 3, 2024
85d9ff2
temp: This removes TS code to get tests to run
yusuf-musleh Jun 3, 2024
c6b7bf8
test: Update existing tests to support changes
yusuf-musleh Jun 3, 2024
14933d2
temp: Rename .tsx -> .jsx & .ts -> .js for tests
yusuf-musleh Jun 3, 2024
8b96268
fix: Fix lint issues
yusuf-musleh Jun 3, 2024
f8db853
feat: library home page bare bones
rpenido Jun 4, 2024
7a8488d
test: Add tests for new functionality
yusuf-musleh Jun 4, 2024
7842ce0
fix: update search modal for new library urls
rpenido Jun 5, 2024
462cda9
feat: Add lib v2/legacy tabs in studio home
yusuf-musleh May 27, 2024
be8b2f4
feat: Add `LIBRARY_MODE` config variable
yusuf-musleh May 28, 2024
27b2581
feat: Add url paths/navigation for each tab
yusuf-musleh May 28, 2024
4ffd651
feat: LibraryV2 redirect to lib mfe or placeholder
yusuf-musleh May 30, 2024
7f97243
feat: Add pagination support for lib v2s
yusuf-musleh May 30, 2024
c86b85a
fix: Redirect to placeholder create lib in v2/mixed disabled mfe
yusuf-musleh Jun 3, 2024
efbc625
temp: This removes TS code to get tests to run
yusuf-musleh Jun 3, 2024
21da6f8
test: Update existing tests to support changes
yusuf-musleh Jun 3, 2024
79e6516
temp: Rename .tsx -> .jsx & .ts -> .js for tests
yusuf-musleh Jun 3, 2024
262cb3f
fix: Fix lint issues
yusuf-musleh Jun 3, 2024
1ea229f
test: Add tests for new functionality
yusuf-musleh Jun 4, 2024
a0a30b7
refactor: Change /legacy-libraries -> /libraries-v1
yusuf-musleh Jun 6, 2024
4deaea9
fix: add i18n messages
rpenido Jun 6, 2024
c2bdecf
fix: libraryAuthoring enabled check
rpenido Jun 6, 2024
5213eff
Merge branch 'yusuf-musleh/lib-v2-tab-studio-home' into rpenido/fal-3…
rpenido Jun 6, 2024
a24b3ba
fix: add Create Library placeholder
rpenido Jun 6, 2024
2859741
refactor: Remove hardcoded mfe path
yusuf-musleh Jun 6, 2024
d853f29
refactor: rename .ts files to .js
rpenido Jun 6, 2024
567dcb4
feat: Add function to construct Lib Auth MFE URL
yusuf-musleh Jun 6, 2024
094086e
feat: Make URL /library-v1 when referencing legacy
yusuf-musleh Jun 6, 2024
a95c990
fix: Add missing part of path
yusuf-musleh Jun 6, 2024
e3ebc55
fix: type and lint errors
rpenido Jun 6, 2024
8ed168d
fix: Issue with destinationUrl
yusuf-musleh Jun 6, 2024
beda37f
test: Add checks for Tab.eventKey in tests
yusuf-musleh Jun 6, 2024
2e3fa43
fix: Revert card item url changes to keep simple
yusuf-musleh Jun 7, 2024
72edfac
fix: add tests
rpenido Jun 7, 2024
8086ebf
Merge branch 'yusuf-musleh/lib-v2-tab-studio-home' into rpenido/fal-3…
rpenido Jun 7, 2024
91443e9
fix: removing unused file
rpenido Jun 7, 2024
a29cf7e
fix: add ts-check
rpenido Jun 7, 2024
4deab76
fix: removing deleted file references
rpenido Jun 7, 2024
e8bca34
chore: trigger CI
rpenido Jun 7, 2024
0078c0e
feat: Initial structure of ComponentCard
ChrisChV Jun 13, 2024
388c40e
fix: fixes from review
rpenido Jun 13, 2024
7d6096e
fix: fix default parameter syntax
rpenido Jun 14, 2024
19b2935
feat: Connect TagCount, Colors and Icons with library components card
ChrisChV Jun 17, 2024
c87c481
feat: Infinite scroll implemented on Components tab
ChrisChV Jun 18, 2024
c63bc2f
fix: new library redirect
rpenido Jun 18, 2024
efe0bed
Revert "fix: new library redirect"
rpenido Jun 19, 2024
942cbff
chore: trigger CI
rpenido Jun 19, 2024
7560fa2
style: Style nits on card component
ChrisChV Jun 19, 2024
2d3be09
fix: new library redirect
rpenido Jun 20, 2024
e8f9f78
fix: remove warning on library home
rpenido Jun 20, 2024
f9920f4
fix: remove unused import
rpenido Jun 20, 2024
7fd6c27
Merge branch 'master' into rpenido/fal-3753-library-home-page-bare-bones
rpenido Jun 20, 2024
94f483b
fix: merging nits
rpenido Jun 20, 2024
b455f97
fix: change version to slug in header
rpenido Jun 20, 2024
3ae6fe8
fix: header outline link for libraries
rpenido Jun 20, 2024
bd12510
style: Add fetchNextPage to infinite scroll useEffect
ChrisChV Jun 20, 2024
d611d29
feat: Variant added to LibraryComponents to show full components or a…
ChrisChV Jun 20, 2024
499aced
style: Nits on lints and code
ChrisChV Jun 20, 2024
da1c2e0
refactor: Create block-type-utils with block type constants
ChrisChV Jun 20, 2024
c8bc5fc
fix: Issues on course-unit tests
ChrisChV Jun 21, 2024
0843a1e
refactor: Calculate tagCount in LibraryComponents instead on serach i…
ChrisChV Jun 21, 2024
e972fb0
Merge branch 'master' into rpenido/fal-3753-library-home-page-bare-bones
rpenido Jun 21, 2024
55acb06
refactor: test renaming to ts
rpenido Jun 21, 2024
a1a0ad8
refactor: renaming files js -> ts
rpenido Jun 24, 2024
87358b7
fix: update typescript code
rpenido Jun 24, 2024
0b4e90e
Merge branch 'master' into rpenido/fal-3753-library-home-page-bare-bones
rpenido Jun 24, 2024
5687b76
test: Added for LibraryComponents
ChrisChV Jun 24, 2024
51d36ce
fix: remove @ts-check
rpenido Jun 25, 2024
fbd418d
fix: remove unused file
rpenido Jun 25, 2024
af011f4
feat: use search manager
rpenido Jun 25, 2024
5c0fadb
refactor: cleanup code
rpenido Jun 25, 2024
3a67927
fix: more cleanup
rpenido Jun 25, 2024
8d9b86b
chore: Fix merge conflicts
ChrisChV Jun 26, 2024
b4374e9
feat: Adjust library home filter styles
yusuf-musleh Jun 26, 2024
01cd595
Merge branch 'master' into rpenido/fal-3764-library-home-filter-by-co…
rpenido Jun 28, 2024
bd3d2c5
fix: remove LibraryV2Placeholder
rpenido Jun 28, 2024
dee7c0b
Merge branch 'master' into rpenido/fal-3753-library-home-page-bare-bones
rpenido Jun 30, 2024
2a5d42b
fix: optional parameters
rpenido Jun 30, 2024
62fe7f5
chore: trigger CI
rpenido Jun 30, 2024
31012df
refactor: Migrate block-type-utils to TS
ChrisChV Jul 1, 2024
1534b61
chore: Fix merge conflicts
ChrisChV Jul 1, 2024
42f2666
test: Fixt LibraryAuthoringPage test
ChrisChV Jul 1, 2024
1af4fbe
Merge branch 'chris/FAL-3757-components-tab' into rpenido/fal-3764-li…
rpenido Jul 2, 2024
99b9b31
feat: fixing merge issues and tests
rpenido Jul 2, 2024
f902335
refactor: create search-manager feature
rpenido Jul 2, 2024
e485ab3
test: fix search-modal locator
rpenido Jul 2, 2024
3cc07ae
Merge branch 'yusuf-musleh/library-home-filters-styling' into rpenido…
rpenido Jul 3, 2024
1bf2708
fix: fix scss files location
rpenido Jul 3, 2024
6aa1b0c
refactor: moving Stats
rpenido Jul 3, 2024
782386f
fix: remove Stats from library home
rpenido Jul 3, 2024
dfd3190
fix: remove loading state if already data is already loaded to avoid …
rpenido Jul 3, 2024
6acee0a
feat: library home page bare bones
rpenido Jul 3, 2024
3400f71
feat: Add clear filter btn to filter widget
yusuf-musleh Jul 3, 2024
7515975
refactor: migrate Header to ts and fix some types
rpenido Jul 3, 2024
c453ef0
fix: add intl to tab names
rpenido Jul 5, 2024
1718c26
fix: remove bottom border to align label with checkbox
rpenido Jul 5, 2024
905dbb5
fix: add intl to tab names
rpenido Jul 5, 2024
fc84f7f
Merge branch 'rpenido/fal-3753-library-home-page-bare-bones' into rpe…
rpenido Jul 9, 2024
d203659
Merge branch 'master' into rpenido/fal-3764-library-home-filter-by-co…
rpenido Jul 9, 2024
8f0971e
fix: removing unused file
rpenido Jul 9, 2024
2ec5a6f
fix: removing unused file
rpenido Jul 9, 2024
e28ef16
feat: adds sort widget to search manager and library component page
pomegranited Jul 9, 2024
9cd428e
fix: type error
pomegranited Jul 10, 2024
2ed545d
fix: move block type intl
rpenido Jul 10, 2024
b440b92
feat: store selected sort option in query string
pomegranited Jul 10, 2024
a10ff79
fix: better way to store sort params in query string
pomegranited Jul 11, 2024
8582f08
Merge branch 'rpenido/fal-3764-library-home-filter-by-content-type' i…
pomegranited Jul 11, 2024
e96194c
fix: navigate to url + params
pomegranited Jul 12, 2024
34c4b4e
test: adds tests for the SearchSortWidget
pomegranited Jul 12, 2024
de713db
fix: stringify enumValue to compare with string
pomegranited Jul 19, 2024
61af79d
feat: Add "Recently Modified" library section (TEMP) (#52)
yusuf-musleh Jul 20, 2024
fbf14ce
fix: style the sort dropdown more like the search filter widgets
pomegranited Jul 22, 2024
fb8acf6
Merge branch 'master' into rpenido/fal-3764-library-home-filter-by-co…
rpenido Jul 23, 2024
4d06a01
fix: eslint
rpenido Jul 23, 2024
37ca09d
fix: remove unused file
rpenido Jul 23, 2024
f591fbe
refactor: renaming index.ts -> index.tsx
rpenido Jul 23, 2024
b0e941d
feat: Recently Published sort option also excludes unpublished compon…
pomegranited Jul 23, 2024
19c869a
fix: removes "Most Relevant" default sort option, use "Clear Filters"…
pomegranited Jul 23, 2024
88e5bae
Merge branch 'jill/FAL-3758-sort-components' into rpenido/bkp/fal-376…
rpenido Jul 24, 2024
dacf7c7
fix: merge errors
rpenido Jul 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
@import "textbooks/Textbooks";
@import "content-tags-drawer/ContentTagsDropDownSelector";
@import "content-tags-drawer/ContentTagsCollapsible";
@import "search-modal/SearchModal";
@import "search-modal";
@import "search-manager";
@import "certificates/scss/Certificates";
@import "group-configurations/GroupConfigurations";
@import "library-authoring";
Expand Down
147 changes: 137 additions & 10 deletions src/library-authoring/LibraryAuthoringPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import {
screen,
} from '@testing-library/react';
import fetchMock from 'fetch-mock-jest';

import initializeStore from '../store';
import { getContentSearchConfigUrl } from '../search-modal/data/api';
import { getContentSearchConfigUrl } from '../search-manager/data/api';
import mockResult from '../search-modal/__mocks__/search-result.json';
import mockEmptyResult from '../search-modal/__mocks__/empty-search-result.json';
import { getContentLibraryApiUrl, type ContentLibrary } from './data/api';
Expand Down Expand Up @@ -51,6 +50,21 @@ const returnEmptyResult = (_url, req) => {
return mockEmptyResult;
};

const returnLowNumberResults = (_url, req) => {
const requestData = JSON.parse(req.body?.toString() ?? '');
const query = requestData?.queries[0]?.q ?? '';
// We have to replace the query (search keywords) in the mock results with the actual query,
// because otherwise we may have an inconsistent state that causes more queries and unexpected results.
mockResult.results[0].query = query;
// Limit number of results to just 2
mockResult.results[0].hits = mockResult.results[0]?.hits.slice(0, 2);
mockResult.results[0].estimatedTotalHits = 2;
// And fake the required '_formatted' fields; it contains the highlighting <mark>...</mark> around matched words
// eslint-disable-next-line no-underscore-dangle, no-param-reassign
mockResult.results[0]?.hits.forEach((hit) => { hit._formatted = { ...hit }; });
return mockResult;
};

const libraryData: ContentLibrary = {
id: 'lib:org1:lib1',
type: 'complex',
Expand Down Expand Up @@ -158,8 +172,9 @@ describe('<LibraryAuthoringPage />', () => {
getByRole, getByText, queryByText, findByText,
} = render(<RootWrapper />);

// Ensure the search endpoint is called
// One called for LibraryComponents and another called for components count
// Ensure the search endpoint is called:
// Call 1: To fetch searchable/filterable/sortable library data
// Call 2: To fetch the recently modified components only
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });

expect(getByText('Content library')).toBeInTheDocument();
Expand Down Expand Up @@ -204,8 +219,10 @@ describe('<LibraryAuthoringPage />', () => {
expect(await findByText('Content library')).toBeInTheDocument();
expect(await findByText(libraryData.title)).toBeInTheDocument();

// Ensure the search endpoint is called
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(1, searchEndpoint, 'post'); });
// Ensure the search endpoint is called:
// Call 1: To fetch searchable/filterable/sortable library data
// Call 2: To fetch the recently modified components only
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });

expect(getByText('You have not added any content to this library yet.')).toBeInTheDocument();
});
Expand All @@ -230,13 +247,16 @@ describe('<LibraryAuthoringPage />', () => {
expect(await findByText('Content library')).toBeInTheDocument();
expect(await findByText(libraryData.title)).toBeInTheDocument();

// Ensure the search endpoint is called
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(1, searchEndpoint, 'post'); });
// Ensure the search endpoint is called:
// Call 1: To fetch searchable/filterable/sortable library data
// Call 2: To fetch the recently modified components only
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });

fireEvent.change(getByRole('searchbox'), { target: { value: 'noresults' } });

// Ensure the search endpoint is called again
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });
// Ensure the search endpoint is called again, only once more since the recently modified call
// should not be impacted by the search
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(3, searchEndpoint, 'post'); });

expect(getByText('No matching components found in this library.')).toBeInTheDocument();

Expand Down Expand Up @@ -268,4 +288,111 @@ describe('<LibraryAuthoringPage />', () => {

expect(screen.queryByText(/add content/i)).not.toBeInTheDocument();
});

it('show the "View All" button when viewing library with many components', async () => {
mockUseParams.mockReturnValue({ libraryId: libraryData.id });
axiosMock.onGet(getContentLibraryApiUrl(libraryData.id)).reply(200, libraryData);

const {
getByRole, getByText, queryByText, getAllByText,
} = render(<RootWrapper />);

// Ensure the search endpoint is called:
// Call 1: To fetch searchable/filterable/sortable library data
// Call 2: To fetch the recently modified components only
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });

expect(getByText('Content library')).toBeInTheDocument();
expect(getByText(libraryData.title)).toBeInTheDocument();

expect(queryByText('You have not added any content to this library yet.')).not.toBeInTheDocument();

expect(getByText('Recently Modified')).toBeInTheDocument();
expect(getByText('Collections (0)')).toBeInTheDocument();
expect(getByText('Components (6)')).toBeInTheDocument();
expect(getAllByText('Test HTML Block')[0]).toBeInTheDocument();

// There should only be one "View All" button, since the Components count
// are above the preview limit (4)
expect(getByText('View All')).toBeInTheDocument();

// Clicking on "View All" button should navigate to the Components tab
fireEvent.click(getByText('View All'));
expect(queryByText('Recently Modified')).not.toBeInTheDocument();
expect(queryByText('Collections (0)')).not.toBeInTheDocument();
expect(queryByText('Components (6)')).not.toBeInTheDocument();
expect(getAllByText('Test HTML Block')[0]).toBeInTheDocument();

// Go back to Home tab
// This step is necessary to avoid the url change leak to other tests
fireEvent.click(getByRole('tab', { name: 'Home' }));
expect(getByText('Recently Modified')).toBeInTheDocument();
expect(getByText('Collections (0)')).toBeInTheDocument();
expect(getByText('Components (6)')).toBeInTheDocument();
});

it('should not show the "View All" button when viewing library with low number of components', async () => {
mockUseParams.mockReturnValue({ libraryId: libraryData.id });
axiosMock.onGet(getContentLibraryApiUrl(libraryData.id)).reply(200, libraryData);
fetchMock.post(searchEndpoint, returnLowNumberResults, { overwriteRoutes: true });

const {
getByText, queryByText, getAllByText,
} = render(<RootWrapper />);

// Ensure the search endpoint is called:
// Call 1: To fetch searchable/filterable/sortable library data
// Call 2: To fetch the recently modified components only
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });

expect(getByText('Content library')).toBeInTheDocument();
expect(getByText(libraryData.title)).toBeInTheDocument();

expect(queryByText('You have not added any content to this library yet.')).not.toBeInTheDocument();

expect(getByText('Recently Modified')).toBeInTheDocument();
expect(getByText('Collections (0)')).toBeInTheDocument();
expect(getByText('Components (2)')).toBeInTheDocument();
expect(getAllByText('Test HTML Block')[0]).toBeInTheDocument();

// There should not be any "View All" button on page since Components count
// is less than the preview limit (4)
expect(queryByText('View All')).not.toBeInTheDocument();
});

it('sort library components', async () => {
mockUseParams.mockReturnValue({ libraryId: libraryData.id });
axiosMock.onGet(getContentLibraryApiUrl(libraryData.id)).reply(200, libraryData);
fetchMock.post(searchEndpoint, returnEmptyResult, { overwriteRoutes: true });

const { findByText, getByText, getByTitle } = render(<RootWrapper />);

// Default sorts by relevance
expect(await findByText('Most Relevant')).toBeInTheDocument();

const testSortOption = (async (optionText, sortBy) => {
fireEvent.click(getByTitle('Sort search results'));
fireEvent.click(getByText(optionText));
const bodyText = sortBy ? `"sort":["${sortBy}"]` : '"sort":[]';
const searchText = sortBy ? `?sort=${encodeURIComponent(sortBy)}` : '';
await waitFor(() => {
expect(fetchMock).toHaveBeenLastCalledWith(searchEndpoint, {
body: expect.stringContaining(bodyText),
method: 'POST',
headers: expect.anything(),
});
});
expect(window.location.search).toEqual(searchText);
});

await testSortOption('Title, A-Z', 'display_name:asc');
await testSortOption('Title, Z-A', 'display_name:desc');
await testSortOption('Newest', 'created:desc');
await testSortOption('Oldest', 'created:asc');
await testSortOption('Recently Published', 'last_published:desc');
await testSortOption('Recently Modified', 'modified:desc');

// Selecting the default sort option clears the url search param
await testSortOption('Most Relevant', '');
});
});
130 changes: 72 additions & 58 deletions src/library-authoring/LibraryAuthoringPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,38 @@
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Button,
Col,
Container,
Icon,
IconButton,
SearchField,
Row,
Tab,
Tabs,
Row,
Col,
} from '@openedx/paragon';
import { Add, InfoOutline } from '@openedx/paragon/icons';
import {
Routes, Route, useLocation, useNavigate, useParams,
Routes, Route, useLocation, useNavigate, useParams, useSearchParams,
} from 'react-router-dom';

import Loading from '../generic/Loading';
import SubHeader from '../generic/sub-header/SubHeader';
import Header from '../header';
import NotFoundAlert from '../generic/NotFoundAlert';
import {
ClearFiltersButton,
FilterByBlockType,
FilterByTags,
SearchContextProvider,
SearchKeywordsField,
SearchSortWidget,
} from '../search-manager';
import LibraryComponents from './components/LibraryComponents';
import LibraryCollections from './LibraryCollections';
import LibraryHome from './LibraryHome';
import { useContentLibrary } from './data/apiHooks';
import messages from './messages';
import { LibrarySidebar } from './library-sidebar';
import { LibraryContext } from './common/context';
import messages from './messages';

enum TabList {
home = '',
Expand All @@ -54,15 +61,14 @@
const intl = useIntl();
const location = useLocation();
const navigate = useNavigate();
const [searchKeywords, setSearchKeywords] = React.useState('');

const { libraryId } = useParams();

const { data: libraryData, isLoading } = useContentLibrary(libraryId);

const currentPath = location.pathname.split('/').pop();
const activeKey = (currentPath && currentPath in TabList) ? TabList[currentPath] : TabList.home;
const { sidebarBodyComponent, openAddContentSidebar } = useContext(LibraryContext);
const [searchParams] = useSearchParams();

if (isLoading) {
return <Loading />;
Expand All @@ -73,7 +79,10 @@
}

const handleTabChange = (key: string) => {
navigate(key);
navigate({
pathname: key,
search: searchParams.toString(),
});
};

return (
Expand All @@ -87,57 +96,62 @@
contextId={libraryId}
isLibrary
/>
<Container size="xl" className="p-4 mt-3">
<SubHeader
title={<SubHeaderTitle title={libraryData.title} />}
subtitle={intl.formatMessage(messages.headingSubtitle)}
headerActions={[
<Button
iconBefore={Add}
variant="primary rounded-0"
onClick={() => openAddContentSidebar()}
disabled={!libraryData.canEditLibrary}
>
{intl.formatMessage(messages.newContentButton)}
</Button>,
]}
/>
<SearchField
value={searchKeywords}
placeholder={intl.formatMessage(messages.searchPlaceholder)}
onChange={(value: string) => setSearchKeywords(value)}
onSubmit={() => {}}
className="w-50"
/>
<Tabs
variant="tabs"
activeKey={activeKey}
onSelect={handleTabChange}
className="my-3"
>
<Tab eventKey={TabList.home} title={intl.formatMessage(messages.homeTab)} />
<Tab eventKey={TabList.components} title={intl.formatMessage(messages.componentsTab)} />
<Tab eventKey={TabList.collections} title={intl.formatMessage(messages.collectionsTab)} />
</Tabs>
<Routes>
<Route
path={TabList.home}
element={<LibraryHome libraryId={libraryId} filter={{ searchKeywords }} />}
/>
<Route
path={TabList.components}
element={<LibraryComponents libraryId={libraryId} filter={{ searchKeywords }} variant="full" />}
/>
<Route
path={TabList.collections}
element={<LibraryCollections />}
/>
<Route
path="*"
element={<NotFoundAlert />}
<SearchContextProvider
extraFilter={`context_key = "${libraryId}"`}
>
<Container size="xl" className="p-4 mt-3">
<SubHeader
title={<SubHeaderTitle title={libraryData.title} />}
subtitle={intl.formatMessage(messages.headingSubtitle)}
headerActions={[
<Button
iconBefore={Add}
variant="primary rounded-0"
onClick={openAddContentSidebar}
disabled={!libraryData.canEditLibrary}
>
{intl.formatMessage(messages.newContentButton)}
</Button>,
]}
/>
</Routes>
</Container>
<SearchKeywordsField className="w-50" />
<div className="d-flex mt-3 align-items-center">
<FilterByTags />
<FilterByBlockType />
<ClearFiltersButton />
<div className="flex-grow-1" />
<SearchSortWidget />
</div>
<Tabs
variant="tabs"
activeKey={activeKey}
onSelect={handleTabChange}
className="my-3"
>
<Tab eventKey={TabList.home} title={intl.formatMessage(messages.homeTab)} />
<Tab eventKey={TabList.components} title={intl.formatMessage(messages.componentsTab)} />
<Tab eventKey={TabList.collections} title={intl.formatMessage(messages.collectionsTab)} />
</Tabs>
<Routes>
<Route
path={TabList.home}
element={<LibraryHome libraryId={libraryId} />}

Check failure on line 138 in src/library-authoring/LibraryAuthoringPage.tsx

View workflow job for this annotation

GitHub Actions / tests

Type '{ libraryId: string; }' is missing the following properties from type 'LibraryHomeProps': tabList, handleTabChange
/>
<Route
path={TabList.components}
element={<LibraryComponents libraryId={libraryId} variant="full" />}
/>
<Route
path={TabList.collections}
element={<LibraryCollections />}
/>
<Route
path="*"
element={<NotFoundAlert />}
/>
</Routes>
</Container>
</SearchContextProvider>
<StudioFooter />
</Col>
{ sidebarBodyComponent !== null && (
Expand Down
Loading
Loading