fix: UI fixes in legacy library migrator
- Keep state of all migration steps on nevigation - Reword alert in confirm dialog - Add scroll to help sidebar in migration - Keep the same migration filter
This commit is contained in:
@@ -162,9 +162,20 @@ describe('<LegacyLibMigrationPage />', () => {
|
||||
});
|
||||
|
||||
it('should back to select legacy libraries', async () => {
|
||||
const user = userEvent.setup();
|
||||
renderPage();
|
||||
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
|
||||
// The filter is Unmigrated by default
|
||||
const filterButton = await screen.findByRole('button', { name: /unmigrated/i });
|
||||
expect(filterButton).toBeInTheDocument();
|
||||
|
||||
// Clear filter to show all
|
||||
await user.click(filterButton);
|
||||
const clearButton = await screen.findByRole('button', { name: /clear filter/i });
|
||||
await user.click(clearButton);
|
||||
|
||||
expect(await screen.findByText('MBA')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Legacy library 1')).toBeInTheDocument();
|
||||
expect(await screen.findByText('MBA 1')).toBeInTheDocument();
|
||||
|
||||
const legacyLibrary = screen.getByRole('checkbox', { name: 'MBA' });
|
||||
legacyLibrary.click();
|
||||
@@ -178,7 +189,13 @@ describe('<LegacyLibMigrationPage />', () => {
|
||||
const backButton = screen.getByRole('button', { name: /back/i });
|
||||
backButton.click();
|
||||
|
||||
// The selected legacy library remains checked
|
||||
expect(legacyLibrary).toBeChecked();
|
||||
|
||||
// The filter remains the same
|
||||
expect(await screen.findByText('MBA')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Legacy library 1')).toBeInTheDocument();
|
||||
expect(await screen.findByText('MBA 1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should select a library destination', async () => {
|
||||
@@ -230,6 +247,8 @@ describe('<LegacyLibMigrationPage />', () => {
|
||||
backButton.click();
|
||||
|
||||
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
|
||||
// The selected v2 library remains checked
|
||||
expect(radioButton).toBeChecked();
|
||||
});
|
||||
|
||||
it('should open the create new library modal', async () => {
|
||||
|
||||
@@ -80,6 +80,7 @@ export const LegacyLibMigrationPage = () => {
|
||||
const [currentStep, setCurrentStep] = useState<MigrationStep>('select-libraries');
|
||||
const [isExitModalOpen, openExitModal, closeExitModal] = useToggle(false);
|
||||
const [legacyLibraries, setLegacyLibraries] = useState<LibraryV1Data[]>([]);
|
||||
const [migrationFilter, setMigrationFilter] = useState<Filter[]>([Filter.unmigrated]);
|
||||
const [destinationLibrary, setDestination] = useState<ContentLibrary>();
|
||||
const [confirmationButtonState, setConfirmationButtonState] = useState('default');
|
||||
const migrate = useUpdateContainerCollections();
|
||||
@@ -127,7 +128,6 @@ export const LegacyLibMigrationPage = () => {
|
||||
openExitModal();
|
||||
break;
|
||||
case 'select-destination':
|
||||
setDestination(undefined);
|
||||
setCurrentStep('select-libraries');
|
||||
break;
|
||||
case 'confirmation-view':
|
||||
@@ -193,7 +193,8 @@ export const LegacyLibMigrationPage = () => {
|
||||
selectedIds={legacyLibrariesIds}
|
||||
handleCheck={handleUpdateLegacyLibraries}
|
||||
hideMigationAlert
|
||||
initialFilter={[Filter.unmigrated]}
|
||||
migrationFilter={migrationFilter}
|
||||
setMigrationFilter={setMigrationFilter}
|
||||
setSelectedLibraries={setLegacyLibraries}
|
||||
/>
|
||||
</Stepper.Step>
|
||||
@@ -221,7 +222,7 @@ export const LegacyLibMigrationPage = () => {
|
||||
</Stepper>
|
||||
</div>
|
||||
</Container>
|
||||
<div className="content-buttons d-flex justify-content-between pl-6 pr-6 bg-white">
|
||||
<div className="content-buttons d-flex justify-content-between pl-6 pr-6 bg-white box-shadow-up-1">
|
||||
<Button className="mt-2 mb-2" variant="outline-primary" onClick={handleBack}>
|
||||
{currentStep === 'select-libraries'
|
||||
? intl.formatMessage(messages.cancel)
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
position: sticky;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
|
||||
@@ -72,8 +72,9 @@ const messages = defineMessages({
|
||||
confirmationViewAlert: {
|
||||
id: 'legacy-libraries-migration.select-destination.alert.text',
|
||||
defaultMessage: 'These {count, plural, one {{count} legacy library} other {{count} legacy libraries}}'
|
||||
+ ' will be migrated to <b>{libraryName}</b> and organized as collections. Any legacy libraries that are used in'
|
||||
+ ' problem banks will maintain their link with migrated content the first time they are migrated.',
|
||||
+ ' will be migrated to <b>{libraryName}</b> and organized as collections. Legacy library content used'
|
||||
+ ' in courses will continue to work as-is. To receive any future changes to migrated content,'
|
||||
+ ' you must update these references within your course.',
|
||||
description: 'Alert text in the confirmation step of the legacy libraries migration page.',
|
||||
},
|
||||
previouslyMigratedAlert: {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { RequestStatus } from '@src/data/constants';
|
||||
import { getLoadingStatuses, getStudioHomeData } from '../data/selectors';
|
||||
import messages from './messages';
|
||||
import { LibrariesList } from './libraries-tab';
|
||||
import { BaseFilterState, Filter, LibrariesList } from './libraries-tab';
|
||||
import LibrariesV2List from './libraries-v2-tab/index';
|
||||
import CoursesTab from './courses-tab';
|
||||
import { WelcomeLibrariesV2Alert } from './libraries-v2-tab/WelcomeLibrariesV2Alert';
|
||||
@@ -29,6 +29,7 @@ const TabsSection = ({
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigate();
|
||||
const { pathname } = useLocation();
|
||||
const [migrationFilter, setMigrationFilter] = useState<Filter[]>(BaseFilterState);
|
||||
const TABS_LIST = {
|
||||
courses: 'courses',
|
||||
libraries: 'libraries',
|
||||
@@ -121,7 +122,10 @@ const TabsSection = ({
|
||||
: messages.librariesTabTitle,
|
||||
)}
|
||||
>
|
||||
<LibrariesList />
|
||||
<LibrariesList
|
||||
migrationFilter={migrationFilter}
|
||||
setMigrationFilter={setMigrationFilter}
|
||||
/>
|
||||
</Tab>,
|
||||
);
|
||||
}
|
||||
@@ -137,7 +141,7 @@ const TabsSection = ({
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}, [showNewCourseContainer, isLoadingCourses]);
|
||||
}, [showNewCourseContainer, isLoadingCourses, migrationFilter]);
|
||||
|
||||
const handleSelectTab = (tab: TabKeyType) => {
|
||||
if (tab === TABS_LIST.courses) {
|
||||
|
||||
@@ -70,7 +70,7 @@ export enum Filter {
|
||||
unmigrated = 'unmigrated',
|
||||
}
|
||||
|
||||
const BaseFilterState = Object.values(Filter);
|
||||
export const BaseFilterState = Object.values(Filter);
|
||||
|
||||
interface MigrationFilterProps {
|
||||
filters: Filter[];
|
||||
@@ -146,7 +146,12 @@ interface LibrariesListProps {
|
||||
handleCheck?: (library: LibraryV1Data, action: 'add' | 'remove') => void;
|
||||
setSelectedLibraries?: (libraries: LibraryV1Data[]) => void;
|
||||
hideMigationAlert?: boolean;
|
||||
initialFilter?: Filter[];
|
||||
// We lift `migrationFilter` and `setMigrationFilter` into props
|
||||
// so that the filter state is maintained consistently across different
|
||||
// steps of the legacy libraries migration flow, and to allow
|
||||
// parent components to control and persist the filter context.
|
||||
migrationFilter: Filter[];
|
||||
setMigrationFilter: React.Dispatch<React.SetStateAction<Filter[]>>;
|
||||
}
|
||||
|
||||
export const LibrariesList = ({
|
||||
@@ -154,13 +159,13 @@ export const LibrariesList = ({
|
||||
handleCheck,
|
||||
setSelectedLibraries,
|
||||
hideMigationAlert = false,
|
||||
initialFilter = BaseFilterState,
|
||||
migrationFilter,
|
||||
setMigrationFilter,
|
||||
}: LibrariesListProps) => {
|
||||
const intl = useIntl();
|
||||
const { isPending, data, isError } = useLibrariesV1Data();
|
||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||
const [search, setSearch] = useState<string>('');
|
||||
const [migrationFilter, setMigrationFilter] = useState<Filter[]>(initialFilter);
|
||||
|
||||
let filteredData = findInValues(data?.libraries, search || '') || [];
|
||||
if (migrationFilter.length === 1) {
|
||||
|
||||
Reference in New Issue
Block a user