feat: Connect bulk migration backend with frontend (#2493)
- Connects the `Confirm` button with the bulk migrate backend - Updates the library page to get the migration task status and refresh the component on success.
This commit is contained in:
@@ -14,9 +14,11 @@ import { getContentLibraryV2CreateApiUrl } from '@src/library-authoring/create-l
|
||||
import { getStudioHomeApiUrl } from '@src/studio-home/data/api';
|
||||
|
||||
import { LegacyLibMigrationPage } from './LegacyLibMigrationPage';
|
||||
import { bulkMigrateLegacyLibrariesUrl } from './data/api';
|
||||
|
||||
const path = '/libraries-v1/migrate/*';
|
||||
let axiosMock: MockAdapter;
|
||||
let mockShowToast;
|
||||
|
||||
mockGetStudioHomeLibraries.applyMock();
|
||||
mockGetContentLibraryV2List.applyMock();
|
||||
@@ -41,7 +43,9 @@ const renderPage = () => (
|
||||
|
||||
describe('<LegacyLibMigrationPage />', () => {
|
||||
beforeEach(() => {
|
||||
axiosMock = initializeMocks().axiosMock;
|
||||
const mocks = initializeMocks();
|
||||
axiosMock = mocks.axiosMock;
|
||||
mockShowToast = mocks.mockShowToast;
|
||||
});
|
||||
|
||||
it('should render legacy library migration page', async () => {
|
||||
@@ -292,6 +296,7 @@ describe('<LegacyLibMigrationPage />', () => {
|
||||
|
||||
it('should confirm migration', async () => {
|
||||
const user = userEvent.setup();
|
||||
axiosMock.onPost(bulkMigrateLegacyLibrariesUrl()).reply(200);
|
||||
renderPage();
|
||||
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
|
||||
expect(await screen.findByText('MBA')).toBeInTheDocument();
|
||||
@@ -334,6 +339,66 @@ describe('<LegacyLibMigrationPage />', () => {
|
||||
const confirmButton = screen.getByRole('button', { name: /confirm/i });
|
||||
confirmButton.click();
|
||||
|
||||
// TODO: expect call migrate API
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
});
|
||||
expect(axiosMock.history.post[0].data).toBe(
|
||||
'{"sources":["library-v1:MBA+123","library-v1:UNIX+LG1","library-v1:MBA+1234"],"target":"lib:SampleTaxonomyOrg1:TL1","create_collections":true,"repeat_handling_strategy":"fork"}',
|
||||
);
|
||||
expect(mockShowToast).toHaveBeenCalledWith('3 legacy libraries are being migrated.');
|
||||
});
|
||||
|
||||
it('should show error when confirm migration', async () => {
|
||||
const user = userEvent.setup();
|
||||
axiosMock.onPost(bulkMigrateLegacyLibrariesUrl()).reply(400);
|
||||
renderPage();
|
||||
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
|
||||
expect(await screen.findByText('MBA')).toBeInTheDocument();
|
||||
|
||||
// The filter is 'unmigrated' by default.
|
||||
// Clear the filter to select all libraries
|
||||
const filterButton = screen.getByRole('button', { name: /unmigrated/i });
|
||||
await user.click(filterButton);
|
||||
const clearButton = await screen.findByRole('button', { name: /clear filter/i });
|
||||
await user.click(clearButton);
|
||||
|
||||
const legacyLibrary1 = screen.getByRole('checkbox', { name: 'MBA' });
|
||||
const legacyLibrary2 = screen.getByRole('checkbox', { name: /legacy library 1 imported library/i });
|
||||
const legacyLibrary3 = screen.getByRole('checkbox', { name: 'MBA 1' });
|
||||
|
||||
legacyLibrary1.click();
|
||||
legacyLibrary2.click();
|
||||
legacyLibrary3.click();
|
||||
|
||||
const nextButton = screen.getByRole('button', { name: /next/i });
|
||||
nextButton.click();
|
||||
|
||||
// Should show alert of SelectDestinationView
|
||||
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
|
||||
const radioButton = screen.getByRole('radio', { name: /test library 1/i });
|
||||
radioButton.click();
|
||||
|
||||
nextButton.click();
|
||||
|
||||
// Should show alert of ConfirmationView
|
||||
expect(await screen.findByText(/these 3 legacy libraries will be migrated to/i)).toBeInTheDocument();
|
||||
expect(screen.getByText('MBA')).toBeInTheDocument();
|
||||
expect(screen.getByText('Legacy library 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('MBA 1')).toBeInTheDocument();
|
||||
expect(screen.getByText(
|
||||
/Previously migrated library. Any problem bank links were already moved will be migrated to/i,
|
||||
)).toBeInTheDocument();
|
||||
|
||||
const confirmButton = screen.getByRole('button', { name: /confirm/i });
|
||||
confirmButton.click();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
});
|
||||
expect(axiosMock.history.post[0].data).toBe(
|
||||
'{"sources":["library-v1:MBA+123","library-v1:UNIX+LG1","library-v1:MBA+1234"],"target":"lib:SampleTaxonomyOrg1:TL1","create_collections":true,"repeat_handling_strategy":"fork"}',
|
||||
);
|
||||
expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration failed.');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -16,11 +21,13 @@ import Header from '@src/header';
|
||||
import SubHeader from '@src/generic/sub-header/SubHeader';
|
||||
import type { ContentLibrary } from '@src/library-authoring/data/api';
|
||||
import type { LibraryV1Data } from '@src/studio-home/data/api';
|
||||
import { ToastContext } from '@src/generic/toast-context';
|
||||
import { Filter, LibrariesList } from '@src/studio-home/tabs-section/libraries-tab';
|
||||
|
||||
import messages from './messages';
|
||||
import { SelectDestinationView } from './SelectDestinationView';
|
||||
import { ConfirmationView } from './ConfirmationView';
|
||||
import { useUpdateContainerCollections } from './data/apiHooks';
|
||||
|
||||
export type MigrationStep = 'select-libraries' | 'select-destination' | 'confirmation-view';
|
||||
|
||||
@@ -66,11 +73,33 @@ const ExitModal = ({
|
||||
|
||||
export const LegacyLibMigrationPage = () => {
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigate();
|
||||
const { showToast } = useContext(ToastContext);
|
||||
const [currentStep, setCurrentStep] = useState<MigrationStep>('select-libraries');
|
||||
const [isExitModalOpen, openExitModal, closeExitModal] = useToggle(false);
|
||||
const [legacyLibraries, setLegacyLibraries] = useState<LibraryV1Data[]>([]);
|
||||
const [destinationLibrary, setDestination] = useState<ContentLibrary>();
|
||||
const [confirmationButtonState, setConfirmationButtonState] = useState('default');
|
||||
const migrate = useUpdateContainerCollections();
|
||||
|
||||
const handleMigrate = useCallback(async () => {
|
||||
if (destinationLibrary) {
|
||||
try {
|
||||
const migrationTask = await migrate.mutateAsync({
|
||||
sources: legacyLibraries.map((lib) => lib.libraryKey),
|
||||
target: destinationLibrary.id,
|
||||
createCollections: true,
|
||||
repeatHandlingStrategy: 'fork',
|
||||
});
|
||||
showToast(intl.formatMessage(messages.migrationInProgress, {
|
||||
count: legacyLibraries.length,
|
||||
}));
|
||||
navigate(`/library/${destinationLibrary.id}?migration_task=${migrationTask.uuid}`);
|
||||
} catch (error) {
|
||||
showToast(intl.formatMessage(messages.migrationFailed));
|
||||
}
|
||||
}
|
||||
}, [migrate, legacyLibraries, destinationLibrary]);
|
||||
|
||||
const handleNext = useCallback(() => {
|
||||
switch (currentStep) {
|
||||
@@ -82,13 +111,13 @@ export const LegacyLibMigrationPage = () => {
|
||||
break;
|
||||
case 'confirmation-view':
|
||||
setConfirmationButtonState('pending');
|
||||
// TODO Call migration API
|
||||
handleMigrate();
|
||||
break;
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
break;
|
||||
}
|
||||
}, [currentStep, setCurrentStep]);
|
||||
}, [currentStep, setCurrentStep, handleMigrate]);
|
||||
|
||||
const handleBack = useCallback(() => {
|
||||
switch (currentStep) {
|
||||
|
||||
61
src/legacy-libraries-migration/data/api.mocks.ts
Normal file
61
src/legacy-libraries-migration/data/api.mocks.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import * as api from './api';
|
||||
|
||||
export async function mockGetMigrationStatus(migrationId: string): Promise<api.MigrateTaskStatusData> {
|
||||
switch (migrationId) {
|
||||
case mockGetMigrationStatus.migrationId:
|
||||
return mockGetMigrationStatus.migrationStatusData;
|
||||
case mockGetMigrationStatus.migrationIdFailed:
|
||||
return mockGetMigrationStatus.migrationStatusFailedData;
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`mockGetMigrationStatus: unknown migration ID "${migrationId}"`);
|
||||
}
|
||||
}
|
||||
|
||||
mockGetMigrationStatus.migrationId = '1';
|
||||
mockGetMigrationStatus.migrationStatusData = {
|
||||
uuid: mockGetMigrationStatus.migrationId,
|
||||
state: 'Succeeded',
|
||||
stateText: 'Succeeded',
|
||||
completedSteps: 9,
|
||||
totalSteps: 9,
|
||||
attempts: 1,
|
||||
created: '',
|
||||
modified: '',
|
||||
artifacts: [],
|
||||
parameters: [
|
||||
{
|
||||
source: 'legacy-lib-1',
|
||||
target: 'lib',
|
||||
compositionLevel: 'component',
|
||||
repeatHandlingStrategy: 'update',
|
||||
preserveUrlSlugs: false,
|
||||
targetCollectionSlug: 'coll-1',
|
||||
forwardSourceToTarget: true,
|
||||
},
|
||||
],
|
||||
} as api.MigrateTaskStatusData;
|
||||
mockGetMigrationStatus.migrationIdFailed = '2';
|
||||
mockGetMigrationStatus.migrationStatusFailedData = {
|
||||
uuid: mockGetMigrationStatus.migrationId,
|
||||
state: 'Failed',
|
||||
stateText: 'Failed',
|
||||
completedSteps: 9,
|
||||
totalSteps: 9,
|
||||
attempts: 1,
|
||||
created: '',
|
||||
modified: '',
|
||||
artifacts: [],
|
||||
parameters: [
|
||||
{
|
||||
source: 'legacy-lib-1',
|
||||
target: 'lib',
|
||||
compositionLevel: 'component',
|
||||
repeatHandlingStrategy: 'update',
|
||||
preserveUrlSlugs: false,
|
||||
targetCollectionSlug: 'coll-1',
|
||||
forwardSourceToTarget: true,
|
||||
},
|
||||
],
|
||||
} as api.MigrateTaskStatusData;
|
||||
mockGetMigrationStatus.applyMock = () => jest.spyOn(api, 'getMigrationStatus').mockImplementation(mockGetMigrationStatus);
|
||||
34
src/legacy-libraries-migration/data/api.test.ts
Normal file
34
src/legacy-libraries-migration/data/api.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { initializeMocks } from '../../testUtils';
|
||||
import * as api from './api';
|
||||
|
||||
let axiosMock;
|
||||
|
||||
describe('legacy libraries migration API', () => {
|
||||
beforeEach(() => {
|
||||
({ axiosMock } = initializeMocks());
|
||||
});
|
||||
|
||||
describe('getMigrationStatus', () => {
|
||||
it('should get migration status', async () => {
|
||||
const migrationId = '1';
|
||||
const url = api.getMigrationStatusUrl(migrationId);
|
||||
axiosMock.onGet(url).reply(200);
|
||||
await api.getMigrationStatus(migrationId);
|
||||
|
||||
expect(axiosMock.history.get[0].url).toEqual(url);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkMigrateLegacyLibraries', () => {
|
||||
it('should call bulk migrate legacy libraries', async () => {
|
||||
const url = api.bulkMigrateLegacyLibrariesUrl();
|
||||
axiosMock.onPost(url).reply(200);
|
||||
await api.bulkMigrateLegacyLibraries({
|
||||
sources: [],
|
||||
target: '1',
|
||||
});
|
||||
|
||||
expect(axiosMock.history.post[0].url).toEqual(url);
|
||||
});
|
||||
});
|
||||
});
|
||||
70
src/legacy-libraries-migration/data/api.ts
Normal file
70
src/legacy-libraries-migration/data/api.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { camelCaseObject, getConfig, snakeCaseObject } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
|
||||
|
||||
/**
|
||||
* Get the URL to check the migration task status
|
||||
*/
|
||||
export const getMigrationStatusUrl = (migrationId: string) => `${getApiBaseUrl()}/api/modulestore_migrator/v1/migrations/${migrationId}/`;
|
||||
|
||||
/**
|
||||
* Get the URL for bulk migrate legacy libraries
|
||||
*/
|
||||
export const bulkMigrateLegacyLibrariesUrl = () => `${getApiBaseUrl()}/api/modulestore_migrator/v1/bulk_migration/`;
|
||||
|
||||
export interface MigrateArtifacts {
|
||||
source: string;
|
||||
target: string;
|
||||
compositionLevel: string;
|
||||
repeatHandlingStrategy: 'update' | 'skip' | 'fork';
|
||||
preserveUrlSlugs: boolean;
|
||||
targetCollectionSlug: string;
|
||||
forwardSourceToTarget: boolean;
|
||||
}
|
||||
|
||||
export interface MigrateTaskStatusData {
|
||||
state: string;
|
||||
stateText: string;
|
||||
completedSteps: number;
|
||||
totalSteps: number;
|
||||
attempts: number;
|
||||
created: string;
|
||||
modified: string;
|
||||
artifacts: string[];
|
||||
uuid: string;
|
||||
parameters: MigrateArtifacts[];
|
||||
}
|
||||
|
||||
export interface BulkMigrateRequestData {
|
||||
sources: string[];
|
||||
target: string;
|
||||
targetCollectionSlugList?: string[];
|
||||
createCollections?: boolean;
|
||||
compositionLevel?: string;
|
||||
repeatHandlingStrategy?: string;
|
||||
preserveUrlSlugs?: boolean;
|
||||
forwardSourceToTarget?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get migration task status
|
||||
*/
|
||||
export async function getMigrationStatus(
|
||||
migrationId: string,
|
||||
): Promise<MigrateTaskStatusData> {
|
||||
const client = getAuthenticatedHttpClient();
|
||||
const { data } = await client.get(getMigrationStatusUrl(migrationId));
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk migrate legacy libraries
|
||||
*/
|
||||
export async function bulkMigrateLegacyLibraries(
|
||||
requestData: BulkMigrateRequestData,
|
||||
): Promise<MigrateTaskStatusData> {
|
||||
const client = getAuthenticatedHttpClient();
|
||||
const { data } = await client.post(bulkMigrateLegacyLibrariesUrl(), snakeCaseObject(requestData));
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
31
src/legacy-libraries-migration/data/apiHooks.ts
Normal file
31
src/legacy-libraries-migration/data/apiHooks.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { skipToken, useMutation, useQuery } from '@tanstack/react-query';
|
||||
|
||||
import * as api from './api';
|
||||
|
||||
export const legacyMigrationQueryKeys = {
|
||||
all: ['contentLibrary'],
|
||||
/**
|
||||
* Base key for data specific to a migration task
|
||||
*/
|
||||
migrationTask: (migrationId?: string | null) => [...legacyMigrationQueryKeys.all, migrationId],
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this mutation to update container collections
|
||||
*/
|
||||
export const useUpdateContainerCollections = () => (
|
||||
useMutation({
|
||||
mutationFn: async (requestData: api.BulkMigrateRequestData) => api.bulkMigrateLegacyLibraries(requestData),
|
||||
})
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the migration status
|
||||
*/
|
||||
export const useMigrationStatus = (migrationId: string | null) => (
|
||||
useQuery({
|
||||
queryKey: legacyMigrationQueryKeys.migrationTask(migrationId),
|
||||
queryFn: migrationId ? () => api.getMigrationStatus(migrationId!) : skipToken,
|
||||
refetchInterval: 1000, // Refresh every second
|
||||
})
|
||||
);
|
||||
@@ -82,6 +82,21 @@ const messages = defineMessages({
|
||||
+ ' moved will be migrated to <b>{libraryName}</b>',
|
||||
description: 'Alert text when the legacy library is already migrated.',
|
||||
},
|
||||
migrationInProgress: {
|
||||
id: 'legacy-libraries-migration.confirmation-step.toast.migration-in-progress',
|
||||
defaultMessage: '{count, plural, one {{count} legacy library is} other {{count} legacy libraries are}} being migrated.',
|
||||
description: 'Toast message that indicates the legacy libraries are being migrated',
|
||||
},
|
||||
migrationFailed: {
|
||||
id: 'legacy-libraries-migration.confirmation-step.toast.migration-failed',
|
||||
defaultMessage: 'Legacy libraries migration failed.',
|
||||
description: 'Toast message that indicates the migration of legacy libraries is failed',
|
||||
},
|
||||
migrationSuccess: {
|
||||
id: 'legacy-libraries-migration.confirmation-step.toast.migration-success',
|
||||
defaultMessage: 'The migration of legacy libraries has been completed successfully.',
|
||||
description: 'Toast message that indicates the migration of legacy libraries is finished',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -10,8 +10,12 @@ import {
|
||||
within,
|
||||
} from '@src/testUtils';
|
||||
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
|
||||
import { mockGetMigrationStatus } from '@src/legacy-libraries-migration/data/api.mocks';
|
||||
import mockEmptyResult from '@src/search-modal/__mocks__/empty-search-result.json';
|
||||
import { mockContentSearchConfig } from '@src/search-manager/data/api.mock';
|
||||
import { getStudioHomeApiUrl } from '@src/studio-home/data/api';
|
||||
|
||||
import mockResult from './__mocks__/library-search.json';
|
||||
import mockEmptyResult from '../search-modal/__mocks__/empty-search-result.json';
|
||||
import {
|
||||
mockContentLibrary,
|
||||
mockGetCollectionMetadata,
|
||||
@@ -19,8 +23,6 @@ import {
|
||||
mockGetLibraryTeam,
|
||||
mockXBlockFields,
|
||||
} from './data/api.mocks';
|
||||
import { mockContentSearchConfig } from '../search-manager/data/api.mock';
|
||||
import { getStudioHomeApiUrl } from '../studio-home/data/api';
|
||||
import { LibraryLayout } from '.';
|
||||
import { getLibraryCollectionsApiUrl, getLibraryContainersApiUrl } from './data/api';
|
||||
|
||||
@@ -33,6 +35,7 @@ mockContentSearchConfig.applyMock();
|
||||
mockContentLibrary.applyMock();
|
||||
mockGetLibraryTeam.applyMock();
|
||||
mockXBlockFields.applyMock();
|
||||
mockGetMigrationStatus.applyMock();
|
||||
|
||||
const searchEndpoint = 'http://mock.meilisearch.local/multi-search';
|
||||
|
||||
@@ -1062,4 +1065,30 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
'This page cannot be shown: Libraries v2 are disabled.',
|
||||
);
|
||||
});
|
||||
|
||||
it('Should show success in migration legacy libraries', async () => {
|
||||
render(<LibraryLayout />, {
|
||||
path,
|
||||
routerProps: {
|
||||
initialEntries: [
|
||||
`/library/${mockContentLibrary.libraryId}?migration_task=${mockGetMigrationStatus.migrationId}`,
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('The migration of legacy libraries has been completed successfully.'));
|
||||
});
|
||||
|
||||
it('Should show fail in migration legacy libraries', async () => {
|
||||
render(<LibraryLayout />, {
|
||||
path,
|
||||
routerProps: {
|
||||
initialEntries: [
|
||||
`/library/${mockContentLibrary.libraryId}?migration_task=${mockGetMigrationStatus.migrationIdFailed}`,
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockShowToast).toHaveBeenCalledWith('Legacy libraries migration failed.'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
@@ -20,13 +21,15 @@ import {
|
||||
Tabs,
|
||||
} from '@openedx/paragon';
|
||||
import { Add, InfoOutline } from '@openedx/paragon/icons';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import Loading from '../generic/Loading';
|
||||
import SubHeader from '../generic/sub-header/SubHeader';
|
||||
import Header from '../header';
|
||||
import NotFoundAlert from '../generic/NotFoundAlert';
|
||||
import { useStudioHome } from '../studio-home/hooks';
|
||||
import { useMigrationStatus } from '@src/legacy-libraries-migration/data/apiHooks';
|
||||
import Loading from '@src/generic/Loading';
|
||||
import SubHeader from '@src/generic/sub-header/SubHeader';
|
||||
import Header from '@src/header';
|
||||
import NotFoundAlert from '@src/generic/NotFoundAlert';
|
||||
import { useStudioHome } from '@src/studio-home/hooks';
|
||||
import {
|
||||
ClearFiltersButton,
|
||||
FilterByBlockType,
|
||||
@@ -35,16 +38,19 @@ import {
|
||||
SearchKeywordsField,
|
||||
SearchSortWidget,
|
||||
TypesFilterData,
|
||||
} from '../search-manager';
|
||||
} from '@src/search-manager';
|
||||
import { ToastContext } from '@src/generic/toast-context';
|
||||
import migrationMessages from '@src/legacy-libraries-migration/messages';
|
||||
|
||||
import LibraryContent from './LibraryContent';
|
||||
import { LibrarySidebar } from './library-sidebar';
|
||||
import { useComponentPickerContext } from './common/context/ComponentPickerContext';
|
||||
import { useLibraryContext } from './common/context/LibraryContext';
|
||||
import { SidebarBodyItemId, useSidebarContext } from './common/context/SidebarContext';
|
||||
import { allLibraryPageTabs, ContentType, useLibraryRoutes } from './routes';
|
||||
|
||||
import messages from './messages';
|
||||
import LibraryFilterByPublished from './generic/filter-by-published';
|
||||
import { libraryQueryPredicate } from './data/apiHooks';
|
||||
|
||||
const HeaderActions = () => {
|
||||
const intl = useIntl();
|
||||
@@ -137,6 +143,16 @@ const LibraryAuthoringPage = ({
|
||||
}: LibraryAuthoringPageProps) => {
|
||||
const intl = useIntl();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const params = new URLSearchParams(location.search);
|
||||
const { showToast } = useContext(ToastContext);
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Get migration status every second if applicable
|
||||
const migrationId = params.get('migration_task');
|
||||
const {
|
||||
data: migrationStatusData,
|
||||
} = useMigrationStatus(migrationId);
|
||||
|
||||
const {
|
||||
isLoadingPage: isLoadingStudioHome,
|
||||
@@ -205,6 +221,30 @@ const LibraryAuthoringPage = ({
|
||||
}
|
||||
}, [navigateTo]);
|
||||
|
||||
// Verify the migration task status
|
||||
if (migrationId) {
|
||||
let deleteMigrationIdParam = false;
|
||||
if (migrationStatusData?.state === 'Succeeded') {
|
||||
showToast(intl.formatMessage(migrationMessages.migrationSuccess));
|
||||
queryClient.invalidateQueries({ predicate: (query) => libraryQueryPredicate(query, libraryId) });
|
||||
deleteMigrationIdParam = true;
|
||||
} else if (migrationStatusData?.state === 'Failed') {
|
||||
showToast(intl.formatMessage(migrationMessages.migrationFailed));
|
||||
deleteMigrationIdParam = true;
|
||||
} else if (migrationStatusData?.state === 'Canceled') {
|
||||
/* istanbul ignore next */
|
||||
deleteMigrationIdParam = true;
|
||||
}
|
||||
|
||||
if (deleteMigrationIdParam) {
|
||||
params.delete('migration_task');
|
||||
navigate({
|
||||
pathname: location.pathname,
|
||||
search: params.toString(),
|
||||
}, { replace: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (isLoadingLibraryData) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user