Skip to content

Commit fa2bd8a

Browse files
authored
chore: backport latest bug fixes (#2602)
Backport of #2584 and #2587
1 parent 2dc087f commit fa2bd8a

File tree

19 files changed

+399
-150
lines changed

19 files changed

+399
-150
lines changed

src/container-comparison/CompareContainersWidget.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { LoadingSpinner } from '@src/generic/Loading';
1313
import { useContainer, useContainerChildren } from '@src/library-authoring/data/apiHooks';
1414
import { BoldText } from '@src/utils';
1515

16+
import { Container, LibraryBlockMetadata } from '@src/library-authoring/data/api';
1617
import ChildrenPreview from './ChildrenPreview';
1718
import ContainerRow from './ContainerRow';
1819
import { useCourseContainerChildren } from './data/apiHooks';
@@ -60,7 +61,7 @@ const CompareContainersWidgetInner = ({
6061
data: libData,
6162
isError: isLibError,
6263
error: libError,
63-
} = useContainerChildren(state === 'removed' ? undefined : upstreamBlockId, true);
64+
} = useContainerChildren<Container | LibraryBlockMetadata>(state === 'removed' ? undefined : upstreamBlockId, true);
6465
const {
6566
data: containerData,
6667
isError: isContainerTitleError,

src/legacy-libraries-migration/ConfirmationView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export const ConfirmationView = ({
8181
</Alert>
8282
{legacyLibraries.map((legacyLib) => (
8383
<ConfirmationCard
84+
key={legacyLib.libraryKey}
8485
legacyLib={legacyLib}
8586
destinationName={destination.title}
8687
/>

src/legacy-libraries-migration/LegacyLibMigrationPage.test.tsx

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
render,
77
screen,
88
waitFor,
9+
within,
910
} from '@src/testUtils';
1011
import studioHomeMock from '@src/studio-home/__mocks__/studioHomeMock';
1112
import { mockGetContentLibraryV2List } from '@src/library-authoring/data/api.mocks';
@@ -184,7 +185,7 @@ describe('<LegacyLibMigrationPage />', () => {
184185
nextButton.click();
185186

186187
// Should show alert of SelectDestinationView
187-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
188+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
188189

189190
const backButton = screen.getByRole('button', { name: /back/i });
190191
backButton.click();
@@ -210,7 +211,7 @@ describe('<LegacyLibMigrationPage />', () => {
210211
nextButton.click();
211212

212213
// Should show alert of SelectDestinationView
213-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
214+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
214215

215216
// The next button is disabled
216217
expect(nextButton).toBeDisabled();
@@ -224,24 +225,31 @@ describe('<LegacyLibMigrationPage />', () => {
224225
});
225226

226227
it('should back to select library destination', async () => {
228+
const user = userEvent.setup();
227229
renderPage();
228230
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
229231
expect(await screen.findByText('MBA')).toBeInTheDocument();
230232

231233
const legacyLibrary = screen.getByRole('checkbox', { name: 'MBA' });
232-
legacyLibrary.click();
234+
await user.click(legacyLibrary);
233235

234-
const nextButton = screen.getByRole('button', { name: /next/i });
235-
nextButton.click();
236+
const nextButton = await screen.findByRole('button', { name: /next/i });
237+
await user.click(nextButton);
236238

237239
// Should show alert of SelectDestinationView
238-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
240+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
239241
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
240242
const radioButton = screen.getByRole('radio', { name: /test library 1/i });
241-
radioButton.click();
243+
await user.click(radioButton);
242244

243-
nextButton.click();
244-
expect(await screen.findByText(/these 1 legacy library will be migrated to/i)).toBeInTheDocument();
245+
await user.click(nextButton);
246+
const alert = await screen.findByRole('alert');
247+
expect(await within(alert).findByText(
248+
/All content from the 1 legacy library you selected will be migrated to/i,
249+
)).toBeInTheDocument();
250+
expect(await within(alert).findByText(
251+
/test library 1/i,
252+
)).toBeInTheDocument();
245253

246254
const backButton = screen.getByRole('button', { name: /back/i });
247255
backButton.click();
@@ -269,7 +277,7 @@ describe('<LegacyLibMigrationPage />', () => {
269277
nextButton.click();
270278

271279
// Should show alert of SelectDestinationView
272-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
280+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
273281

274282
const createButton = await screen.findByRole('button', { name: /create new library/i });
275283
expect(createButton).toBeInTheDocument();
@@ -336,18 +344,24 @@ describe('<LegacyLibMigrationPage />', () => {
336344
legacyLibrary3.click();
337345

338346
const nextButton = screen.getByRole('button', { name: /next/i });
339-
nextButton.click();
347+
await user.click(nextButton);
340348

341349
// Should show alert of SelectDestinationView
342-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
350+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
343351
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
344352
const radioButton = screen.getByRole('radio', { name: /test library 1/i });
345-
radioButton.click();
353+
await user.click(radioButton);
346354

347-
nextButton.click();
355+
await user.click(nextButton);
348356

349357
// Should show alert of ConfirmationView
350-
expect(await screen.findByText(/these 3 legacy libraries will be migrated to/i)).toBeInTheDocument();
358+
const alert = await screen.findByRole('alert');
359+
expect(await within(alert).findByText(
360+
/All content from the 3 legacy libraries you selected will be migrated to/i,
361+
)).toBeInTheDocument();
362+
expect(await within(alert).findByText(
363+
/test library 1/i,
364+
)).toBeInTheDocument();
351365
expect(screen.getByText('MBA')).toBeInTheDocument();
352366
expect(screen.getByText('Legacy library 1')).toBeInTheDocument();
353367
expect(screen.getByText('MBA 1')).toBeInTheDocument();
@@ -390,18 +404,26 @@ describe('<LegacyLibMigrationPage />', () => {
390404
legacyLibrary3.click();
391405

392406
const nextButton = screen.getByRole('button', { name: /next/i });
393-
nextButton.click();
407+
await user.click(nextButton);
394408

395409
// Should show alert of SelectDestinationView
396-
expect(await screen.findByText(/any legacy libraries that are used/i)).toBeInTheDocument();
410+
expect(await screen.findByText(/you selected will be migrated to this new library/i)).toBeInTheDocument();
397411
expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
398412
const radioButton = screen.getByRole('radio', { name: /test library 1/i });
399-
radioButton.click();
413+
await user.click(radioButton);
400414

401-
nextButton.click();
415+
await user.click(nextButton);
402416

403417
// Should show alert of ConfirmationView
404-
expect(await screen.findByText(/these 3 legacy libraries will be migrated to/i)).toBeInTheDocument();
418+
const alert = await screen.findByRole('alert');
419+
expect(await within(alert).findByText(
420+
/All content from the 3 legacy libraries you selected will be migrated to /i,
421+
{ exact: false },
422+
)).toBeInTheDocument();
423+
expect(await within(alert).findByText(
424+
/test library 1/i,
425+
{ exact: false },
426+
)).toBeInTheDocument();
405427
expect(screen.getByText('MBA')).toBeInTheDocument();
406428
expect(screen.getByText('Legacy library 1')).toBeInTheDocument();
407429
expect(screen.getByText('MBA 1')).toBeInTheDocument();

src/legacy-libraries-migration/messages.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,18 @@ const messages = defineMessages({
6565
id: 'legacy-libraries-migration.select-destination.alert.text',
6666
defaultMessage: 'All content from the'
6767
+ ' {count, plural, one {{count} legacy library} other {{count} legacy libraries}} you selected will'
68-
+ ' be migrated to this new library, organized into collections. Any legacy libraries that are used in'
69-
+ ' problem banks will maintain their link with migrated content the first time they are migrated.',
68+
+ ' be migrated to this new library, organized into collections. Legacy library content used in courses will'
69+
+ ' continue to work as-is. To receive any future changes to migrated content, you must update these'
70+
+ ' references within your course.',
7071
description: 'Alert text in the select destination step of the legacy libraries migration page.',
7172
},
7273
confirmationViewAlert: {
7374
id: 'legacy-libraries-migration.select-destination.alert.text',
74-
defaultMessage: 'These {count, plural, one {{count} legacy library} other {{count} legacy libraries}}'
75-
+ ' will be migrated to <b>{libraryName}</b> and organized as collections. Legacy library content used'
76-
+ ' in courses will continue to work as-is. To receive any future changes to migrated content,'
77-
+ ' you must update these references within your course.',
75+
defaultMessage: 'All content from the'
76+
+ ' {count, plural, one {{count} legacy library} other {{count} legacy libraries}} you selected will'
77+
+ ' be migrated to <b>{libraryName}</b>, organized into collections. Legacy library content used in courses will'
78+
+ ' continue to work as-is. To receive any future changes to migrated content, you must update these'
79+
+ ' references within your course.',
7880
description: 'Alert text in the confirmation step of the legacy libraries migration page.',
7981
},
8082
previouslyMigratedAlert: {

src/library-authoring/common/context/SidebarContext.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export interface DefaultTabs {
7272
export interface SidebarItemInfo {
7373
type: SidebarBodyItemId;
7474
id: string;
75+
index?: number;
7576
}
7677

7778
export enum SidebarActions {
@@ -88,7 +89,7 @@ export type SidebarContextData = {
8889
openCollectionInfoSidebar: (collectionId: string) => void;
8990
openComponentInfoSidebar: (usageKey: string) => void;
9091
openContainerInfoSidebar: (usageKey: string) => void;
91-
openItemSidebar: (selectedItemId: string, type: SidebarBodyItemId) => void;
92+
openItemSidebar: (selectedItemId: string, type: SidebarBodyItemId, index?: number) => void;
9293
sidebarItemInfo?: SidebarItemInfo;
9394
sidebarAction: SidebarActions;
9495
setSidebarAction: (action: SidebarActions) => void;
@@ -154,35 +155,38 @@ export const SidebarProvider = ({
154155
setSidebarItemInfo({ id: '', type: SidebarBodyItemId.Info });
155156
}, []);
156157

157-
const openComponentInfoSidebar = useCallback((usageKey: string) => {
158+
const openComponentInfoSidebar = useCallback((usageKey: string, index?: number) => {
158159
setSidebarItemInfo({
159160
id: usageKey,
160161
type: SidebarBodyItemId.ComponentInfo,
162+
index,
161163
});
162164
}, []);
163165

164-
const openCollectionInfoSidebar = useCallback((newCollectionId: string) => {
166+
const openCollectionInfoSidebar = useCallback((newCollectionId: string, index?: number) => {
165167
setSidebarItemInfo({
166168
id: newCollectionId,
167169
type: SidebarBodyItemId.CollectionInfo,
170+
index,
168171
});
169172
}, []);
170173

171-
const openContainerInfoSidebar = useCallback((usageKey: string) => {
174+
const openContainerInfoSidebar = useCallback((usageKey: string, index?: number) => {
172175
setSidebarItemInfo({
173176
id: usageKey,
174177
type: SidebarBodyItemId.ContainerInfo,
178+
index,
175179
});
176180
}, []);
177181

178182
const { navigateTo } = useLibraryRoutes();
179-
const openItemSidebar = useCallback((selectedItemId: string, type: SidebarBodyItemId) => {
180-
navigateTo({ selectedItemId });
181-
setSidebarItemInfo({ id: selectedItemId, type });
183+
const openItemSidebar = useCallback((selectedItemId: string, type: SidebarBodyItemId, index?: number) => {
184+
navigateTo({ selectedItemId, index });
185+
setSidebarItemInfo({ id: selectedItemId, type, index });
182186
}, [navigateTo, setSidebarItemInfo]);
183187

184188
// Set the initial sidebar state based on the URL parameters and context.
185-
const { selectedItemId } = useParams();
189+
const { selectedItemId, index: indexParam } = useParams();
186190
const { collectionId, containerId } = useLibraryContext();
187191
const { componentPickerMode } = useComponentPickerContext();
188192

@@ -198,12 +202,15 @@ export const SidebarProvider = ({
198202

199203
// Handle selected item id changes
200204
if (selectedItemId) {
205+
// if a item is selected that means we have list of items displayed
206+
// which means we can get the index from url and set it.
207+
const indexNumber = indexParam ? Number(indexParam) : undefined;
201208
if (selectedItemId.startsWith('lct:')) {
202-
openContainerInfoSidebar(selectedItemId);
209+
openContainerInfoSidebar(selectedItemId, indexNumber);
203210
} else if (selectedItemId.startsWith('lb:')) {
204-
openComponentInfoSidebar(selectedItemId);
211+
openComponentInfoSidebar(selectedItemId, indexNumber);
205212
} else {
206-
openCollectionInfoSidebar(selectedItemId);
213+
openCollectionInfoSidebar(selectedItemId, indexNumber);
207214
}
208215
} else if (collectionId) {
209216
openCollectionInfoSidebar(collectionId);

src/library-authoring/component-info/ComponentInfo.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ const ComponentActions = ({
111111
const [isPublisherOpen, openPublisher, closePublisher] = useToggle(false);
112112
const canEdit = canEditComponent(componentId);
113113

114+
const { sidebarItemInfo } = useSidebarContext();
115+
114116
if (isPublisherOpen) {
115117
return (
116118
<ComponentPublisher
@@ -141,7 +143,7 @@ const ComponentActions = ({
141143
)}
142144
</div>
143145
<div className="mt-2">
144-
<ComponentMenu usageKey={componentId} />
146+
<ComponentMenu usageKey={componentId} index={sidebarItemInfo?.index} />
145147
</div>
146148
</div>
147149
);

src/library-authoring/components/ComponentMenu.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ import { useClipboard } from '@src/generic/clipboard';
1212
import { getBlockType } from '@src/generic/key-utils';
1313
import { ToastContext } from '@src/generic/toast-context';
1414

15-
import { useLibraryContext } from '../common/context/LibraryContext';
16-
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
17-
import { useRemoveItemsFromCollection } from '../data/apiHooks';
15+
import { useLibraryContext } from '@src/library-authoring/common/context/LibraryContext';
16+
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '@src/library-authoring/common/context/SidebarContext';
17+
import { useRemoveItemsFromCollection } from '@src/library-authoring/data/apiHooks';
18+
import containerMessages from '@src/library-authoring/containers/messages';
19+
import { useLibraryRoutes } from '@src/library-authoring/routes';
20+
import { useRunOnNextRender } from '@src/utils';
1821
import { canEditComponent } from './ComponentEditorModal';
1922
import ComponentDeleter from './ComponentDeleter';
2023
import ComponentRemover from './ComponentRemover';
2124
import messages from './messages';
22-
import containerMessages from '../containers/messages';
23-
import { useLibraryRoutes } from '../routes';
24-
import { useRunOnNextRender } from '../../utils';
2525

26-
export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
26+
interface Props {
27+
usageKey: string;
28+
index?: number;
29+
}
30+
31+
export const ComponentMenu = ({ usageKey, index }: Props) => {
2732
const intl = useIntl();
2833
const {
2934
libraryId,
@@ -135,6 +140,7 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
135140
{isRemoveModalOpen && (
136141
<ComponentRemover
137142
usageKey={usageKey}
143+
index={index}
138144
close={closeRemoveModal}
139145
/>
140146
)}

0 commit comments

Comments
 (0)