diff --git a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx index d34e3c112d9fb..9f48783fde24d 100644 --- a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx @@ -54,10 +54,10 @@ describe('useCasesBreadcrumbs', () => { describe('set all_cases breadcrumbs', () => { it('call setBreadcrumbs with all items', async () => { renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.cases), { wrapper }); - expect(mockSetBreadcrumbs).toHaveBeenCalledWith([ - { href: '/test', onClick: expect.any(Function), text: 'Test' }, - { text: 'Cases' }, - ]); + expect(mockSetBreadcrumbs).toHaveBeenCalledWith( + [{ href: '/test', onClick: expect.any(Function), text: 'Test' }, { text: 'Cases' }], + { project: { value: [] } } + ); expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([]); }); @@ -76,11 +76,14 @@ describe('useCasesBreadcrumbs', () => { describe('set create_case breadcrumbs', () => { it('call setBreadcrumbs with all items', () => { renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.casesCreate), { wrapper }); - expect(mockSetBreadcrumbs).toHaveBeenCalledWith([ - { href: '/test', onClick: expect.any(Function), text: 'Test' }, - { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, - { text: 'Create' }, - ]); + expect(mockSetBreadcrumbs).toHaveBeenCalledWith( + [ + { href: '/test', onClick: expect.any(Function), text: 'Test' }, + { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, + { text: 'Create' }, + ], + { project: { value: [] } } + ); expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([]); }); @@ -100,11 +103,14 @@ describe('useCasesBreadcrumbs', () => { const title = 'Fake Title'; it('call setBreadcrumbs with title', () => { renderHook(() => useCasesTitleBreadcrumbs(title), { wrapper }); - expect(mockSetBreadcrumbs).toHaveBeenCalledWith([ - { href: '/test', onClick: expect.any(Function), text: 'Test' }, - { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, - { text: title }, - ]); + expect(mockSetBreadcrumbs).toHaveBeenCalledWith( + [ + { href: '/test', onClick: expect.any(Function), text: 'Test' }, + { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, + { text: title }, + ], + { project: { value: [{ text: title }] } } + ); expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([{ text: title }]); }); @@ -123,11 +129,14 @@ describe('useCasesBreadcrumbs', () => { describe('set settings breadcrumbs', () => { it('call setBreadcrumbs with all items', () => { renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.casesConfigure), { wrapper }); - expect(mockSetBreadcrumbs).toHaveBeenCalledWith([ - { href: '/test', onClick: expect.any(Function), text: 'Test' }, - { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, - { text: 'Settings' }, - ]); + expect(mockSetBreadcrumbs).toHaveBeenCalledWith( + [ + { href: '/test', onClick: expect.any(Function), text: 'Test' }, + { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, + { text: 'Settings' }, + ], + { project: { value: [] } } + ); expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([]); }); diff --git a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts index 6312918842ba3..1750cd54e7d53 100644 --- a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts +++ b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts @@ -29,34 +29,48 @@ function getTitleFromBreadcrumbs(breadcrumbs: ChromeBreadcrumb[]): string[] { return breadcrumbs.map(({ text }) => text?.toString() ?? '').reverse(); } +const useGetBreadcrumbsWithNavigation = () => { + const { navigateToUrl } = useKibana().services.application; + + return useCallback( + (breadcrumbs: ChromeBreadcrumb[]): ChromeBreadcrumb[] => { + return breadcrumbs.map((breadcrumb) => { + const { href, onClick } = breadcrumb; + if (!href || onClick) { + return breadcrumb; + } + return { + ...breadcrumb, + onClick: (event) => { + if (event) { + event.preventDefault(); + } + navigateToUrl(href); + }, + }; + }); + }, + [navigateToUrl] + ); +}; + const useApplyBreadcrumbs = () => { - const { - chrome: { docTitle, setBreadcrumbs }, - application: { navigateToUrl }, - } = useKibana().services; + const { docTitle, setBreadcrumbs } = useKibana().services.chrome; + const getBreadcrumbsWithNavigation = useGetBreadcrumbsWithNavigation(); + return useCallback( - (breadcrumbs: ChromeBreadcrumb[]) => { - docTitle.change(getTitleFromBreadcrumbs(breadcrumbs)); - setBreadcrumbs( - breadcrumbs.map((breadcrumb) => { - const { href, onClick } = breadcrumb; - return { - ...breadcrumb, - ...(href && !onClick - ? { - onClick: (event) => { - if (event) { - event.preventDefault(); - } - navigateToUrl(href); - }, - } - : {}), - }; - }) - ); + ( + leadingRawBreadcrumbs: ChromeBreadcrumb[], + trailingRawBreadcrumbs: ChromeBreadcrumb[] = [] + ) => { + const leadingBreadcrumbs = getBreadcrumbsWithNavigation(leadingRawBreadcrumbs); + const trailingBreadcrumbs = getBreadcrumbsWithNavigation(trailingRawBreadcrumbs); + const allBreadcrumbs = [...leadingBreadcrumbs, ...trailingBreadcrumbs]; + + docTitle.change(getTitleFromBreadcrumbs(allBreadcrumbs)); + setBreadcrumbs(allBreadcrumbs, { project: { value: trailingBreadcrumbs } }); }, - [docTitle, setBreadcrumbs, navigateToUrl] + [docTitle, setBreadcrumbs, getBreadcrumbsWithNavigation] ); }; @@ -103,9 +117,8 @@ export const useCasesTitleBreadcrumbs = (caseTitle: string) => { text: casesBreadcrumbTitle[CasesDeepLinkId.cases], href: getAppUrl({ deepLinkId: CasesDeepLinkId.cases }), }, - titleBreadcrumb, ]; - applyBreadcrumbs(casesBreadcrumbs); + applyBreadcrumbs(casesBreadcrumbs, [titleBreadcrumb]); KibanaServices.get().serverless?.setBreadcrumbs([titleBreadcrumb]); }, [caseTitle, appTitle, getAppUrl, applyBreadcrumbs]); };