mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `9.0`: - [[Solution Side Nav] Add back external link indicator to sidenav (#215946)](https://github.com/elastic/kibana/pull/215946) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Krzysztof Kowalczyk","email":"krzysztof.kowalczyk@elastic.co"},"sourceCommit":{"committedDate":"2025-04-03T22:34:23Z","message":"[Solution Side Nav] Add back external link indicator to sidenav (#215946)\n\n## Summary\n\nThis PR adds back external link indicator to sidenav items.\n\n","sha":"e21739b657d57a884b7a8da713a34f4f5c8273a2","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","enhancement","v9.0.0","Team:SharedUX","backport:version","v9.1.0","v8.19.0"],"title":"[Solution Side Nav] Add back external link indicator to sidenav","number":215946,"url":"https://github.com/elastic/kibana/pull/215946","mergeCommit":{"message":"[Solution Side Nav] Add back external link indicator to sidenav (#215946)\n\n## Summary\n\nThis PR adds back external link indicator to sidenav items.\n\n","sha":"e21739b657d57a884b7a8da713a34f4f5c8273a2"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/215946","number":215946,"mergeCommit":{"message":"[Solution Side Nav] Add back external link indicator to sidenav (#215946)\n\n## Summary\n\nThis PR adds back external link indicator to sidenav items.\n\n","sha":"e21739b657d57a884b7a8da713a34f4f5c8273a2"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
001bcfefcf
commit
6cdbf70834
6 changed files with 38 additions and 28 deletions
|
@ -175,7 +175,7 @@ describe('initNavigation()', () => {
|
|||
path: 'group1.foo',
|
||||
href: '/app/foo',
|
||||
deepLink: getNavLink({ id: 'foo', title: 'FOO' }),
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
});
|
||||
expect(node.children![0].href).toBe(node.children![0]!.deepLink!.href);
|
||||
|
@ -240,14 +240,14 @@ describe('initNavigation()', () => {
|
|||
title: '',
|
||||
path: 'node-1',
|
||||
type: 'navGroup',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
children: [
|
||||
{
|
||||
id: 'node-0', // auto generated
|
||||
path: 'node-1.node-0',
|
||||
title: '',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
children: [
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ describe('initNavigation()', () => {
|
|||
},
|
||||
href: '/app/foo',
|
||||
id: 'foo',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
path: 'node-1.node-0.foo',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'FOO',
|
||||
|
@ -277,21 +277,21 @@ describe('initNavigation()', () => {
|
|||
title: 'Footer group',
|
||||
path: 'node-4',
|
||||
type: 'navGroup',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
children: [
|
||||
{
|
||||
id: 'node-0', // auto generated
|
||||
path: 'node-4.node-0',
|
||||
title: '',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
children: [
|
||||
{
|
||||
deepLink: expect.any(Object), // we are not testing the deepLink here
|
||||
href: '/app/foo',
|
||||
id: 'foo',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
path: 'node-4.node-0.foo',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'FOO',
|
||||
|
@ -330,7 +330,7 @@ describe('initNavigation()', () => {
|
|||
},
|
||||
"href": "/app/discover",
|
||||
"id": "discover",
|
||||
"isElasticInternalLink": false,
|
||||
"isExternalLink": false,
|
||||
"onClick": undefined,
|
||||
"path": "rootNav:analytics.discover",
|
||||
"sideNavStatus": "visible",
|
||||
|
@ -349,7 +349,7 @@ describe('initNavigation()', () => {
|
|||
},
|
||||
"href": "/app/dashboards",
|
||||
"id": "dashboards",
|
||||
"isElasticInternalLink": false,
|
||||
"isExternalLink": false,
|
||||
"onClick": undefined,
|
||||
"path": "rootNav:analytics.dashboards",
|
||||
"sideNavStatus": "visible",
|
||||
|
@ -368,7 +368,7 @@ describe('initNavigation()', () => {
|
|||
},
|
||||
"href": "/app/visualize",
|
||||
"id": "visualize",
|
||||
"isElasticInternalLink": false,
|
||||
"isExternalLink": false,
|
||||
"onClick": undefined,
|
||||
"path": "rootNav:analytics.visualize",
|
||||
"sideNavStatus": "visible",
|
||||
|
@ -379,7 +379,7 @@ describe('initNavigation()', () => {
|
|||
"href": undefined,
|
||||
"icon": "stats",
|
||||
"id": "rootNav:analytics",
|
||||
"isElasticInternalLink": false,
|
||||
"isExternalLink": false,
|
||||
"onClick": undefined,
|
||||
"path": "rootNav:analytics",
|
||||
"renderAs": "accordion",
|
||||
|
@ -457,7 +457,7 @@ describe('initNavigation()', () => {
|
|||
deepLink: undefined,
|
||||
href: 'https://cloud.elastic.co/userAndRoles',
|
||||
id: 'node-0',
|
||||
isElasticInternalLink: true,
|
||||
isExternalLink: true,
|
||||
path: 'group1.node-0',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'Users and roles',
|
||||
|
@ -468,7 +468,7 @@ describe('initNavigation()', () => {
|
|||
deepLink: undefined,
|
||||
href: 'https://cloud.elastic.co/performance',
|
||||
id: 'node-1',
|
||||
isElasticInternalLink: true,
|
||||
isExternalLink: true,
|
||||
path: 'group1.node-1',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'Performance',
|
||||
|
@ -479,7 +479,7 @@ describe('initNavigation()', () => {
|
|||
deepLink: undefined,
|
||||
href: 'https://cloud.elastic.co/billing',
|
||||
id: 'node-2',
|
||||
isElasticInternalLink: true,
|
||||
isExternalLink: true,
|
||||
path: 'group1.node-2',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'Billing and subscription',
|
||||
|
@ -490,7 +490,7 @@ describe('initNavigation()', () => {
|
|||
deepLink: undefined,
|
||||
href: 'https://cloud.elastic.co/deployment',
|
||||
id: 'node-3',
|
||||
isElasticInternalLink: true,
|
||||
isExternalLink: true,
|
||||
path: 'group1.node-3',
|
||||
sideNavStatus: 'visible',
|
||||
title: 'Project',
|
||||
|
@ -804,7 +804,7 @@ describe('getActiveNodes$()', () => {
|
|||
id: 'root',
|
||||
title: 'Root',
|
||||
path: 'root',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
type: 'navGroup',
|
||||
},
|
||||
|
@ -812,7 +812,7 @@ describe('getActiveNodes$()', () => {
|
|||
id: 'item1',
|
||||
title: 'ITEM1',
|
||||
path: 'root.item1',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
href: '/app/item1',
|
||||
deepLink: {
|
||||
|
@ -861,7 +861,7 @@ describe('getActiveNodes$()', () => {
|
|||
id: 'root',
|
||||
title: 'Root',
|
||||
path: 'root',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
type: 'navGroup',
|
||||
},
|
||||
|
@ -869,7 +869,7 @@ describe('getActiveNodes$()', () => {
|
|||
id: 'item1',
|
||||
title: 'ITEM1',
|
||||
path: 'root.item1',
|
||||
isElasticInternalLink: false,
|
||||
isExternalLink: false,
|
||||
sideNavStatus: 'visible',
|
||||
href: '/app/item1',
|
||||
deepLink: {
|
||||
|
|
|
@ -321,8 +321,8 @@ const initNavNode = <
|
|||
|
||||
const id = getNavigationNodeId(node, () => `node-${index}`) as Id;
|
||||
const title = getTitleForNode(node, { deepLink, cloudLinks });
|
||||
const isElasticInternalLink = cloudLink != null;
|
||||
const href = isElasticInternalLink ? cloudLinks[cloudLink]?.href : node.href;
|
||||
const isExternalLink = cloudLink != null;
|
||||
const href = isExternalLink ? cloudLinks[cloudLink]?.href : node.href;
|
||||
const path = parentNodePath ? `${parentNodePath}.${id}` : id;
|
||||
|
||||
if (href && !isAbsoluteLink(href) && !onClick) {
|
||||
|
@ -337,7 +337,7 @@ const initNavNode = <
|
|||
path,
|
||||
title,
|
||||
deepLink,
|
||||
isElasticInternalLink,
|
||||
isExternalLink,
|
||||
sideNavStatus,
|
||||
};
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ export interface ChromeProjectNavigationNode extends NodeDefinitionBase {
|
|||
/**
|
||||
* Flag to indicate if the node is an "external" cloud link
|
||||
*/
|
||||
isElasticInternalLink?: boolean;
|
||||
isExternalLink?: boolean;
|
||||
}
|
||||
|
||||
export type PanelSelectedNode = Pick<
|
||||
|
|
|
@ -118,7 +118,6 @@ const serializeNavNode = (
|
|||
const serialized: ChromeProjectNavigationNode = {
|
||||
...navNode,
|
||||
};
|
||||
|
||||
serialized.renderAs = getRenderAs(serialized, { isSideNavCollapsed });
|
||||
serialized.spaceBefore = getSpaceBefore(serialized, {
|
||||
isSideNavCollapsed,
|
||||
|
@ -258,7 +257,7 @@ const getEuiProps = (
|
|||
// if it is the highest match in the URL, not if one of its children is also active.
|
||||
const onlyIfHighestMatch = isAccordion && !isCollapsible;
|
||||
const isActive = isActiveFromUrl(navNode.path, activeNodes, onlyIfHighestMatch);
|
||||
const isExternal = Boolean(href) && !navNode.isElasticInternalLink && isAbsoluteLink(href!);
|
||||
const isExternal = Boolean(href) && navNode.isExternalLink && isAbsoluteLink(href!);
|
||||
const isAccordionExpanded = !getIsCollapsed(path);
|
||||
|
||||
let isSelected = isActive;
|
||||
|
@ -369,7 +368,7 @@ function nodeToEuiCollapsibleNavProps(
|
|||
_navNode,
|
||||
deps
|
||||
);
|
||||
const { id, path, href, renderAs, isCollapsible, spaceBefore } = navNode;
|
||||
const { id, path, href, renderAs, isCollapsible, spaceBefore, isExternalLink } = navNode;
|
||||
|
||||
if (navNode.renderItem) {
|
||||
// Leave the rendering to the consumer
|
||||
|
@ -411,7 +410,9 @@ function nodeToEuiCollapsibleNavProps(
|
|||
// Render as an accordion or a link (handled by EUI) depending if
|
||||
// "items" is undefined or not. If it is undefined --> a link, otherwise an
|
||||
// accordion is rendered.
|
||||
...(subItems ? { items: subItems, isCollapsible } : { href, linkProps }),
|
||||
...(subItems
|
||||
? { items: subItems, isCollapsible }
|
||||
: { href, ...linkProps, external: isExternalLink }),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ interface Props {
|
|||
export const PanelNavItem: FC<Props> = ({ item, parentIsAccordion }) => {
|
||||
const { navigateToUrl } = useServices();
|
||||
const { close: closePanel } = usePanel();
|
||||
const { id, icon, deepLink, openInNewTab, renderItem } = item;
|
||||
const { id, icon, deepLink, openInNewTab, isExternalLink, renderItem } = item;
|
||||
|
||||
const href = deepLink?.url ?? item.href;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
|
@ -53,6 +54,9 @@ export const PanelNavItem: FC<Props> = ({ item, parentIsAccordion }) => {
|
|||
&.sideNavPanelLink:hover {
|
||||
background-color: ${transparentize(euiTheme.colors.lightShade, 0.5)};
|
||||
}
|
||||
& svg[class*='EuiExternalLinkIcon'] {
|
||||
margin-left: auto;
|
||||
}
|
||||
`
|
||||
)}
|
||||
size="s"
|
||||
|
@ -60,6 +64,7 @@ export const PanelNavItem: FC<Props> = ({ item, parentIsAccordion }) => {
|
|||
href={href}
|
||||
iconType={icon}
|
||||
onClick={onClick}
|
||||
external={isExternalLink}
|
||||
target={openInNewTab ? '_blank' : undefined}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -111,6 +111,7 @@ const generalLayoutNavTree: NavigationTreeDefinitionUI = {
|
|||
title: 'Item 01',
|
||||
href: '/app/kibana',
|
||||
icon: 'iInCircle',
|
||||
isExternalLink: true,
|
||||
},
|
||||
{
|
||||
id: 'item02',
|
||||
|
@ -203,6 +204,7 @@ const generalLayoutNavTree: NavigationTreeDefinitionUI = {
|
|||
title: 'Item 17',
|
||||
href: '/app/kibana',
|
||||
icon: 'iInCircle',
|
||||
isExternalLink: true,
|
||||
},
|
||||
{
|
||||
id: 'sub2',
|
||||
|
@ -240,6 +242,7 @@ const generalLayoutNavTree: NavigationTreeDefinitionUI = {
|
|||
title: 'Item-Labs',
|
||||
href: '/app/kibana',
|
||||
withBadge: true,
|
||||
isExternalLink: true,
|
||||
badgeOptions: {
|
||||
icon: 'bell',
|
||||
tooltip: 'This is a tooltip',
|
||||
|
@ -414,6 +417,7 @@ const generalLayoutNavTree: NavigationTreeDefinitionUI = {
|
|||
title: 'Item-Beta',
|
||||
href: '/app/kibana',
|
||||
withBadge: true,
|
||||
isExternalLink: true,
|
||||
},
|
||||
{
|
||||
id: 'item-labs',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue