Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/library-authoring/common/context/SidebarContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const CONTAINER_INFO_TABS = {
Manage: 'manage',
Usage: 'usage',
Settings: 'settings',
Details: 'details',
} as const;
export type ContainerInfoTab = typeof CONTAINER_INFO_TABS[keyof typeof CONTAINER_INFO_TABS];
export const isContainerInfoTab = (tab: string): tab is ContainerInfoTab => (
Expand Down
21 changes: 14 additions & 7 deletions src/library-authoring/component-info/ComponentDetails.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import {
render as baseRender,
screen,
fireEvent,
findByDeepTextContent,
} from '@src/testUtils';
import { mockFetchIndexDocuments, mockContentSearchConfig } from '@src/search-manager/data/api.mock';

import {
mockContentLibrary,
mockGetEntityLinks,
mockLibraryBlockCreationEntry,
mockLibraryBlockDraftHistory,
mockLibraryBlockMetadata,
mockLibraryBlockPublishHistory,
mockLibraryBlockPublishHistoryEntries,
mockXBlockAssets,
mockXBlockOLX,
} from '../data/api.mocks';
Expand All @@ -21,6 +26,10 @@ import ComponentDetails from './ComponentDetails';
mockContentSearchConfig.applyMock();
mockContentLibrary.applyMock();
mockLibraryBlockMetadata.applyMock();
mockLibraryBlockCreationEntry.applyMock();
mockLibraryBlockDraftHistory.applyMock();
mockLibraryBlockPublishHistory.applyMock();
mockLibraryBlockPublishHistoryEntries.applyMock();
mockXBlockAssets.applyMock();
mockXBlockOLX.applyMock();
mockGetEntityLinks.applyMock();
Expand Down Expand Up @@ -60,7 +69,9 @@ describe('<ComponentDetails />', () => {

it('should render the component details error', async () => {
render(mockLibraryBlockMetadata.usageKeyError404);
expect(await screen.findByText(/Mocked request failed with status code 404/)).toBeInTheDocument();
// Metadata and history queries fail silently; the section renders empty without crashing
expect(await screen.findByText('Component History')).toBeInTheDocument();
expect(screen.queryByText(/Mocked request failed/)).not.toBeInTheDocument();
});

it('should render the component usage', async () => {
Expand Down Expand Up @@ -96,11 +107,7 @@ describe('<ComponentDetails />', () => {

it('should render the component history', async () => {
render(mockLibraryBlockMetadata.usageKeyPublished);
// Show created date
expect(await screen.findByText('June 20, 2024')).toBeInTheDocument();
// Show modified date
expect(await screen.findByText('June 21, 2024')).toBeInTheDocument();
// Show last published date
expect(await screen.findByText('June 22, 2024')).toBeInTheDocument();
// usageKeyPublished matches usageKeyEmpty in mockLibraryBlockCreationEntry (TEST2 key)
expect(await findByDeepTextContent(/Author created.*Introduction to Testing 2/i)).toBeInTheDocument();
});
});
24 changes: 4 additions & 20 deletions src/library-authoring/component-info/ComponentDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Stack } from '@openedx/paragon';

import AlertError from '../../generic/alert-error';
import Loading from '../../generic/Loading';
import { useSidebarContext } from '../common/context/SidebarContext';
import { useLibraryBlockMetadata } from '../data/apiHooks';
import HistoryWidget from '../generic/history-widget';
import { ComponentAdvancedInfo } from './ComponentAdvancedInfo';
import { ComponentUsage } from './ComponentUsage';
import messages from './messages';
import { HistoryComponentLog } from '../generic/history-log/HistoryLog';
Comment thread
bradenmacdonald marked this conversation as resolved.

const ComponentDetails = () => {
const { sidebarItemInfo } = useSidebarContext();
Expand All @@ -20,21 +17,6 @@ const ComponentDetails = () => {
throw new Error('usageKey is required');
}

const {
data: componentMetadata,
isError,
error,
isPending,
} = useLibraryBlockMetadata(usageKey);

if (isError) {
return <AlertError error={error} />;
}

if (isPending) {
return <Loading />;
}

return (
<Stack gap={3}>
<>
Expand All @@ -48,7 +30,9 @@ const ComponentDetails = () => {
<h3 className="h5">
<FormattedMessage {...messages.detailsTabHistoryTitle} />
</h3>
<HistoryWidget {...componentMetadata} />
<HistoryComponentLog
componentId={usageKey}
/>
</>
<ComponentAdvancedInfo />
</Stack>
Expand Down
23 changes: 23 additions & 0 deletions src/library-authoring/containers/ContainerDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import messages from './messages';
import { HistoryContainerLog } from '../generic/history-log/HistoryLog';
import { useSidebarContext } from '../common/context/SidebarContext';

export const ContainerDetails = () => {
const { sidebarItemInfo } = useSidebarContext();

const usageKey = sidebarItemInfo?.id;

return (
<>
<h4>
<FormattedMessage {...messages.detailsTabHistoryHeading} />
</h4>
{usageKey && (
<HistoryContainerLog
containerId={usageKey}
/>
)}
</>
);
};
6 changes: 6 additions & 0 deletions src/library-authoring/containers/ContainerInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { useContainer } from '../data/apiHooks';
import ContainerDeleter from './ContainerDeleter';
import { ContainerPublisher } from './ContainerPublisher';
import { PublishDraftButton, PublishedChip } from '../generic/publish-status-buttons';
import { ContainerDetails } from './ContainerDetails';

type ContainerPreviewProps = {
containerId: string;
Expand Down Expand Up @@ -239,6 +240,11 @@ const ContainerInfo = () => {
intl.formatMessage(messages.settingsTabTitle),
<ContainerSettings />,
)}
{renderTab(
CONTAINER_INFO_TABS.Details,
intl.formatMessage(messages.detailsTabTitle),
<ContainerDetails />,
)}
</Tabs>
</Stack>
);
Expand Down
13 changes: 13 additions & 0 deletions src/library-authoring/containers/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ const messages = defineMessages({
defaultMessage: 'Settings',
description: 'Title for settings tab',
},
// TODO: These messages (detailsTabTitle, detailsTabHistoryHeading, etc.) should be shared
// across all sidebar types (components, containers, collections) since the tab names and
// headings are identical. Currently they are duplicated in each sidebar's messages file.
detailsTabTitle: {
id: 'course-authoring.library-authoring.container-sidebar.details-tab.title',
defaultMessage: 'Details',
description: 'Title for details tab',
},
Comment thread
ChrisChV marked this conversation as resolved.
detailsTabHistoryHeading: {
id: 'course-authoring.library-authoring.container-sidebar.details-tab.history-heading',
defaultMessage: 'History',
description: 'Heading for details tab history section',
},
updateContainerSuccessMsg: {
id: 'course-authoring.library-authoring.update-container-success-msg',
defaultMessage: 'Container updated successfully.',
Expand Down
Loading