mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution][Notes] - add feature flag, new expandable flyout tab and manage entry (#186299)
This commit is contained in:
parent
0dd4f9b8c7
commit
072cad1ab8
16 changed files with 153 additions and 48 deletions
|
@ -86,4 +86,5 @@ export enum SecurityPageName {
|
|||
entityAnalyticsManagement = 'entity_analytics-management',
|
||||
entityAnalyticsAssetClassification = 'entity_analytics-asset-classification',
|
||||
coverageOverview = 'coverage-overview',
|
||||
notesManagement = 'notes-management',
|
||||
}
|
||||
|
|
|
@ -121,20 +121,7 @@ export const ENTITY_ANALYTICS_PATH = '/entity_analytics' as const;
|
|||
export const ENTITY_ANALYTICS_MANAGEMENT_PATH = `/entity_analytics_management` as const;
|
||||
export const ENTITY_ANALYTICS_ASSET_CRITICALITY_PATH =
|
||||
`/entity_analytics_asset_criticality` as const;
|
||||
export const APP_OVERVIEW_PATH = `${APP_PATH}${OVERVIEW_PATH}` as const;
|
||||
export const APP_LANDING_PATH = `${APP_PATH}${LANDING_PATH}` as const;
|
||||
export const APP_DETECTION_RESPONSE_PATH = `${APP_PATH}${DETECTION_RESPONSE_PATH}` as const;
|
||||
export const APP_MANAGEMENT_PATH = `${APP_PATH}${MANAGEMENT_PATH}` as const;
|
||||
|
||||
export const APP_ALERTS_PATH = `${APP_PATH}${ALERTS_PATH}` as const;
|
||||
export const APP_RULES_PATH = `${APP_PATH}${RULES_PATH}` as const;
|
||||
export const APP_EXCEPTIONS_PATH = `${APP_PATH}${EXCEPTIONS_PATH}` as const;
|
||||
|
||||
export const APP_HOSTS_PATH = `${APP_PATH}${HOSTS_PATH}` as const;
|
||||
export const APP_USERS_PATH = `${APP_PATH}${USERS_PATH}` as const;
|
||||
export const APP_NETWORK_PATH = `${APP_PATH}${NETWORK_PATH}` as const;
|
||||
export const APP_KUBERNETES_PATH = `${APP_PATH}${KUBERNETES_PATH}` as const;
|
||||
export const APP_TIMELINES_PATH = `${APP_PATH}${TIMELINES_PATH}` as const;
|
||||
export const APP_CASES_PATH = `${APP_PATH}${CASES_PATH}` as const;
|
||||
export const APP_ENDPOINTS_PATH = `${APP_PATH}${ENDPOINTS_PATH}` as const;
|
||||
export const APP_POLICIES_PATH = `${APP_PATH}${POLICIES_PATH}` as const;
|
||||
|
@ -145,8 +132,7 @@ export const APP_HOST_ISOLATION_EXCEPTIONS_PATH =
|
|||
export const APP_BLOCKLIST_PATH = `${APP_PATH}${BLOCKLIST_PATH}` as const;
|
||||
export const APP_RESPONSE_ACTIONS_HISTORY_PATH =
|
||||
`${APP_PATH}${RESPONSE_ACTIONS_HISTORY_PATH}` as const;
|
||||
export const APP_ENTITY_ANALYTICS_PATH = `${APP_PATH}${ENTITY_ANALYTICS_PATH}` as const;
|
||||
export const APP_DATA_QUALITY_PATH = `${APP_PATH}${DATA_QUALITY_PATH}` as const;
|
||||
export const NOTES_MANAGEMENT_PATH = `/notes_management` as const;
|
||||
|
||||
// cloud logs to exclude from default index pattern
|
||||
export const EXCLUDE_ELASTIC_CLOUD_INDICES = ['-*elastic-cloud-logs-*'];
|
||||
|
|
|
@ -114,6 +114,11 @@ export const allowedExperimentalValues = Object.freeze({
|
|||
*/
|
||||
expandableFlyoutDisabled: false,
|
||||
|
||||
/**
|
||||
* Enables new notes
|
||||
*/
|
||||
notesEnabled: false,
|
||||
|
||||
/**
|
||||
* Enables the Assistant Model Evaluation advanced setting and API endpoint, introduced in `8.11.0`.
|
||||
*/
|
||||
|
|
|
@ -25,6 +25,10 @@ export const ENTITY_ANALYTICS_RISK_SCORE = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
export const NOTES = i18n.translate('xpack.securitySolution.navigation.notesManagement', {
|
||||
defaultMessage: 'Notes',
|
||||
});
|
||||
|
||||
export const ASSET_CRITICALITY = i18n.translate(
|
||||
'xpack.securitySolution.navigation.assetCriticality',
|
||||
{
|
||||
|
@ -143,12 +147,6 @@ export const HOST_ISOLATION_EXCEPTIONS = i18n.translate(
|
|||
defaultMessage: 'Host isolation exceptions',
|
||||
}
|
||||
);
|
||||
export const DETECT = i18n.translate('xpack.securitySolution.navigation.detect', {
|
||||
defaultMessage: 'Detect',
|
||||
});
|
||||
export const FINDINGS = i18n.translate('xpack.securitySolution.navigation.findings', {
|
||||
defaultMessage: 'Findings',
|
||||
});
|
||||
export const EXPLORE = i18n.translate('xpack.securitySolution.navigation.explore', {
|
||||
defaultMessage: 'Explore',
|
||||
});
|
||||
|
@ -177,10 +175,3 @@ export const PROTECTION_UPDATES = i18n.translate(
|
|||
export const CREATE_NEW_RULE = i18n.translate('xpack.securitySolution.navigation.newRuleTitle', {
|
||||
defaultMessage: 'Create new rule',
|
||||
});
|
||||
|
||||
export const THREAT_INTELLIGENCE = i18n.translate(
|
||||
'xpack.securitySolution.navigation.threatIntelligence',
|
||||
{
|
||||
defaultMessage: 'Intelligence',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { memo } from 'react';
|
||||
|
||||
/**
|
||||
* List all the notes for a document id and allows to create new notes associated with that document.
|
||||
* Displayed in the document details expandable flyout left section.
|
||||
*/
|
||||
export const NotesDetails = memo(() => {
|
||||
return <></>;
|
||||
});
|
||||
|
||||
NotesDetails.displayName = 'NotesDetails';
|
|
@ -9,6 +9,7 @@ import type { FC } from 'react';
|
|||
import React, { memo, useMemo } from 'react';
|
||||
import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout';
|
||||
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
|
||||
import { DocumentDetailsLeftPanelKey } from '../shared/constants/panel_keys';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { PanelHeader } from './header';
|
||||
|
@ -20,11 +21,12 @@ import { EventKind } from '../shared/constants/event_kinds';
|
|||
import { useLeftPanelContext } from './context';
|
||||
import { LeftPanelTour } from './components/tour';
|
||||
|
||||
export type LeftPanelPaths = 'visualize' | 'insights' | 'investigation' | 'response';
|
||||
export type LeftPanelPaths = 'visualize' | 'insights' | 'investigation' | 'response' | 'notes';
|
||||
export const LeftPanelVisualizeTab: LeftPanelPaths = 'visualize';
|
||||
export const LeftPanelInsightsTab: LeftPanelPaths = 'insights';
|
||||
export const LeftPanelInvestigationTab: LeftPanelPaths = 'investigation';
|
||||
export const LeftPanelResponseTab: LeftPanelPaths = 'response';
|
||||
export const LeftPanelNotesTab: LeftPanelPaths = 'notes';
|
||||
|
||||
export interface LeftPanelProps extends FlyoutPanelProps {
|
||||
key: typeof DocumentDetailsLeftPanelKey;
|
||||
|
@ -41,14 +43,18 @@ export const LeftPanel: FC<Partial<LeftPanelProps>> = memo(({ path }) => {
|
|||
const { openLeftPanel } = useExpandableFlyoutApi();
|
||||
const { eventId, indexName, scopeId, getFieldsData } = useLeftPanelContext();
|
||||
const eventKind = getField(getFieldsData('event.kind'));
|
||||
const notesEnabled = useIsExperimentalFeatureEnabled('notesEnabled');
|
||||
|
||||
const tabsDisplayed = useMemo(
|
||||
() =>
|
||||
const tabsDisplayed = useMemo(() => {
|
||||
const tabList =
|
||||
eventKind === EventKind.signal
|
||||
? [tabs.insightsTab, tabs.investigationTab, tabs.responseTab]
|
||||
: [tabs.insightsTab],
|
||||
[eventKind]
|
||||
);
|
||||
: [tabs.insightsTab];
|
||||
if (notesEnabled) {
|
||||
tabList.push(tabs.notesTab);
|
||||
}
|
||||
return tabList;
|
||||
}, [eventKind, notesEnabled]);
|
||||
|
||||
const selectedTabId = useMemo(() => {
|
||||
const defaultTab = tabsDisplayed[0].id;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import type { ReactElement } from 'react';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { NotesTab } from './tabs/notes_tab';
|
||||
import { VisualizeTab } from './tabs/visualize_tab';
|
||||
import { InvestigationTab } from './tabs/investigation_tab';
|
||||
import { InsightsTab } from './tabs/insights_tab';
|
||||
|
@ -15,6 +16,7 @@ import type { LeftPanelPaths } from '.';
|
|||
import {
|
||||
INSIGHTS_TAB_TEST_ID,
|
||||
INVESTIGATION_TAB_TEST_ID,
|
||||
NOTES_TAB_TEST_ID,
|
||||
RESPONSE_TAB_TEST_ID,
|
||||
VISUALIZE_TAB_TEST_ID,
|
||||
} from './test_ids';
|
||||
|
@ -74,3 +76,15 @@ export const responseTab: LeftPanelTabType = {
|
|||
),
|
||||
content: <ResponseTab />,
|
||||
};
|
||||
|
||||
export const notesTab: LeftPanelTabType = {
|
||||
id: 'notes',
|
||||
'data-test-subj': NOTES_TAB_TEST_ID,
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.notes.tabLabel"
|
||||
defaultMessage="Notes"
|
||||
/>
|
||||
),
|
||||
content: <NotesTab />,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
import { NotesDetails } from '../components/notes_details';
|
||||
import { NOTES_TAB_CONTENT_TEST_ID } from './test_ids';
|
||||
|
||||
/**
|
||||
* Notes view displayed in the document details expandable flyout left section
|
||||
* // TODO to be implemented
|
||||
*/
|
||||
export const NotesTab = memo(() => {
|
||||
return (
|
||||
<EuiPanel data-test-subj={NOTES_TAB_CONTENT_TEST_ID} hasShadow={false}>
|
||||
<NotesDetails />
|
||||
</EuiPanel>
|
||||
);
|
||||
});
|
||||
|
||||
NotesTab.displayName = 'NotesTab';
|
|
@ -29,3 +29,4 @@ export const INSIGHTS_TAB_CORRELATIONS_BUTTON_TEST_ID =
|
|||
`${INSIGHTS_TAB_TEST_ID}CorrelationsButton` as const;
|
||||
export const INVESTIGATION_TAB_CONTENT_TEST_ID = `${PREFIX}InvestigationsTabContent` as const;
|
||||
export const RESPONSE_TAB_CONTENT_TEST_ID = `${PREFIX}ResponseTabContent` as const;
|
||||
export const NOTES_TAB_CONTENT_TEST_ID = `${PREFIX}NotesTabContent` as const;
|
||||
|
|
|
@ -11,3 +11,4 @@ export const VISUALIZE_TAB_TEST_ID = `${PREFIX}VisualizeTab` as const;
|
|||
export const INSIGHTS_TAB_TEST_ID = `${PREFIX}InsightsTab` as const;
|
||||
export const INVESTIGATION_TAB_TEST_ID = `${PREFIX}InvestigationTab` as const;
|
||||
export const RESPONSE_TAB_TEST_ID = `${PREFIX}ResponseTab` as const;
|
||||
export const NOTES_TAB_TEST_ID = `${PREFIX}NotesTab` as const;
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
EVENT_FILTERS_PATH,
|
||||
HOST_ISOLATION_EXCEPTIONS_PATH,
|
||||
MANAGE_PATH,
|
||||
NOTES_MANAGEMENT_PATH,
|
||||
POLICIES_PATH,
|
||||
RESPONSE_ACTIONS_HISTORY_PATH,
|
||||
SecurityPageName,
|
||||
|
@ -39,6 +40,7 @@ import {
|
|||
TRUSTED_APPLICATIONS,
|
||||
ENTITY_ANALYTICS_RISK_SCORE,
|
||||
ASSET_CRITICALITY,
|
||||
NOTES,
|
||||
} from '../app/translations';
|
||||
import { licenseService } from '../common/hooks/use_license';
|
||||
import type { LinkItem } from '../common/links/types';
|
||||
|
@ -85,6 +87,12 @@ const categories = [
|
|||
}),
|
||||
linkIds: [SecurityPageName.cloudDefendPolicies],
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.securitySolution.appLinks.category.investigations', {
|
||||
defaultMessage: 'Investigations',
|
||||
}),
|
||||
linkIds: [SecurityPageName.notesManagement],
|
||||
},
|
||||
];
|
||||
|
||||
export const links: LinkItem = {
|
||||
|
@ -215,6 +223,18 @@ export const links: LinkItem = {
|
|||
hideTimeline: true,
|
||||
},
|
||||
cloudDefendLink,
|
||||
{
|
||||
id: SecurityPageName.notesManagement,
|
||||
title: NOTES,
|
||||
description: i18n.translate('xpack.securitySolution.appLinks.notesManagementDescription', {
|
||||
defaultMessage: 'Visualize and delete notes.',
|
||||
}),
|
||||
landingIcon: IconTool, // TODO get new icon
|
||||
path: NOTES_MANAGEMENT_PATH,
|
||||
skipUrlState: true,
|
||||
hideTimeline: true,
|
||||
experimentalKey: 'notesEnabled',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Page to allow users to manage notes. The page is accessible via the Investigations section within the Manage page.
|
||||
* // TODO to be implemented
|
||||
*/
|
||||
export const NoteManagementPage = () => {
|
||||
return <></>;
|
||||
};
|
||||
|
||||
NoteManagementPage.displayName = 'NoteManagementPage';
|
|
@ -5,14 +5,38 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
|
||||
import { Timelines } from './pages';
|
||||
import { TIMELINES_PATH } from '../../common/constants';
|
||||
|
||||
import type { SecuritySubPluginRoutes } from '../app/types';
|
||||
import { SecurityPageName } from '../app/types';
|
||||
import { Switch } from 'react-router-dom';
|
||||
import { Route } from '@kbn/shared-ux-router';
|
||||
import { SpyRoute } from '../common/utils/route/spy_routes';
|
||||
import { NotFoundPage } from '../app/404';
|
||||
import { NoteManagementPage } from '../notes/pages/note_management_page';
|
||||
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
|
||||
import { SecurityPageName } from '../app/types';
|
||||
import type { SecuritySubPluginRoutes } from '../app/types';
|
||||
import { NOTES_MANAGEMENT_PATH, TIMELINES_PATH } from '../../common/constants';
|
||||
import { Timelines } from './pages';
|
||||
|
||||
const NoteManagementTelemetry = () => (
|
||||
<PluginTemplateWrapper>
|
||||
<TrackApplicationView viewId={SecurityPageName.notesManagement}>
|
||||
<NoteManagementPage />
|
||||
<SpyRoute pageName={SecurityPageName.notesManagement} />
|
||||
</TrackApplicationView>
|
||||
</PluginTemplateWrapper>
|
||||
);
|
||||
|
||||
const NoteManagementContainer = memo(() => {
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={NOTES_MANAGEMENT_PATH} exact component={NoteManagementTelemetry} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
);
|
||||
});
|
||||
NoteManagementContainer.displayName = 'NoteManagementContainer';
|
||||
|
||||
const TimelinesRoutes = () => (
|
||||
<PluginTemplateWrapper>
|
||||
|
@ -27,4 +51,8 @@ export const routes: SecuritySubPluginRoutes = [
|
|||
path: TIMELINES_PATH,
|
||||
component: TimelinesRoutes,
|
||||
},
|
||||
{
|
||||
path: NOTES_MANAGEMENT_PATH,
|
||||
component: NoteManagementContainer,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -36624,7 +36624,6 @@
|
|||
"xpack.securitySolution.navigation.case": "Cas",
|
||||
"xpack.securitySolution.navigation.coverageOverviewDashboard": "Couverture MITRE ATT&CK®",
|
||||
"xpack.securitySolution.navigation.dashboards": "Tableaux de bord",
|
||||
"xpack.securitySolution.navigation.detect": "Détecter",
|
||||
"xpack.securitySolution.navigation.detectionResponse": "Détection et réponse",
|
||||
"xpack.securitySolution.navigation.detectionRules": "Règles de détection (SIEM)",
|
||||
"xpack.securitySolution.navigation.ecsDataQualityDashboard": "Qualité des données",
|
||||
|
@ -36632,7 +36631,6 @@
|
|||
"xpack.securitySolution.navigation.entityRiskScore": "Score de risque des entités",
|
||||
"xpack.securitySolution.navigation.exceptions": "Listes d'exceptions partagées",
|
||||
"xpack.securitySolution.navigation.explore": "Explorer",
|
||||
"xpack.securitySolution.navigation.findings": "Résultats",
|
||||
"xpack.securitySolution.navigation.gettingStarted": "Démarrer",
|
||||
"xpack.securitySolution.navigation.hosts": "Hôtes",
|
||||
"xpack.securitySolution.navigation.kubernetes": "Kubernetes",
|
||||
|
@ -36644,7 +36642,6 @@
|
|||
"xpack.securitySolution.navigation.protectionUpdates": "Mises à jour de la protection",
|
||||
"xpack.securitySolution.navigation.responseActionsHistory": "Historique des actions de réponse",
|
||||
"xpack.securitySolution.navigation.rules": "Règles",
|
||||
"xpack.securitySolution.navigation.threatIntelligence": "Intelligence",
|
||||
"xpack.securitySolution.navigation.timelines": "Chronologies",
|
||||
"xpack.securitySolution.navigation.users": "Utilisateurs",
|
||||
"xpack.securitySolution.network.ipDetails.ipOverview.asDestinationDropDownOptionLabel": "Comme destination",
|
||||
|
|
|
@ -36599,7 +36599,6 @@
|
|||
"xpack.securitySolution.navigation.case": "ケース",
|
||||
"xpack.securitySolution.navigation.coverageOverviewDashboard": "MITRE ATT&CK®の範囲",
|
||||
"xpack.securitySolution.navigation.dashboards": "ダッシュボード",
|
||||
"xpack.securitySolution.navigation.detect": "検知",
|
||||
"xpack.securitySolution.navigation.detectionResponse": "検出と対応",
|
||||
"xpack.securitySolution.navigation.detectionRules": "検出ルール(SIEM)",
|
||||
"xpack.securitySolution.navigation.ecsDataQualityDashboard": "データ品質",
|
||||
|
@ -36607,7 +36606,6 @@
|
|||
"xpack.securitySolution.navigation.entityRiskScore": "エンティティリスクスコア",
|
||||
"xpack.securitySolution.navigation.exceptions": "共有例外リスト",
|
||||
"xpack.securitySolution.navigation.explore": "探索",
|
||||
"xpack.securitySolution.navigation.findings": "調査結果",
|
||||
"xpack.securitySolution.navigation.gettingStarted": "使ってみる",
|
||||
"xpack.securitySolution.navigation.hosts": "ホスト",
|
||||
"xpack.securitySolution.navigation.kubernetes": "Kubernetes",
|
||||
|
@ -36619,7 +36617,6 @@
|
|||
"xpack.securitySolution.navigation.protectionUpdates": "保護更新",
|
||||
"xpack.securitySolution.navigation.responseActionsHistory": "対応アクション履歴",
|
||||
"xpack.securitySolution.navigation.rules": "ルール",
|
||||
"xpack.securitySolution.navigation.threatIntelligence": "インテリジェンス",
|
||||
"xpack.securitySolution.navigation.timelines": "タイムライン",
|
||||
"xpack.securitySolution.navigation.users": "ユーザー",
|
||||
"xpack.securitySolution.network.ipDetails.ipOverview.asDestinationDropDownOptionLabel": "送信先として",
|
||||
|
|
|
@ -36642,7 +36642,6 @@
|
|||
"xpack.securitySolution.navigation.case": "案例",
|
||||
"xpack.securitySolution.navigation.coverageOverviewDashboard": "MITRE ATT&CK® 支持",
|
||||
"xpack.securitySolution.navigation.dashboards": "仪表板",
|
||||
"xpack.securitySolution.navigation.detect": "检测",
|
||||
"xpack.securitySolution.navigation.detectionResponse": "检测和响应",
|
||||
"xpack.securitySolution.navigation.detectionRules": "检测规则 (SIEM)",
|
||||
"xpack.securitySolution.navigation.ecsDataQualityDashboard": "数据质量",
|
||||
|
@ -36650,7 +36649,6 @@
|
|||
"xpack.securitySolution.navigation.entityRiskScore": "实体风险分数",
|
||||
"xpack.securitySolution.navigation.exceptions": "共享例外列表",
|
||||
"xpack.securitySolution.navigation.explore": "浏览",
|
||||
"xpack.securitySolution.navigation.findings": "结果",
|
||||
"xpack.securitySolution.navigation.gettingStarted": "开始使用",
|
||||
"xpack.securitySolution.navigation.hosts": "主机",
|
||||
"xpack.securitySolution.navigation.kubernetes": "Kubernetes",
|
||||
|
@ -36662,7 +36660,6 @@
|
|||
"xpack.securitySolution.navigation.protectionUpdates": "防护更新",
|
||||
"xpack.securitySolution.navigation.responseActionsHistory": "响应操作历史记录",
|
||||
"xpack.securitySolution.navigation.rules": "规则",
|
||||
"xpack.securitySolution.navigation.threatIntelligence": "情报",
|
||||
"xpack.securitySolution.navigation.timelines": "时间线",
|
||||
"xpack.securitySolution.navigation.users": "用户",
|
||||
"xpack.securitySolution.network.ipDetails.ipOverview.asDestinationDropDownOptionLabel": "作为目标",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue