Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export enum SecurityPageName {
network = 'network',
timelines = 'timelines',
case = 'case',
management = 'management',
administration = 'administration',
}

export const APP_OVERVIEW_PATH = `${APP_PATH}/overview`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
CASES,
DETECTIONS,
HOSTS,
MANAGEMENT,
ADMINISTRATION,
NETWORK,
OVERVIEW,
TIMELINES,
Expand Down Expand Up @@ -73,7 +73,7 @@ describe('top-level navigation common to all pages in the Security app', () => {
});

it('navigates to the Administration page', () => {
navigateFromHeaderTo(MANAGEMENT);
navigateFromHeaderTo(ADMINISTRATION);
cy.url().should('include', ADMINISTRATION_URL);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const HOSTS = '[data-test-subj="navigation-hosts"]';

export const KQL_INPUT = '[data-test-subj="queryInput"]';

export const MANAGEMENT = '[data-test-subj="navigation-management"]';
export const ADMINISTRATION = '[data-test-subj="navigation-administration"]';

export const NETWORK = '[data-test-subj="navigation-network"]';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ export const navTabs: SiemNavTab = {
disabled: false,
urlKey: 'case',
},
[SecurityPageName.management]: {
id: SecurityPageName.management,
[SecurityPageName.administration]: {
id: SecurityPageName.administration,
name: i18n.ADMINISTRATION,
href: APP_MANAGEMENT_PATH,
disabled: false,
urlKey: SecurityPageName.management,
urlKey: SecurityPageName.administration,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/p
import { getBreadcrumbs as getCaseDetailsBreadcrumbs } from '../../../../cases/pages/utils';
import { getBreadcrumbs as getDetectionRulesBreadcrumbs } from '../../../../detections/pages/detection_engine/rules/utils';
import { getBreadcrumbs as getTimelinesBreadcrumbs } from '../../../../timelines/pages';
import { getBreadcrumbs as getAdminBreadcrumbs } from '../../../../management/pages';
import { SecurityPageName } from '../../../../app/types';
import {
RouteSpyState,
HostRouteSpyState,
NetworkRouteSpyState,
TimelineRouteSpyState,
AdministrationRouteSpyState,
} from '../../../utils/route/types';
import { getAppOverviewUrl } from '../../link_to';

Expand Down Expand Up @@ -61,6 +63,10 @@ const isCaseRoutes = (spyState: RouteSpyState): spyState is RouteSpyState =>
const isAlertsRoutes = (spyState: RouteSpyState) =>
spyState != null && spyState.pageName === SecurityPageName.detections;

const isAdminRoutes = (spyState: RouteSpyState): spyState is AdministrationRouteSpyState =>
spyState != null && spyState.pageName === SecurityPageName.administration;

// eslint-disable-next-line complexity
export const getBreadcrumbsForRoute = (
object: RouteSpyState & TabNavigationProps,
getUrlForApp: GetUrlForApp
Expand Down Expand Up @@ -159,6 +165,27 @@ export const getBreadcrumbsForRoute = (
),
];
}

if (isAdminRoutes(spyState) && object.navTabs) {
const tempNav: SearchNavTab = { urlKey: 'administration', isDetailPage: false };
let urlStateKeys = [getOr(tempNav, spyState.pageName, object.navTabs)];
if (spyState.tabName != null) {
urlStateKeys = [...urlStateKeys, getOr(tempNav, spyState.tabName, object.navTabs)];
}

return [
...siemRootBreadcrumb,
...getAdminBreadcrumbs(
spyState,
urlStateKeys.reduce(
(acc: string[], item: SearchNavTab) => [...acc, getSearch(item, object)],
[]
),
getUrlForApp
),
];
}

if (
spyState != null &&
object.navTabs &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ describe('SIEM Navigation', () => {
name: 'Cases',
urlKey: 'case',
},
management: {
administration: {
disabled: false,
href: '/app/security/administration',
id: 'management',
id: 'administration',
name: 'Administration',
urlKey: 'management',
urlKey: 'administration',
},
hosts: {
disabled: false,
Expand Down Expand Up @@ -218,12 +218,12 @@ describe('SIEM Navigation', () => {
name: 'Hosts',
urlKey: 'host',
},
management: {
administration: {
disabled: false,
href: '/app/security/administration',
id: 'management',
id: 'administration',
name: 'Administration',
urlKey: 'management',
urlKey: 'administration',
},
network: {
disabled: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type SiemNavTabKey =
| SecurityPageName.detections
| SecurityPageName.timelines
| SecurityPageName.case
| SecurityPageName.management;
| SecurityPageName.administration;

export type SiemNavTab = Record<SiemNavTabKey, NavTab>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ export type UrlStateType =
| 'network'
| 'overview'
| 'timeline'
| 'management';
| 'administration';
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ export const getUrlType = (pageName: string): UrlStateType => {
return 'timeline';
} else if (pageName === SecurityPageName.case) {
return 'case';
} else if (pageName === SecurityPageName.administration) {
return 'administration';
}
return 'overview';
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const URL_STATE_KEYS: Record<UrlStateType, KeyUrlState[]> = {
CONSTANTS.timerange,
CONSTANTS.timeline,
],
management: [],
administration: [],
network: [
CONSTANTS.appQuery,
CONSTANTS.filters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { TimelineType } from '../../../../common/types/timeline';

import { HostsTableType } from '../../../hosts/store/model';
import { NetworkRouteType } from '../../../network/pages/navigation/types';
import { AdministrationSubTab as AdministrationType } from '../../../management/types';
import { FlowTarget } from '../../../graphql/types';

export type SiemRouteType = HostsTableType | NetworkRouteType | TimelineType;
export type SiemRouteType = HostsTableType | NetworkRouteType | TimelineType | AdministrationType;
export interface RouteSpyState {
pageName: string;
detailName: string | undefined;
Expand All @@ -38,6 +39,10 @@ export interface TimelineRouteSpyState extends RouteSpyState {
tabName: TimelineType | undefined;
}

export interface AdministrationRouteSpyState extends RouteSpyState {
tabName: AdministrationType | undefined;
}

export type RouteSpyAction =
| {
type: 'updateSearch';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { ManagementStoreGlobalNamespace, ManagementSubTab } from '../types';
import { ManagementStoreGlobalNamespace, AdministrationSubTab } from '../types';
import { APP_ID } from '../../../common/constants';
import { SecurityPageName } from '../../app/types';

// --[ ROUTING ]---------------------------------------------------------------------------
export const MANAGEMENT_APP_ID = `${APP_ID}:${SecurityPageName.management}`;
export const MANAGEMENT_APP_ID = `${APP_ID}:${SecurityPageName.administration}`;
export const MANAGEMENT_ROUTING_ROOT_PATH = '';
export const MANAGEMENT_ROUTING_HOSTS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${ManagementSubTab.hosts})`;
export const MANAGEMENT_ROUTING_POLICIES_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${ManagementSubTab.policies})`;
export const MANAGEMENT_ROUTING_POLICY_DETAILS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${ManagementSubTab.policies})/:policyId`;
export const MANAGEMENT_ROUTING_HOSTS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.hosts})`;
export const MANAGEMENT_ROUTING_POLICIES_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.policies})`;
export const MANAGEMENT_ROUTING_POLICY_DETAILS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.policies})/:policyId`;

// --[ STORE ]---------------------------------------------------------------------------
/** The SIEM global store namespace where the management state will be mounted */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
MANAGEMENT_ROUTING_POLICIES_PATH,
MANAGEMENT_ROUTING_POLICY_DETAILS_PATH,
} from './constants';
import { ManagementSubTab } from '../types';
import { AdministrationSubTab } from '../types';
import { appendSearch } from '../../common/components/link_to/helpers';
import { HostIndexUIQueryParams } from '../pages/endpoint_hosts/types';

Expand Down Expand Up @@ -47,7 +47,7 @@ export const getHostListPath = (

if (name === 'hostList') {
return `${generatePath(MANAGEMENT_ROUTING_HOSTS_PATH, {
tabName: ManagementSubTab.hosts,
tabName: AdministrationSubTab.hosts,
})}${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
}
return `${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
Expand All @@ -65,17 +65,17 @@ export const getHostDetailsPath = (
const urlSearch = `${urlQueryParams && !isEmpty(search) ? '&' : ''}${search ?? ''}`;

return `${generatePath(MANAGEMENT_ROUTING_HOSTS_PATH, {
tabName: ManagementSubTab.hosts,
tabName: AdministrationSubTab.hosts,
})}${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
};

export const getPoliciesPath = (search?: string) =>
`${generatePath(MANAGEMENT_ROUTING_POLICIES_PATH, {
tabName: ManagementSubTab.policies,
tabName: AdministrationSubTab.policies,
})}${appendSearch(search)}`;

export const getPolicyDetailPath = (policyId: string, search?: string) =>
`${generatePath(MANAGEMENT_ROUTING_POLICY_DETAILS_PATH, {
tabName: ManagementSubTab.policies,
tabName: AdministrationSubTab.policies,
policyId,
})}${appendSearch(search)}`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';

export const HOSTS_TAB = i18n.translate('xpack.securitySolution.hostsTab', {
defaultMessage: 'Hosts',
});

export const POLICIES_TAB = i18n.translate('xpack.securitySolution.policiesTab', {
defaultMessage: 'Policies',
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import React, { memo, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import { useParams } from 'react-router-dom';
import { PageView, PageViewProps } from '../../common/components/endpoint/page_view';
import { ManagementSubTab } from '../types';
import { AdministrationSubTab } from '../types';
import { SecurityPageName } from '../../app/types';
import { useFormatUrl } from '../../common/components/link_to';
import { getHostListPath, getPoliciesPath } from '../common/routing';
import { useNavigateByRouterEventHandler } from '../../common/hooks/endpoint/use_navigate_by_router_event_handler';

export const ManagementPageView = memo<Omit<PageViewProps, 'tabs'>>((options) => {
const { formatUrl, search } = useFormatUrl(SecurityPageName.management);
const { tabName } = useParams<{ tabName: ManagementSubTab }>();
const { formatUrl, search } = useFormatUrl(SecurityPageName.administration);
const { tabName } = useParams<{ tabName: AdministrationSubTab }>();

const goToEndpoint = useNavigateByRouterEventHandler(
getHostListPath({ name: 'hostList' }, search)
Expand All @@ -30,20 +30,20 @@ export const ManagementPageView = memo<Omit<PageViewProps, 'tabs'>>((options) =>
}
return [
{
name: i18n.translate('xpack.securitySolution.managementTabs.endpoints', {
name: i18n.translate('xpack.securitySolution.managementTabs.hosts', {
defaultMessage: 'Hosts',
}),
id: ManagementSubTab.hosts,
isSelected: tabName === ManagementSubTab.hosts,
id: AdministrationSubTab.hosts,
isSelected: tabName === AdministrationSubTab.hosts,
href: formatUrl(getHostListPath({ name: 'hostList' })),
onClick: goToEndpoint,
},
{
name: i18n.translate('xpack.securitySolution.managementTabs.policies', {
defaultMessage: 'Policies',
}),
id: ManagementSubTab.policies,
isSelected: tabName === ManagementSubTab.policies,
id: AdministrationSubTab.policies,
isSelected: tabName === AdministrationSubTab.policies,
href: formatUrl(getPoliciesPath()),
onClick: goToPolicies,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
const policyStatus = useHostSelector(
policyResponseStatus
) as keyof typeof POLICY_STATUS_TO_HEALTH_COLOR;
const { formatUrl } = useFormatUrl(SecurityPageName.management);
const { formatUrl } = useFormatUrl(SecurityPageName.administration);

const detailsResultsUpper = useMemo(() => {
return [
Expand Down Expand Up @@ -106,7 +106,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
path: agentDetailsWithFlyoutPath,
state: {
onDoneNavigateTo: [
'securitySolution:management',
'securitySolution:administration',
{
path: getHostDetailsPath({ name: 'hostDetails', selected_host: details.host.id }),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const PolicyResponseFlyoutPanel = memo<{
const responseAttentionCount = useHostSelector(policyResponseFailedOrWarningActionCount);
const loading = useHostSelector(policyResponseLoading);
const error = useHostSelector(policyResponseError);
const { formatUrl } = useFormatUrl(SecurityPageName.management);
const { formatUrl } = useFormatUrl(SecurityPageName.administration);
const [detailsUri, detailsRoutePath] = useMemo(
() => [
formatUrl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const HostList = () => {
policyItemsLoading,
endpointPackageVersion,
} = useHostSelector(selector);
const { formatUrl, search } = useFormatUrl(SecurityPageName.management);
const { formatUrl, search } = useFormatUrl(SecurityPageName.administration);

const dispatch = useDispatch<(a: HostAction) => void>();

Expand Down Expand Up @@ -127,12 +127,12 @@ export const HostList = () => {
}`,
state: {
onCancelNavigateTo: [
'securitySolution:management',
'securitySolution:administration',
{ path: getHostListPath({ name: 'hostList' }) },
],
onCancelUrl: formatUrl(getHostListPath({ name: 'hostList' })),
onSaveNavigateTo: [
'securitySolution:management',
'securitySolution:administration',
{ path: getHostListPath({ name: 'hostList' }) },
],
},
Expand All @@ -145,7 +145,7 @@ export const HostList = () => {
path: `#/configs/${selectedPolicyId}?openEnrollmentFlyout=true`,
state: {
onDoneNavigateTo: [
'securitySolution:management',
'securitySolution:administration',
{ path: getHostListPath({ name: 'hostList' }) },
],
},
Expand Down Expand Up @@ -422,7 +422,7 @@ export const HostList = () => {
</>
)}
{renderTableOrEmptyState}
<SpyRoute pageName={SecurityPageName.management} />
<SpyRoute pageName={SecurityPageName.administration} />
</ManagementPageView>
);
};
Loading