Skip to content

Commit ae82486

Browse files
authored
fix: cannot open item sidebar after closing with 'X' button (#2241)
When closing an item (component, unit, section, container, etc) sidebar, and trying to reopen it inmediately by clicking the card, it was not opening because navigateTo was being used, but the URL already was the same you were being navigated to. So we also have to update the sidebar item info in the sidebar context in order for it to reopen properly.
1 parent dd28539 commit ae82486

File tree

9 files changed

+51
-40
lines changed

9 files changed

+51
-40
lines changed

src/library-authoring/LibraryAuthoringPage.test.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ describe('<LibraryAuthoringPage />', () => {
398398
});
399399
}, 10000);
400400

401-
it('should open and close the component sidebar', async () => {
401+
it('should open, close and re-open the component sidebar', async () => {
402402
const mockResult0 = { ...mockResult }.results[0].hits[0];
403403
const displayName = 'Introduction to Testing';
404404
expect(mockResult0.display_name).toStrictEqual(displayName);
@@ -416,6 +416,10 @@ describe('<LibraryAuthoringPage />', () => {
416416
fireEvent.click(closeButton);
417417

418418
await waitFor(() => expect(screen.queryByTestId('library-sidebar')).not.toBeInTheDocument());
419+
420+
fireEvent.click((await screen.findAllByText(displayName))[0]);
421+
422+
await waitFor(() => expect(screen.queryByTestId('library-sidebar')).toBeInTheDocument());
419423
});
420424

421425
it('should open component sidebar, showing manage tab on clicking add to collection menu item - component', async () => {

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useParams } from 'react-router-dom';
1010
import { useStateWithUrlSearchParam } from '../../../hooks';
1111
import { useComponentPickerContext } from './ComponentPickerContext';
1212
import { useLibraryContext } from './LibraryContext';
13+
import { useLibraryRoutes } from '../../routes';
1314

1415
export enum SidebarBodyItemId {
1516
AddContent = 'add-content',
@@ -86,6 +87,7 @@ export type SidebarContextData = {
8687
openCollectionInfoSidebar: (collectionId: string) => void;
8788
openComponentInfoSidebar: (usageKey: string) => void;
8889
openContainerInfoSidebar: (usageKey: string) => void;
90+
openItemSidebar: (selectedItemId: string, type: SidebarBodyItemId) => void;
8991
sidebarItemInfo?: SidebarItemInfo;
9092
sidebarAction: SidebarActions;
9193
setSidebarAction: (action: SidebarActions) => void;
@@ -172,6 +174,12 @@ export const SidebarProvider = ({
172174
});
173175
}, []);
174176

177+
const { navigateTo } = useLibraryRoutes();
178+
const openItemSidebar = useCallback((selectedItemId: string, type: SidebarBodyItemId) => {
179+
navigateTo({ selectedItemId });
180+
setSidebarItemInfo({ id: selectedItemId, type });
181+
}, [navigateTo, setSidebarItemInfo]);
182+
175183
// Set the initial sidebar state based on the URL parameters and context.
176184
const { selectedItemId } = useParams();
177185
const { collectionId, containerId } = useLibraryContext();
@@ -236,6 +244,7 @@ export const SidebarProvider = ({
236244
sidebarItemInfo,
237245
openCollectionInfoSidebar,
238246
openContainerInfoSidebar,
247+
openItemSidebar,
239248
sidebarAction,
240249
setSidebarAction,
241250
resetSidebarAction,
@@ -254,6 +263,7 @@ export const SidebarProvider = ({
254263
sidebarItemInfo,
255264
openCollectionInfoSidebar,
256265
openContainerInfoSidebar,
266+
openItemSidebar,
257267
sidebarAction,
258268
setSidebarAction,
259269
resetSidebarAction,
@@ -281,6 +291,7 @@ export function useSidebarContext(): SidebarContextData {
281291
openComponentInfoSidebar: () => {},
282292
openCollectionInfoSidebar: () => {},
283293
openContainerInfoSidebar: () => {},
294+
openItemSidebar: () => {},
284295
sidebarAction: SidebarActions.None,
285296
setSidebarAction: () => {},
286297
resetSidebarAction: () => {},

src/library-authoring/components/CollectionCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type CollectionCardProps = {
116116
const CollectionCard = ({ hit } : CollectionCardProps) => {
117117
const { componentPickerMode } = useComponentPickerContext();
118118
const { setCollectionId, showOnlyPublished } = useLibraryContext();
119-
const { openCollectionInfoSidebar, sidebarItemInfo } = useSidebarContext();
119+
const { openCollectionInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
120120

121121
const {
122122
type: itemType,
@@ -144,7 +144,7 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
144144
if (doubleClicked) {
145145
navigateTo({ collectionId });
146146
} else {
147-
navigateTo({ selectedItemId: collectionId });
147+
openItemSidebar(collectionId, SidebarBodyItemId.CollectionInfo);
148148
}
149149

150150
// In component picker mode, we want to open the sidebar or the collection
@@ -154,7 +154,7 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
154154
} else {
155155
openCollectionInfoSidebar(collectionId);
156156
}
157-
}, [collectionId, navigateTo, openCollectionInfoSidebar, setCollectionId, componentPickerMode]);
157+
}, [collectionId, navigateTo, openItemSidebar, openCollectionInfoSidebar, setCollectionId, componentPickerMode]);
158158

159159
return (
160160
<BaseCard

src/library-authoring/components/ComponentCard.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
initializeMocks,
77
} from '../../testUtils';
88
import { LibraryProvider } from '../common/context/LibraryContext';
9+
import { SidebarProvider } from '../common/context/SidebarContext';
910
import { getClipboardUrl } from '../../generic/data/api';
1011
import { ContentHit } from '../../search-manager';
1112
import ComponentCard from './ComponentCard';
@@ -53,7 +54,9 @@ const render = () => baseRender(<ComponentCard hit={contentHit} />, {
5354
params: { libraryId },
5455
extraWrapper: ({ children }) => (
5556
<LibraryProvider libraryId={libraryId}>
56-
{ children }
57+
<SidebarProvider>
58+
{ children }
59+
</SidebarProvider>
5760
</LibraryProvider>
5861
),
5962
});

src/library-authoring/components/ComponentCard.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { type ContentHit, PublishStatus } from '../../search-manager';
77
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
88
import { useLibraryContext } from '../common/context/LibraryContext';
99
import { SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
10-
import { useLibraryRoutes } from '../routes';
1110
import AddComponentWidget from './AddComponentWidget';
1211
import BaseCard from './BaseCard';
1312
import { ComponentMenu } from './ComponentMenu';
@@ -18,7 +17,7 @@ type ComponentCardProps = {
1817

1918
const ComponentCard = ({ hit }: ComponentCardProps) => {
2019
const { showOnlyPublished } = useLibraryContext();
21-
const { openComponentInfoSidebar, sidebarItemInfo } = useSidebarContext();
20+
const { openComponentInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
2221
const { componentPickerMode } = useComponentPickerContext();
2322

2423
const {
@@ -35,16 +34,15 @@ const ComponentCard = ({ hit }: ComponentCardProps) => {
3534
showOnlyPublished ? formatted.published?.displayName : formatted.displayName
3635
) ?? '';
3736

38-
const { navigateTo } = useLibraryRoutes();
3937
const selectComponent = useCallback(() => {
4038
if (!componentPickerMode) {
41-
navigateTo({ selectedItemId: usageKey });
39+
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
4240
} else {
4341
// In component picker mode, we want to open the sidebar
4442
// without changing the URL
4543
openComponentInfoSidebar(usageKey);
4644
}
47-
}, [usageKey, navigateTo, openComponentInfoSidebar]);
45+
}, [usageKey, openItemSidebar, openComponentInfoSidebar, componentPickerMode]);
4846

4947
const selected = sidebarItemInfo?.type === SidebarBodyItemId.ComponentInfo
5048
&& sidebarItemInfo.id === usageKey;

src/library-authoring/components/ComponentMenu.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { MoreVert } from '@openedx/paragon/icons';
1010

1111
import { getBlockType } from '@src/generic/key-utils';
1212
import { useLibraryContext } from '../common/context/LibraryContext';
13-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
13+
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
1414
import { useClipboard } from '../../generic/clipboard';
1515
import { ToastContext } from '../../generic/toast-context';
1616
import {
@@ -36,11 +36,11 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
3636

3737
const {
3838
sidebarItemInfo,
39-
openComponentInfoSidebar,
4039
closeLibrarySidebar,
4140
setSidebarAction,
41+
openItemSidebar,
4242
} = useSidebarContext();
43-
const { navigateTo, insideCollection } = useLibraryRoutes();
43+
const { insideCollection } = useLibraryRoutes();
4444

4545
const canEdit = usageKey && canEditComponent(usageKey);
4646
const { showToast } = useContext(ToastContext);
@@ -93,9 +93,9 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
9393
};
9494

9595
const handleEdit = useCallback(() => {
96-
navigateTo({ selectedItemId: usageKey });
96+
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
9797
openComponentEditor(usageKey);
98-
}, [usageKey, navigateTo]);
98+
}, [usageKey, openItemSidebar, openComponentEditor]);
9999

100100
const scheduleJumpToCollection = useRunOnNextRender(() => {
101101
// TODO: Ugly hack to make sure sidebar shows add to collection section
@@ -104,13 +104,12 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
104104
});
105105

106106
const showManageCollections = useCallback(() => {
107-
navigateTo({ selectedItemId: usageKey });
107+
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
108108
scheduleJumpToCollection();
109109
}, [
110110
scheduleJumpToCollection,
111-
openComponentInfoSidebar,
112111
usageKey,
113-
navigateTo,
112+
openItemSidebar,
114113
]);
115114

116115
const containerType = containerId ? getBlockType(containerId) : 'collection';

src/library-authoring/containers/ContainerCard.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ToastContext } from '@src/generic/toast-context';
1616
import { type ContainerHit, Highlight, PublishStatus } from '../../search-manager';
1717
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
1818
import { useLibraryContext } from '../common/context/LibraryContext';
19-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
19+
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
2020
import { useRemoveItemsFromCollection } from '../data/apiHooks';
2121
import { useLibraryRoutes } from '../routes';
2222
import messages from './messages';
@@ -245,7 +245,7 @@ type ContainerCardProps = {
245245
const ContainerCard = ({ hit } : ContainerCardProps) => {
246246
const { componentPickerMode } = useComponentPickerContext();
247247
const { showOnlyPublished } = useLibraryContext();
248-
const { openContainerInfoSidebar, sidebarItemInfo } = useSidebarContext();
248+
const { openContainerInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
249249

250250
const {
251251
blockType: itemType,
@@ -276,11 +276,11 @@ const ContainerCard = ({ hit } : ContainerCardProps) => {
276276
// without changing the URL
277277
openContainerInfoSidebar(containerKey);
278278
} else if (!doubleClicked) {
279-
navigateTo({ selectedItemId: containerKey });
279+
openItemSidebar(containerKey, SidebarBodyItemId.ContainerInfo);
280280
} else {
281281
navigateTo({ containerId: containerKey });
282282
}
283-
}, [containerKey, openContainerInfoSidebar, navigateTo]);
283+
}, [containerKey, openContainerInfoSidebar, openItemSidebar, navigateTo]);
284284

285285
return (
286286
<BaseCard

src/library-authoring/section-subsections/LibraryContainerChildren.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { Container } from '../data/api';
2323
import { ToastContext } from '../../generic/toast-context';
2424
import TagCount from '../../generic/tag-count';
2525
import { useLibraryRoutes } from '../routes';
26-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
26+
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
2727
import { useRunOnNextRender } from '../../utils';
2828
import { ContainerMenu } from '../containers/ContainerCard';
2929

@@ -46,8 +46,7 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
4646
const { showToast } = useContext(ToastContext);
4747
const updateMutation = useUpdateContainer(container.originalId, containerKey);
4848
const { showOnlyPublished } = useLibraryContext();
49-
const { navigateTo } = useLibraryRoutes();
50-
const { setSidebarAction } = useSidebarContext();
49+
const { setSidebarAction, openItemSidebar } = useSidebarContext();
5150

5251
const handleSaveDisplayName = async (newDisplayName: string) => {
5352
try {
@@ -67,10 +66,10 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
6766
setTimeout(() => setSidebarAction(SidebarActions.JumpToManageTags), 250);
6867
});
6968

70-
const jumpToManageTags = () => {
71-
navigateTo({ selectedItemId: container.originalId });
69+
const jumpToManageTags = useCallback(() => {
70+
openItemSidebar(container.originalId, SidebarBodyItemId.ContainerInfo);
7271
scheduleJumpToTags();
73-
};
72+
}, [openItemSidebar, scheduleJumpToTags, container.originalId]);
7473

7574
return (
7675
<>
@@ -127,7 +126,7 @@ export const LibraryContainerChildren = ({ containerKey, readOnly }: LibraryCont
127126
const [orderedChildren, setOrderedChildren] = useState<LibraryContainerMetadataWithUniqueId[]>([]);
128127
const { showOnlyPublished, readOnly: libReadOnly } = useLibraryContext();
129128
const { navigateTo } = useLibraryRoutes();
130-
const { sidebarItemInfo } = useSidebarContext();
129+
const { sidebarItemInfo, openItemSidebar } = useSidebarContext();
131130
const [activeDraggingId, setActiveDraggingId] = useState<string | null>(null);
132131
const orderMutator = useUpdateContainerChildren(containerKey);
133132
const { showToast } = useContext(ToastContext);
@@ -169,11 +168,11 @@ export const LibraryContainerChildren = ({ containerKey, readOnly }: LibraryCont
169168
const handleChildClick = useCallback((child: LibraryContainerMetadataWithUniqueId, numberOfClicks: number) => {
170169
const doubleClicked = numberOfClicks > 1;
171170
if (!doubleClicked) {
172-
navigateTo({ selectedItemId: child.originalId });
171+
openItemSidebar(child.originalId, SidebarBodyItemId.ContainerInfo);
173172
} else {
174173
navigateTo({ containerId: child.originalId });
175174
}
176-
}, [navigateTo]);
175+
}, [openItemSidebar, navigateTo]);
177176

178177
const getComponentStyle = useCallback((childId: string) => {
179178
const style: { marginBottom: string, borderRadius: string, outline?: string } = {

src/library-authoring/units/LibraryUnitBlocks.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ import {
2626
useUpdateXBlockFields,
2727
} from '../data/apiHooks';
2828
import { LibraryBlock } from '../LibraryBlock';
29-
import { useLibraryRoutes } from '../routes';
3029
import messages from './messages';
31-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
30+
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
3231
import { ToastContext } from '../../generic/toast-context';
3332
import { canEditComponent } from '../components/ComponentEditorModal';
3433
import { useRunOnNextRender } from '../../utils';
@@ -57,8 +56,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
5756
const intl = useIntl();
5857
const { showOnlyPublished } = useLibraryContext();
5958
const { showToast } = useContext(ToastContext);
60-
const { navigateTo } = useLibraryRoutes();
61-
const { setSidebarAction } = useSidebarContext();
59+
const { setSidebarAction, openItemSidebar } = useSidebarContext();
6260

6361
const updateMutation = useUpdateXBlockFields(block.originalId);
6462

@@ -84,7 +82,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
8482

8583
/* istanbul ignore next */
8684
const jumpToManageTags = () => {
87-
navigateTo({ selectedItemId: block.originalId });
85+
openItemSidebar(block.originalId, SidebarBodyItemId.ComponentInfo);
8886
scheduleJumpToTags();
8987
};
9088

@@ -132,19 +130,18 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
132130
/** ComponentBlock to render preview of given component under Unit */
133131
const ComponentBlock = ({ block, readOnly, isDragging }: ComponentBlockProps) => {
134132
const { showOnlyPublished } = useLibraryContext();
135-
const { navigateTo } = useLibraryRoutes();
136133

137134
const { openComponentEditor } = useLibraryContext();
138-
const { sidebarItemInfo } = useSidebarContext();
135+
const { sidebarItemInfo, openItemSidebar } = useSidebarContext();
139136

140137
const handleComponentSelection = useCallback((numberOfClicks: number) => {
141-
navigateTo({ selectedItemId: block.originalId });
138+
openItemSidebar(block.originalId, SidebarBodyItemId.ComponentInfo);
142139
const canEdit = canEditComponent(block.originalId);
143140
if (numberOfClicks > 1 && canEdit) {
144141
// Open editor on double click.
145142
openComponentEditor(block.originalId);
146143
}
147-
}, [block, navigateTo, canEditComponent, openComponentEditor]);
144+
}, [block, openItemSidebar, canEditComponent, openComponentEditor]);
148145

149146
useEffect(() => {
150147
if (block.isNew) {

0 commit comments

Comments
 (0)