refactor: course import analysis and details page in libraries (#2774)
* Updates analysis details body text * Updates partial banner text * Rounds percentage of supported blocks * Removes unsupported children blocks from total counts and percentages. * Updates spacing in analysis page.
This commit is contained in:
@@ -109,6 +109,7 @@ describe('<ImportDetailsPage />', () => {
|
||||
});
|
||||
|
||||
it('should render Partial Succeeded state', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockGetModulestoreMigratedBlocksInfo.applyMockPartial();
|
||||
(useGetContentHits as jest.Mock).mockReturnValue({
|
||||
isPending: false,
|
||||
@@ -143,12 +144,12 @@ describe('<ImportDetailsPage />', () => {
|
||||
expect(await screen.findByText(/partial import successful/i)).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByText(/Total Blocks/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('2/5')).toBeInTheDocument();
|
||||
expect(await screen.findByText('2/3')).toBeInTheDocument();
|
||||
expect(await screen.findByText(/Components/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('1/4')).toBeInTheDocument();
|
||||
expect(await screen.findByText('1/2')).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByText(
|
||||
/40% of course test course has been imported successfully/i,
|
||||
/66% of course test course has been imported successfully/i,
|
||||
)).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByRole('cell', {
|
||||
@@ -165,7 +166,7 @@ describe('<ImportDetailsPage />', () => {
|
||||
name: /view imported content/i,
|
||||
});
|
||||
|
||||
await viewImportedContentBtn.click();
|
||||
await user.click(viewImportedContentBtn);
|
||||
await waitFor(() => expect(mockNavigate).toHaveBeenCalledWith('/library/lib:Axim:TEST/collection/coll'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -100,12 +100,6 @@ const ImportDetailsContent = () => {
|
||||
// The migrations of this block is failed
|
||||
counts.unsupported += 1;
|
||||
resultUnsupportedIds.push(block.sourceKey);
|
||||
|
||||
if (block.unsupportedReason) {
|
||||
// Verify if the unsupported block has children
|
||||
const match = block.unsupportedReason.match(/It has (\d+) children/);
|
||||
counts.unsupported += match ? Number(match[1]) : 0;
|
||||
}
|
||||
} else {
|
||||
counts.totalBlocks += 1;
|
||||
const blockType = getBlockType(block.sourceKey);
|
||||
|
||||
@@ -181,12 +181,12 @@ const messages = defineMessages({
|
||||
},
|
||||
importCourseAnalysisCompleteSomeContentBody: {
|
||||
id: 'library-authoring.import-course.review-details.analysis-complete.100.body',
|
||||
defaultMessage: '{unsupportedBlockPercentage}% of content cannot be imported. For details see below.',
|
||||
defaultMessage: '{supportedBlockPercentage}% of course content will be imported into a collection in your library called {courseName}. Some content will not be imported. For details see below.',
|
||||
description: 'Body of the info card when course import analysis is complete and some data can be imported.',
|
||||
},
|
||||
importCourseAnalysisDetailsUnsupportedBlocksBody: {
|
||||
id: 'library-authoring.import-course.review-details.analysis-details.unsupportedBlocks.body',
|
||||
defaultMessage: 'The following block types cannot be imported into your library because they\'re are not yet supported. These block types will be replaced with a placeholder block in the library. For more information, reference the Help & Support sidebar.',
|
||||
defaultMessage: 'Some block types cannot be imported into your library because they’re not yet supported. These blocks will be replaced with a placeholder block in the library. For more information, reference the Help & Support sidebar.',
|
||||
description: 'Body of analysis details when some unsupported blocks are present',
|
||||
},
|
||||
importCourseComponentsUnsupportedInfo: {
|
||||
|
||||
@@ -120,7 +120,7 @@ describe('ReviewImportDetails', () => {
|
||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||
expect(await screen.findByText(/Import Analysis Complete/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText(
|
||||
/12.50% of content cannot be imported. For details see below./i,
|
||||
/88% of course content will be imported into a collection in your library called Test Course. Some content will not be imported. For details see below./i,
|
||||
)).toBeInTheDocument();
|
||||
expect(await screen.findByText(/Total Blocks/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('7/8')).toBeInTheDocument();
|
||||
@@ -135,7 +135,7 @@ describe('ReviewImportDetails', () => {
|
||||
expect(markAnalysisComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('considers children blocks of unsupportedBlocks', async () => {
|
||||
it('skips children blocks from total counts', async () => {
|
||||
(useCourseDetails as jest.Mock).mockReturnValue({ isPending: false, data: { title: 'Test Course' } });
|
||||
(useMigrationInfo as jest.Mock).mockReturnValue({
|
||||
isPending: false,
|
||||
@@ -161,7 +161,7 @@ describe('ReviewImportDetails', () => {
|
||||
}).mockReturnValueOnce({
|
||||
isPending: false,
|
||||
data: {
|
||||
problem: 2,
|
||||
problem: 2, // should be ignored from total count.
|
||||
},
|
||||
});
|
||||
|
||||
@@ -170,10 +170,10 @@ describe('ReviewImportDetails', () => {
|
||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||
expect(await screen.findByText(/Import Analysis Complete/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText(
|
||||
/25.00% of content cannot be imported. For details see below./i,
|
||||
/90% of course content will be imported into a collection in your library called Test Course. Some content will not be imported. For details see below./i,
|
||||
)).toBeInTheDocument();
|
||||
expect(await screen.findByText(/Total Blocks/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('9/12')).toBeInTheDocument();
|
||||
expect(await screen.findByText('9/10')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Sections')).toBeInTheDocument();
|
||||
expect(await screen.findByText('1')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Subsections')).toBeInTheDocument();
|
||||
@@ -181,7 +181,7 @@ describe('ReviewImportDetails', () => {
|
||||
expect(await screen.findByText('Units')).toBeInTheDocument();
|
||||
expect(await screen.findByText('3')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Components')).toBeInTheDocument();
|
||||
expect(await screen.findByText('3/6')).toBeInTheDocument();
|
||||
expect(await screen.findByText('3/4')).toBeInTheDocument();
|
||||
expect(markAnalysisComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
|
||||
@@ -91,7 +91,8 @@ const Banner = ({ courseId, isBlockDataPending, unsupportedBlockPercentage }: Ba
|
||||
<FormattedMessage
|
||||
{...messages.importCourseAnalysisCompleteSomeContentBody}
|
||||
values={{
|
||||
unsupportedBlockPercentage: unsupportedBlockPercentage.toFixed(2),
|
||||
supportedBlockPercentage: (100 - unsupportedBlockPercentage).toFixed(0),
|
||||
courseName: data?.title || '',
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
@@ -207,8 +208,8 @@ export const ReviewImportDetails = ({ courseId, markAnalysisComplete }: Props) =
|
||||
if (!blockTypes || !totalBlocks) {
|
||||
return 0;
|
||||
}
|
||||
return (finalUnssupportedBlocks / (totalBlocks + finalUnssupportedBlocks)) * 100;
|
||||
}, [blockTypes, finalUnssupportedBlocks]);
|
||||
return (totalUnsupportedBlocks / (totalBlocks + totalUnsupportedBlocks)) * 100;
|
||||
}, [blockTypes, totalUnsupportedBlocks]);
|
||||
|
||||
return (
|
||||
<Stack gap={4}>
|
||||
@@ -217,24 +218,26 @@ export const ReviewImportDetails = ({ courseId, markAnalysisComplete }: Props) =
|
||||
isBlockDataPending={isBlockDataPending}
|
||||
unsupportedBlockPercentage={unsupportedBlockPercentage}
|
||||
/>
|
||||
<h4><FormattedMessage {...messages.importCourseAnalysisSummary} /></h4>
|
||||
<SummaryCard
|
||||
totalBlocks={totalBlocks}
|
||||
totalComponents={totalComponents}
|
||||
sections={blockTypes?.chapter}
|
||||
subsections={blockTypes?.sequential}
|
||||
units={blockTypes?.vertical}
|
||||
unsupportedBlocks={finalUnssupportedBlocks}
|
||||
isPending={isBlockDataPending}
|
||||
/>
|
||||
{!isBlockDataPending && finalUnssupportedBlocks > 0
|
||||
<Stack gap={2}>
|
||||
<h4><FormattedMessage {...messages.importCourseAnalysisSummary} /></h4>
|
||||
<SummaryCard
|
||||
totalBlocks={totalBlocks}
|
||||
totalComponents={totalComponents}
|
||||
sections={blockTypes?.chapter}
|
||||
subsections={blockTypes?.sequential}
|
||||
units={blockTypes?.vertical}
|
||||
unsupportedBlocks={totalUnsupportedBlocks}
|
||||
isPending={isBlockDataPending}
|
||||
/>
|
||||
</Stack>
|
||||
{!isBlockDataPending && totalUnsupportedBlocks > 0
|
||||
&& (
|
||||
<>
|
||||
<Stack gap={2}>
|
||||
<h4><FormattedMessage {...messages.importCourseAnalysisDetails} /></h4>
|
||||
<Stack className="align-items-center" gap={3}>
|
||||
<FormattedMessage {...messages.importCourseAnalysisDetailsUnsupportedBlocksBody} />
|
||||
</Stack>
|
||||
</>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user