From 145d295a75e0124a8cc406a67109faef7f05413e Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 11 Feb 2025 15:04:25 -0700 Subject: [PATCH] [Solution nav] Use flyout for Stack management Security Solution (#210471) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 949d5d176216652676fc9bdfbd75f282227ffeb0 from https://github.com/elastic/kibana/pull/208632#issuecomment-2644086780. ## Summary Closes https://github.com/elastic/kibana/issues/208636 Part of https://github.com/elastic/kibana-team/issues/1439
Security / Serverless (no longer in this PR) ![optimized-serverless-security 4 48 01 PM](https://github.com/user-attachments/assets/33df6104-8de7-405e-8fd6-3082fc2dadb6)
Security / Stateful (no longer in this PR) ![optimized-stateful-security 4 48 01 PM](https://github.com/user-attachments/assets/4e654a8f-e802-4484-850e-f7b67a4fefa8)
### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] New lists of Stack Management navigation items were added for flyout menus in serverless projects using static declarations. There is a risk that these lists have missing items, which could hurt user experience by making the pages harder to navigate to. --- .../public/navigation/side_navigation.ts | 1 + .../public/navigation/side_navigation.ts | 90 ++++++++++++++++++- .../test_suites/security/ftr/navigation.ts | 7 +- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution_ess/public/navigation/side_navigation.ts b/x-pack/solutions/security/plugins/security_solution_ess/public/navigation/side_navigation.ts index 9e08345dac8f1..7ae283b863efe 100644 --- a/x-pack/solutions/security/plugins/security_solution_ess/public/navigation/side_navigation.ts +++ b/x-pack/solutions/security/plugins/security_solution_ess/public/navigation/side_navigation.ts @@ -37,6 +37,7 @@ export const initSideNavigation = async (services: Services) => { management.id = 'stack_management'; management.spaceBefore = null; management.children = stackManagementLinks; + delete management.link; } }) ) diff --git a/x-pack/solutions/security/plugins/security_solution_serverless/public/navigation/side_navigation.ts b/x-pack/solutions/security/plugins/security_solution_serverless/public/navigation/side_navigation.ts index b8e7bdea916c5..f27dbbfb9ec79 100644 --- a/x-pack/solutions/security/plugins/security_solution_serverless/public/navigation/side_navigation.ts +++ b/x-pack/solutions/security/plugins/security_solution_serverless/public/navigation/side_navigation.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import type { GroupDefinition } from '@kbn/core-chrome-browser'; +import type { AppDeepLinkId, GroupDefinition, NodeDefinition } from '@kbn/core-chrome-browser'; import produce from 'immer'; import { map } from 'rxjs'; import { type Services } from '../common/services'; @@ -29,6 +29,14 @@ export const initSideNavigation = async (services: Services) => { const footerGroup: GroupDefinition | undefined = draft.footer?.find( ({ type }) => type === 'navGroup' ) as GroupDefinition; + const management = footerGroup?.children.find((child) => child.link === 'management'); + if (management) { + management.renderAs = 'panelOpener'; + management.id = 'stack_management'; + management.spaceBefore = null; + management.children = stackManagementLinks; + delete management.link; + } if (footerGroup) { footerGroup.title = PROJECT_SETTINGS_TITLE; footerGroup.children.push({ cloudLink: 'billingAndSub', openInNewTab: true }); @@ -42,3 +50,83 @@ export const initSideNavigation = async (services: Services) => { dataTestSubj: 'securitySolutionSideNav', }); }; + +// Stack Management static node definition +const stackManagementLinks: Array> = [ + { + title: i18n.translate('xpack.securitySolutionServerless.navLinks.projectSettings.mngt.data', { + defaultMessage: 'Data', + }), + breadcrumbStatus: 'hidden', + children: [ + { link: 'management:index_management', breadcrumbStatus: 'hidden' }, + { link: 'management:transform', breadcrumbStatus: 'hidden' }, + { link: 'management:ingest_pipelines', breadcrumbStatus: 'hidden' }, + { link: 'management:dataViews', breadcrumbStatus: 'hidden' }, + { link: 'management:jobsListLink', breadcrumbStatus: 'hidden' }, + { link: 'management:pipelines', breadcrumbStatus: 'hidden' }, + { link: 'management:data_quality', breadcrumbStatus: 'hidden' }, + { link: 'management:data_usage', breadcrumbStatus: 'hidden' }, + ], + }, + { + title: i18n.translate('xpack.securitySolutionServerless.navLinks.projectSettings.mngt.access', { + defaultMessage: 'Access', + }), + breadcrumbStatus: 'hidden', + children: [ + { link: 'management:api_keys', breadcrumbStatus: 'hidden' }, + { link: 'management:roles', breadcrumbStatus: 'hidden' }, + { + cloudLink: 'userAndRoles', + title: i18n.translate( + 'xpack.securitySolutionServerless.navLinks.projectSettings.mngt.usersAndRoles', + { defaultMessage: 'Manage organization members' } + ), + }, + ], + }, + { + title: i18n.translate( + 'xpack.securitySolutionServerless.navLinks.projectSettings.mngt.alertsAndInsights', + { defaultMessage: 'Alerts and Insights' } + ), + breadcrumbStatus: 'hidden', + children: [ + { link: 'management:triggersActions', breadcrumbStatus: 'hidden' }, + { link: 'management:triggersActionsConnectors', breadcrumbStatus: 'hidden' }, + { link: 'management:maintenanceWindows', breadcrumbStatus: 'hidden' }, + { link: 'securitySolutionUI:entity_analytics-management', breadcrumbStatus: 'hidden' }, + { + link: 'securitySolutionUI:entity_analytics-entity_store_management', + breadcrumbStatus: 'hidden', + }, + ], + }, + { + title: i18n.translate( + 'xpack.securitySolutionServerless.navLinks.projectSettings.mngt.content', + { defaultMessage: 'Content' } + ), + breadcrumbStatus: 'hidden', + children: [ + { link: 'management:spaces', breadcrumbStatus: 'hidden' }, + { link: 'management:objects', breadcrumbStatus: 'hidden' }, + { link: 'management:filesManagement', breadcrumbStatus: 'hidden' }, + { link: 'management:reporting', breadcrumbStatus: 'hidden' }, + { link: 'management:tags', breadcrumbStatus: 'hidden' }, + { link: 'maps' }, + { link: 'visualize' }, + ], + }, + { + title: i18n.translate('xpack.securitySolutionServerless.navLinks.projectSettings.mngt.other', { + defaultMessage: 'Other', + }), + breadcrumbStatus: 'hidden', + children: [ + { link: 'management:settings', breadcrumbStatus: 'hidden' }, + { link: 'management:securityAiAssistantManagement', breadcrumbStatus: 'hidden' }, + ], + }, +]; diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts index b7d7ef5c6dbbb..b5ecfa9e63a38 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts @@ -49,7 +49,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await svlCommonNavigation.search.hideSearch(); await headerPage.waitUntilLoadingHasFinished(); - await expect(await browser.getCurrentUrl()).contain('app/security/dashboards'); + expect(await browser.getCurrentUrl()).contain('app/security/dashboards'); }); it('shows cases in sidebar navigation', async () => { @@ -74,12 +74,13 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await testSubjects.existOrFail('cases-all-title'); }); }); + it('navigates to maintenance windows', async () => { await svlCommonPage.loginAsAdmin(); await svlSecNavigation.navigateToLandingPage(); await svlCommonNavigation.sidenav.openSection('category-management'); - await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'management' }); - await testSubjects.click('app-card-maintenanceWindows'); + await svlCommonNavigation.sidenav.clickLink({ navId: 'stack_management' }); + await svlCommonNavigation.sidenav.clickPanelLink('management:maintenanceWindows'); await svlCommonNavigation.breadcrumbs.expectBreadcrumbTexts([ 'Stack Management', 'Maintenance Windows',