Skip to content

Commit

Permalink
[Serverless/Breadcrumbs] Use EuiBreadcrumbs instead of `EuiHeaderBr…
Browse files Browse the repository at this point in the history
…eadcrumbs` (elastic#169838)

## Summary

fix elastic#166593


https://github.com/elastic/kibana/assets/7784120/2569007b-92b6-47d0-a893-8747fbf17d2b

- "Projects" link removed, now it is part of breadcrumb. This also makes
the header more responsive as we get the flexibility from the
breadcrumbs.
- Added "View all projects"
- Added "Manage project" link
  • Loading branch information
Dosant authored and delanni committed Nov 6, 2023
1 parent b25a8d5 commit c4c2173
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,11 @@ export class ChromeService {
projectNavigation.setProjectName(projectName);
};

const setProjectUrl = (projectUrl: string) => {
validateChromeStyle();
projectNavigation.setProjectUrl(projectUrl);
};

const isIE = () => {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE '); // IE 10 or older
Expand Down Expand Up @@ -387,8 +392,6 @@ export class ChromeService {
loadingCount$={http.getLoadingCount$()}
headerBanner$={headerBanner$.pipe(takeUntil(this.stop$))}
homeHref$={projectNavigation.getProjectHome$()}
projectsUrl$={projectNavigation.getProjectsUrl$()}
projectName$={projectNavigation.getProjectName$()}
docLinks={docLinks}
kibanaVersion={injectedMetadata.getKibanaVersion()}
prependBasePath={http.basePath.prepend}
Expand Down Expand Up @@ -521,6 +524,7 @@ export class ChromeService {
project: {
setHome: setProjectHome,
setProjectsUrl,
setProjectUrl,
setProjectName,
setNavigation: setProjectNavigation,
setSideNavComponent: setProjectSideNavComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,40 @@
* Side Public License, v 1.
*/

import { EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui';
import {
AppDeepLinkId,
ChromeProjectBreadcrumb,
ChromeProjectNavigationNode,
ChromeSetProjectBreadcrumbsParams,
ChromeBreadcrumb,
} from '@kbn/core-chrome-browser';
import { createHomeBreadcrumb } from './home_breadcrumbs';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';

export function buildBreadcrumbs({
homeHref,
projectsUrl,
projectName,
projectUrl,
projectBreadcrumbs,
activeNodes,
chromeBreadcrumbs,
}: {
homeHref: string;
projectsUrl?: string;
projectName?: string;
projectUrl?: string;
projectBreadcrumbs: {
breadcrumbs: ChromeProjectBreadcrumb[];
params: ChromeSetProjectBreadcrumbsParams;
};
chromeBreadcrumbs: ChromeBreadcrumb[];
activeNodes: ChromeProjectNavigationNode[][];
}): ChromeProjectBreadcrumb[] {
const homeBreadcrumb = createHomeBreadcrumb({
homeHref,
});
const rootCrumb = buildRootCrumb({ projectsUrl, projectName, projectUrl });

if (projectBreadcrumbs.params.absolute) {
return [homeBreadcrumb, ...projectBreadcrumbs.breadcrumbs];
return [rootCrumb, ...projectBreadcrumbs.breadcrumbs];
}

// breadcrumbs take the first active path
Expand All @@ -52,7 +57,7 @@ export function buildBreadcrumbs({

// if there are project breadcrumbs set, use them
if (projectBreadcrumbs.breadcrumbs.length !== 0) {
return [homeBreadcrumb, ...navBreadcrumbs, ...projectBreadcrumbs.breadcrumbs];
return [rootCrumb, ...navBreadcrumbs, ...projectBreadcrumbs.breadcrumbs];
}

// otherwise try to merge legacy breadcrumbs with navigational project breadcrumbs using deeplinkid
Expand All @@ -70,12 +75,50 @@ export function buildBreadcrumbs({
}

if (chromeBreadcrumbStartIndex === -1) {
return [homeBreadcrumb, ...navBreadcrumbs];
return [rootCrumb, ...navBreadcrumbs];
} else {
return [
homeBreadcrumb,
rootCrumb,
...navBreadcrumbs.slice(0, navBreadcrumbEndIndex),
...chromeBreadcrumbs.slice(chromeBreadcrumbStartIndex),
];
}
}

function buildRootCrumb({
projectsUrl,
projectName,
projectUrl,
}: {
projectsUrl?: string;
projectName?: string;
projectUrl?: string;
}): ChromeProjectBreadcrumb {
return {
text:
projectName ??
i18n.translate('core.ui.primaryNav.cloud.projectLabel', {
defaultMessage: 'Project',
}),
popoverContent: (
<EuiContextMenuPanel
size="s"
items={[
<EuiContextMenuItem key="project" href={projectUrl} icon={'gear'}>
<FormattedMessage
id="core.ui.primaryNav.cloud.linkToProject"
defaultMessage="Manage project"
/>
</EuiContextMenuItem>,
<EuiContextMenuItem key="projects" href={projectsUrl} icon={'grid'}>
<FormattedMessage
id="core.ui.primaryNav.cloud.linkToAllProjects"
defaultMessage="View all projects"
/>
</EuiContextMenuItem>,
]}
/>
),
popoverProps: { panelPaddingSize: 'none' },
};
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,35 @@ describe('breadcrumbs', () => {
expect(breadcrumbs).toMatchInlineSnapshot(`
Array [
Object {
"data-test-subj": "breadcrumb-home",
"href": "/",
"text": <EuiIcon
type="home"
"popoverContent": <EuiContextMenuPanel
items={
Array [
<EuiContextMenuItem
icon="gear"
>
<FormattedMessage
defaultMessage="Manage project"
id="core.ui.primaryNav.cloud.linkToProject"
values={Object {}}
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
icon="grid"
>
<FormattedMessage
defaultMessage="View all projects"
id="core.ui.primaryNav.cloud.linkToAllProjects"
values={Object {}}
/>
</EuiContextMenuItem>,
]
}
size="s"
/>,
"title": "Home",
"popoverProps": Object {
"panelPaddingSize": "none",
},
"text": "Project",
},
Object {
"deepLinkId": "navItem1",
Expand Down Expand Up @@ -125,12 +148,35 @@ describe('breadcrumbs', () => {
expect(breadcrumbs).toMatchInlineSnapshot(`
Array [
Object {
"data-test-subj": "breadcrumb-home",
"href": "/",
"text": <EuiIcon
type="home"
"popoverContent": <EuiContextMenuPanel
items={
Array [
<EuiContextMenuItem
icon="gear"
>
<FormattedMessage
defaultMessage="Manage project"
id="core.ui.primaryNav.cloud.linkToProject"
values={Object {}}
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
icon="grid"
>
<FormattedMessage
defaultMessage="View all projects"
id="core.ui.primaryNav.cloud.linkToAllProjects"
values={Object {}}
/>
</EuiContextMenuItem>,
]
}
size="s"
/>,
"title": "Home",
"popoverProps": Object {
"panelPaddingSize": "none",
},
"text": "Project",
},
Object {
"href": "/custom1",
Expand Down Expand Up @@ -158,12 +204,35 @@ describe('breadcrumbs', () => {
expect(breadcrumbs).toMatchInlineSnapshot(`
Array [
Object {
"data-test-subj": "breadcrumb-home",
"href": "/",
"text": <EuiIcon
type="home"
"popoverContent": <EuiContextMenuPanel
items={
Array [
<EuiContextMenuItem
icon="gear"
>
<FormattedMessage
defaultMessage="Manage project"
id="core.ui.primaryNav.cloud.linkToProject"
values={Object {}}
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
icon="grid"
>
<FormattedMessage
defaultMessage="View all projects"
id="core.ui.primaryNav.cloud.linkToAllProjects"
values={Object {}}
/>
</EuiContextMenuItem>,
]
}
size="s"
/>,
"title": "Home",
"popoverProps": Object {
"panelPaddingSize": "none",
},
"text": "Project",
},
Object {
"deepLinkId": "navItem1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class ProjectNavigationService {
private projectHome$ = new BehaviorSubject<string | undefined>(undefined);
private projectsUrl$ = new BehaviorSubject<string | undefined>(undefined);
private projectName$ = new BehaviorSubject<string | undefined>(undefined);
private projectUrl$ = new BehaviorSubject<string | undefined>(undefined);
private projectNavigation$ = new BehaviorSubject<ChromeProjectNavigation | undefined>(undefined);
private activeNodes$ = new BehaviorSubject<ChromeProjectNavigationNode[][]>([]);
private projectNavigationNavTreeFlattened: Record<string, ChromeProjectNavigationNode> = {};
Expand Down Expand Up @@ -106,6 +107,9 @@ export class ProjectNavigationService {
getProjectName$: () => {
return this.projectName$.asObservable();
},
setProjectUrl: (projectUrl: string) => {
this.projectUrl$.next(projectUrl);
},
setProjectNavigation: (projectNavigation: ChromeProjectNavigation) => {
this.projectNavigation$.next(projectNavigation);
this.projectNavigationNavTreeFlattened = flattenNav(projectNavigation.navigationTree);
Expand Down Expand Up @@ -136,17 +140,30 @@ export class ProjectNavigationService {
return combineLatest([
this.projectBreadcrumbs$,
this.activeNodes$,
this.projectHome$.pipe(map((homeHref) => homeHref ?? '/')),
chromeBreadcrumbs$,
this.projectsUrl$,
this.projectUrl$,
this.projectName$,
]).pipe(
map(([projectBreadcrumbs, activeNodes, homeHref, chromeBreadcrumbs]) => {
return buildBreadcrumbs({
homeHref: this.http?.basePath.prepend?.(homeHref) ?? homeHref,
map(
([
projectBreadcrumbs,
activeNodes,
chromeBreadcrumbs,
});
})
projectsUrl,
projectUrl,
projectName,
]) => {
return buildBreadcrumbs({
projectUrl,
projectName,
projectsUrl,
projectBreadcrumbs,
activeNodes,
chromeBreadcrumbs,
});
}
)
);
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ export interface InternalChromeStart extends ChromeStart {
*/
setProjectName(projectName: string): void;

/**
* Sets the project url.
* @param projectUrl
*/
setProjectUrl(projectUrl: string): void;

/**
* Sets the project navigation config to be used for rendering project navigation.
* It is used for default project sidenav, project breadcrumbs, tracking active deep link.
Expand Down
Loading

0 comments on commit c4c2173

Please sign in to comment.