diff --git a/packages/kbn-babel-preset/styled_components_files.js b/packages/kbn-babel-preset/styled_components_files.js index f9fa1d2f0b43a..50be6833a8006 100644 --- a/packages/kbn-babel-preset/styled_components_files.js +++ b/packages/kbn-babel-preset/styled_components_files.js @@ -286,18 +286,7 @@ module.exports = { /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detection_engine[\/\\]rule_management_ui[\/\\]components[\/\\]rules_table[\/\\]upgrade_prebuilt_rules_table[\/\\]use_ml_jobs_upgrade_modal[\/\\]ml_jobs_upgrade_modal.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detection_engine[\/\\]rule_response_actions[\/\\]response_action_type_form.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detection_engine[\/\\]rule_response_actions[\/\\]response_actions_form.test.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_by_rule_panel[\/\\]alerts_by_rule.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_histogram_panel[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_progress_bar_panel[\/\\]alerts_progress_bar.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_summary_charts_panel[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_treemap_panel[\/\\]alerts_treemap[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]alerts_treemap_panel[\/\\]alerts_treemap[\/\\]no_data[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]chart_panels[\/\\]chart_collapse[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]chart_panels[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]common[\/\\]components.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_kpis[\/\\]severity_level_panel[\/\\]severity_level_chart.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_table[\/\\]additional_filters_action[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]alerts_table[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]osquery[\/\\]osquery_flyout.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]rules[\/\\]pre_packaged_rules[\/\\]load_empty_prompt.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]rules[\/\\]related_integrations[\/\\]integrations_description[\/\\]index.tsx/, @@ -310,8 +299,6 @@ module.exports = { /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]status[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]value_lists_management_flyout[\/\\]reference_error_modal[\/\\]reference_error_modal.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]components[\/\\]value_lists_management_flyout[\/\\]table_helpers.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]pages[\/\\]detection_engine[\/\\]detection_engine.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]detections[\/\\]pages[\/\\]detection_engine[\/\\]rules[\/\\]helpers.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]asset_criticality[\/\\]asset_criticality_selector.stories.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]asset_criticality_file_uploader[\/\\]asset_criticality_file_uploader.stories.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]exceptions[\/\\]components[\/\\]exceptions_utility[\/\\]index.tsx/, diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 2cb95a100463c..f8c4636011a60 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -34471,7 +34471,6 @@ "xpack.securitySolution.components.chartCollapse.noResultMessage": "Aucun", "xpack.securitySolution.components.chartCollapse.topGroup": "Générant le plus d'alertes", "xpack.securitySolution.components.chartCollapse.topRule": "Règle Générant le plus d'alertes :", - "xpack.securitySolution.components.chartSelect.chartsOption": "Graphiques", "xpack.securitySolution.components.chartSelect.chartsOptionTitle": "Résumé", "xpack.securitySolution.components.chartSelect.legendTitle": "Sélectionner un onglet", "xpack.securitySolution.components.chartSelect.tableOptionTitle": "Comptes", @@ -34770,12 +34769,9 @@ "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.sourceLabel": "source", "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.userNameLabel": "utilisateur", "xpack.securitySolution.detectionEngine.alerts.alertsByType.alertRuleChartTitle": "Alertes par nom", - "xpack.securitySolution.detectionEngine.alerts.chartsTitle": "Graphiques", "xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage": "Impossible de fermer l'alerte ou les alertes.", "xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle": "Fermé", "xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage": "Fermeture réussie de {totalAlerts} {totalAlerts, plural, =1 {alerte} other {alertes}}.", - "xpack.securitySolution.detectionEngine.alerts.count.columnLabel": "{topN} principales valeurs de {fieldName}", - "xpack.securitySolution.detectionEngine.alerts.count.countTableColumnTitle": "Nombre d'enregistrements", "xpack.securitySolution.detectionEngine.alerts.count.countTableTitle": "Décompte", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailure": "Impossible de créer une chronologie pour l’ID de document : {id}", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailureTitle": "Impossible de créer une chronologie d'alerte de nouveaux termes", @@ -34785,7 +34781,6 @@ "xpack.securitySolution.detectionEngine.alerts.createThresholdTimelineFailureTitle": "Impossible de créer une chronologie d'alerte de seuil", "xpack.securitySolution.detectionEngine.alerts.fetchExceptionFilterFailure": "Erreur lors de la récupération du filtre d'exception.", "xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle": "Tendance", - "xpack.securitySolution.detectionEngine.alerts.histogram.notAvailableTooltip": "Non disponible pour la vue de tendance", "xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "Affichage de : {modifier}{totalAlertsFormatted} {totalAlerts, plural, =1 {alerte} other {alertes}}", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByLabel": "Regrouper par", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByTopLabel": "Regrouper par top", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 0082247b82e70..444b39f09ffc8 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -34333,7 +34333,6 @@ "xpack.securitySolution.components.chartCollapse.noResultMessage": "なし", "xpack.securitySolution.components.chartCollapse.topGroup": "上位のアラート", "xpack.securitySolution.components.chartCollapse.topRule": "上位のアラートルール:", - "xpack.securitySolution.components.chartSelect.chartsOption": "チャート", "xpack.securitySolution.components.chartSelect.chartsOptionTitle": "まとめ", "xpack.securitySolution.components.chartSelect.legendTitle": "タブを選択", "xpack.securitySolution.components.chartSelect.tableOptionTitle": "カウント", @@ -34631,12 +34630,9 @@ "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.sourceLabel": "ソース", "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.userNameLabel": "ユーザー", "xpack.securitySolution.detectionEngine.alerts.alertsByType.alertRuleChartTitle": "名前別アラート", - "xpack.securitySolution.detectionEngine.alerts.chartsTitle": "チャート", "xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage": "アラートをクローズできませんでした。", "xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle": "停止中", "xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, other {件のアラート}}を正常にクローズしました。", - "xpack.securitySolution.detectionEngine.alerts.count.columnLabel": "{fieldName}の上位{topN}の値", - "xpack.securitySolution.detectionEngine.alerts.count.countTableColumnTitle": "レコード数", "xpack.securitySolution.detectionEngine.alerts.count.countTableTitle": "カウント", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailure": "document _idのタイムラインを作成できませんでした:{id}", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailureTitle": "新しい用語アラートタイムラインを作成できませんでした", @@ -34646,7 +34642,6 @@ "xpack.securitySolution.detectionEngine.alerts.createThresholdTimelineFailureTitle": "しきい値アラートタイムラインを作成できませんでした", "xpack.securitySolution.detectionEngine.alerts.fetchExceptionFilterFailure": "例外フィルターの取得エラー。", "xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle": "傾向", - "xpack.securitySolution.detectionEngine.alerts.histogram.notAvailableTooltip": "傾向ビューでは使用できません", "xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "{modifier}{totalAlertsFormatted} {totalAlerts, plural, other {件のアラート}}を表示しています", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByLabel": "グループ分けの条件", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByTopLabel": "上位でグループ化", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 8e5e3514bb8f2..74732ac411f3f 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -33802,7 +33802,6 @@ "xpack.securitySolution.components.chartCollapse.noResultMessage": "无", "xpack.securitySolution.components.chartCollapse.topGroup": "排名靠前已告警项", "xpack.securitySolution.components.chartCollapse.topRule": "排名靠前已告警规则:", - "xpack.securitySolution.components.chartSelect.chartsOption": "图表", "xpack.securitySolution.components.chartSelect.chartsOptionTitle": "摘要", "xpack.securitySolution.components.chartSelect.legendTitle": "选择选项卡", "xpack.securitySolution.components.chartSelect.tableOptionTitle": "计数", @@ -34101,12 +34100,9 @@ "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.sourceLabel": "源", "xpack.securitySolution.detectionEngine.alerts.alertsByGrouping.userNameLabel": "user", "xpack.securitySolution.detectionEngine.alerts.alertsByType.alertRuleChartTitle": "按名称排列的告警", - "xpack.securitySolution.detectionEngine.alerts.chartsTitle": "图表", "xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage": "无法关闭告警。", "xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle": "已关闭", "xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage": "已成功关闭 {totalAlerts} 个{totalAlerts, plural, other {告警}}。", - "xpack.securitySolution.detectionEngine.alerts.count.columnLabel": "排名前 {topN} 的 {fieldName} 值", - "xpack.securitySolution.detectionEngine.alerts.count.countTableColumnTitle": "记录计数", "xpack.securitySolution.detectionEngine.alerts.count.countTableTitle": "计数", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailure": "无法创建文档 _id 的时间线:{id}", "xpack.securitySolution.detectionEngine.alerts.createNewTermsTimelineFailureTitle": "无法创建新的字词告警时间线", @@ -34116,7 +34112,6 @@ "xpack.securitySolution.detectionEngine.alerts.createThresholdTimelineFailureTitle": "无法创建阈值告警时间线", "xpack.securitySolution.detectionEngine.alerts.fetchExceptionFilterFailure": "提取例外筛选时出错。", "xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle": "趋势", - "xpack.securitySolution.detectionEngine.alerts.histogram.notAvailableTooltip": "不适用于趋势视图", "xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "正在显示:{modifier}{totalAlertsFormatted} 个{totalAlerts, plural, other {告警}}", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByLabel": "分组依据", "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.groupByTopLabel": "按顶部分组", diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/top_n/top_n.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/top_n/top_n.tsx index 7b21dcd945d8d..4bab8b0c64954 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/top_n/top_n.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/top_n/top_n.tsx @@ -142,7 +142,6 @@ const TopNComponent: React.FC = ({ filters={applicableFilters} headerChildren={headerChildren} onlyField={field} - paddingSize={paddingSize} setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget} hideQueryToggle /> diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 5a5fa5e10795a..a12154be33afc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -747,6 +747,7 @@ const RuleDetailsPageComponent: React.FC = ({ filters={alertMergedFilters} signalIndexName={signalIndexName} defaultStackByOption={defaultRuleStackByOption} + title={i18n.HISTOGRAM_HEADER} updateDateRange={updateDateRangeCallback} /> diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts index 0fc2b5952c5de..4f75af0ab110e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts @@ -76,3 +76,10 @@ export const DELETE_CONFIRMATION_BODY = i18n.translate( defaultMessage: 'This action will delete the rule. Click "Delete" to continue.', } ); + +export const HISTOGRAM_HEADER = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle', + { + defaultMessage: 'Trend', + } +); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_rule_panel/alerts_by_rule.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_rule_panel/alerts_by_rule.tsx index 4cda599776fa9..34bff7c0c5222 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_rule_panel/alerts_by_rule.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_rule_panel/alerts_by_rule.tsx @@ -6,9 +6,9 @@ */ import type { EuiBasicTableColumn } from '@elastic/eui'; -import { EuiInMemoryTable, EuiSpacer, EuiText } from '@elastic/eui'; +import { EuiInMemoryTable, EuiSpacer, EuiText, useEuiTheme } from '@elastic/eui'; import React from 'react'; -import styled from 'styled-components'; +import { css } from '@emotion/react'; import type { SortOrder } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { ALERT_RULE_NAME } from '@kbn/rule-data-utils'; import { TableId } from '@kbn/securitysolution-data-table'; @@ -18,18 +18,13 @@ import { ALERTS_HEADERS_RULE_NAME } from '../../alerts_table/translations'; import { COUNT_TABLE_TITLE } from '../alerts_count_panel/translations'; import { CellActionsMode, - SecurityCellActionsTrigger, SecurityCellActions, + SecurityCellActionsTrigger, SecurityCellActionType, } from '../../../../common/components/cell_actions'; import { getSourcererScopeId } from '../../../../helpers'; -const Wrapper = styled.div` - margin-top: -${({ theme }) => theme.eui.euiSizeM}; -`; -const TableWrapper = styled.div` - height: 210px; -`; +const TABLE_HEIGHT = 210; // px export interface AlertsByRuleProps { data: AlertsByRuleData[]; @@ -89,16 +84,28 @@ const SORTING: { sort: { field: keyof AlertsByRuleData; direction: SortOrder } } }, }; -const PAGINATION: {} = { +const PAGINATION = { pageSize: 25, showPerPageOptions: false, }; export const AlertsByRule: React.FC = ({ data, isLoading }) => { + const { euiTheme } = useEuiTheme(); + return ( - +
- +
= ({ data, isLoading }) = sorting={SORTING} pagination={PAGINATION} /> - - +
+
); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.test.tsx index 806be83a738d3..504a1b582ae1f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.test.tsx @@ -10,12 +10,9 @@ import { act } from '@testing-library/react'; import { mount } from 'enzyme'; import type { Action } from '@kbn/ui-actions-plugin/public'; import { AlertsCountPanel } from '.'; - -import type { Status } from '../../../../../common/api/detection_engine'; import { DEFAULT_STACK_BY_FIELD, DEFAULT_STACK_BY_FIELD1 } from '../common/config'; import { TestProviders } from '../../../../common/mock'; import { ChartContextMenu } from '../chart_panels/chart_context_menu'; -import { COUNTS } from '../chart_panels/chart_select/translations'; import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; const from = '2022-07-28T08:20:18.966Z'; @@ -46,18 +43,17 @@ jest.mock('../common/hooks', () => ({ const mockSetIsExpanded = jest.fn(); const defaultProps = { - inspectTitle: COUNTS, - signalIndexName: 'signalIndexName', - stackByField0: DEFAULT_STACK_BY_FIELD, - stackByField1: DEFAULT_STACK_BY_FIELD1, + chartOptionsContextMenu: jest.fn(), + extraActions: [{ id: 'resetGroupByFields' }] as Action[], + filters: [], + panelHeight: 300, setStackByField0: jest.fn(), setStackByField1: jest.fn(), + stackByField0: DEFAULT_STACK_BY_FIELD, + stackByField1: DEFAULT_STACK_BY_FIELD1, + title:
{'test'}
, isExpanded: true, setIsExpanded: mockSetIsExpanded, - showBuildingBlockAlerts: false, - showOnlyThreatIndicatorAlerts: false, - status: 'open' as Status, - extraActions: [{ id: 'resetGroupByFields' }] as Action[], }; describe('AlertsCountPanel', () => { @@ -77,34 +73,6 @@ describe('AlertsCountPanel', () => { }); }); - it('renders with the specified `alignHeader` alignment', async () => { - await act(async () => { - const wrapper = mount( - - - - ); - - expect( - wrapper.find('[data-test-subj="headerSectionInnerFlexGroup"]').last().getDOMNode().className - ).toContain('flexEnd'); - }); - }); - - it('renders the inspect button by default', async () => { - await act(async () => { - const wrapper = mount( - - - - ); - - expect(wrapper.find('button[data-test-subj="inspect-icon-button"]').first().exists()).toBe( - true - ); - }); - }); - it('it does NOT render the inspect button when a `chartOptionsContextMenu` is provided', async () => { const chartOptionsContextMenu = (queryId: string) => ( { expect(wrapper.find('[data-test-subj="visualization-embeddable"]').exists()).toEqual(true); }); }); + it('when isExpanded is false, hide counts panel', async () => { await act(async () => { const wrapper = mount( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.tsx index a9d9821601d25..c0b691190a0b5 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/index.tsx @@ -21,14 +21,13 @@ import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; export const DETECTIONS_ALERTS_COUNT_ID = 'detections-alerts-count'; +const CHART_HEIGHT = 218; // px interface AlertsCountPanelProps { - alignHeader?: 'center' | 'baseline' | 'stretch' | 'flexStart' | 'flexEnd'; - chartOptionsContextMenu?: (queryId: string) => React.ReactNode; - extraActions?: Action[]; - filters?: Filter[]; - inspectTitle: string; - panelHeight?: number; + chartOptionsContextMenu: (queryId: string) => React.ReactNode; + extraActions: Action[]; + filters: Filter[]; + panelHeight: number; setStackByField0: (stackBy: string) => void; setStackByField0ComboboxInputRef?: (inputRef: HTMLInputElement | null) => void; setStackByField1: (stackBy: string | undefined) => void; @@ -37,20 +36,16 @@ interface AlertsCountPanelProps { stackByField0ComboboxRef?: React.RefObject>; stackByField1: string | undefined; stackByField1ComboboxRef?: React.RefObject>; - stackByWidth?: number; - title?: React.ReactNode; + title: React.ReactNode; isExpanded: boolean; setIsExpanded: (status: boolean) => void; } -const CHART_HEIGHT = 218; // px export const AlertsCountPanel = memo( ({ - alignHeader, chartOptionsContextMenu, extraActions, filters, - inspectTitle, panelHeight, setStackByField0, setStackByField0ComboboxInputRef, @@ -60,7 +55,6 @@ export const AlertsCountPanel = memo( stackByField0ComboboxRef, stackByField1, stackByField1ComboboxRef, - stackByWidth, title = i18n.COUNT_TABLE_TITLE, isExpanded, setIsExpanded, @@ -81,15 +75,14 @@ export const AlertsCountPanel = memo( return ( ( stackByField0ComboboxRef={stackByField0ComboboxRef} stackByField1={stackByField1} stackByField1ComboboxRef={stackByField1ComboboxRef} - stackByWidth={stackByWidth} uniqueQueryId={uniqueQueryId} useLensCompatibleFields={true} /> @@ -120,7 +112,7 @@ export const AlertsCountPanel = memo( getLensAttributes={getLensAttributes} height={CHART_HEIGHT} id={`${uniqueQueryId}-embeddable`} - inspectTitle={inspectTitle} + inspectTitle={i18n.COUNTS} scopeId={SourcererScopeName.detections} stackByField={stackByField0} timerange={timerange} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/translations.ts index 14f4d38003d58..57df8c3f81665 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/translations.ts @@ -7,10 +7,10 @@ import { i18n } from '@kbn/i18n'; -export const COUNT_TABLE_COLUMN_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.count.countTableColumnTitle', +export const COUNTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.count.tableOptionTitle', { - defaultMessage: 'Count of records', + defaultMessage: 'Counts', } ); @@ -21,10 +21,4 @@ export const COUNT_TABLE_TITLE = i18n.translate( } ); -export const COLUMN_LABEL = ({ fieldName, topN }: { fieldName: string; topN: number }) => - i18n.translate('xpack.securitySolution.detectionEngine.alerts.count.columnLabel', { - values: { fieldName, topN }, - defaultMessage: 'Top {topN} values of {fieldName}', - }); - export * from '../common/translations'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx index b19f8b8ad607a..889168d8d4abe 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx @@ -111,14 +111,13 @@ jest.mock('../../../../common/components/visualization_actions/use_visualization const mockSetIsExpanded = jest.fn(); const defaultProps = { - setQuery: jest.fn(), - showBuildingBlockAlerts: false, - showOnlyThreatIndicatorAlerts: false, - showTotalAlertsCount: true, + filters: [], signalIndexName: 'signalIndexName', + title:
{'test'}
, updateDateRange: jest.fn(), isExpanded: true, setIsExpanded: mockSetIsExpanded, + showTotalAlertsCount: true, }; const mockSetToggle = jest.fn(); const mockUseQueryToggle = useQueryToggle as jest.Mock; @@ -231,42 +230,6 @@ describe('AlertsHistogramPanel', () => { }); }); - describe('stackByWidth', () => { - test('it renders the first StackByComboBox with the specified `stackByWidth`', () => { - const stackByWidth = 1234; - - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="stackByComboBox"]').first()).toHaveStyleRule( - 'width', - `${stackByWidth}px` - ); - }); - - test('it renders the placeholder StackByComboBox with the specified `stackByWidth`', () => { - const stackByWidth = 1234; - - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="stackByPlaceholder"]').first()).toHaveStyleRule( - 'width', - `${stackByWidth}px` - ); - }); - }); - describe('placeholder spacer', () => { test('it does NOT render the group by placeholder spacer by default', () => { const wrapper = mount( @@ -276,15 +239,6 @@ describe('AlertsHistogramPanel', () => { ); expect(wrapper.find('[data-test-subj="placeholderSpacer"]').exists()).toBe(false); }); - - test('it renders the placeholder spacer when `showGroupByPlaceholder` is true', () => { - const wrapper = mount( - - - - ); - expect(wrapper.find('[data-test-subj="placeholderSpacer"]').exists()).toBe(true); - }); }); describe('placeholder tooltip', () => { @@ -296,15 +250,6 @@ describe('AlertsHistogramPanel', () => { ); expect(wrapper.find('[data-test-subj="placeholderTooltip"]').exists()).toBe(false); }); - - test('it renders the placeholder tooltip when `showGroupByPlaceholder` is true', () => { - const wrapper = mount( - - - - ); - expect(wrapper.find('[data-test-subj="placeholderTooltip"]').exists()).toBe(true); - }); }); describe('placeholder', () => { @@ -316,15 +261,6 @@ describe('AlertsHistogramPanel', () => { ); expect(wrapper.find('[data-test-subj="stackByPlaceholder"]').exists()).toBe(false); }); - - test('it renders the placeholder when `showGroupByPlaceholder` is true', () => { - const wrapper = mount( - - - - ); - expect(wrapper.find('[data-test-subj="stackByPlaceholder"]').exists()).toBe(true); - }); }); describe('Button view alerts', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx index 0c1c33da81e50..9e0ac74ac8adc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx @@ -6,17 +6,15 @@ */ import type { Action } from '@kbn/ui-actions-plugin/public'; +import { css } from '@emotion/react'; import type { EuiComboBox, EuiTitleSize } from '@elastic/eui'; -import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiToolTip } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import type { SyntheticEvent } from 'react'; -import React, { memo, useCallback, useMemo, useState, useEffect } from 'react'; -import styled from 'styled-components'; -import { isEmpty, noop } from 'lodash/fp'; +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; +import { isEmpty } from 'lodash/fp'; import { v4 as uuidv4 } from 'uuid'; import { sumBy } from 'lodash'; - import type { Filter } from '@kbn/es-query'; - import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { APP_UI_ID } from '../../../../../common/constants'; import type { UpdateDateRange } from '../../../../common/components/charts/common'; @@ -24,19 +22,17 @@ import { HeaderSection } from '../../../../common/components/header_section'; import { getDetectionEngineUrl, useFormatUrl } from '../../../../common/components/link_to'; import { useKibana } from '../../../../common/lib/kibana'; import { - showInitialLoadingSpinner, - createGenericSubtitle, createEmbeddedDataSubtitle, + createGenericSubtitle, + showInitialLoadingSpinner, } from './helpers'; import * as i18n from './translations'; import { LinkButton } from '../../../../common/components/links'; import { SecurityPageName } from '../../../../app/types'; -import { DEFAULT_STACK_BY_FIELD, PANEL_HEIGHT } from '../common/config'; +import { DEFAULT_STACK_BY_FIELD } from '../common/config'; import type { AlertsStackByField } from '../common/types'; import { KpiPanel, StackByComboBox } from '../common/components'; - import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { GROUP_BY_TOP_LABEL } from '../common/translations'; import { getAlertsHistogramLensAttributes as getLensAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram'; import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; @@ -44,11 +40,6 @@ import { useAlertHistogramCount } from '../../../hooks/alerts_visualization/use_ import { useVisualizationResponse } from '../../../../common/components/visualization_actions/use_visualization_response'; export const DETECTIONS_HISTOGRAM_ID = 'detections-histogram'; - -const ViewAlertsFlexItem = styled(EuiFlexItem)` - margin-left: ${({ theme }) => theme.eui.euiSizeL}; -`; - const CHART_HEIGHT = 155; // px interface AlertsHistogramPanelProps { @@ -57,24 +48,20 @@ interface AlertsHistogramPanelProps { comboboxRef?: React.RefObject>; defaultStackByOption?: string; extraActions?: Action[]; - filters?: Filter[]; + filters: Filter[]; headerChildren?: React.ReactNode; inspectTitle?: React.ReactNode; onFieldSelected?: (field: string) => void; /** Override all defaults, and only display this field */ onlyField?: AlertsStackByField; - paddingSize?: 's' | 'm' | 'l' | 'none'; panelHeight?: number; setComboboxInputRef?: (inputRef: HTMLInputElement | null) => void; - showGroupByPlaceholder?: boolean; showLinkToAlerts?: boolean; showStackBy?: boolean; showTotalAlertsCount?: boolean; signalIndexName: string | null; stackByLabel?: string; - stackByWidth?: number; - timelineId?: string; - title?: React.ReactNode; + title: React.ReactNode; titleSize?: EuiTitleSize; updateDateRange: UpdateDateRange; hideQueryToggle?: boolean; @@ -94,21 +81,19 @@ export const AlertsHistogramPanel = memo( inspectTitle, onFieldSelected, onlyField, - paddingSize = 'm', - panelHeight = PANEL_HEIGHT, + panelHeight, setComboboxInputRef, - showGroupByPlaceholder = false, showLinkToAlerts = false, showStackBy = true, showTotalAlertsCount = false, stackByLabel, - stackByWidth, - title = i18n.HISTOGRAM_HEADER, - titleSize = 'm', + title, + titleSize = 's', hideQueryToggle = false, isExpanded, setIsExpanded, }) => { + const { euiTheme } = useEuiTheme(); const { to, from } = useGlobalTime(); // create a unique, but stable (across re-renders) query id @@ -185,7 +170,12 @@ export const AlertsHistogramPanel = memo( const linkButton = useMemo(() => { if (showLinkToAlerts) { return ( - + ( > {i18n.VIEW_ALERTS} - + ); } - }, [showLinkToAlerts, goToDetectionEngine, formatUrl]); + }, [showLinkToAlerts, euiTheme.size.l, goToDetectionEngine, formatUrl]); const titleText = useMemo( () => (onlyField == null ? title : i18n.TOP(onlyField)), @@ -226,10 +216,8 @@ export const AlertsHistogramPanel = memo( return ( ( {showStackBy && ( - <> - - {showGroupByPlaceholder && ( - <> - - - - - - )} - + )} {headerChildren != null && headerChildren} @@ -292,7 +258,7 @@ export const AlertsHistogramPanel = memo( filters, }} getLensAttributes={getLensAttributes} - height={chartHeight ?? CHART_HEIGHT} + height={chartHeight} id={visualizationId} inspectTitle={inspectTitle ?? title} scopeId={SourcererScopeName.detections} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/translations.ts index 0f5e48a2399cc..3f97ae1e1c8ae 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/translations.ts @@ -13,20 +13,6 @@ export const TOP = (fieldName: string) => defaultMessage: `Top {fieldName}`, }); -export const HISTOGRAM_HEADER = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle', - { - defaultMessage: 'Trend', - } -); - -export const NOT_AVAILABLE_TOOLTIP = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.histogram.notAvailableTooltip', - { - defaultMessage: 'Not available for trend view', - } -); - export const VIEW_ALERTS = i18n.translate( 'xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel', { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/alerts_progress_bar.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/alerts_progress_bar.tsx index bfd5ed32f9021..94b51f000ea92 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/alerts_progress_bar.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/alerts_progress_bar.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { EuiButtonIcon, EuiFlexGroup, @@ -18,45 +19,20 @@ import { useEuiTheme, } from '@elastic/eui'; import React, { useMemo, useState } from 'react'; -import styled from 'styled-components'; +import { css } from '@emotion/react'; import { TableId } from '@kbn/securitysolution-data-table'; import type { AlertsProgressBarData, GroupBySelection } from './types'; import type { AddFilterProps } from '../common/types'; import { getAggregateData } from './helpers'; import * as i18n from './translations'; import { - SecurityCellActionType, CellActionsMode, - SecurityCellActionsTrigger, SecurityCellActions, + SecurityCellActionsTrigger, + SecurityCellActionType, } from '../../../../common/components/cell_actions'; import { getSourcererScopeId } from '../../../../helpers'; -const ProgressWrapper = styled.div` - height: 160px; -`; - -const StyledEuiHorizontalRule = styled(EuiHorizontalRule)` - margin-top: 0; - margin-bottom: ${({ theme }) => theme.eui.euiSizeS}; -`; - -const StyledEuiFlexGroup = styled(EuiFlexGroup)` - margin-top: -${({ theme }) => theme.eui.euiSizeM}; -`; - -const StyledEuiProgress = styled(EuiProgress)` - margin-bottom: ${({ theme }) => theme.eui.euiSizeS}; -`; - -const DataStatsWrapper = styled.div` - width: 250px; -`; - -const EmptyAction = styled.div` - padding-left: ${({ theme }) => theme.eui.euiSizeL}; -`; - /** * Individual progress bar per row */ @@ -94,6 +70,8 @@ const ProgressBarRow: React.FC<{ item: AlertsProgressBarData }> = ({ item }) => ); }; +const HEIGHT = 160; // px + export interface AlertsProcessBarProps { data: AlertsProgressBarData[]; isLoading: boolean; @@ -107,6 +85,7 @@ export const AlertsProgressBar: React.FC = ({ addFilter, groupBySelection, }) => { + const { euiTheme } = useEuiTheme(); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const onButtonClick = () => setIsPopoverOpen(!isPopoverOpen); const closePopover = () => setIsPopoverOpen(false); @@ -125,7 +104,11 @@ export const AlertsProgressBar: React.FC = ({ ); const dataStatsMessage = ( - +
{i18n.DATA_STATISTICS_TITLE(formattedNonEmptyPercent)} {i18n.DATA_STATISTICS_MESSAGE(groupBySelection)} @@ -141,12 +124,18 @@ export const AlertsProgressBar: React.FC = ({ {i18n.NON_EMPTY_FILTER(groupBySelection)} - +
); return ( <> - +
{groupBySelection}
@@ -163,13 +152,30 @@ export const AlertsProgressBar: React.FC = ({ {dataStatsMessage}
-
+
{isLoading ? ( - + ) : ( <> - - + +
{nonEmpty === 0 ? ( <> @@ -204,7 +210,11 @@ export const AlertsProgressBar: React.FC = ({ extraActionsColor="text" /> ) : ( - +
)} @@ -214,7 +224,7 @@ export const AlertsProgressBar: React.FC = ({ )} - +
)} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.test.tsx index 4513a0591803a..8bb6f712106a6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { act, render, fireEvent, waitFor } from '@testing-library/react'; +import { act, fireEvent, render, waitFor } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; import { AlertsSummaryChartsPanel } from '.'; @@ -21,7 +21,12 @@ jest.mock('react-router-dom', () => { describe('AlertsSummaryChartsPanel', () => { const mockSetIsExpanded = jest.fn(); const defaultProps = { + addFilter: jest.fn(), + filters: [], + panelHeight: 100, + query: { query: '', language: '' }, signalIndexName: 'signalIndexName', + title:
{'test'}
, isExpanded: true, setIsExpanded: mockSetIsExpanded, groupBySelection: 'host.name' as GroupBySelection, @@ -39,19 +44,6 @@ describe('AlertsSummaryChartsPanel', () => { }); }); - test('it renders the header with the specified `alignHeader` alignment', async () => { - await act(async () => { - const { container } = render( - - - - ); - expect( - container.querySelector('[data-test-subj="headerSectionInnerFlexGroup"]')?.classList[1] - ).toContain('flexEnd'); - }); - }); - describe('Query', () => { test('it render with a illegal KQL', async () => { jest.mock('@kbn/es-query', () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.tsx index 791f8eb9dc1ce..fb7a28ce7d388 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/index.tsx @@ -4,12 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; + +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; +import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import React, { useCallback } from 'react'; import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types'; import type { Filter, Query } from '@kbn/es-query'; -import styled from 'styled-components'; -import * as i18n from './translations'; import { KpiPanel } from '../common/components'; import { HeaderSection } from '../../../../common/components/header_section'; import { SeverityLevelPanel } from '../severity_level_panel'; @@ -18,23 +19,17 @@ import { AlertsProgressBarPanel } from '../alerts_progress_bar_panel'; import type { GroupBySelection } from '../alerts_progress_bar_panel/types'; import type { AddFilterProps } from '../common/types'; -const StyledFlexGroup = styled(EuiFlexGroup)` - @media only screen and (min-width: ${({ theme }) => theme.eui.euiBreakpoints.l}) { - } -`; - const StyledFlexItem = styled(EuiFlexItem)` min-width: 355px; `; interface Props { - alignHeader?: 'center' | 'baseline' | 'stretch' | 'flexStart' | 'flexEnd'; - filters?: Filter[]; - addFilter?: ({ field, value, negate }: AddFilterProps) => void; - panelHeight?: number; - query?: Query; + addFilter: ({ field, value, negate }: AddFilterProps) => void; + filters: Filter[]; + panelHeight: number; + query: Query; signalIndexName: string | null; - title?: React.ReactNode; + title: React.ReactNode; runtimeMappings?: MappingRuntimeFields; isExpanded: boolean; setIsExpanded: (status: boolean) => void; @@ -43,19 +38,20 @@ interface Props { } export const AlertsSummaryChartsPanel: React.FC = ({ - alignHeader, - filters, addFilter, + filters, panelHeight, query, runtimeMappings, signalIndexName, - title = i18n.CHARTS_TITLE, + title, isExpanded, setIsExpanded, groupBySelection, setGroupBySelection, }: Props) => { + const { euiTheme } = useEuiTheme(); + const toggleQuery = useCallback( (status: boolean) => { setIsExpanded(status); @@ -64,14 +60,9 @@ export const AlertsSummaryChartsPanel: React.FC = ({ ); return ( - + = ({ toggleQuery={toggleQuery} /> {isExpanded && ( - = ({ addFilter={addFilter} /> - + )} ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/translations.ts deleted file mode 100644 index c55bca449e82d..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_summary_charts_panel/translations.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; - -export const CHARTS_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.chartsTitle', - { - defaultMessage: 'Charts', - } -); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.test.tsx index ea0c7a3f2d0dd..9263fae14e34a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.test.tsx @@ -8,7 +8,6 @@ import { render, screen } from '@testing-library/react'; import { Settings } from '@elastic/charts'; import React from 'react'; - import { TestProviders } from '../../../../../common/mock'; import { mockAlertSearchResponse, @@ -23,7 +22,6 @@ import { AlertsTreemap } from '.'; const defaultProps: Props = { data: mockAlertSearchResponse, maxBuckets: 1000, - minChartHeight: 370, stackByField0: 'kibana.alert.rule.name', stackByField1: 'host.name', }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx index ac8c08878881a..37b221efbefd3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx @@ -10,8 +10,7 @@ import { Chart, Partition, PartitionLayout, Settings } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; - +import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; import { useThemes } from '../../../../../common/components/charts/common'; import { DraggableLegend } from '../../../../../common/components/charts/draggable_legend'; @@ -39,24 +38,14 @@ export interface Props { addFilter?: ({ field, value }: { field: string; value: string | number }) => void; data: AlertSearchResponse; maxBuckets: number; - minChartHeight?: number; stackByField0: string; stackByField1: string | undefined; } -const LegendContainer = styled.div` - margin-left: ${({ theme }) => theme.eui.euiSizeS}; -`; - -const ChartFlexItem = styled(EuiFlexItem)<{ $minChartHeight: number }>` - min-height: ${({ $minChartHeight }) => `${$minChartHeight}px`}; -`; - const AlertsTreemapComponent: React.FC = ({ addFilter, data, maxBuckets, - minChartHeight = DEFAULT_MIN_CHART_HEIGHT, stackByField0, stackByField1, }: Props) => { @@ -170,7 +159,12 @@ const AlertsTreemapComponent: React.FC = ({ return (
- + {stackByField1 != null && !isEmpty(stackByField1) && normalizedData.length === 0 ? ( ) : ( @@ -191,21 +185,25 @@ const AlertsTreemapComponent: React.FC = ({ /> )} - + - - - {legendItems.length > 0 && ( + {legendItems.length > 0 && ( + +
- )} - - +
+
+ )}
); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/no_data/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/no_data/index.tsx index d60b0bbba1852..72e8f04e085d8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/no_data/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/no_data/index.tsx @@ -7,34 +7,40 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; import React from 'react'; -import styled from 'styled-components'; - +import { css } from '@emotion/react'; import * as i18n from '../translations'; -const NoDataLabel = styled(EuiText)` - text-align: center; -`; - interface Props { reason?: string; } const NoDataComponent: React.FC = ({ reason }) => ( - - - + + + {i18n.NO_DATA_LABEL} - - - {reason != null && ( - <> - - - {reason} - - - )} +
+ + {reason != null && ( + + + + {reason} + + + )} ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.test.tsx index 6ad6ae488ce5e..fc93d5c321a9a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.test.tsx @@ -14,7 +14,6 @@ import { DEFAULT_STACK_BY_FIELD, DEFAULT_STACK_BY_FIELD1 } from '../common/confi import { useQueryAlerts } from '../../../containers/detection_engine/alerts/use_query'; import { ChartContextMenu } from '../chart_panels/chart_context_menu'; import { ChartSelect } from '../chart_panels/chart_select'; -import { TREEMAP } from '../chart_panels/chart_select/translations'; import { TestProviders } from '../../../../common/mock/test_providers'; import type { Props } from '.'; import { AlertsTreemapPanel } from '.'; @@ -51,7 +50,6 @@ jest.mock('../../../containers/detection_engine/alerts/use_query', () => ({ const defaultProps: Props = { addFilter: jest.fn(), - alignHeader: 'flexStart', chartOptionsContextMenu: (queryId: string) => ( ), - inspectTitle: TREEMAP, isPanelExpanded: true, filters: [ { @@ -97,19 +94,12 @@ const defaultProps: Props = { }, }, ], + height: 100, query: { query: '', language: 'kuery', }, riskSubAggregationField: 'signal.rule.risk_score', - runtimeMappings: { - test_via_alerts_table: { - type: 'keyword', - script: { - source: 'emit("Hello World!");', - }, - }, - }, setIsPanelExpanded: jest.fn(), setStackByField0: jest.fn(), setStackByField1: jest.fn(), @@ -147,52 +137,6 @@ describe('AlertsTreemapPanel', () => { await waitFor(() => expect(screen.getByTestId('treemapPanel')).toBeInTheDocument()); }); - it('renders the panel with a hidden overflow-x', async () => { - render( - - - - ); - - await waitFor(() => - expect(screen.getByTestId('treemapPanel')).toHaveStyleRule('overflow-x', 'hidden') - ); - }); - - it('renders the panel with the expected class to style the overflow-y scroll bar', async () => { - render( - - - - ); - - await waitFor(() => expect(screen.getByTestId('treemapPanel')).toHaveClass('eui-yScroll')); - }); - - it('renders the panel with an auto overflow-y to allow vertical scrolling when necessary when the panel is expanded', async () => { - render( - - - - ); - - await waitFor(() => - expect(screen.getByTestId('treemapPanel')).toHaveStyleRule('overflow-y', 'auto') - ); - }); - - it('renders the panel with a hidden overflow-y when the panel is NOT expanded', async () => { - render( - - - - ); - - await waitFor(() => - expect(screen.getByTestId('treemapPanel')).toHaveStyleRule('overflow-y', 'hidden') - ); - }); - it('renders the chart selector as a custom header title', async () => { render( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.tsx index daff3097acb4d..f277554a7f8e1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/index.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types'; import type { EuiComboBox } from '@elastic/eui'; import { EuiProgress } from '@elastic/eui'; import type { Filter, Query } from '@kbn/es-query'; @@ -13,7 +12,7 @@ import { buildEsQuery } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; import React, { useEffect, useMemo } from 'react'; import { v4 as uuidv4 } from 'uuid'; - +import { i18n } from '@kbn/i18n'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { AlertsTreemap, DEFAULT_MIN_CHART_HEIGHT } from './alerts_treemap'; import { KpiPanel } from '../common/components'; @@ -27,23 +26,21 @@ import { DEFAULT_STACK_BY_FIELD0_SIZE, getAlertsRiskQuery } from './alerts_treem import type { AlertsTreeMapAggregation } from './alerts_treemap/types'; import { useKibana } from '../../../../common/lib/kibana'; -const DEFAULT_HEIGHT = DEFAULT_MIN_CHART_HEIGHT + 134; // px - -const COLLAPSED_HEIGHT = 64; // px +const TREEMAP = i18n.translate('xpack.securitySolution.components.chartSelect.treemapOption', { + defaultMessage: 'Treemap', +}); +const DEFAULT_HEIGHT = DEFAULT_MIN_CHART_HEIGHT + 134; // px const ALERTS_TREEMAP_ID = 'alerts-treemap'; export interface Props { - addFilter?: ({ field, value }: { field: string; value: string | number }) => void; - alignHeader?: 'center' | 'baseline' | 'stretch' | 'flexStart' | 'flexEnd'; - chartOptionsContextMenu?: (queryId: string) => React.ReactNode; - inspectTitle: string; + addFilter: ({ field, value }: { field: string; value: string | number }) => void; + chartOptionsContextMenu: (queryId: string) => React.ReactNode; isPanelExpanded: boolean; - filters?: Filter[]; - height?: number; - query?: Query; + filters: Filter[]; + height: number; + query: Query; riskSubAggregationField: string; - runtimeMappings?: MappingRuntimeFields; setIsPanelExpanded: (value: boolean) => void; setStackByField0: (stackBy: string) => void; setStackByField0ComboboxInputRef?: (inputRef: HTMLInputElement | null) => void; @@ -54,21 +51,17 @@ export interface Props { stackByField0ComboboxRef?: React.RefObject>; stackByField1: string | undefined; stackByField1ComboboxRef?: React.RefObject>; - stackByWidth?: number; title: React.ReactNode; } const AlertsTreemapPanelComponent: React.FC = ({ addFilter, - alignHeader, chartOptionsContextMenu, - inspectTitle, isPanelExpanded, filters, height = DEFAULT_HEIGHT, query, riskSubAggregationField, - runtimeMappings, setIsPanelExpanded, setStackByField0, setStackByField0ComboboxInputRef, @@ -79,7 +72,6 @@ const AlertsTreemapPanelComponent: React.FC = ({ stackByField0ComboboxRef, stackByField1, stackByField1ComboboxRef, - stackByWidth, title, }: Props) => { const { to, from, deleteQuery, setQuery } = useGlobalTime(); @@ -116,7 +108,7 @@ const AlertsTreemapPanelComponent: React.FC = ({ additionalFilters, from, riskSubAggregationField, - runtimeMappings, + runtimeMappings: undefined, stackByField0, stackByField1, to, @@ -132,7 +124,7 @@ const AlertsTreemapPanelComponent: React.FC = ({ additionalFilters, from, riskSubAggregationField, - runtimeMappings, + runtimeMappings: undefined, stackByField0, stackByField1, to, @@ -142,7 +134,6 @@ const AlertsTreemapPanelComponent: React.FC = ({ additionalFilters, from, riskSubAggregationField, - runtimeMappings, setAlertsQuery, stackByField0, stackByField1, @@ -161,19 +152,12 @@ const AlertsTreemapPanelComponent: React.FC = ({ return ( - + = ({ stackByField0ComboboxRef={stackByField0ComboboxRef} stackByField1={stackByField1} stackByField1ComboboxRef={stackByField1ComboboxRef} - stackByWidth={stackByWidth} uniqueQueryId={uniqueQueryId} /> )} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx index 54853d6402e86..66b779ef51cb6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx @@ -4,13 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiText, useEuiTheme } from '@elastic/eui'; -import { ALERT_SEVERITY, ALERT_RULE_NAME } from '@kbn/rule-data-utils'; +import { ALERT_RULE_NAME, ALERT_SEVERITY } from '@kbn/rule-data-utils'; import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types'; import type { Filter, Query } from '@kbn/es-query'; import { v4 as uuid } from 'uuid'; +import { css } from '@emotion/react'; import { capitalize } from 'lodash'; -import React, { useMemo } from 'react'; +import React, { memo, useMemo } from 'react'; import styled from 'styled-components'; import type { GroupBySelection } from '../../alerts_progress_bar_panel/types'; import { getGroupByLabel } from '../../alerts_progress_bar_panel/helpers'; @@ -47,22 +49,42 @@ const combinedAggregations = (groupBySelection: GroupBySelection) => { }; }; -const StyledEuiFlexGroup = styled(EuiFlexGroup)` - margin-top: ${({ theme }) => theme.eui.euiSizeXS}; - @media only screen and (min-width: ${({ theme }) => theme.eui.euiBreakpoints.l}) { - } -`; - const SeverityWrapper = styled(EuiFlexItem)` min-width: 380px; `; -const StyledEuiText = styled(EuiText)` - border-left: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; - padding-left: ${({ theme }) => theme.eui.euiSizeL}; - // allows text to truncate - max-width: 250px; -`; +const TopAlertedComponent = memo( + ({ + title, + children, + 'data-test-subj': dataTestSubj, + }: { + title: string; + children: React.ReactNode; + ['data-test-subj']: string; + }) => { + const { euiTheme } = useEuiTheme(); + + return ( + + {title} + {children} + + ); + } +); +TopAlertedComponent.displayName = 'TopAlertedComponent'; + interface Props { groupBySelection: GroupBySelection; filters?: Filter[]; @@ -111,7 +133,16 @@ export const ChartCollapse: React.FC = ({ return ( {!isLoading && ( - + {severities.map((severity) => ( @@ -127,26 +158,22 @@ export const ChartCollapse: React.FC = ({ - - {i18n.TOP_RULE_TITLE} {topRule} - + - - {`${i18n.TOP_GROUP_TITLE} ${groupBy}: `} {topGroup} - + = ({ - + )} ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_select/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_select/translations.ts index 2da0abc04ec42..e92593520471c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_select/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_select/translations.ts @@ -18,10 +18,6 @@ export const TREEMAP = i18n.translate( } ); -export const CHARTS = i18n.translate('xpack.securitySolution.components.chartSelect.chartsOption', { - defaultMessage: 'Charts', -}); - export const COUNTS = i18n.translate( 'xpack.securitySolution.components.chartSelect.tableOptionTitle', { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/index.tsx index c37c7b0513a51..e4dfc94106cc0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/index.tsx @@ -5,10 +5,10 @@ * 2.0. */ +import { css } from '@emotion/react'; import type { Filter, Query } from '@kbn/es-query'; -import { EuiFlexItem, EuiSkeletonText } from '@elastic/eui'; +import { EuiFlexItem, EuiSkeletonText, useEuiTheme } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; import { useAlertsLocalStorage } from './alerts_local_storage'; import type { AlertsSettings } from './alerts_local_storage/types'; import { ChartContextMenu } from './chart_context_menu'; @@ -33,14 +33,6 @@ const CHART_PANEL_HEIGHT = 375; // px const DETECTIONS_ALERTS_CHARTS_PANEL_ID = 'detection-alerts-charts-panel'; -const FullHeightFlexItem = styled(EuiFlexItem)` - height: 100%; -`; - -const ChartSelectContainer = styled.div` - margin-left: ${({ theme }) => theme.eui.euiSizeS}; -`; - export interface Props { addFilter: ({ field, value, negate }: AddFilterProps) => void; alertsDefaultFilters: Filter[]; @@ -60,6 +52,8 @@ const ChartPanelsComponent: React.FC = ({ signalIndexName, updateDateRangeCallback, }: Props) => { + const { euiTheme } = useEuiTheme(); + const { toggleStatus: isExpanded, setToggleStatus: setIsExpanded } = useQueryToggle( DETECTIONS_ALERTS_CHARTS_PANEL_ID ); @@ -145,12 +139,16 @@ const ChartPanelsComponent: React.FC = ({ const title = useMemo(() => { return isExpanded ? ( - +
- +
) : ( = ({ /> ); }, [ + isExpanded, + euiTheme.size.s, alertViewSelection, setAlertViewSelection, - isExpanded, groupBySelection, alertsDefaultFilters, query, @@ -174,7 +173,7 @@ const ChartPanelsComponent: React.FC = ({ return (
{alertViewSelection === 'trend' && ( - + {isLoadingIndexPattern ? ( ) : ( @@ -189,31 +188,26 @@ const ChartPanelsComponent: React.FC = ({ onFieldSelected={updateCommonStackBy0} panelHeight={CHART_PANEL_HEIGHT} setComboboxInputRef={setStackByField0ComboboxInputRef} - showGroupByPlaceholder={false} - showTotalAlertsCount={false} signalIndexName={signalIndexName} stackByLabel={GROUP_BY_LABEL} title={title} - titleSize={'s'} updateDateRange={updateDateRangeCallback} isExpanded={isExpanded} setIsExpanded={setIsExpanded} /> )} - + )} {alertViewSelection === 'table' && ( - + {isLoadingIndexPattern ? ( ) : ( = ({ setIsExpanded={setIsExpanded} /> )} - + )} {alertViewSelection === 'treemap' && ( - + {isLoadingIndexPattern ? ( ) : ( = ({ title={title} /> )} - + )} {alertViewSelection === 'charts' && ( - + {isLoadingIndexPattern ? ( ) : ( = ({ setGroupBySelection={setGroupBySelection} /> )} - + )}
); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.test.tsx index 3967655d6f089..fb425109b6742 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.test.tsx @@ -9,7 +9,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; -import { KpiPanel, StackByComboBox } from './components'; +import { StackByComboBox } from './components'; import * as i18n from './translations'; jest.mock('react-router-dom', () => { @@ -56,44 +56,6 @@ jest.mock('../../../../common/lib/kibana/kibana_react', () => { }); describe('components', () => { - describe('KpiPanel', () => { - test('it has a hidden overflow-x', () => { - render( - - - {'test'} - - - ); - - expect(screen.getByTestId('test')).toHaveStyleRule('overflow-x', 'hidden'); - }); - - test('it has a hidden overflow-y by default', () => { - render( - - - {'test'} - - - ); - - expect(screen.getByTestId('test')).toHaveStyleRule('overflow-y', 'hidden'); - }); - - test('it uses the `$overflowY` prop for the value of overflow-y when provided', () => { - render( - - - {'test'} - - - ); - - expect(screen.getByTestId('test')).toHaveStyleRule('overflow-y', 'auto'); - }); - }); - describe('StackByComboBox', () => { test('it invokes onSelect when a field is selected', async () => { const onSelect = jest.fn(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx index 3a0dccc492475..cb303d5d8583d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx @@ -5,51 +5,75 @@ * 2.0. */ +import { css } from '@emotion/react'; import type { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; -import { EuiPanel, EuiComboBox } from '@elastic/eui'; -import styled from 'styled-components'; +import { EuiComboBox, EuiPanel, useEuiTheme } from '@elastic/eui'; import type { LegacyRef } from 'react'; import React, { useCallback, useMemo } from 'react'; -import { PANEL_HEIGHT, MOBILE_PANEL_HEIGHT } from './config'; import { useStackByFields } from './hooks'; import * as i18n from './translations'; const DEFAULT_WIDTH = 400; +const DEFAULT_EXPANDED_PANEL_HEIGHT = 300; +const DEFAULT_MOBILE_EXPANDED_PANEL_HEIGHT = 300; +const DEFAULT_COLLAPSED_PANEL_HEIGHT = 64; // px + +export interface KpiPanelProps { + /** + * Height to use when the panel is expanded + */ + height?: number | undefined; + /** + * True if the panel is expanded + */ + toggleStatus: boolean; + /** + * Data test subject string for testing + */ + ['data-test-subj']: string; + /** + * Children component + */ + children: React.ReactNode; +} + +export const KpiPanel = ({ + height, + toggleStatus, + 'data-test-subj': dataTestSubj, + children, +}: KpiPanelProps) => { + const { euiTheme } = useEuiTheme(); + + return ( + + {children} + + ); +}; -export const KpiPanel = styled(EuiPanel)<{ - height?: number; - $overflowY?: - | 'auto' - | 'clip' - | 'hidden' - | 'hidden visible' - | 'inherit' - | 'initial' - | 'revert' - | 'revert-layer' - | 'scroll' - | 'unset' - | 'visible'; - $toggleStatus: boolean; -}>` - display: flex; - flex-direction: column; - position: relative; - overflow-x: hidden; - overflow-y: ${({ $overflowY }) => $overflowY ?? 'hidden'}; - @media only screen and (min-width: ${(props) => props.theme.eui.euiBreakpoints.m}) { - ${({ height, $toggleStatus }) => - $toggleStatus && - ` - height: ${height != null ? height : PANEL_HEIGHT}px; - `} - } - ${({ $toggleStatus }) => - $toggleStatus && - ` - height: ${MOBILE_PANEL_HEIGHT}px; - `} -`; interface StackedBySelectProps { 'aria-label'?: string; 'data-test-subj'?: string; @@ -63,11 +87,6 @@ interface StackedBySelectProps { width?: number; } -export const StackByComboBoxWrapper = styled.div<{ width: number }>` - max-width: 400px; - width: ${({ width }) => width}px; -`; - export const StackByComboBox = React.forwardRef( ( { @@ -109,7 +128,12 @@ export const StackByComboBox = React.forwardRef( return { asPlainText: true }; }, []); return ( - +
- +
); } ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/config.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/config.ts index 8c026a740efb4..a4ccb6e6155aa 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/config.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/common/config.ts @@ -7,6 +7,3 @@ export const DEFAULT_STACK_BY_FIELD = 'kibana.alert.rule.name'; export const DEFAULT_STACK_BY_FIELD1 = 'host.name'; - -export const PANEL_HEIGHT = 300; -export const MOBILE_PANEL_HEIGHT = 500; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx index 104bb7ccb092f..f5f993918ca1d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import React, { useCallback, useMemo } from 'react'; +import { css } from '@emotion/react'; import { ALERT_SEVERITY } from '@kbn/rule-data-utils'; -import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, @@ -24,9 +25,6 @@ import { getSeverityColor } from './helpers'; const DONUT_HEIGHT = 150; -const StyledEuiLoadingSpinner = styled(EuiLoadingSpinner)` - margin: auto; -`; export interface SeverityLevelProps { data: SeverityData[]; isLoading: boolean; @@ -75,7 +73,12 @@ export const SeverityLevelChart: React.FC = ({ {isLoading ? ( - + ) : ( theme.eui.euiSizeS}; -`; - -const BuildingBlockContainer = styled(AdditionalFiltersItem)` - background: ${({ theme }) => theme.eui.euiColorHighlight}; -`; - -const CenterText = styled.span` - text-align: center; -`; - export const AdditionalFiltersAction = ({ areEventsLoading, onShowBuildingBlockAlertsChanged, @@ -42,10 +32,22 @@ export const AdditionalFiltersAction = ({ onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void; showOnlyThreatIndicatorAlerts: boolean; }) => { + const { euiTheme } = useEuiTheme(); const UtilityBarAdditionalFiltersContent = useCallback( (closePopover: () => void) => ( - - + + - - + + - - + + ), [ + euiTheme.colors.highlight, + euiTheme.size.s, onShowBuildingBlockAlertsChanged, onShowOnlyThreatIndicatorAlertsChanged, showBuildingBlockAlerts, @@ -95,7 +103,11 @@ export const AdditionalFiltersAction = ({ ownFocus popoverContent={UtilityBarAdditionalFiltersContent} > - + {i18n.ADDITIONAL_FILTERS_ACTIONS} {additionalFilterCount > 0 && ( <> @@ -106,7 +118,7 @@ export const AdditionalFiltersAction = ({ >{`${additionalFilterCount}`} )} - + ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 5b442a59f75c2..2a2a3aad23403 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -12,7 +12,7 @@ import type { Filter } from '@kbn/es-query'; import type { AlertsTableProps, RenderContext } from '@kbn/response-ops-alerts-table/types'; import { ALERT_BUILDING_BLOCK_TYPE, AlertConsumers } from '@kbn/rule-data-utils'; import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; -import styled from 'styled-components'; +import styled from '@emotion/styled'; import { useDispatch } from 'react-redux'; import { getEsQueryConfig } from '@kbn/data-plugin/public'; import { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 75a5e7eb0bc67..2b2f743580e3c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -10,13 +10,13 @@ // TODO: Refactor code - component can be broken apart import { EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, EuiLoadingSpinner, EuiSpacer, EuiWindowEvent, - EuiHorizontalRule, - EuiFlexItem, } from '@elastic/eui'; -import styled from 'styled-components'; +import styled from '@emotion/styled'; import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type { ConnectedProps } from 'react-redux'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index f9edd66e7fb20..898e53bb18bf7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -7,8 +7,7 @@ import memoizeOne from 'memoize-one'; import { useLocation } from 'react-router-dom'; - -import styled from 'styled-components'; +import styled from '@emotion/styled'; import { EuiFlexItem } from '@elastic/eui'; import type { Severity, @@ -22,9 +21,9 @@ import type { ActionVariables } from '@kbn/triggers-actions-ui-plugin/public'; import { requiredOptional } from '@kbn/zod-helpers'; import { toSimpleRuleSchedule } from '../../../../../common/api/detection_engine/model/rule_schema/to_simple_rule_schedule'; import { - ALERT_SUPPRESSION_FIELDS_FIELD_NAME, - ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, ALERT_SUPPRESSION_DURATION_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../../detection_engine/rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../detection_engine/rule_creation/components/threshold_alert_suppression_edit'; @@ -38,11 +37,11 @@ import { import type { AboutStepRule, AboutStepRuleDetails, + ActionsStepRule, DefineStepRule, ScheduleStepRule, - ActionsStepRule, } from './types'; -import { DataSourceType, AlertSuppressionDurationType } from './types'; +import { AlertSuppressionDurationType, DataSourceType } from './types'; import { SeverityLevel } from '../../../../detection_engine/rule_creation_ui/components/step_about_rule/data'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../common/detection_engine/constants'; import type { RuleAction, RuleResponse } from '../../../../../common/api/detection_engine'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/signals_by_category/signals_by_category.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/signals_by_category/signals_by_category.tsx index f25ef25081d05..4fec800f32dc2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/signals_by_category/signals_by_category.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/signals_by_category/signals_by_category.tsx @@ -8,18 +8,13 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; import type { Filter } from '@kbn/es-query'; - import { AlertsHistogramPanel } from '../../../detections/components/alerts_kpis/alerts_histogram_panel'; import { useSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_signal_index'; import { setAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; - import { InputsModelId } from '../../../common/store/inputs/constants'; import type { UpdateDateRange } from '../../../common/components/charts/common'; - import type { AlertsStackByField } from '../../../detections/components/alerts_kpis/common/types'; - import * as i18n from '../../pages/translations'; - import { useFiltersForSignalsByCategory } from './use_filters_for_signals_by_category'; interface Props { @@ -27,7 +22,6 @@ interface Props { headerChildren?: React.ReactNode; /** Override all defaults, and only display this field */ onlyField?: AlertsStackByField; - paddingSize?: 's' | 'm' | 'l' | 'none'; setAbsoluteRangeDatePickerTarget?: InputsModelId; hideQueryToggle?: boolean; } @@ -36,7 +30,6 @@ const SignalsByCategoryComponent: React.FC = ({ filters, headerChildren, onlyField, - paddingSize, setAbsoluteRangeDatePickerTarget = InputsModelId.global, hideQueryToggle = false, }) => { @@ -66,7 +59,6 @@ const SignalsByCategoryComponent: React.FC = ({ filters={filtersForSignalsByCategory} headerChildren={headerChildren} onlyField={onlyField} - paddingSize={paddingSize} showLinkToAlerts={onlyField == null ? true : false} showStackBy={onlyField == null} showTotalAlertsCount={true}