Skip to content

Commit 398c28d

Browse files
committed
feat: display both collections and components in recent section
1 parent 31a0864 commit 398c28d

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

src/library-authoring/LibraryAuthoringPage.test.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,8 @@ describe('<LibraryAuthoringPage />', () => {
436436
const doc = await renderLibraryPage();
437437

438438
// Click on the first component
439-
waitFor(() => expect(doc.queryByText(displayName)).toBeInTheDocument());
440-
fireEvent.click(doc.getAllByText(displayName)[0]);
439+
expect((await doc.findAllByText(displayName))[0]).toBeInTheDocument();
440+
fireEvent.click((await doc.findAllByText(displayName))[0]);
441441

442442
const sidebar = doc.getByTestId('library-sidebar');
443443

@@ -549,4 +549,20 @@ describe('<LibraryAuthoringPage />', () => {
549549

550550
expect(doc.getByText(/no matching components/i)).toBeInTheDocument();
551551
});
552+
553+
it('shows both components and collections in recently modified section', async () => {
554+
const doc = await renderLibraryPage();
555+
556+
expect(await doc.findByText('Content library')).toBeInTheDocument();
557+
expect((await doc.findAllByText(libraryTitle))[0]).toBeInTheDocument();
558+
559+
// "Recently Modified" header + sort shown
560+
expect(doc.getAllByText('Recently Modified').length).toEqual(2);
561+
const recentModifiedContainer = (await doc.findAllByText('Recently Modified'))[1].parentElement?.parentElement?.parentElement;
562+
if (recentModifiedContainer) {
563+
const container = within(recentModifiedContainer);
564+
expect(container.queryAllByText('Text').length).toBeGreaterThan(0);
565+
expect(container.queryAllByText('Collection').length).toBeGreaterThan(0);
566+
}
567+
});
552568
});

src/library-authoring/LibraryRecentlyModified.tsx

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,77 @@
1-
import React from 'react';
1+
import React, { useMemo } from 'react';
22
import { useIntl } from '@edx/frontend-platform/i18n';
3+
import { orderBy } from 'lodash';
4+
import { CardGrid } from '@openedx/paragon';
35

46
import { SearchContextProvider, useSearchContext } from '../search-manager';
5-
import { SearchSortOption } from '../search-manager/data/api';
6-
import LibraryComponents from './components/LibraryComponents';
7-
import LibrarySection from './components/LibrarySection';
7+
import { type CollectionHit, type ContentHit, SearchSortOption } from '../search-manager/data/api';
8+
import LibrarySection, { LIBRARY_SECTION_PREVIEW_LIMIT } from './components/LibrarySection';
89
import messages from './messages';
10+
import ComponentCard from './components/ComponentCard';
11+
import { useLibraryBlockTypes } from './data/apiHooks';
12+
import CollectionCard from './components/CollectionCard';
913

1014
const RecentlyModified: React.FC<{ libraryId: string }> = ({ libraryId }) => {
1115
const intl = useIntl();
12-
const { totalHits: componentCount } = useSearchContext();
16+
const {
17+
hits,
18+
collectionHits,
19+
totalHits,
20+
totalCollectionHits,
21+
} = useSearchContext();
22+
23+
const componentCount = totalHits + totalCollectionHits;
24+
// Since we only display a fixed number of items in preview,
25+
// only these number of items are use in sort step below
26+
const componentList = hits.slice(0, LIBRARY_SECTION_PREVIEW_LIMIT);
27+
const collectionList = collectionHits.slice(0, LIBRARY_SECTION_PREVIEW_LIMIT);
28+
// Sort them by `modified` field in reverse and display them
29+
const recentItems = orderBy([
30+
...componentList,
31+
...collectionList,
32+
], ['modified'], ['desc']).slice(0, LIBRARY_SECTION_PREVIEW_LIMIT);
33+
34+
const { data: blockTypesData } = useLibraryBlockTypes(libraryId);
35+
const blockTypes = useMemo(() => {
36+
const result = {};
37+
if (blockTypesData) {
38+
blockTypesData.forEach(blockType => {
39+
result[blockType.blockType] = blockType;
40+
});
41+
}
42+
return result;
43+
}, [blockTypesData]);
1344

1445
return componentCount > 0
1546
? (
1647
<LibrarySection
1748
title={intl.formatMessage(messages.recentlyModifiedTitle)}
1849
contentCount={componentCount}
1950
>
20-
<LibraryComponents libraryId={libraryId} variant="preview" />
51+
<CardGrid
52+
columnSizes={{
53+
sm: 12,
54+
md: 6,
55+
lg: 4,
56+
xl: 3,
57+
}}
58+
hasEqualColumnHeights
59+
>
60+
{recentItems.map((contentHit) => (
61+
contentHit.type === 'collection' ? (
62+
<CollectionCard
63+
key={contentHit.id}
64+
collectionHit={contentHit as CollectionHit}
65+
/>
66+
) : (
67+
<ComponentCard
68+
key={contentHit.id}
69+
contentHit={contentHit as ContentHit}
70+
blockTypeDisplayName={blockTypes[(contentHit as ContentHit).blockType]?.displayName ?? ''}
71+
/>
72+
)
73+
))}
74+
</CardGrid>
2175
</LibrarySection>
2276
)
2377
: null;

src/library-authoring/__mocks__/library-search.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
}
2121
],
2222
"created": 1721857069.042984,
23-
"modified": 1725398676.078056,
23+
"modified": 1725878053.420395,
2424
"last_published": 1725035862.450613,
2525
"usage_key": "lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd",
2626
"block_type": "html",
@@ -293,7 +293,7 @@
293293
}
294294
],
295295
"created": 1725534795.628254,
296-
"modified": 1725534795.628266,
296+
"modified": 1725878053.420395,
297297
"context_key": "lib:OpenedX:CSPROB2",
298298
"org": "OpenedX",
299299
"access_id": 16,

0 commit comments

Comments
 (0)