diff --git a/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx b/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx index 223d73fa5cf432..27cff985534e8c 100644 --- a/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx +++ b/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx @@ -31,32 +31,18 @@ describe('PreviewSection', () => { const component =
{'component'}
; const left = 500; - it('should render close button in header', () => { - const showBackButton = false; - + it('should render back button and close button in header', () => { const { getByTestId } = render( - + ); expect(getByTestId(PREVIEW_SECTION_CLOSE_BUTTON_TEST_ID)).toBeInTheDocument(); - }); - - it('should render back button in header', () => { - const showBackButton = true; - - const { getByTestId } = render( - - - - ); - expect(getByTestId(PREVIEW_SECTION_BACK_BUTTON_TEST_ID)).toBeInTheDocument(); }); it('should render banner', () => { - const showBackButton = false; const title = 'test'; const banner: PreviewBanner = { title, @@ -66,12 +52,7 @@ describe('PreviewSection', () => { const { getByTestId, getByText } = render( - + ); diff --git a/packages/kbn-expandable-flyout/src/components/preview_section.tsx b/packages/kbn-expandable-flyout/src/components/preview_section.tsx index 7a49e2ca463ce7..bc0c1c2e9d93ae 100644 --- a/packages/kbn-expandable-flyout/src/components/preview_section.tsx +++ b/packages/kbn-expandable-flyout/src/components/preview_section.tsx @@ -68,10 +68,6 @@ interface PreviewSectionProps { * Left position used when rendering the panel */ leftPosition: number; - /** - * Display the back button in the header - */ - showBackButton: boolean; /** * Preview banner shown at the top of preview panel */ @@ -84,7 +80,6 @@ interface PreviewSectionProps { */ export const PreviewSection: React.FC = ({ component, - showBackButton, leftPosition, banner, }: PreviewSectionProps) => { @@ -103,7 +98,7 @@ export const PreviewSection: React.FC = ({ /> ); - const header = showBackButton ? ( + const header = ( = ({ {closeButton} - ) : ( - - {closeButton} - ); return ( diff --git a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts index dcfcf429e1086d..5c7b716b003b5d 100644 --- a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts +++ b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts @@ -7,6 +7,7 @@ */ import { useCallback, useMemo } from 'react'; +import { useHistory } from 'react-router-dom'; import { REDUX_ID_FOR_MEMORY_STORAGE } from '../constants'; import { useExpandableFlyoutContext } from '../context'; import { @@ -30,6 +31,7 @@ export type { ExpandableFlyoutApi }; */ export const useExpandableFlyoutApi = () => { const dispatch = useDispatch(); + const history = useHistory(); const { urlKey } = useExpandableFlyoutContext(); // if no urlKey is provided, we are in memory storage mode and use the reserved word 'memory' @@ -75,10 +77,13 @@ export const useExpandableFlyoutApi = () => { [dispatch, id] ); - const previousPreviewPanel = useCallback( - () => dispatch(previousPreviewPanelAction({ id })), - [dispatch, id] - ); + const previousPreviewPanel = useCallback(() => { + dispatch(previousPreviewPanelAction({ id })); + + if (id !== REDUX_ID_FOR_MEMORY_STORAGE) { + history.goBack(); + } + }, [dispatch, id, history]); const closePanels = useCallback(() => dispatch(closePanelsAction({ id })), [dispatch, id]); diff --git a/packages/kbn-expandable-flyout/src/index.tsx b/packages/kbn-expandable-flyout/src/index.tsx index 7bcfa050fbfa55..ba11b597e0b065 100644 --- a/packages/kbn-expandable-flyout/src/index.tsx +++ b/packages/kbn-expandable-flyout/src/index.tsx @@ -70,7 +70,6 @@ export const ExpandableFlyout: React.FC = ({ ? mostRecentPreview?.params?.banner : undefined; - const showBackButton = !!preview && preview.length > 1; const previewSection = useMemo( () => registeredPanels.find((panel) => panel.key === mostRecentPreview?.id), [mostRecentPreview, registeredPanels] @@ -129,7 +128,6 @@ export const ExpandableFlyout: React.FC = ({ {showPreview ? ( diff --git a/packages/kbn-expandable-flyout/src/provider.test.tsx b/packages/kbn-expandable-flyout/src/provider.test.tsx index c6246eff9fa32a..f47b538ed851ea 100644 --- a/packages/kbn-expandable-flyout/src/provider.test.tsx +++ b/packages/kbn-expandable-flyout/src/provider.test.tsx @@ -67,7 +67,7 @@ describe('UrlSynchronizer', () => { expect(mockSet).toHaveBeenCalledWith('urlKey', { left: undefined, right: undefined, - preview: undefined, + preview: [undefined], }); }); diff --git a/packages/kbn-expandable-flyout/src/provider.tsx b/packages/kbn-expandable-flyout/src/provider.tsx index d88df39ab61eb6..7ad9ddd084963d 100644 --- a/packages/kbn-expandable-flyout/src/provider.tsx +++ b/packages/kbn-expandable-flyout/src/provider.tsx @@ -49,14 +49,14 @@ export const UrlSynchronizer = () => { dispatch( urlChangedAction({ ...currentValue, - preview: currentValue?.preview?.[0], + preview: currentValue?.preview?.at(-1), id: urlKey, }) ); } const subscription = urlStorage.change$(urlKey).subscribe((value) => { - dispatch(urlChangedAction({ ...value, preview: value?.preview?.[0], id: urlKey })); + dispatch(urlChangedAction({ ...value, preview: value?.preview?.at(-1), id: urlKey })); }); return () => subscription.unsubscribe(); @@ -68,7 +68,7 @@ export const UrlSynchronizer = () => { } const { left, right, preview } = panels; - urlStorage.set(urlKey, { left, right, preview }); + urlStorage.set(urlKey, { left, right, preview: [preview?.at(-1)] }); }, [needsSync, panels, urlKey, urlStorage]); return null; diff --git a/packages/kbn-expandable-flyout/src/reducer.test.ts b/packages/kbn-expandable-flyout/src/reducer.test.ts index df03d9277f946b..7f0a5c289e2951 100644 --- a/packages/kbn-expandable-flyout/src/reducer.test.ts +++ b/packages/kbn-expandable-flyout/src/reducer.test.ts @@ -622,7 +622,7 @@ describe('reducer', () => { const action = previousPreviewPanelAction({ id: id1 }); const newState: State = reducer(state, action); - expect(newState).toEqual({ ...initialState, needsSync: true }); + expect(newState).toEqual({ ...initialState, needsSync: false }); }); it(`should return unmodified state when previous preview panel when no preview panel exist`, () => { @@ -638,7 +638,7 @@ describe('reducer', () => { const action = previousPreviewPanelAction({ id: id1 }); const newState: State = reducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ ...state, needsSync: false }); }); it('should remove only last preview panel', () => { @@ -662,7 +662,7 @@ describe('reducer', () => { preview: [previewPanel1], }, }, - needsSync: true, + needsSync: false, }); }); @@ -687,7 +687,7 @@ describe('reducer', () => { preview: [previewPanel1], }, }, - needsSync: true, + needsSync: false, }); }); }); diff --git a/packages/kbn-expandable-flyout/src/reducer.ts b/packages/kbn-expandable-flyout/src/reducer.ts index 617ad5e3a7c952..32465f554ab7fd 100644 --- a/packages/kbn-expandable-flyout/src/reducer.ts +++ b/packages/kbn-expandable-flyout/src/reducer.ts @@ -7,6 +7,7 @@ */ import { createReducer } from '@reduxjs/toolkit'; +import deepEqual from 'react-fast-compare'; import { openPanelsAction, openLeftPanelAction, @@ -69,7 +70,11 @@ export const reducer = createReducer(initialState, (builder) => { builder.addCase(openPreviewPanelAction, (state, { payload: { preview, id } }) => { if (id in state.byId) { if (state.byId[id].preview) { - state.byId[id].preview?.push(preview); + const previewIdenticalToLastOne = deepEqual(preview, state.byId[id].preview?.at(-1)); + // Only append preview when it does not match the last item in state.byId[id].preview + if (!previewIdenticalToLastOne) { + state.byId[id].preview?.push(preview); + } } else { state.byId[id].preview = preview ? [preview] : undefined; } @@ -89,7 +94,8 @@ export const reducer = createReducer(initialState, (builder) => { state.byId[id].preview?.pop(); } - state.needsSync = true; + // if state is stored in url, click go back in preview should utilize browser history + state.needsSync = false; }); builder.addCase(closePanelsAction, (state, { payload: { id } }) => {