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.
This commit is contained in:
committed by
GitHub
parent
dd2853900b
commit
ae82486d72
@@ -398,7 +398,7 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
});
|
||||
}, 10000);
|
||||
|
||||
it('should open and close the component sidebar', async () => {
|
||||
it('should open, close and re-open the component sidebar', async () => {
|
||||
const mockResult0 = { ...mockResult }.results[0].hits[0];
|
||||
const displayName = 'Introduction to Testing';
|
||||
expect(mockResult0.display_name).toStrictEqual(displayName);
|
||||
@@ -416,6 +416,10 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
fireEvent.click(closeButton);
|
||||
|
||||
await waitFor(() => expect(screen.queryByTestId('library-sidebar')).not.toBeInTheDocument());
|
||||
|
||||
fireEvent.click((await screen.findAllByText(displayName))[0]);
|
||||
|
||||
await waitFor(() => expect(screen.queryByTestId('library-sidebar')).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it('should open component sidebar, showing manage tab on clicking add to collection menu item - component', async () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useParams } from 'react-router-dom';
|
||||
import { useStateWithUrlSearchParam } from '../../../hooks';
|
||||
import { useComponentPickerContext } from './ComponentPickerContext';
|
||||
import { useLibraryContext } from './LibraryContext';
|
||||
import { useLibraryRoutes } from '../../routes';
|
||||
|
||||
export enum SidebarBodyItemId {
|
||||
AddContent = 'add-content',
|
||||
@@ -86,6 +87,7 @@ export type SidebarContextData = {
|
||||
openCollectionInfoSidebar: (collectionId: string) => void;
|
||||
openComponentInfoSidebar: (usageKey: string) => void;
|
||||
openContainerInfoSidebar: (usageKey: string) => void;
|
||||
openItemSidebar: (selectedItemId: string, type: SidebarBodyItemId) => void;
|
||||
sidebarItemInfo?: SidebarItemInfo;
|
||||
sidebarAction: SidebarActions;
|
||||
setSidebarAction: (action: SidebarActions) => void;
|
||||
@@ -172,6 +174,12 @@ export const SidebarProvider = ({
|
||||
});
|
||||
}, []);
|
||||
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
const openItemSidebar = useCallback((selectedItemId: string, type: SidebarBodyItemId) => {
|
||||
navigateTo({ selectedItemId });
|
||||
setSidebarItemInfo({ id: selectedItemId, type });
|
||||
}, [navigateTo, setSidebarItemInfo]);
|
||||
|
||||
// Set the initial sidebar state based on the URL parameters and context.
|
||||
const { selectedItemId } = useParams();
|
||||
const { collectionId, containerId } = useLibraryContext();
|
||||
@@ -236,6 +244,7 @@ export const SidebarProvider = ({
|
||||
sidebarItemInfo,
|
||||
openCollectionInfoSidebar,
|
||||
openContainerInfoSidebar,
|
||||
openItemSidebar,
|
||||
sidebarAction,
|
||||
setSidebarAction,
|
||||
resetSidebarAction,
|
||||
@@ -254,6 +263,7 @@ export const SidebarProvider = ({
|
||||
sidebarItemInfo,
|
||||
openCollectionInfoSidebar,
|
||||
openContainerInfoSidebar,
|
||||
openItemSidebar,
|
||||
sidebarAction,
|
||||
setSidebarAction,
|
||||
resetSidebarAction,
|
||||
@@ -281,6 +291,7 @@ export function useSidebarContext(): SidebarContextData {
|
||||
openComponentInfoSidebar: () => {},
|
||||
openCollectionInfoSidebar: () => {},
|
||||
openContainerInfoSidebar: () => {},
|
||||
openItemSidebar: () => {},
|
||||
sidebarAction: SidebarActions.None,
|
||||
setSidebarAction: () => {},
|
||||
resetSidebarAction: () => {},
|
||||
|
||||
@@ -116,7 +116,7 @@ type CollectionCardProps = {
|
||||
const CollectionCard = ({ hit } : CollectionCardProps) => {
|
||||
const { componentPickerMode } = useComponentPickerContext();
|
||||
const { setCollectionId, showOnlyPublished } = useLibraryContext();
|
||||
const { openCollectionInfoSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
const { openCollectionInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
|
||||
const {
|
||||
type: itemType,
|
||||
@@ -144,7 +144,7 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
|
||||
if (doubleClicked) {
|
||||
navigateTo({ collectionId });
|
||||
} else {
|
||||
navigateTo({ selectedItemId: collectionId });
|
||||
openItemSidebar(collectionId, SidebarBodyItemId.CollectionInfo);
|
||||
}
|
||||
|
||||
// In component picker mode, we want to open the sidebar or the collection
|
||||
@@ -154,7 +154,7 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
|
||||
} else {
|
||||
openCollectionInfoSidebar(collectionId);
|
||||
}
|
||||
}, [collectionId, navigateTo, openCollectionInfoSidebar, setCollectionId, componentPickerMode]);
|
||||
}, [collectionId, navigateTo, openItemSidebar, openCollectionInfoSidebar, setCollectionId, componentPickerMode]);
|
||||
|
||||
return (
|
||||
<BaseCard
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
initializeMocks,
|
||||
} from '../../testUtils';
|
||||
import { LibraryProvider } from '../common/context/LibraryContext';
|
||||
import { SidebarProvider } from '../common/context/SidebarContext';
|
||||
import { getClipboardUrl } from '../../generic/data/api';
|
||||
import { ContentHit } from '../../search-manager';
|
||||
import ComponentCard from './ComponentCard';
|
||||
@@ -53,7 +54,9 @@ const render = () => baseRender(<ComponentCard hit={contentHit} />, {
|
||||
params: { libraryId },
|
||||
extraWrapper: ({ children }) => (
|
||||
<LibraryProvider libraryId={libraryId}>
|
||||
{ children }
|
||||
<SidebarProvider>
|
||||
{ children }
|
||||
</SidebarProvider>
|
||||
</LibraryProvider>
|
||||
),
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@ import { type ContentHit, PublishStatus } from '../../search-manager';
|
||||
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
|
||||
import { useLibraryContext } from '../common/context/LibraryContext';
|
||||
import { SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { useLibraryRoutes } from '../routes';
|
||||
import AddComponentWidget from './AddComponentWidget';
|
||||
import BaseCard from './BaseCard';
|
||||
import { ComponentMenu } from './ComponentMenu';
|
||||
@@ -18,7 +17,7 @@ type ComponentCardProps = {
|
||||
|
||||
const ComponentCard = ({ hit }: ComponentCardProps) => {
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
const { openComponentInfoSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
const { openComponentInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
const { componentPickerMode } = useComponentPickerContext();
|
||||
|
||||
const {
|
||||
@@ -35,16 +34,15 @@ const ComponentCard = ({ hit }: ComponentCardProps) => {
|
||||
showOnlyPublished ? formatted.published?.displayName : formatted.displayName
|
||||
) ?? '';
|
||||
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
const selectComponent = useCallback(() => {
|
||||
if (!componentPickerMode) {
|
||||
navigateTo({ selectedItemId: usageKey });
|
||||
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
|
||||
} else {
|
||||
// In component picker mode, we want to open the sidebar
|
||||
// without changing the URL
|
||||
openComponentInfoSidebar(usageKey);
|
||||
}
|
||||
}, [usageKey, navigateTo, openComponentInfoSidebar]);
|
||||
}, [usageKey, openItemSidebar, openComponentInfoSidebar, componentPickerMode]);
|
||||
|
||||
const selected = sidebarItemInfo?.type === SidebarBodyItemId.ComponentInfo
|
||||
&& sidebarItemInfo.id === usageKey;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MoreVert } from '@openedx/paragon/icons';
|
||||
|
||||
import { getBlockType } from '@src/generic/key-utils';
|
||||
import { useLibraryContext } from '../common/context/LibraryContext';
|
||||
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { useClipboard } from '../../generic/clipboard';
|
||||
import { ToastContext } from '../../generic/toast-context';
|
||||
import {
|
||||
@@ -36,11 +36,11 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
|
||||
|
||||
const {
|
||||
sidebarItemInfo,
|
||||
openComponentInfoSidebar,
|
||||
closeLibrarySidebar,
|
||||
setSidebarAction,
|
||||
openItemSidebar,
|
||||
} = useSidebarContext();
|
||||
const { navigateTo, insideCollection } = useLibraryRoutes();
|
||||
const { insideCollection } = useLibraryRoutes();
|
||||
|
||||
const canEdit = usageKey && canEditComponent(usageKey);
|
||||
const { showToast } = useContext(ToastContext);
|
||||
@@ -93,9 +93,9 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
|
||||
};
|
||||
|
||||
const handleEdit = useCallback(() => {
|
||||
navigateTo({ selectedItemId: usageKey });
|
||||
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
|
||||
openComponentEditor(usageKey);
|
||||
}, [usageKey, navigateTo]);
|
||||
}, [usageKey, openItemSidebar, openComponentEditor]);
|
||||
|
||||
const scheduleJumpToCollection = useRunOnNextRender(() => {
|
||||
// TODO: Ugly hack to make sure sidebar shows add to collection section
|
||||
@@ -104,13 +104,12 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
|
||||
});
|
||||
|
||||
const showManageCollections = useCallback(() => {
|
||||
navigateTo({ selectedItemId: usageKey });
|
||||
openItemSidebar(usageKey, SidebarBodyItemId.ComponentInfo);
|
||||
scheduleJumpToCollection();
|
||||
}, [
|
||||
scheduleJumpToCollection,
|
||||
openComponentInfoSidebar,
|
||||
usageKey,
|
||||
navigateTo,
|
||||
openItemSidebar,
|
||||
]);
|
||||
|
||||
const containerType = containerId ? getBlockType(containerId) : 'collection';
|
||||
|
||||
@@ -16,7 +16,7 @@ import { ToastContext } from '@src/generic/toast-context';
|
||||
import { type ContainerHit, Highlight, PublishStatus } from '../../search-manager';
|
||||
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
|
||||
import { useLibraryContext } from '../common/context/LibraryContext';
|
||||
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { useRemoveItemsFromCollection } from '../data/apiHooks';
|
||||
import { useLibraryRoutes } from '../routes';
|
||||
import messages from './messages';
|
||||
@@ -245,7 +245,7 @@ type ContainerCardProps = {
|
||||
const ContainerCard = ({ hit } : ContainerCardProps) => {
|
||||
const { componentPickerMode } = useComponentPickerContext();
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
const { openContainerInfoSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
const { openContainerInfoSidebar, openItemSidebar, sidebarItemInfo } = useSidebarContext();
|
||||
|
||||
const {
|
||||
blockType: itemType,
|
||||
@@ -276,11 +276,11 @@ const ContainerCard = ({ hit } : ContainerCardProps) => {
|
||||
// without changing the URL
|
||||
openContainerInfoSidebar(containerKey);
|
||||
} else if (!doubleClicked) {
|
||||
navigateTo({ selectedItemId: containerKey });
|
||||
openItemSidebar(containerKey, SidebarBodyItemId.ContainerInfo);
|
||||
} else {
|
||||
navigateTo({ containerId: containerKey });
|
||||
}
|
||||
}, [containerKey, openContainerInfoSidebar, navigateTo]);
|
||||
}, [containerKey, openContainerInfoSidebar, openItemSidebar, navigateTo]);
|
||||
|
||||
return (
|
||||
<BaseCard
|
||||
|
||||
@@ -23,7 +23,7 @@ import { Container } from '../data/api';
|
||||
import { ToastContext } from '../../generic/toast-context';
|
||||
import TagCount from '../../generic/tag-count';
|
||||
import { useLibraryRoutes } from '../routes';
|
||||
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { useRunOnNextRender } from '../../utils';
|
||||
import { ContainerMenu } from '../containers/ContainerCard';
|
||||
|
||||
@@ -46,8 +46,7 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
|
||||
const { showToast } = useContext(ToastContext);
|
||||
const updateMutation = useUpdateContainer(container.originalId, containerKey);
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
const { setSidebarAction } = useSidebarContext();
|
||||
const { setSidebarAction, openItemSidebar } = useSidebarContext();
|
||||
|
||||
const handleSaveDisplayName = async (newDisplayName: string) => {
|
||||
try {
|
||||
@@ -67,10 +66,10 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
|
||||
setTimeout(() => setSidebarAction(SidebarActions.JumpToManageTags), 250);
|
||||
});
|
||||
|
||||
const jumpToManageTags = () => {
|
||||
navigateTo({ selectedItemId: container.originalId });
|
||||
const jumpToManageTags = useCallback(() => {
|
||||
openItemSidebar(container.originalId, SidebarBodyItemId.ContainerInfo);
|
||||
scheduleJumpToTags();
|
||||
};
|
||||
}, [openItemSidebar, scheduleJumpToTags, container.originalId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -127,7 +126,7 @@ export const LibraryContainerChildren = ({ containerKey, readOnly }: LibraryCont
|
||||
const [orderedChildren, setOrderedChildren] = useState<LibraryContainerMetadataWithUniqueId[]>([]);
|
||||
const { showOnlyPublished, readOnly: libReadOnly } = useLibraryContext();
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
const { sidebarItemInfo } = useSidebarContext();
|
||||
const { sidebarItemInfo, openItemSidebar } = useSidebarContext();
|
||||
const [activeDraggingId, setActiveDraggingId] = useState<string | null>(null);
|
||||
const orderMutator = useUpdateContainerChildren(containerKey);
|
||||
const { showToast } = useContext(ToastContext);
|
||||
@@ -169,11 +168,11 @@ export const LibraryContainerChildren = ({ containerKey, readOnly }: LibraryCont
|
||||
const handleChildClick = useCallback((child: LibraryContainerMetadataWithUniqueId, numberOfClicks: number) => {
|
||||
const doubleClicked = numberOfClicks > 1;
|
||||
if (!doubleClicked) {
|
||||
navigateTo({ selectedItemId: child.originalId });
|
||||
openItemSidebar(child.originalId, SidebarBodyItemId.ContainerInfo);
|
||||
} else {
|
||||
navigateTo({ containerId: child.originalId });
|
||||
}
|
||||
}, [navigateTo]);
|
||||
}, [openItemSidebar, navigateTo]);
|
||||
|
||||
const getComponentStyle = useCallback((childId: string) => {
|
||||
const style: { marginBottom: string, borderRadius: string, outline?: string } = {
|
||||
|
||||
@@ -26,9 +26,8 @@ import {
|
||||
useUpdateXBlockFields,
|
||||
} from '../data/apiHooks';
|
||||
import { LibraryBlock } from '../LibraryBlock';
|
||||
import { useLibraryRoutes } from '../routes';
|
||||
import messages from './messages';
|
||||
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
|
||||
import { ToastContext } from '../../generic/toast-context';
|
||||
import { canEditComponent } from '../components/ComponentEditorModal';
|
||||
import { useRunOnNextRender } from '../../utils';
|
||||
@@ -57,8 +56,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
|
||||
const intl = useIntl();
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
const { showToast } = useContext(ToastContext);
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
const { setSidebarAction } = useSidebarContext();
|
||||
const { setSidebarAction, openItemSidebar } = useSidebarContext();
|
||||
|
||||
const updateMutation = useUpdateXBlockFields(block.originalId);
|
||||
|
||||
@@ -84,7 +82,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
|
||||
|
||||
/* istanbul ignore next */
|
||||
const jumpToManageTags = () => {
|
||||
navigateTo({ selectedItemId: block.originalId });
|
||||
openItemSidebar(block.originalId, SidebarBodyItemId.ComponentInfo);
|
||||
scheduleJumpToTags();
|
||||
};
|
||||
|
||||
@@ -132,19 +130,18 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
|
||||
/** ComponentBlock to render preview of given component under Unit */
|
||||
const ComponentBlock = ({ block, readOnly, isDragging }: ComponentBlockProps) => {
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
const { navigateTo } = useLibraryRoutes();
|
||||
|
||||
const { openComponentEditor } = useLibraryContext();
|
||||
const { sidebarItemInfo } = useSidebarContext();
|
||||
const { sidebarItemInfo, openItemSidebar } = useSidebarContext();
|
||||
|
||||
const handleComponentSelection = useCallback((numberOfClicks: number) => {
|
||||
navigateTo({ selectedItemId: block.originalId });
|
||||
openItemSidebar(block.originalId, SidebarBodyItemId.ComponentInfo);
|
||||
const canEdit = canEditComponent(block.originalId);
|
||||
if (numberOfClicks > 1 && canEdit) {
|
||||
// Open editor on double click.
|
||||
openComponentEditor(block.originalId);
|
||||
}
|
||||
}, [block, navigateTo, canEditComponent, openComponentEditor]);
|
||||
}, [block, openItemSidebar, canEditComponent, openComponentEditor]);
|
||||
|
||||
useEffect(() => {
|
||||
if (block.isNew) {
|
||||
|
||||
Reference in New Issue
Block a user