fix: show before and after title in diff preview (#2509)
Fix display of Before and After display name in section/subsection sync preview modal.
This commit is contained in:
@@ -11,4 +11,5 @@ coverage:
|
|||||||
ignore:
|
ignore:
|
||||||
- "src/grading-settings/grading-scale/react-ranger.js"
|
- "src/grading-settings/grading-scale/react-ranger.js"
|
||||||
- "src/generic/DraggableList/verticalSortableList.ts"
|
- "src/generic/DraggableList/verticalSortableList.ts"
|
||||||
|
- "src/container-comparison/data/api.mock.ts"
|
||||||
- "src/index.js"
|
- "src/index.js"
|
||||||
|
|||||||
@@ -1,64 +1,79 @@
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { mockGetContainerChildren, mockGetContainerMetadata } from '../library-authoring/data/api.mocks';
|
import MockAdapter from 'axios-mock-adapter/types';
|
||||||
import { initializeMocks, render, screen } from '../testUtils';
|
import { getLibraryContainerApiUrl } from '@src/library-authoring/data/api';
|
||||||
|
import { mockGetContainerChildren, mockGetContainerMetadata } from '@src/library-authoring/data/api.mocks';
|
||||||
|
import { initializeMocks, render, screen } from '@src/testUtils';
|
||||||
import { CompareContainersWidget } from './CompareContainersWidget';
|
import { CompareContainersWidget } from './CompareContainersWidget';
|
||||||
import { mockGetCourseContainerChildren } from './data/api.mock';
|
import { mockGetCourseContainerChildren } from './data/api.mock';
|
||||||
|
|
||||||
mockGetCourseContainerChildren.applyMock();
|
mockGetCourseContainerChildren.applyMock();
|
||||||
mockGetContainerChildren.applyMock();
|
mockGetContainerChildren.applyMock();
|
||||||
|
let axiosMock: MockAdapter;
|
||||||
|
|
||||||
describe('CompareContainersWidget', () => {
|
describe('CompareContainersWidget', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
initializeMocks();
|
({ axiosMock } = initializeMocks());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders the component with a title', async () => {
|
test('renders the component with a title', async () => {
|
||||||
|
const url = getLibraryContainerApiUrl(mockGetContainerMetadata.sectionId);
|
||||||
|
axiosMock.onGet(url).reply(200, { publishedDisplayName: 'Test Title' });
|
||||||
render(<CompareContainersWidget
|
render(<CompareContainersWidget
|
||||||
title="Test Title"
|
|
||||||
upstreamBlockId={mockGetContainerMetadata.sectionId}
|
upstreamBlockId={mockGetContainerMetadata.sectionId}
|
||||||
downstreamBlockId={mockGetCourseContainerChildren.sectionId}
|
downstreamBlockId={mockGetCourseContainerChildren.sectionId}
|
||||||
/>);
|
/>);
|
||||||
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
||||||
expect((await screen.findAllByText('subsection block 0')).length).toEqual(2);
|
expect((await screen.findAllByText('subsection block 0')).length).toEqual(1);
|
||||||
|
expect((await screen.findAllByText('subsection block 00')).length).toEqual(1);
|
||||||
expect((await screen.findAllByText('This subsection will be modified')).length).toEqual(3);
|
expect((await screen.findAllByText('This subsection will be modified')).length).toEqual(3);
|
||||||
expect((await screen.findAllByText('This subsection was modified')).length).toEqual(3);
|
expect((await screen.findAllByText('This subsection was modified')).length).toEqual(3);
|
||||||
expect((await screen.findAllByText('subsection block 1')).length).toEqual(2);
|
expect((await screen.findAllByText('subsection block 1')).length).toEqual(1);
|
||||||
expect((await screen.findAllByText('subsection block 2')).length).toEqual(2);
|
expect((await screen.findAllByText('subsection block 2')).length).toEqual(1);
|
||||||
|
expect((await screen.findAllByText('subsection block 11')).length).toEqual(1);
|
||||||
|
expect((await screen.findAllByText('subsection block 22')).length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders loading spinner when data is pending', async () => {
|
test('renders loading spinner when data is pending', async () => {
|
||||||
|
const url = getLibraryContainerApiUrl(mockGetContainerMetadata.sectionIdLoading);
|
||||||
|
axiosMock.onGet(url).reply(() => new Promise(() => {}));
|
||||||
render(<CompareContainersWidget
|
render(<CompareContainersWidget
|
||||||
title="Test Title"
|
|
||||||
upstreamBlockId={mockGetContainerMetadata.sectionIdLoading}
|
upstreamBlockId={mockGetContainerMetadata.sectionIdLoading}
|
||||||
downstreamBlockId={mockGetCourseContainerChildren.sectionIdLoading}
|
downstreamBlockId={mockGetCourseContainerChildren.sectionIdLoading}
|
||||||
/>);
|
/>);
|
||||||
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
|
||||||
const spinner = await screen.findAllByRole('status');
|
const spinner = await screen.findAllByRole('status');
|
||||||
expect(spinner.length).toEqual(2);
|
expect(spinner.length).toEqual(4);
|
||||||
expect(spinner[0].textContent).toEqual('Loading...');
|
expect(spinner[0].textContent).toEqual('Loading...');
|
||||||
expect(spinner[1].textContent).toEqual('Loading...');
|
expect(spinner[1].textContent).toEqual('Loading...');
|
||||||
|
expect(spinner[2].textContent).toEqual('Loading...');
|
||||||
|
expect(spinner[3].textContent).toEqual('Loading...');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('calls onRowClick when a row is clicked and updates diff view', async () => {
|
test('calls onRowClick when a row is clicked and updates diff view', async () => {
|
||||||
|
// mocks title
|
||||||
|
axiosMock.onGet(getLibraryContainerApiUrl(mockGetContainerMetadata.sectionId)).reply(200, { publishedDisplayName: 'Test Title' });
|
||||||
|
axiosMock.onGet(
|
||||||
|
getLibraryContainerApiUrl('lct:org1:Demo_course_generated:subsection:subsection-0'),
|
||||||
|
).reply(200, { publishedDisplayName: 'subsection block 0' });
|
||||||
|
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
render(<CompareContainersWidget
|
render(<CompareContainersWidget
|
||||||
title="Test Title"
|
|
||||||
upstreamBlockId={mockGetContainerMetadata.sectionId}
|
upstreamBlockId={mockGetContainerMetadata.sectionId}
|
||||||
downstreamBlockId={mockGetCourseContainerChildren.sectionId}
|
downstreamBlockId={mockGetCourseContainerChildren.sectionId}
|
||||||
/>);
|
/>);
|
||||||
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
||||||
let blocks = await screen.findAllByText('subsection block 0');
|
// left i.e. before side block
|
||||||
expect(blocks.length).toEqual(2);
|
let block = await screen.findByText('subsection block 00');
|
||||||
await user.click(blocks[0]);
|
await user.click(block);
|
||||||
// Breadcrumbs
|
// Breadcrumbs - shows old and new name
|
||||||
const breadcrumbs = await screen.findAllByRole('button', { name: 'subsection block 0' });
|
expect(await screen.findByRole('button', { name: 'subsection block 00' })).toBeInTheDocument();
|
||||||
expect(breadcrumbs.length).toEqual(2);
|
expect(await screen.findByRole('button', { name: 'subsection block 0' })).toBeInTheDocument();
|
||||||
|
|
||||||
const removedRows = await screen.findAllByText('This unit was removed');
|
const removedRows = await screen.findAllByText('This unit was removed');
|
||||||
// clicking on removed or added rows does not updated the page.
|
// clicking on removed or added rows does not updated the page.
|
||||||
await user.click(removedRows[0]);
|
await user.click(removedRows[0]);
|
||||||
// Still in same page
|
// Still in same page
|
||||||
expect((await screen.findAllByRole('button', { name: 'subsection block 0' })).length).toEqual(2);
|
expect(await screen.findByRole('button', { name: 'subsection block 00' })).toBeInTheDocument();
|
||||||
|
expect(await screen.findByRole('button', { name: 'subsection block 0' })).toBeInTheDocument();
|
||||||
|
|
||||||
// Back breadcrumb
|
// Back breadcrumb
|
||||||
const backbtns = await screen.findAllByRole('button', { name: 'Back' });
|
const backbtns = await screen.findAllByRole('button', { name: 'Back' });
|
||||||
@@ -67,11 +82,12 @@ describe('CompareContainersWidget', () => {
|
|||||||
// Go back
|
// Go back
|
||||||
await user.click(backbtns[0]);
|
await user.click(backbtns[0]);
|
||||||
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
expect((await screen.findAllByText('Test Title')).length).toEqual(2);
|
||||||
blocks = await screen.findAllByText('subsection block 0');
|
// right i.e. after side block
|
||||||
expect(blocks.length).toEqual(2);
|
block = await screen.findByText('subsection block 0');
|
||||||
|
|
||||||
// After side click also works
|
// After side click also works
|
||||||
await user.click(blocks[1]);
|
await user.click(block);
|
||||||
expect((await screen.findAllByRole('button', { name: 'subsection block 0' })).length).toEqual(2);
|
expect(await screen.findByRole('button', { name: 'subsection block 00' })).toBeInTheDocument();
|
||||||
|
expect(await screen.findByRole('button', { name: 'subsection block 0' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import {
|
|||||||
import { ArrowBack } from '@openedx/paragon/icons';
|
import { ArrowBack } from '@openedx/paragon/icons';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { ContainerType } from '@src/generic/key-utils';
|
import { ContainerType } from '@src/generic/key-utils';
|
||||||
|
import ErrorAlert from '@src/generic/alert-error';
|
||||||
import { LoadingSpinner } from '@src/generic/Loading';
|
import { LoadingSpinner } from '@src/generic/Loading';
|
||||||
import { useContainerChildren } from '@src/library-authoring/data/apiHooks';
|
import { useContainer, useContainerChildren } from '@src/library-authoring/data/apiHooks';
|
||||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||||
import ChildrenPreview from './ChildrenPreview';
|
import ChildrenPreview from './ChildrenPreview';
|
||||||
import ContainerRow from './ContainerRow';
|
import ContainerRow from './ContainerRow';
|
||||||
@@ -15,7 +16,6 @@ import { diffPreviewContainerChildren, isRowClickable } from './utils';
|
|||||||
import messages from './messages';
|
import messages from './messages';
|
||||||
|
|
||||||
interface ContainerInfoProps {
|
interface ContainerInfoProps {
|
||||||
title: string;
|
|
||||||
upstreamBlockId: string;
|
upstreamBlockId: string;
|
||||||
downstreamBlockId: string;
|
downstreamBlockId: string;
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,6 @@ interface Props extends ContainerInfoProps {
|
|||||||
* Actual implementation of the displaying diff between children of containers.
|
* Actual implementation of the displaying diff between children of containers.
|
||||||
*/
|
*/
|
||||||
const CompareContainersWidgetInner = ({
|
const CompareContainersWidgetInner = ({
|
||||||
title,
|
|
||||||
upstreamBlockId,
|
upstreamBlockId,
|
||||||
downstreamBlockId,
|
downstreamBlockId,
|
||||||
parent,
|
parent,
|
||||||
@@ -38,11 +37,17 @@ const CompareContainersWidgetInner = ({
|
|||||||
onBackBtnClick,
|
onBackBtnClick,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data, isPending } = useCourseContainerChildren(downstreamBlockId);
|
const { data, isError, error } = useCourseContainerChildren(downstreamBlockId);
|
||||||
const {
|
const {
|
||||||
data: libData,
|
data: libData,
|
||||||
isPending: libPending,
|
isError: isLibError,
|
||||||
|
error: libError,
|
||||||
} = useContainerChildren(upstreamBlockId, true);
|
} = useContainerChildren(upstreamBlockId, true);
|
||||||
|
const {
|
||||||
|
data: containerData,
|
||||||
|
isError: isContainerTitleError,
|
||||||
|
error: containerTitleError,
|
||||||
|
} = useContainer(upstreamBlockId);
|
||||||
|
|
||||||
const result = useMemo(() => {
|
const result = useMemo(() => {
|
||||||
if (!data || !libData) {
|
if (!data || !libData) {
|
||||||
@@ -52,7 +57,7 @@ const CompareContainersWidgetInner = ({
|
|||||||
}, [data, libData]);
|
}, [data, libData]);
|
||||||
|
|
||||||
const renderBeforeChildren = useCallback(() => {
|
const renderBeforeChildren = useCallback(() => {
|
||||||
if (isPending) {
|
if (!result[0]) {
|
||||||
return <div className="m-auto"><LoadingSpinner /></div>;
|
return <div className="m-auto"><LoadingSpinner /></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,10 +72,10 @@ const CompareContainersWidgetInner = ({
|
|||||||
onClick={() => onRowClick(child)}
|
onClick={() => onRowClick(child)}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
}, [isPending, result]);
|
}, [result]);
|
||||||
|
|
||||||
const renderAfterChildren = useCallback(() => {
|
const renderAfterChildren = useCallback(() => {
|
||||||
if (libPending || isPending) {
|
if (!result[1]) {
|
||||||
return <div className="m-auto"><LoadingSpinner /></div>;
|
return <div className="m-auto"><LoadingSpinner /></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +89,13 @@ const CompareContainersWidgetInner = ({
|
|||||||
onClick={() => onRowClick(child)}
|
onClick={() => onRowClick(child)}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
}, [libPending, isPending, result]);
|
}, [result]);
|
||||||
|
|
||||||
|
const getTitleComponent = useCallback((title?: string | null) => {
|
||||||
|
if (!title) {
|
||||||
|
return <div className="m-auto"><LoadingSpinner /></div>;
|
||||||
|
}
|
||||||
|
|
||||||
const getTitleComponent = () => {
|
|
||||||
if (parent.length === 0) {
|
if (parent.length === 0) {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
@@ -95,6 +104,7 @@ const CompareContainersWidgetInner = ({
|
|||||||
ariaLabel={intl.formatMessage(messages.breadcrumbAriaLabel)}
|
ariaLabel={intl.formatMessage(messages.breadcrumbAriaLabel)}
|
||||||
links={[
|
links={[
|
||||||
{
|
{
|
||||||
|
// This raises failed prop-type error as label expects a string but it works without any issues
|
||||||
label: <Stack direction="horizontal" gap={1}><Icon size="xs" src={ArrowBack} />Back</Stack>,
|
label: <Stack direction="horizontal" gap={1}><Icon size="xs" src={ArrowBack} />Back</Stack>,
|
||||||
onClick: onBackBtnClick,
|
onClick: onBackBtnClick,
|
||||||
variant: 'link',
|
variant: 'link',
|
||||||
@@ -110,20 +120,24 @@ const CompareContainersWidgetInner = ({
|
|||||||
linkAs={Button}
|
linkAs={Button}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
}, [parent]);
|
||||||
|
|
||||||
|
if (isError || isLibError || isContainerTitleError) {
|
||||||
|
return <ErrorAlert error={error || libError || containerTitleError} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col col-6 p-1">
|
<div className="col col-6 p-1">
|
||||||
<Card className="p-4">
|
<Card className="p-4">
|
||||||
<ChildrenPreview title={getTitleComponent()} side="Before">
|
<ChildrenPreview title={getTitleComponent(data?.displayName)} side="Before">
|
||||||
{renderBeforeChildren()}
|
{renderBeforeChildren()}
|
||||||
</ChildrenPreview>
|
</ChildrenPreview>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="col col-6 p-1">
|
<div className="col col-6 p-1">
|
||||||
<Card className="p-4">
|
<Card className="p-4">
|
||||||
<ChildrenPreview title={getTitleComponent()} side="After">
|
<ChildrenPreview title={getTitleComponent(containerData?.publishedDisplayName)} side="After">
|
||||||
{renderAfterChildren()}
|
{renderAfterChildren()}
|
||||||
</ChildrenPreview>
|
</ChildrenPreview>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -137,11 +151,10 @@ const CompareContainersWidgetInner = ({
|
|||||||
* and allows the user to select the container to view. This is a wrapper component that maintains current
|
* and allows the user to select the container to view. This is a wrapper component that maintains current
|
||||||
* source state. Actual implementation of the diff view is done by CompareContainersWidgetInner.
|
* source state. Actual implementation of the diff view is done by CompareContainersWidgetInner.
|
||||||
*/
|
*/
|
||||||
export const CompareContainersWidget = ({ title, upstreamBlockId, downstreamBlockId }: ContainerInfoProps) => {
|
export const CompareContainersWidget = ({ upstreamBlockId, downstreamBlockId }: ContainerInfoProps) => {
|
||||||
const [currentContainerState, setCurrentContainerState] = useState<ContainerInfoProps & {
|
const [currentContainerState, setCurrentContainerState] = useState<ContainerInfoProps & {
|
||||||
parent: ContainerInfoProps[];
|
parent: ContainerInfoProps[];
|
||||||
}>({
|
}>({
|
||||||
title,
|
|
||||||
upstreamBlockId,
|
upstreamBlockId,
|
||||||
downstreamBlockId,
|
downstreamBlockId,
|
||||||
parent: [],
|
parent: [],
|
||||||
@@ -153,11 +166,9 @@ export const CompareContainersWidget = ({ title, upstreamBlockId, downstreamBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCurrentContainerState((prev) => ({
|
setCurrentContainerState((prev) => ({
|
||||||
title: row.name,
|
|
||||||
upstreamBlockId: row.id!,
|
upstreamBlockId: row.id!,
|
||||||
downstreamBlockId: row.downstreamId!,
|
downstreamBlockId: row.downstreamId!,
|
||||||
parent: [...prev.parent, {
|
parent: [...prev.parent, {
|
||||||
title: prev.title,
|
|
||||||
upstreamBlockId: prev.upstreamBlockId,
|
upstreamBlockId: prev.upstreamBlockId,
|
||||||
downstreamBlockId: prev.downstreamBlockId,
|
downstreamBlockId: prev.downstreamBlockId,
|
||||||
}],
|
}],
|
||||||
@@ -172,7 +183,6 @@ export const CompareContainersWidget = ({ title, upstreamBlockId, downstreamBloc
|
|||||||
}
|
}
|
||||||
const prevParent = prev.parent[prev.parent.length - 1];
|
const prevParent = prev.parent[prev.parent.length - 1];
|
||||||
return {
|
return {
|
||||||
title: prevParent!.title,
|
|
||||||
upstreamBlockId: prevParent!.upstreamBlockId,
|
upstreamBlockId: prevParent!.upstreamBlockId,
|
||||||
downstreamBlockId: prevParent!.downstreamBlockId,
|
downstreamBlockId: prevParent!.downstreamBlockId,
|
||||||
parent: prev.parent.slice(0, -1),
|
parent: prev.parent.slice(0, -1),
|
||||||
@@ -182,7 +192,6 @@ export const CompareContainersWidget = ({ title, upstreamBlockId, downstreamBloc
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CompareContainersWidgetInner
|
<CompareContainersWidgetInner
|
||||||
title={currentContainerState.title}
|
|
||||||
upstreamBlockId={currentContainerState.upstreamBlockId}
|
upstreamBlockId={currentContainerState.upstreamBlockId}
|
||||||
downstreamBlockId={currentContainerState.downstreamBlockId}
|
downstreamBlockId={currentContainerState.downstreamBlockId}
|
||||||
parent={currentContainerState.parent}
|
parent={currentContainerState.parent}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
import { CourseContainerChildrenData } from '@src/course-unit/data/types';
|
import { CourseContainerChildrenData } from '@src/course-unit/data/types';
|
||||||
import * as unitApi from '@src/course-unit/data/api';
|
import * as unitApi from '@src/course-unit/data/api';
|
||||||
|
|
||||||
@@ -9,15 +10,19 @@ import * as unitApi from '@src/course-unit/data/api';
|
|||||||
export async function mockGetCourseContainerChildren(containerId: string): Promise<CourseContainerChildrenData> {
|
export async function mockGetCourseContainerChildren(containerId: string): Promise<CourseContainerChildrenData> {
|
||||||
const numChildren: number = 3;
|
const numChildren: number = 3;
|
||||||
let blockType: string;
|
let blockType: string;
|
||||||
|
let displayName: string;
|
||||||
switch (containerId) {
|
switch (containerId) {
|
||||||
case mockGetCourseContainerChildren.unitId:
|
case mockGetCourseContainerChildren.unitId:
|
||||||
blockType = 'text';
|
blockType = 'text';
|
||||||
|
displayName = 'unit block 00';
|
||||||
break;
|
break;
|
||||||
case mockGetCourseContainerChildren.sectionId:
|
case mockGetCourseContainerChildren.sectionId:
|
||||||
blockType = 'subsection';
|
blockType = 'subsection';
|
||||||
|
displayName = 'Test Title';
|
||||||
break;
|
break;
|
||||||
case mockGetCourseContainerChildren.subsectionId:
|
case mockGetCourseContainerChildren.subsectionId:
|
||||||
blockType = 'unit';
|
blockType = 'unit';
|
||||||
|
displayName = 'subsection block 00';
|
||||||
break;
|
break;
|
||||||
case mockGetCourseContainerChildren.unitIdLoading:
|
case mockGetCourseContainerChildren.unitIdLoading:
|
||||||
case mockGetCourseContainerChildren.sectionIdLoading:
|
case mockGetCourseContainerChildren.sectionIdLoading:
|
||||||
@@ -25,6 +30,7 @@ export async function mockGetCourseContainerChildren(containerId: string): Promi
|
|||||||
return new Promise(() => { });
|
return new Promise(() => { });
|
||||||
default:
|
default:
|
||||||
blockType = 'unit';
|
blockType = 'unit';
|
||||||
|
displayName = 'subsection block 00';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const children = Array(numChildren).fill(mockGetCourseContainerChildren.childTemplate).map((child, idx) => (
|
const children = Array(numChildren).fill(mockGetCourseContainerChildren.childTemplate).map((child, idx) => (
|
||||||
@@ -32,7 +38,7 @@ export async function mockGetCourseContainerChildren(containerId: string): Promi
|
|||||||
...child,
|
...child,
|
||||||
// Generate a unique ID for each child block to avoid "duplicate key" errors in tests
|
// Generate a unique ID for each child block to avoid "duplicate key" errors in tests
|
||||||
id: `block-v1:UNIX+UX1+2025_T3+type@${blockType}+block@${idx}`,
|
id: `block-v1:UNIX+UX1+2025_T3+type@${blockType}+block@${idx}`,
|
||||||
name: `${blockType} block ${idx}`,
|
name: `${blockType} block ${idx}${idx}`,
|
||||||
blockType,
|
blockType,
|
||||||
upstreamLink: {
|
upstreamLink: {
|
||||||
upstreamRef: `lct:org1:Demo_course_generated:${blockType}:${blockType}-${idx}`,
|
upstreamRef: `lct:org1:Demo_course_generated:${blockType}:${blockType}-${idx}`,
|
||||||
@@ -47,6 +53,7 @@ export async function mockGetCourseContainerChildren(containerId: string): Promi
|
|||||||
canPasteComponent: true,
|
canPasteComponent: true,
|
||||||
isPublished: false,
|
isPublished: false,
|
||||||
children,
|
children,
|
||||||
|
displayName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mockGetCourseContainerChildren.unitId = 'block-v1:UNIX+UX1+2025_T3+type@unit+block@0';
|
mockGetCourseContainerChildren.unitId = 'block-v1:UNIX+UX1+2025_T3+type@unit+block@0';
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
error: {
|
||||||
|
id: 'course-authoring.container-comparison.diff.error.message',
|
||||||
|
defaultMessage: 'Unexpected error: Failed to fetch container data',
|
||||||
|
description: 'Generic error message',
|
||||||
|
},
|
||||||
removedDiffBeforeMessage: {
|
removedDiffBeforeMessage: {
|
||||||
id: 'course-authoring.container-comparison.diff.before.removed-message',
|
id: 'course-authoring.container-comparison.diff.before.removed-message',
|
||||||
defaultMessage: 'This {blockType} will be removed in the new version',
|
defaultMessage: 'This {blockType} will be removed in the new version',
|
||||||
|
|||||||
@@ -42,4 +42,5 @@ export interface CourseContainerChildrenData {
|
|||||||
canPasteComponent: boolean;
|
canPasteComponent: boolean;
|
||||||
children: ContainerChildData[],
|
children: ContainerChildData[],
|
||||||
isPublished: boolean;
|
isPublished: boolean;
|
||||||
|
displayName: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ export const PreviewLibraryXBlockChanges = ({
|
|||||||
if (blockData.isContainer) {
|
if (blockData.isContainer) {
|
||||||
return (
|
return (
|
||||||
<CompareContainersWidget
|
<CompareContainersWidget
|
||||||
title={blockData.displayName}
|
|
||||||
upstreamBlockId={blockData.upstreamBlockId}
|
upstreamBlockId={blockData.upstreamBlockId}
|
||||||
downstreamBlockId={blockData.downstreamBlockId}
|
downstreamBlockId={blockData.downstreamBlockId}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user