Skip to content

Commit 22b3f3e

Browse files
committed
feat: Update the history log to use the create entry
1 parent 1f1ece7 commit 22b3f3e

5 files changed

Lines changed: 86 additions & 23 deletions

File tree

src/library-authoring/data/api.mocks.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,40 @@ mockLibraryBlockPublishHistoryEntries.applyMock = () => jest.spyOn(
12921292
'getLibraryBlockPublishHistoryEntries',
12931293
).mockImplementation(mockLibraryBlockPublishHistoryEntries);
12941294

1295+
/**
1296+
* Mock for `getLibraryBlockCreationEntry()`
1297+
*
1298+
* Use `mockLibraryBlockCreationEntry.applyMock()` to apply it to the whole test suite.
1299+
*/
1300+
export async function mockLibraryBlockCreationEntry(usageKey: string): Promise<api.LibraryHistoryEntry> {
1301+
const thisMock = mockLibraryBlockCreationEntry;
1302+
switch (usageKey) {
1303+
case thisMock.usageKeyThatNeverLoads:
1304+
return new Promise<any>(() => {});
1305+
case thisMock.usageKey: return thisMock.data;
1306+
case thisMock.usageKeyEmpty: return thisMock.dataEmpty;
1307+
default: throw new Error(`No mock has been set up for usageKey "${usageKey}"`);
1308+
}
1309+
}
1310+
mockLibraryBlockCreationEntry.usageKeyThatNeverLoads = 'lb:Axim:infiniteLoading:html:123';
1311+
mockLibraryBlockCreationEntry.usageKey = 'lb:Axim:TEST1:html:571fe018-f3ce-45c9-8f53-5dafcb422fd1';
1312+
mockLibraryBlockCreationEntry.usageKeyEmpty = 'lb:Axim:TEST2:html:571fe018-f3ce-45c9-8f53-5dafcb422fd2';
1313+
mockLibraryBlockCreationEntry.data = {
1314+
changedBy: mockContributor('author'),
1315+
changedAt: '2024-01-01T00:00:00Z',
1316+
title: 'Introduction to Testing 1',
1317+
blockType: 'html',
1318+
action: 'created',
1319+
} satisfies api.LibraryHistoryEntry;
1320+
mockLibraryBlockCreationEntry.dataEmpty = {
1321+
changedBy: mockContributor('Author'),
1322+
changedAt: '2024-01-01T00:00:00Z',
1323+
title: 'Introduction to Testing 2',
1324+
blockType: 'html',
1325+
action: 'created',
1326+
} satisfies api.LibraryHistoryEntry;
1327+
mockLibraryBlockCreationEntry.applyMock = () => jest.spyOn(api, 'getLibraryBlockCreationEntry').mockImplementation(mockLibraryBlockCreationEntry);
1328+
12951329
export const mockGetMigrationInfo = {
12961330
applyMock: () => jest.spyOn(api, 'getMigrationInfo').mockResolvedValue(
12971331
camelCaseObject({

src/library-authoring/data/api.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ export const getLibraryBlockPublishHistoryUrl = (usageKey: string) => `${getLibr
6565
*/
6666
export const getLibraryBlockPublishHistoryEntriesUrl = (usageKey: string, publishGroupId: string) => `${getLibraryBlockMetadataUrl(usageKey)}publish_history/${publishGroupId}/entries/`
6767

68+
/**
69+
* Get the URL for the creation entry of a component.
70+
*/
71+
export const getLibraryBlockCreationEntryUrl = (usageKey: string) => `${getLibraryBlockMetadataUrl(usageKey)}creation_entry/`;
72+
6873
/**
6974
* Get the URL for content library list API.
7075
*/
@@ -948,7 +953,7 @@ export interface LibraryHistoryEntry {
948953
changedAt: string;
949954
title: string;
950955
blockType: string;
951-
action: 'edited' | 'renamed';
956+
action: 'edited' | 'renamed' | 'created';
952957
}
953958

954959
/**
@@ -972,6 +977,13 @@ export async function getLibraryBlockPublishHistoryEntries(usageKey: string, pub
972977
*/
973978
export async function getLibraryBlockDraftHistory(usageKey: string): Promise<LibraryHistoryEntry[]> {
974979
const { data } = await getAuthenticatedHttpClient().get(getLibraryBlockDraftHistoryUrl(usageKey));
975-
console.log(data);
980+
return camelCaseObject(data);
981+
}
982+
983+
/**
984+
* Get the creation entry for a library block.
985+
*/
986+
export async function getLibraryBlockCreationEntry(usageKey: string): Promise<LibraryHistoryEntry> {
987+
const { data } = await getAuthenticatedHttpClient().get(getLibraryBlockCreationEntryUrl(usageKey));
976988
return camelCaseObject(data);
977989
}

src/library-authoring/data/apiHooks.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export const xblockQueryKeys = {
125125
draftHistory: (usageKey: string) => [...xblockQueryKeys.xblock(usageKey), 'draftHistory'],
126126
publishHistory: (usageKey: string) => [...xblockQueryKeys.xblock(usageKey), 'publishHistory'],
127127
publishHistoryEntries: (usageKey: string, publishGroupId: string) => [...xblockQueryKeys.xblock(usageKey), 'publishHistory', publishGroupId, 'entries'],
128+
creationEntry: (usageKey: string) => [...xblockQueryKeys.xblock(usageKey), 'creationEntry'],
128129

129130
/**
130131
* Predicate used to invalidate all metadata only (not OLX, fields, assets, etc.).
@@ -1060,6 +1061,16 @@ export const useLibraryBlockPublishHistoryEntries = (
10601061
})
10611062
);
10621063

1064+
/**
1065+
* Returns the creation entry for a library block.
1066+
*/
1067+
export const useLibraryBlockCreationEntry = (usageKey: string | undefined) => (
1068+
useQuery({
1069+
queryKey: xblockQueryKeys.creationEntry(usageKey!),
1070+
queryFn: usageKey ? () => api.getLibraryBlockCreationEntry(usageKey) : skipToken,
1071+
})
1072+
);
1073+
10631074
/**
10641075
* Returns the migration blocks info of a given library
10651076
*/

src/library-authoring/generic/history-log/HistoryLog.test.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import {
1010
mockLibraryBlockDraftHistory,
1111
mockLibraryBlockPublishHistory,
1212
mockLibraryBlockPublishHistoryEntries,
13-
mockLibraryBlockMetadata,
13+
mockLibraryBlockCreationEntry,
1414
} from '../../data/api.mocks';
1515
import { HistoryComponentLog } from './HistoryLog';
1616

1717
mockLibraryBlockDraftHistory.applyMock();
1818
mockLibraryBlockPublishHistory.applyMock();
1919
mockLibraryBlockPublishHistoryEntries.applyMock();
20-
mockLibraryBlockMetadata.applyMock();
20+
mockLibraryBlockCreationEntry.applyMock();
2121

2222
const renderComponent = (componentId: string) => render(
2323
<HistoryComponentLog componentId={componentId} displayName="Test Component" />,
@@ -43,12 +43,12 @@ describe('<HistoryComponentLog />', () => {
4343
});
4444

4545
it('shows loading spinner while fetching', () => {
46-
renderComponent(mockLibraryBlockMetadata.usageKeyThatNeverLoads);
46+
renderComponent(mockLibraryBlockCreationEntry.usageKeyThatNeverLoads);
4747
expect(screen.getByRole('status')).toBeInTheDocument();
4848
});
4949

5050
it('renders draft history group with entries when they exist', async () => {
51-
renderComponent(mockLibraryBlockMetadata.usageKeyNeverPublished);
51+
renderComponent(mockLibraryBlockCreationEntry.usageKey);
5252
const trigger = await findByTextContent(/Test Component is a draft/i);
5353
expect(trigger).toBeInTheDocument();
5454
fireEvent.click(trigger);
@@ -57,19 +57,19 @@ describe('<HistoryComponentLog />', () => {
5757
});
5858

5959
it('does not render draft history group when there are no draft entries', async () => {
60-
renderComponent(mockLibraryBlockMetadata.usageKeyPublished);
60+
renderComponent(mockLibraryBlockCreationEntry.usageKeyEmpty);
6161
await waitFor(() => expect(screen.queryByRole('status')).not.toBeInTheDocument());
6262
expect(screen.queryByText('Test Component is a draft')).not.toBeInTheDocument();
6363
});
6464

6565
it('renders publish history group when one exists', async () => {
66-
renderComponent(mockLibraryBlockMetadata.usageKeyNeverPublished);
66+
renderComponent(mockLibraryBlockCreationEntry.usageKey);
6767
expect(await findByTextContent(/author published.*Protons/i)).toBeInTheDocument();
6868
expect(await screen.findByText(/5 authors contributed/i)).toBeInTheDocument();
6969
});
7070

7171
it('loads and shows publish history entries after expanding the publish group', async () => {
72-
renderComponent(mockLibraryBlockMetadata.usageKeyNeverPublished);
72+
renderComponent(mockLibraryBlockCreationEntry.usageKey);
7373
expect(await screen.findByText(/5 authors contributed/i)).toBeInTheDocument();
7474
const publishTrigger = await findByTextContent(/author published.*Protons/i);
7575

@@ -79,13 +79,13 @@ describe('<HistoryComponentLog />', () => {
7979
});
8080

8181
it('does not render publish history group when list is empty', async () => {
82-
renderComponent(mockLibraryBlockMetadata.usageKeyPublished);
82+
renderComponent(mockLibraryBlockCreationEntry.usageKeyEmpty);
8383
await waitFor(() => expect(screen.queryByRole('status')).not.toBeInTheDocument());
8484
expect(screen.queryByText(/published/i)).not.toBeInTheDocument();
8585
});
8686

8787
it('always renders the created group with fallback user when createdBy is null', async () => {
88-
renderComponent(mockLibraryBlockMetadata.usageKeyNeverPublished);
88+
renderComponent(mockLibraryBlockCreationEntry.usageKey);
8989
expect(await findByTextContent(/Author created.*Introduction to Testing 1/i)).toBeInTheDocument();
9090
});
9191
});

src/library-authoring/generic/history-log/HistoryLog.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { LoadingSpinner } from "@src/generic/Loading";
2-
import { useLibraryBlockDraftHistory, useLibraryBlockMetadata, useLibraryBlockPublishHistory } from "@src/library-authoring/data/apiHooks";
2+
import {
3+
useLibraryBlockCreationEntry,
4+
useLibraryBlockDraftHistory,
5+
useLibraryBlockPublishHistory,
6+
} from "@src/library-authoring/data/apiHooks";
37
import { HistoryCreatedLogGroup, HistoryDraftLogGroup, HistoryPublishLogGroup } from "./HistoryLogGroup";
48

59
export interface HistoryComponentLogProps {
@@ -22,11 +26,11 @@ export const HistoryComponentLog = ({
2226
} = useLibraryBlockPublishHistory(componentId);
2327

2428
const {
25-
data: componentData,
26-
isPending: isPendingComponentData,
27-
} = useLibraryBlockMetadata(componentId);
28-
29-
if (isPendingDraftHistory || isPendingComponentData || isPendingPublishHistoryGroups) {
29+
data: creationEntry,
30+
isPending: isPendingCreationEntry,
31+
} = useLibraryBlockCreationEntry(componentId);
32+
33+
if (isPendingDraftHistory || isPendingPublishHistoryGroups || isPendingCreationEntry) {
3034
return <LoadingSpinner />
3135
}
3236

@@ -50,12 +54,14 @@ export const HistoryComponentLog = ({
5054
)
5155
})
5256
)}
53-
<HistoryCreatedLogGroup
54-
user={componentData?.createdBy}
55-
displayName={componentData?.displayName ?? ''}
56-
itemType={componentData?.blockType ?? ''}
57-
createdAt={componentData?.created ?? ''}
58-
/>
57+
{creationEntry && (
58+
<HistoryCreatedLogGroup
59+
user={creationEntry.changedBy.username}
60+
displayName={creationEntry.title}
61+
itemType={creationEntry.blockType}
62+
createdAt={creationEntry.changedAt}
63+
/>
64+
)}
5965
</div>
6066
);
6167
};

0 commit comments

Comments
 (0)