diff --git a/.gitignore b/.gitignore index 02f11f927518..c5c048f10d7d 100644 --- a/.gitignore +++ b/.gitignore @@ -146,9 +146,9 @@ role_users.json .devcontainer/.env # Ignore temporary files in oas_docs -output/kibana.serverless.tmp1.yaml -output/kibana.serverless.tmp2.yaml -output/kibana.tmp1.yaml -output/kibana.tmp2.yaml -output/kibana.new.yaml -output/kibana.serverless.new.yaml +oas_docs/output/kibana.serverless.tmp1.yaml +oas_docs/output/kibana.serverless.tmp2.yaml +oas_docs/output/kibana.tmp1.yaml +oas_docs/output/kibana.tmp2.yaml +oas_docs/output/kibana.new.yaml +oas_docs/output/kibana.serverless.new.yaml diff --git a/docs/setup/configuring-reporting.asciidoc b/docs/setup/configuring-reporting.asciidoc index 946ec1145d01..041012c8dba8 100644 --- a/docs/setup/configuring-reporting.asciidoc +++ b/docs/setup/configuring-reporting.asciidoc @@ -214,13 +214,13 @@ If using PNG/PDF {report-features}, make sure the {kib} server operating system If you are using RHEL operating systems, install the following packages: -* `ipa-gothic-fonts` * `xorg-x11-fonts-100dpi` * `xorg-x11-fonts-75dpi` * `xorg-x11-utils` * `xorg-x11-fonts-cyrillic` * `xorg-x11-fonts-Type1` * `xorg-x11-fonts-misc` +* `vlgothic-fonts` * `fontconfig` * `freetype` diff --git a/oas_docs/kibana.info.serverless.yaml b/oas_docs/kibana.info.serverless.yaml index efc8955856de..fca516d797f2 100644 --- a/oas_docs/kibana.info.serverless.yaml +++ b/oas_docs/kibana.info.serverless.yaml @@ -28,8 +28,8 @@ info: ``` version: "1.0.2" license: - name: Elastic License 2.0 - url: https://www.elastic.co/licensing/elastic-license + name: Attribution-NonCommercial-NoDerivatives 4.0 International + url: https://creativecommons.org/licenses/by-nc-nd/4.0/ contact: name: Kibana Team x-feedbackLink: diff --git a/oas_docs/kibana.info.yaml b/oas_docs/kibana.info.yaml index 13db5ef72883..40795333fcf4 100644 --- a/oas_docs/kibana.info.yaml +++ b/oas_docs/kibana.info.yaml @@ -26,8 +26,8 @@ info: For more information about the console, refer to [Run API requests](https://www.elastic.co/guide/en/kibana/current/console-kibana.html). version: '1.0.2' license: - name: Elastic License 2.0 - url: https://www.elastic.co/licensing/elastic-license + name: Attribution-NonCommercial-NoDerivatives 4.0 International + url: https://creativecommons.org/licenses/by-nc-nd/4.0/ contact: name: Kibana Team x-feedbackLink: diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index f7e0765267b2..8d81681f3789 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -48,8 +48,8 @@ info: ``` license: - name: Elastic License 2.0 - url: 'https://www.elastic.co/licensing/elastic-license' + name: Attribution-NonCommercial-NoDerivatives 4.0 International + url: 'https://creativecommons.org/licenses/by-nc-nd/4.0/' title: Kibana Serverless APIs version: 1.0.2 x-feedbackLink: diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index a4bc05d9fb2e..dfe69b9be340 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -47,8 +47,8 @@ info: For more information about the console, refer to [Run API requests](https://www.elastic.co/guide/en/kibana/current/console-kibana.html). license: - name: Elastic License 2.0 - url: 'https://www.elastic.co/licensing/elastic-license' + name: Attribution-NonCommercial-NoDerivatives 4.0 International + url: 'https://creativecommons.org/licenses/by-nc-nd/4.0/' title: Kibana APIs version: 1.0.2 x-feedbackLink: diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx index 12c58c0c8763..7552a0c4bc42 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx @@ -8,7 +8,15 @@ import { i18n } from '@kbn/i18n'; import useUpdateEffect from 'react-use/lib/useUpdateEffect'; -import React, { useState, useCallback, Dispatch, FocusEvent, useContext, useMemo } from 'react'; +import React, { + useState, + useCallback, + Dispatch, + FocusEvent, + useContext, + useMemo, + ChangeEventHandler, +} from 'react'; import { css } from '@emotion/react'; import { @@ -126,9 +134,9 @@ export function ColorRangeItem({ [colorRange.start, colorRanges, dispatch, index, popoverInFocus, dataBounds, palettes, isLast] ); - const onValueChange = useCallback( + const onValueChange = useCallback>( ({ target: { value: targetValue } }) => { - setLocalValue(targetValue); + setLocalValue(+targetValue); dispatch({ type: 'updateValue', payload: { index, value: targetValue, accessor, dataBounds, palettes }, @@ -138,7 +146,7 @@ export function ColorRangeItem({ ); const onUpdateColor = useCallback( - (color) => { + (color: string) => { dispatch({ type: 'updateColor', payload: { index, color, dataBounds, palettes } }); }, [dispatch, index, dataBounds, palettes] diff --git a/packages/kbn-dom-drag-drop/index.ts b/packages/kbn-dom-drag-drop/index.ts index f188b6c6659a..f9e4f3f4f5bb 100644 --- a/packages/kbn-dom-drag-drop/index.ts +++ b/packages/kbn-dom-drag-drop/index.ts @@ -14,6 +14,7 @@ export { type DraggingIdentifier, type DragDropAction, type DropOverlayWrapperProps, + type DroppableProps, Draggable, Droppable, useDragDropContext, diff --git a/packages/kbn-grouping/src/components/accordion_panel/index.tsx b/packages/kbn-grouping/src/components/accordion_panel/index.tsx index ae13509b51a9..37a531b386b4 100644 --- a/packages/kbn-grouping/src/components/accordion_panel/index.tsx +++ b/packages/kbn-grouping/src/components/accordion_panel/index.tsx @@ -102,7 +102,7 @@ const GroupPanelComponent = ({ ); const onToggle = useCallback( - (isOpen) => { + (isOpen: boolean) => { if (onToggleGroup) { onToggleGroup(isOpen, groupBucket); } diff --git a/packages/kbn-grouping/src/hooks/use_grouping.tsx b/packages/kbn-grouping/src/hooks/use_grouping.tsx index 284343a29d74..f01dcc29aa79 100644 --- a/packages/kbn-grouping/src/hooks/use_grouping.tsx +++ b/packages/kbn-grouping/src/hooks/use_grouping.tsx @@ -56,7 +56,7 @@ export type DynamicGroupingProps = Pick< /** Interface for configuring grouping package where T is the consumer `GroupingAggregation` * @interface GroupingArgs */ -interface GroupingArgs { +export interface GroupingArgs { componentProps: StaticGroupingProps; defaultGroupingOptions: GroupOption[]; fields: FieldSpec[]; diff --git a/packages/kbn-investigation-shared/src/rest_specs/create_item.ts b/packages/kbn-investigation-shared/src/rest_specs/create_item.ts index c94673313a50..a0696df4040d 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/create_item.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/create_item.ts @@ -7,14 +7,14 @@ */ import * as t from 'io-ts'; -import { investigationItemsSchema } from '../schema'; +import { itemSchema } from '../schema'; import { investigationItemResponseSchema } from './investigation_item'; const createInvestigationItemParamsSchema = t.type({ path: t.type({ investigationId: t.string, }), - body: investigationItemsSchema, + body: itemSchema, }); const createInvestigationItemResponseSchema = investigationItemResponseSchema; diff --git a/packages/kbn-investigation-shared/src/rest_specs/index.ts b/packages/kbn-investigation-shared/src/rest_specs/index.ts index 50c1e300cd96..cb13c1188648 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/index.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/index.ts @@ -17,6 +17,7 @@ export type * from './investigation_note'; export type * from './create_item'; export type * from './delete_item'; export type * from './get_items'; +export type * from './investigation_item'; export * from './create'; export * from './create_note'; @@ -29,3 +30,4 @@ export * from './investigation_note'; export * from './create_item'; export * from './delete_item'; export * from './get_items'; +export * from './investigation_item'; diff --git a/packages/kbn-investigation-shared/src/schema/investigation_item.ts b/packages/kbn-investigation-shared/src/schema/investigation_item.ts index 8689224960c5..717bf246e359 100644 --- a/packages/kbn-investigation-shared/src/schema/investigation_item.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation_item.ts @@ -8,20 +8,23 @@ import * as t from 'io-ts'; -const esqlItemSchema = t.type({ +const itemSchema = t.type({ title: t.string, - type: t.literal('esql'), - params: t.type({ - esql: t.string, - suggestion: t.any, - }), + type: t.string, + params: t.record(t.string, t.any), }); -const investigationItemsSchema = esqlItemSchema; // replace with union with various item types - const investigationItemSchema = t.intersection([ - t.type({ id: t.string, createdAt: t.number, createdBy: t.string }), - investigationItemsSchema, + t.type({ + id: t.string, + createdAt: t.number, + createdBy: t.string, + }), + itemSchema, ]); -export { investigationItemSchema, investigationItemsSchema, esqlItemSchema }; +type Item = t.TypeOf; +type InvestigationItem = t.TypeOf; + +export type { Item, InvestigationItem }; +export { investigationItemSchema, itemSchema }; diff --git a/packages/kbn-management/settings/components/field_input/code_editor.tsx b/packages/kbn-management/settings/components/field_input/code_editor.tsx index ac1ea672d8a1..397fd8b80492 100644 --- a/packages/kbn-management/settings/components/field_input/code_editor.tsx +++ b/packages/kbn-management/settings/components/field_input/code_editor.tsx @@ -70,7 +70,7 @@ export const CodeEditor = ({ onChange, type, isReadOnly, name, ...props }: CodeE editorModel.setValue(trimmedValue); }, []); - const editorDidMount = useCallback( + const editorDidMount = useCallback>( (editor) => { setEditorCalculatedHeight(editor); diff --git a/packages/kbn-management/settings/components/field_input/input/array_input.tsx b/packages/kbn-management/settings/components/field_input/input/array_input.tsx index 0dc9b8ddc406..f77c66f5f15e 100644 --- a/packages/kbn-management/settings/components/field_input/input/array_input.tsx +++ b/packages/kbn-management/settings/components/field_input/input/array_input.tsx @@ -13,6 +13,7 @@ import { getFieldInputValue } from '@kbn/management-settings-utilities'; import { useUpdate } from '@kbn/management-settings-utilities'; import { debounce } from 'lodash'; +import { OnInputChangeFn } from '@kbn/management-settings-types'; import { useServices } from '../services'; import { InputProps } from '../types'; import { TEST_SUBJ_PREFIX_FIELD } from '.'; @@ -39,7 +40,7 @@ export const ArrayInput = ({ const onUpdate = useUpdate({ onInputChange, field }); const updateValue = useCallback( - async (newValue: string, onUpdateFn) => { + async (newValue: string, onUpdateFn: OnInputChangeFn<'array'>) => { const parsedValue = newValue .replace(REGEX, ',') .split(',') diff --git a/packages/kbn-management/settings/components/field_input/input/number_input.tsx b/packages/kbn-management/settings/components/field_input/input/number_input.tsx index 8a29429eff59..303dfe386866 100644 --- a/packages/kbn-management/settings/components/field_input/input/number_input.tsx +++ b/packages/kbn-management/settings/components/field_input/input/number_input.tsx @@ -12,6 +12,7 @@ import { EuiFieldNumber, EuiFieldNumberProps } from '@elastic/eui'; import { getFieldInputValue, useUpdate } from '@kbn/management-settings-utilities'; import { debounce } from 'lodash'; +import { OnInputChangeFn } from '@kbn/management-settings-types'; import { InputProps } from '../types'; import { TEST_SUBJ_PREFIX_FIELD } from '.'; import { useServices } from '../services'; @@ -36,7 +37,7 @@ export const NumberInput = ({ const onUpdate = useUpdate({ onInputChange, field }); const updateValue = useCallback( - async (newValue: number, onUpdateFn) => { + async (newValue: number, onUpdateFn: OnInputChangeFn<'number'>) => { const validationResponse = await validateChange(field.id, newValue); if (validationResponse.successfulValidation && !validationResponse.valid) { onUpdateFn({ diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 2d09f5a2b2ad..9f0c22671707 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -145,8 +145,6 @@ export const OBSERVABILITY_ENTITY_CENTRIC_EXPERIENCE = 'observability:entityCent export const OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID = 'observability:logSources'; export const OBSERVABILITY_AI_ASSISTANT_LOGS_INDEX_PATTERN_ID = 'observability:aiAssistantLogsIndexPattern'; -export const OBSERVABILITY_AI_ASSISTANT_RESPONSE_LANGUAGE = - 'observability:aiAssistantResponseLanguage'; export const OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING = 'observability:aiAssistantSimulatedFunctionCalling'; export const OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN = diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx index 75c7001c462d..bf7f77837fee 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx @@ -64,7 +64,7 @@ export const AutocompleteFieldListsComponent: React.FC name, []); + const getLabel = useCallback(({ name }: ListSchema) => name, []); const optionsMemo = useMemo( () => filterFieldToList(listData, selectedField), diff --git a/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx b/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx index 6d45d4d5ab37..722bb33f9f30 100644 --- a/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx @@ -44,7 +44,7 @@ export const OperatorComponent: React.FC = ({ selectedField, 'aria-label': ariaLabel, }): JSX.Element => { - const getLabel = useCallback(({ message }): string => message, []); + const getLabel = useCallback(({ message }: OperatorOption): string => message, []); const optionsMemo = useMemo( (): OperatorOption[] => operatorOptions != null && operatorOptions.length > 0 diff --git a/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx b/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx index a40393bac8fc..ab5c81d30eb5 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx @@ -9,7 +9,7 @@ import React, { useCallback } from 'react'; import type { FC } from 'react'; -import type { IconType, SearchFilterConfig } from '@elastic/eui'; +import type { EuiSearchBarProps, IconType, SearchFilterConfig } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSearchBar } from '@elastic/eui'; import type { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import type { GetExceptionItemProps } from '../types'; @@ -73,7 +73,7 @@ const SearchBarComponent: FC = ({ onSearch, onAddExceptionClick, }) => { - const handleOnSearch = useCallback( + const handleOnSearch = useCallback>( ({ queryText }): void => { onSearch({ search: queryText }); }, diff --git a/packages/kbn-unified-data-table/src/components/data_table_additional_display_settings.tsx b/packages/kbn-unified-data-table/src/components/data_table_additional_display_settings.tsx index cbead22b3999..9b6629d2c960 100644 --- a/packages/kbn-unified-data-table/src/components/data_table_additional_display_settings.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table_additional_display_settings.tsx @@ -7,7 +7,7 @@ */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { EuiFormRow, EuiHorizontalRule, EuiRange } from '@elastic/eui'; +import { EuiFormRow, EuiHorizontalRule, EuiRange, EuiRangeProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { debounce } from 'lodash'; import { RowHeightSettings, RowHeightSettingsProps } from './row_height_settings'; @@ -63,9 +63,9 @@ export const UnifiedDataTableAdditionalDisplaySettings: React.FC< [onChangeSampleSize] ); - const onChangeActiveSampleSize = useCallback( + const onChangeActiveSampleSize = useCallback>( (event) => { - if (!event.target.value) { + if (!('value' in event.target) || !event.target.value) { setActiveSampleSize(''); return; } diff --git a/packages/kbn-visualization-ui-components/components/color_picker.tsx b/packages/kbn-visualization-ui-components/components/color_picker.tsx index 3a2613d16d66..442140e82c2b 100644 --- a/packages/kbn-visualization-ui-components/components/color_picker.tsx +++ b/packages/kbn-visualization-ui-components/components/color_picker.tsx @@ -28,6 +28,17 @@ const tooltipContent = { }), }; +export interface ColorPickerProps { + overwriteColor?: string | null; + defaultColor?: string | null; + isClearable?: boolean; + setConfig: (config: { color?: string }) => void; + label?: string; + disableHelpTooltip?: boolean; + disabledMessage?: string; + showAlpha?: boolean; +} + export const ColorPicker = ({ overwriteColor, defaultColor, @@ -37,16 +48,7 @@ export const ColorPicker = ({ disableHelpTooltip, disabledMessage, showAlpha, -}: { - overwriteColor?: string | null; - defaultColor?: string | null; - isClearable?: boolean; - setConfig: (config: { color?: string }) => void; - label?: string; - disableHelpTooltip?: boolean; - disabledMessage?: string; - showAlpha?: boolean; -}) => { +}: ColorPickerProps) => { const [colorText, setColorText] = useState(overwriteColor || defaultColor); const [validatedColor, setValidatedColor] = useState(overwriteColor || defaultColor); const [currentColorAlpha, setCurrentColorAlpha] = useState(getColorAlpha(colorText)); diff --git a/packages/kbn-visualization-ui-components/components/query_input/filter_query_input.tsx b/packages/kbn-visualization-ui-components/components/query_input/filter_query_input.tsx index b954c37e3f7d..3c031ac82da0 100644 --- a/packages/kbn-visualization-ui-components/components/query_input/filter_query_input.tsx +++ b/packages/kbn-visualization-ui-components/components/query_input/filter_query_input.tsx @@ -33,6 +33,18 @@ export const defaultFilter: Query = { language: 'kuery', }; +export interface FilterQueryInputProps { + inputFilter: Query | undefined; + onChange: (query: Query) => void; + dataView: DataViewBase; + helpMessage?: string | null; + label?: string; + initiallyOpen?: boolean; + ['data-test-subj']?: string; + queryInputServices: QueryInputServices; + appName: string; +} + export function FilterQueryInput({ inputFilter, onChange, @@ -43,17 +55,7 @@ export function FilterQueryInput({ ['data-test-subj']: dataTestSubj, queryInputServices, appName, -}: { - inputFilter: Query | undefined; - onChange: (query: Query) => void; - dataView: DataViewBase; - helpMessage?: string | null; - label?: string; - initiallyOpen?: boolean; - ['data-test-subj']?: string; - queryInputServices: QueryInputServices; - appName: string; -}) { +}: FilterQueryInputProps) { const [filterPopoverOpen, setFilterPopoverOpen] = useState(Boolean(initiallyOpen)); const onClosePopup: EuiPopoverProps['closePopover'] = useCallback(() => { diff --git a/packages/kbn-visualization-ui-components/index.ts b/packages/kbn-visualization-ui-components/index.ts index 239849da05a5..c6d4d7a8c545 100644 --- a/packages/kbn-visualization-ui-components/index.ts +++ b/packages/kbn-visualization-ui-components/index.ts @@ -40,6 +40,7 @@ export type { IconSet, AccessorConfig, QueryInputServices, + ColorPickerProps, } from './components'; export type { FormatFactory, LineStyle } from './types'; diff --git a/packages/react/kibana_mount/utils.ts b/packages/react/kibana_mount/utils.ts index d012a373f6a0..10294c8f0f81 100644 --- a/packages/react/kibana_mount/utils.ts +++ b/packages/react/kibana_mount/utils.ts @@ -17,7 +17,7 @@ export const useIfMounted = () => { [] ); - const ifMounted = useCallback((func) => { + const ifMounted = useCallback((func?: () => void) => { if (isMounted.current && func) { func(); } diff --git a/packages/serverless/settings/observability_project/index.ts b/packages/serverless/settings/observability_project/index.ts index 07a9c84e210f..bcaab96e8bd0 100644 --- a/packages/serverless/settings/observability_project/index.ts +++ b/packages/serverless/settings/observability_project/index.ts @@ -34,7 +34,6 @@ export const OBSERVABILITY_PROJECT_SETTINGS = [ settings.OBSERVABILITY_APM_ENABLE_SERVICE_INVENTORY_TABLE_SEARCH_BAR, settings.OBSERVABILITY_ENTITY_CENTRIC_EXPERIENCE, settings.OBSERVABILITY_AI_ASSISTANT_LOGS_INDEX_PATTERN_ID, - settings.OBSERVABILITY_AI_ASSISTANT_RESPONSE_LANGUAGE, settings.OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING, settings.OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN, ]; diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx index 0e1ebe988e60..145571da1102 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx +++ b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx @@ -194,7 +194,7 @@ export const GaugeComponent: FC = ({ const getColor = useCallback( ( - value, + value: number, paletteConfig: PaletteOutput, bands: number[], percentageMode?: boolean diff --git a/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx b/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx index 0c7f855c6639..b76bc5ec611b 100644 --- a/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx +++ b/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx @@ -18,6 +18,8 @@ import { Wordcloud, RenderChangeListener, LEGACY_LIGHT_THEME, + ElementClickListener, + WordCloudElementEvent, } from '@elastic/charts'; import { EmptyPlaceholder } from '@kbn/charts-plugin/public'; import { @@ -190,13 +192,13 @@ export const TagCloudChart = ({ [] ); - const handleWordClick = useCallback( + const handleWordClick = useCallback( (elements) => { if (!bucket) { return; } const termsBucketId = getColumnByAccessor(bucket, visData.columns)!.id; - const clickedValue = elements[0][0].text; + const clickedValue = (elements[0] as WordCloudElementEvent)[0].text; const columnIndex = visData.columns.findIndex((col) => col.id === termsBucketId); if (columnIndex < 0) { diff --git a/src/plugins/charts/public/services/active_cursor/use_active_cursor.ts b/src/plugins/charts/public/services/active_cursor/use_active_cursor.ts index e06c6096664c..aff01a5871ad 100644 --- a/src/plugins/charts/public/services/active_cursor/use_active_cursor.ts +++ b/src/plugins/charts/public/services/active_cursor/use_active_cursor.ts @@ -11,7 +11,7 @@ import { animationFrameScheduler } from 'rxjs'; import { useCallback, useEffect, RefObject } from 'react'; import { filter, debounceTime } from 'rxjs'; -import type { Chart } from '@elastic/charts'; +import type { Chart, PointerUpdateListener } from '@elastic/charts'; import { parseSyncOptions } from './active_cursor_utils'; @@ -24,9 +24,9 @@ export const useActiveCursor = ( activeCursor: ActiveCursor, chartRef: RefObject, syncOptions: ActiveCursorSyncOption -) => { +): PointerUpdateListener => { const { accessors, isDateHistogram } = parseSyncOptions(syncOptions); - const handleCursorUpdate = useCallback( + const handleCursorUpdate = useCallback( (cursor) => { activeCursor.activeCursor$?.next({ cursor, diff --git a/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx b/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx index 486978b63ec5..f0398d1bf60f 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx @@ -157,7 +157,7 @@ export const OptionsListPopoverSuggestions = ({ }, [loadMoreSuggestions, totalCardinality]); const renderOption = useCallback( - (option, searchStringValue) => { + (option: EuiSelectableOption, searchStringValue: string) => { if (!allowExpensiveQueries || searchTechnique === 'exact') return option.label; return ( diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index d7af8ac5ffed..34ac9a1ccffc 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -9,22 +9,32 @@ import type { KibanaRequest } from '@kbn/core/server'; import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; import { i18n } from '@kbn/i18n'; -import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-types'; +import type { + IKibanaSearchRequest, + IKibanaSearchResponse, + ISearchGeneric, +} from '@kbn/search-types'; import type { Datatable, ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { getStartEndParams } from '@kbn/esql-utils'; - import { zipObject } from 'lodash'; -import { Observable, defer, throwError } from 'rxjs'; -import { catchError, map, switchMap, tap } from 'rxjs'; -import { buildEsQuery } from '@kbn/es-query'; -import type { ISearchGeneric } from '@kbn/search-types'; -import type { ESQLSearchResponse, ESQLSearchParams } from '@kbn/es-types'; +import { catchError, defer, map, Observable, switchMap, tap, throwError } from 'rxjs'; +import { buildEsQuery, type Filter } from '@kbn/es-query'; +import type { ESQLSearchParams, ESQLSearchResponse } from '@kbn/es-types'; import { getEsQueryConfig } from '../../es_query'; import { getTime } from '../../query'; -import { ESQL_ASYNC_SEARCH_STRATEGY, KibanaContext, ESQL_TABLE_TYPE } from '..'; +import { ESQL_ASYNC_SEARCH_STRATEGY, ESQL_TABLE_TYPE, KibanaContext } from '..'; import { UiSettingsCommon } from '../..'; +declare global { + interface Window { + /** + * Debug setting to make requests complete slower than normal. Only available on snapshots where `error_query` is enabled in ES. + */ + ELASTIC_ESQL_DELAY_SECONDS?: number; + } +} + type Input = KibanaContext | null; type Output = Observable; @@ -166,12 +176,31 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { fieldName: timeField, }); - params.filter = buildEsQuery( - undefined, - input.query || [], - [...(input.filters ?? []), ...(timeFilter ? [timeFilter] : [])], - esQueryConfigs - ); + // Used for debugging & inside automated tests to simulate a slow query + const delayFilter: Filter | undefined = window.ELASTIC_ESQL_DELAY_SECONDS + ? { + meta: {}, + query: { + error_query: { + indices: [ + { + name: '*', + error_type: 'warning', + stall_time_seconds: window.ELASTIC_ESQL_DELAY_SECONDS, + }, + ], + }, + }, + } + : undefined; + + const filters = [ + ...(input.filters ?? []), + ...(timeFilter ? [timeFilter] : []), + ...(delayFilter ? [delayFilter] : []), + ]; + + params.filter = buildEsQuery(undefined, input.query || [], filters, esQueryConfigs); } let startTime = Date.now(); diff --git a/src/plugins/data_view_editor/public/components/data_view_editor_flyout_content.tsx b/src/plugins/data_view_editor/public/components/data_view_editor_flyout_content.tsx index 98897ed4472d..22ed26e702eb 100644 --- a/src/plugins/data_view_editor/public/components/data_view_editor_flyout_content.tsx +++ b/src/plugins/data_view_editor/public/components/data_view_editor_flyout_content.tsx @@ -196,7 +196,7 @@ const IndexPatternEditorFlyoutContentComponent = ({ const getRollupIndices = (rollupCaps: RollupIndicesCapsResponse) => Object.keys(rollupCaps); const onTypeChange = useCallback( - (newType) => { + (newType: INDEX_PATTERN_TYPE) => { form.setFieldValue('title', ''); form.setFieldValue('name', ''); form.setFieldValue('timestampField', ''); diff --git a/src/plugins/discover/public/application/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx index 4d6d815fd796..e0f0dbbd820c 100644 --- a/src/plugins/discover/public/application/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment, useCallback, useMemo, useState, FC, PropsWithChildren } from 'react'; +import React, { Fragment, useCallback, useMemo, useState, FC } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiSpacer, EuiText, useEuiPaddingSize } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -241,7 +241,7 @@ export function ContextAppContent({ ); } -const WrapperWithPadding: FC> = ({ children }) => { +const WrapperWithPadding: FC = ({ children }) => { const padding = useEuiPaddingSize('s'); return ( diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx index fa8128c0b95e..ac71b1a43703 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx @@ -250,7 +250,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) // As unifiedFieldListSidebarContainerRef ref can be empty in the beginning, // we need to fetch the data once API becomes available and after documents are fetched const initializeUnifiedFieldListSidebarContainerApi = useCallback( - (api) => { + (api: UnifiedFieldListSidebarContainerApi) => { if (!api) { return; } diff --git a/src/plugins/es_ui_shared/static/forms/components/fields/select_field.tsx b/src/plugins/es_ui_shared/static/forms/components/fields/select_field.tsx index b09215146a59..3794f605e4e6 100644 --- a/src/plugins/es_ui_shared/static/forms/components/fields/select_field.tsx +++ b/src/plugins/es_ui_shared/static/forms/components/fields/select_field.tsx @@ -11,7 +11,7 @@ import { EuiFormRow, EuiSelect } from '@elastic/eui'; import { FieldHook, getFieldValidityAndErrorMessage } from '../../hook_form_lib'; -interface Props { +export interface Props { field: FieldHook; euiFieldProps: { options: Array< diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 3a8c0b9b6076..8bc81a6f1d49 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -487,10 +487,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, }, - 'observability:aiAssistantResponseLanguage': { - type: 'keyword', - _meta: { description: 'Non-default value of setting.' }, - }, 'observability:aiAssistantSimulatedFunctionCalling': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 92e507ebef85..9821fd1bad43 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -55,7 +55,6 @@ export interface UsageStats { 'observability:logsExplorer:allowedDataViews': string[]; 'observability:logSources': string[]; 'observability:aiAssistantLogsIndexPattern': string; - 'observability:aiAssistantResponseLanguage': string; 'observability:aiAssistantSimulatedFunctionCalling': boolean; 'observability:aiAssistantSearchConnectorIndexPattern': string; 'visualization:heatmap:maxBuckets': number; diff --git a/src/plugins/links/public/components/dashboard_link/dashboard_link_destination_picker.tsx b/src/plugins/links/public/components/dashboard_link/dashboard_link_destination_picker.tsx index 8868dd1a2776..30bd3d3879da 100644 --- a/src/plugins/links/public/components/dashboard_link/dashboard_link_destination_picker.tsx +++ b/src/plugins/links/public/components/dashboard_link/dashboard_link_destination_picker.tsx @@ -94,7 +94,7 @@ export const DashboardLinkDestinationPicker = ({ ); const renderOption = useCallback( - (option, searchValue, contentClassName) => { + (option: DashboardComboBoxOption, searchValue: string, contentClassName: string) => { const { label, key: dashboardId } = option; return ( diff --git a/src/plugins/links/public/components/editor/links_editor.tsx b/src/plugins/links/public/components/editor/links_editor.tsx index 0ee31cd84152..ac8879d1dd85 100644 --- a/src/plugins/links/public/components/editor/links_editor.tsx +++ b/src/plugins/links/public/components/editor/links_editor.tsx @@ -10,6 +10,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import useMountedState from 'react-use/lib/useMountedState'; import { + DropResult, EuiButton, EuiButtonEmpty, EuiButtonGroup, @@ -101,7 +102,7 @@ const LinksEditor = ({ }, [initialLinks]); const onDragEnd = useCallback( - ({ source, destination }) => { + ({ source, destination }: DropResult) => { if (source && destination) { const newList = euiDragDropReorder(orderedLinks, source.index, destination.index).map( (link, i) => { diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index ebd98b2190c1..8563b5beaf57 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10456,12 +10456,6 @@ "description": "Non-default value of setting." } }, - "observability:aiAssistantResponseLanguage": { - "type": "keyword", - "_meta": { - "description": "Non-default value of setting." - } - }, "observability:aiAssistantSimulatedFunctionCalling": { "type": "boolean", "_meta": { diff --git a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx index 1c598d06a143..00d1eee9bcba 100644 --- a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx +++ b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx @@ -5,12 +5,13 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import React, { ComponentProps, useCallback, useEffect, useRef, useState } from 'react'; import type { Observable } from 'rxjs'; import type { AggregateQuery, Query } from '@kbn/es-query'; -import { isEqual } from 'lodash'; +import { isEqual, isObject } from 'lodash'; import type { LensEmbeddableOutput, Suggestion } from '@kbn/lens-plugin/public'; import type { Datatable } from '@kbn/expressions-plugin/common'; +import { EditLensConfigPanelComponent } from '@kbn/lens-plugin/public/plugin'; import { deriveLensSuggestionFromLensAttributes } from '../utils/external_vis_context'; import { @@ -49,13 +50,16 @@ export function ChartConfigPanel({ const previousAdapters = useRef | undefined>(undefined); const previousQuery = useRef(undefined); - const updatePanelState = useCallback( + const updatePanelState = useCallback< + ComponentProps['updatePanelState'] + >( (datasourceState, visualizationState, visualizationId) => { const updatedSuggestion: Suggestion = { - ...currentSuggestionContext?.suggestion, - visualizationId: visualizationId ?? currentSuggestionContext?.suggestion?.visualizationId, - ...(datasourceState && { datasourceState }), - ...(visualizationState && { visualizationState }), + ...currentSuggestionContext.suggestion!, + visualizationId: + visualizationId ?? currentSuggestionContext.suggestion?.visualizationId ?? '', + ...(isObject(datasourceState) && { datasourceState }), + ...(isObject(visualizationState) && { visualizationState }), }; onSuggestionContextEdit({ ...currentSuggestionContext, @@ -65,7 +69,9 @@ export function ChartConfigPanel({ [currentSuggestionContext, onSuggestionContextEdit] ); - const updateSuggestion = useCallback( + const updateSuggestion = useCallback< + NonNullable['updateSuggestion']> + >( (attributes) => { const updatedSuggestion = deriveLensSuggestionFromLensAttributes({ externalVisContext: { diff --git a/src/plugins/unified_histogram/public/chart/toolbar_selector.tsx b/src/plugins/unified_histogram/public/chart/toolbar_selector.tsx index b9115847b7b0..58d6b5db0023 100644 --- a/src/plugins/unified_histogram/public/chart/toolbar_selector.tsx +++ b/src/plugins/unified_histogram/public/chart/toolbar_selector.tsx @@ -60,9 +60,11 @@ export const ToolbarSelector: React.FC = ({ [] ); - const onSelectionChange = useCallback( + const onSelectionChange = useCallback< + NonNullable['onChange']> + >( (newOptions) => { - const chosenOption = newOptions.find(({ checked }: SelectableEntry) => checked === 'on'); + const chosenOption = newOptions.find(({ checked }) => checked === 'on'); onChange?.( chosenOption?.value && chosenOption?.value !== EMPTY_OPTION ? chosenOption : undefined @@ -139,7 +141,7 @@ export const ToolbarSelector: React.FC = ({ anchorPosition="downLeft" > {popoverTitle} - id={`${dataTestSubj}Selectable`} singleSelection aria-label={popoverTitle} diff --git a/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts b/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts index 44a216178f6d..1491556fc37d 100644 --- a/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts +++ b/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts @@ -7,10 +7,9 @@ */ import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; -import { Suggestion } from '@kbn/lens-plugin/public'; import { renderHook } from '@testing-library/react-hooks'; import { act } from 'react-test-renderer'; -import { UnifiedHistogramFetchStatus } from '../../types'; +import { UnifiedHistogramFetchStatus, UnifiedHistogramSuggestionContext } from '../../types'; import { dataViewMock } from '../../__mocks__/data_view'; import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield'; import { lensAdaptersMock } from '../../__mocks__/lens_adapters'; @@ -451,10 +450,12 @@ describe('useStateProps', () => { expect(stateService.setBreakdownField).toHaveBeenLastCalledWith('field'); act(() => { - onSuggestionContextChange({ title: 'Stacked Bar' } as Suggestion); + onSuggestionContextChange({ + suggestion: { title: 'Stacked Bar' }, + } as UnifiedHistogramSuggestionContext); }); expect(stateService.setCurrentSuggestionContext).toHaveBeenLastCalledWith({ - title: 'Stacked Bar', + suggestion: { title: 'Stacked Bar' }, }); }); diff --git a/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts b/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts index f5c8e8e3bc02..58ec13fd5d1a 100644 --- a/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts +++ b/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts @@ -10,7 +10,11 @@ import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/co import { AggregateQuery, isOfAggregateQueryType, Query } from '@kbn/es-query'; import type { RequestAdapter } from '@kbn/inspector-plugin/public'; import { useCallback, useEffect, useMemo } from 'react'; -import { UnifiedHistogramChartLoadEvent, UnifiedHistogramFetchStatus } from '../../types'; +import { + UnifiedHistogramChartLoadEvent, + UnifiedHistogramFetchStatus, + UnifiedHistogramSuggestionContext, +} from '../../types'; import type { UnifiedHistogramStateService } from '../services/state_service'; import { breakdownFieldSelector, @@ -150,7 +154,7 @@ export const useStateProps = ({ ); const onSuggestionContextChange = useCallback( - (suggestionContext) => { + (suggestionContext: UnifiedHistogramSuggestionContext | undefined) => { stateService?.setCurrentSuggestionContext(suggestionContext); }, [stateService] diff --git a/src/plugins/unified_search/public/dataview_picker/dataview_list.tsx b/src/plugins/unified_search/public/dataview_picker/dataview_list.tsx index 559174711af3..1b32952c1567 100644 --- a/src/plugins/unified_search/public/dataview_picker/dataview_list.tsx +++ b/src/plugins/unified_search/public/dataview_picker/dataview_list.tsx @@ -16,6 +16,7 @@ import { EuiPanel, EuiButtonGroup, toSentenceCase, + Direction, } from '@elastic/eui'; import type { DataViewListItem } from '@kbn/data-views-plugin/public'; import { i18n } from '@kbn/i18n'; @@ -107,8 +108,8 @@ export function DataViewsList({ ); const onChangeSortDirection = useCallback( - (value) => { - sortingService.setDirection(value); + (value: string) => { + sortingService.setDirection(value as Direction); setSortedDataViewsList((dataViews) => sortingService.sortData(dataViews)); }, [sortingService] diff --git a/src/plugins/unified_search/public/filters_builder/filter_item/params_editor.tsx b/src/plugins/unified_search/public/filters_builder/filter_item/params_editor.tsx index b51defaf2282..4dac0d33163d 100644 --- a/src/plugins/unified_search/public/filters_builder/filter_item/params_editor.tsx +++ b/src/plugins/unified_search/public/filters_builder/filter_item/params_editor.tsx @@ -10,10 +10,11 @@ import React, { useCallback, useContext } from 'react'; import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import type { Filter } from '@kbn/es-query'; import { EuiToolTip, EuiFormRow } from '@elastic/eui'; +import { FilterMetaParams } from '@kbn/es-query/src/filters/build_filters'; import type { Operator } from '../../filter_bar/filter_editor'; import { getFieldValidityAndErrorMessage } from '../../filter_bar/filter_editor/lib'; import { FiltersBuilderContextType } from '../context'; -import { ParamsEditorInput } from './params_editor_input'; +import { ParamsEditorInput, ParamsEditorInputProps } from './params_editor_input'; interface ParamsEditorProps { dataView: DataView; @@ -37,15 +38,15 @@ export function ParamsEditor({ filtersForSuggestions, }: ParamsEditorProps) { const { disabled, suggestionsAbstraction } = useContext(FiltersBuilderContextType); - const onParamsChange = useCallback( + const onParamsChange = useCallback( (selectedParams) => { - onHandleParamsChange(selectedParams); + onHandleParamsChange(selectedParams as FilterMetaParams); }, [onHandleParamsChange] ); - const onParamsUpdate = useCallback( - (value) => { + const onParamsUpdate = useCallback( + (value: any) => { onHandleParamsUpdate(value); }, [onHandleParamsUpdate] diff --git a/src/plugins/unified_search/public/filters_builder/filter_item/params_editor_input.tsx b/src/plugins/unified_search/public/filters_builder/filter_item/params_editor_input.tsx index c3138f7a14e2..d59ffa9782e3 100644 --- a/src/plugins/unified_search/public/filters_builder/filter_item/params_editor_input.tsx +++ b/src/plugins/unified_search/public/filters_builder/filter_item/params_editor_input.tsx @@ -34,7 +34,7 @@ export const strings = { }), }; -interface ParamsEditorInputProps { +export interface ParamsEditorInputProps { dataView: DataView; params: unknown; onParamsChange: (params: unknown) => void; diff --git a/src/plugins/unified_search/public/saved_query_form/save_query_form.tsx b/src/plugins/unified_search/public/saved_query_form/save_query_form.tsx index e9d7a548fada..09a55047d277 100644 --- a/src/plugins/unified_search/public/saved_query_form/save_query_form.tsx +++ b/src/plugins/unified_search/public/saved_query_form/save_query_form.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useState, useCallback } from 'react'; +import React, { useState, useCallback, ChangeEventHandler } from 'react'; import { EuiButton, EuiForm, EuiFormRow, EuiFieldText, EuiSwitch } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { isEqual } from 'lodash'; @@ -117,7 +117,7 @@ export function SaveQueryForm({ shouldIncludeTimefilter, ]); - const onInputChange = useCallback((event) => { + const onInputChange = useCallback>((event) => { setFormErrors([]); setTitle(event.target.value); }, []); diff --git a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.tsx b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.tsx index d62061d7d6cf..825b15884912 100644 --- a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.tsx +++ b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.tsx @@ -24,6 +24,7 @@ import { EuiHorizontalRule, EuiProgress, PrettyDuration, + EuiSelectableProps, } from '@elastic/eui'; import { EuiContextMenuClass } from '@elastic/eui/src/components/context_menu/context_menu'; import { i18n } from '@kbn/i18n'; @@ -282,9 +283,17 @@ export const SavedQueryManagementList = ({ } }, [onLoad, selectedSavedQuery, onClose]); - const handleSelect = useCallback((savedQueryToSelect) => { - setSelectedSavedQuery(savedQueryToSelect); - }, []); + const handleSelect = useCallback['onChange']>>( + (choices) => { + const choice = choices.find(({ checked }) => checked); + if (choice) { + setSelectedSavedQuery( + currentPageQueries.find((savedQuery) => savedQuery.id === choice.value) + ); + } + }, + [currentPageQueries] + ); const handleDelete = useCallback((savedQueryToDelete: SavedQuery) => { setShowDeletionConfirmationModal(true); @@ -439,14 +448,7 @@ export const SavedQueryManagementList = ({ {noSavedQueriesDescriptionText} } - onChange={(choices) => { - const choice = choices.find(({ checked }) => checked); - if (choice) { - handleSelect( - currentPageQueries.find((savedQuery) => savedQuery.id === choice.value) - ); - } - }} + onChange={handleSelect} renderOption={renderOption} css={{ '.euiSelectableList__list': { diff --git a/src/plugins/vis_default_editor/public/components/agg_params.tsx b/src/plugins/vis_default_editor/public/components/agg_params.tsx index aa1fe36d797e..8e67a2624501 100644 --- a/src/plugins/vis_default_editor/public/components/agg_params.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_params.tsx @@ -11,7 +11,7 @@ import { EuiForm, EuiAccordion, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import useUnmount from 'react-use/lib/useUnmount'; -import { IAggConfig, AggGroupNames } from '@kbn/data-plugin/public'; +import { IAggConfig, AggGroupNames, IAggType } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { Schema } from '@kbn/visualizations-plugin/public'; @@ -124,7 +124,7 @@ function DefaultEditorAggParams({ !!error || isInvalidParamsTouched(agg.type, aggType, paramsState); const onAggSelect = useCallback( - (value) => { + (value: IAggType) => { if (agg.type !== value) { onAggTypeChange(agg.id, value); // reset touched and valid of params diff --git a/src/plugins/vis_default_editor/public/components/agg_select.tsx b/src/plugins/vis_default_editor/public/components/agg_select.tsx index 09aee4b21726..e65b56753ab1 100644 --- a/src/plugins/vis_default_editor/public/components/agg_select.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_select.tsx @@ -104,14 +104,14 @@ function DefaultEditorAggSelect({ }, [setValue] ); - const onSearchChange = useCallback((searchValue) => setIsDirty(Boolean(searchValue)), []); + const onSearchChange = useCallback((searchValue: string) => setIsDirty(Boolean(searchValue)), []); const setTouched = useCallback( () => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.TOUCHED, payload: true }), [onChangeAggType] ); const setValidity = useCallback( - (valid) => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.VALID, payload: valid }), + (valid: boolean) => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.VALID, payload: valid }), [onChangeAggType] ); diff --git a/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx index 89a6109c52fc..699dbe347027 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx @@ -67,7 +67,7 @@ const defaultConfig = { }; function FromToList({ showValidation, onBlur, ...rest }: FromToListProps) { - const renderInputRow = useCallback( + const renderInputRow = useCallback( (item: FromToModel, index, onChangeValue) => ( <> diff --git a/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx index a63848c1d14c..ca42f1bd23f0 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx @@ -63,7 +63,7 @@ const defaultConfig = { }; function MaskList({ showValidation, onBlur, ...rest }: MaskListProps) { - const renderInputRow = useCallback( + const renderInputRow = useCallback( ({ mask }: MaskModel, index, onChangeValue) => ( setIsDirty(Boolean(searchValue)), []); + const onSearchChange = useCallback((searchValue: string) => setIsDirty(Boolean(searchValue)), []); return ( setValue(ev.target.value), [setValue]); + const onChange = useCallback>( + (e) => setValue(e.target.value), + [setValue] + ); return ( setStateParamValue(PARAMS.NAME, optionId === PARAMS.ROWS), + (optionId: string) => setStateParamValue(PARAMS.NAME, optionId === PARAMS.ROWS), [setStateParamValue] ); diff --git a/src/plugins/vis_default_editor/public/components/controls/string.tsx b/src/plugins/vis_default_editor/public/components/controls/string.tsx index 254c29918066..90b47ebf5c0d 100644 --- a/src/plugins/vis_default_editor/public/components/controls/string.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/string.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useEffect, useCallback } from 'react'; +import React, { useEffect, useCallback, ChangeEventHandler } from 'react'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { AggParamEditorProps } from '../agg_param_props'; @@ -26,7 +26,10 @@ function StringParamEditor({ setValidity(isValid); }, [isValid, setValidity]); - const onChange = useCallback((ev) => setValue(ev.target.value), [setValue]); + const onChange = useCallback>( + (e) => setValue(e.target.value), + [setValue] + ); return ( void; @@ -18,9 +19,9 @@ function useSubAggParamsHandlers( aggParam: AggParamType, subAgg: IAggConfig, setValue: SetValue -) { - const setAggParamValue = useCallback( - (aggId, paramName, val) => { +): Pick { + const setAggParamValue = useCallback( + (_, paramName, val) => { const parsedParams = subAgg.serialize(); const params = { ...parsedParams, @@ -35,13 +36,13 @@ function useSubAggParamsHandlers( [agg, aggParam, setValue, subAgg] ); - const onAggTypeChange = useCallback( - (aggId, aggType) => { + const onAggTypeChange = useCallback( + (_, aggType) => { const parsedAgg = subAgg.serialize(); const parsedAggParams = parsedAgg.params as SerializableRecord; // we should share between aggs only field and base params: json, label, time shift. - const params = { + const params: AggConfigSerialized = { ...parsedAgg, params: { field: parsedAggParams.field, @@ -49,6 +50,7 @@ function useSubAggParamsHandlers( customLabel: parsedAggParams.customLabel, timeShift: parsedAggParams.timeShift, }, + // @ts-ignore - Need to verify type type: aggType, }; diff --git a/src/plugins/vis_default_editor/public/components/options/color_ranges.tsx b/src/plugins/vis_default_editor/public/components/options/color_ranges.tsx index 67a6c9c6e8f4..059518926a3e 100644 --- a/src/plugins/vis_default_editor/public/components/options/color_ranges.tsx +++ b/src/plugins/vis_default_editor/public/components/options/color_ranges.tsx @@ -39,8 +39,8 @@ function ColorRanges({ }, [colorsRange]); const validateRange = useCallback( - ({ from, to }, index) => { - if (!colorsRange[index]) { + ({ from, to }: RangeValues, index: number) => { + if (from === undefined || to === undefined || !colorsRange[index]) { return [false, false]; } diff --git a/src/plugins/vis_default_editor/public/components/options/index.ts b/src/plugins/vis_default_editor/public/components/options/index.ts index 09373dc64eb8..fa2aab156861 100644 --- a/src/plugins/vis_default_editor/public/components/options/index.ts +++ b/src/plugins/vis_default_editor/public/components/options/index.ts @@ -9,11 +9,9 @@ export { BasicOptions } from './basic_options'; export { SwitchOption } from './switch'; export { SelectOption } from './select'; -export type { SetColorRangeValue } from './color_ranges'; -export { ColorRanges } from './color_ranges'; -export type { SetColorSchemaOptionsValue } from './color_schema'; -export { ColorSchemaOptions } from './color_schema'; -export { NumberInputOption } from './number_input'; +export { ColorRanges, type SetColorRangeValue } from './color_ranges'; +export { ColorSchemaOptions, type SetColorSchemaOptionsValue } from './color_schema'; +export { NumberInputOption, type NumberInputOptionProps } from './number_input'; export { RangeOption } from './range'; export { RequiredNumberInputOption } from './required_number_input'; export { TextInputOption } from './text_input'; diff --git a/src/plugins/vis_default_editor/public/components/options/legend_size_settings.tsx b/src/plugins/vis_default_editor/public/components/options/legend_size_settings.tsx index bbe47295c99e..43d6b6d230b5 100644 --- a/src/plugins/vis_default_editor/public/components/options/legend_size_settings.tsx +++ b/src/plugins/vis_default_editor/public/components/options/legend_size_settings.tsx @@ -71,7 +71,7 @@ export const LegendSizeSettings = ({ }, [isVerticalLegend, legendSize, onLegendSizeChange]); const onLegendSizeOptionChange = useCallback( - (option) => onLegendSizeChange(option === DEFAULT_LEGEND_SIZE ? undefined : option), + (size: LegendSize) => onLegendSizeChange(size === DEFAULT_LEGEND_SIZE ? undefined : size), [onLegendSizeChange] ); diff --git a/src/plugins/vis_default_editor/public/components/options/number_input.tsx b/src/plugins/vis_default_editor/public/components/options/number_input.tsx index 604a5896308a..643d4ad60890 100644 --- a/src/plugins/vis_default_editor/public/components/options/number_input.tsx +++ b/src/plugins/vis_default_editor/public/components/options/number_input.tsx @@ -62,4 +62,4 @@ function NumberInputOption({ ); } -export { NumberInputOption }; +export { NumberInputOption, type NumberInputOptionProps }; diff --git a/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx index 678a6c2edaf9..4b14ade5ef43 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useCallback, useState } from 'react'; +import React, { SetStateAction, useCallback, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, @@ -42,7 +42,7 @@ function DefaultEditorControls({ const { enableAutoApply } = vis.type.editorConfig; const [autoApplyEnabled, setAutoApplyEnabled] = useState(false); const toggleAutoApply = useCallback( - (nextAutoApplyEnabled) => setAutoApplyEnabled(nextAutoApplyEnabled), + (nextAutoApplyEnabled: SetStateAction) => setAutoApplyEnabled(nextAutoApplyEnabled), [] ); const onClickDiscard = useCallback(() => dispatch(discardChanges(vis)), [dispatch, vis]); diff --git a/src/plugins/vis_default_editor/public/index.ts b/src/plugins/vis_default_editor/public/index.ts index ffa5e5f88e66..1e251976d30a 100644 --- a/src/plugins/vis_default_editor/public/index.ts +++ b/src/plugins/vis_default_editor/public/index.ts @@ -27,6 +27,7 @@ export { ColorRanges, BasicOptions, type SetColorRangeValue, + type NumberInputOptionProps, type SetColorSchemaOptionsValue, } from './components/options'; export type { RangeValues } from './components/controls/ranges'; diff --git a/src/plugins/vis_types/heatmap/public/editor/components/heatmap.tsx b/src/plugins/vis_types/heatmap/public/editor/components/heatmap.tsx index 14f09472df75..de483e34f7b1 100644 --- a/src/plugins/vis_types/heatmap/public/editor/components/heatmap.tsx +++ b/src/plugins/vis_types/heatmap/public/editor/components/heatmap.tsx @@ -69,7 +69,10 @@ const HeatmapOptions = (props: HeatmapOptionsProps) => { } }, [stateParams]); - const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]); + const handleLegendSizeChange = useCallback( + (size?: LegendSize) => setValue('legendSize', size), + [setValue] + ); return ( <> diff --git a/src/plugins/vis_types/heatmap/public/editor/components/labels_panel.tsx b/src/plugins/vis_types/heatmap/public/editor/components/labels_panel.tsx index 0b16e538fb48..0134d8d056ec 100644 --- a/src/plugins/vis_types/heatmap/public/editor/components/labels_panel.tsx +++ b/src/plugins/vis_types/heatmap/public/editor/components/labels_panel.tsx @@ -47,7 +47,10 @@ function LabelsPanel({ valueAxis, setValue, isNewLibrary }: LabelsPanelProps) { [setValueAxisLabels] ); - const setColor = useCallback((value) => setValueAxisLabels('color', value), [setValueAxisLabels]); + const setColor = useCallback( + (value: string) => setValueAxisLabels('color', value), + [setValueAxisLabels] + ); return ( diff --git a/src/plugins/vis_types/pie/public/editor/components/pie.tsx b/src/plugins/vis_types/pie/public/editor/components/pie.tsx index b1369e4e9092..8b5a6bdd7c49 100644 --- a/src/plugins/vis_types/pie/public/editor/components/pie.tsx +++ b/src/plugins/vis_types/pie/public/editor/components/pie.tsx @@ -117,14 +117,17 @@ const PieOptions = (props: PieOptionsProps) => { }, [props.palettes]); const handleEmptySizeRatioChange = useCallback( - (sizeId) => { + (sizeId: string) => { const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value; setValue('emptySizeRatio', emptySizeRatio); }, [setValue] ); - const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]); + const handleLegendSizeChange = useCallback( + (size?: LegendSize) => setValue('legendSize', size), + [setValue] + ); const handleLegendDisplayChange = useCallback( (name: keyof PartitionVisParams, show: boolean) => { diff --git a/src/plugins/vis_types/timeseries/public/application/components/annotations_editor.tsx b/src/plugins/vis_types/timeseries/public/application/components/annotations_editor.tsx index b1c4adae3859..9af19c8dc18f 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/annotations_editor.tsx +++ b/src/plugins/vis_types/timeseries/public/application/components/annotations_editor.tsx @@ -74,7 +74,7 @@ export const AnnotationsEditor = (props: AnnotationsEditorProps) => { ); const handleDelete = useCallback( - (annotation) => () => + (annotation: Annotation) => () => collectionActions.handleDelete(getCollectionActionsProps(props), annotation), [props] ); diff --git a/src/plugins/vis_types/vega/public/vega_inspector/components/inspector_data_grid.tsx b/src/plugins/vis_types/vega/public/vega_inspector/components/inspector_data_grid.tsx index 688247c5eb6d..e9341ec5a4a2 100644 --- a/src/plugins/vis_types/vega/public/vega_inspector/components/inspector_data_grid.tsx +++ b/src/plugins/vis_types/vega/public/vega_inspector/components/inspector_data_grid.tsx @@ -19,12 +19,12 @@ interface InspectorDataGridProps extends VegaRuntimeData { export const InspectorDataGrid = ({ columns, data, dataGridAriaLabel }: InspectorDataGridProps) => { const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE }); const onChangeItemsPerPage = useCallback( - (pageSize) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })), + (pageSize: number) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })), [setPagination] ); const onChangePage = useCallback( - (pageIndex) => setPagination((p) => ({ ...p, pageIndex })), + (pageIndex: number) => setPagination((p) => ({ ...p, pageIndex })), [setPagination] ); diff --git a/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/chart_options.tsx b/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/chart_options.tsx index 1d609187f83c..8611f17d585d 100644 --- a/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/chart_options.tsx +++ b/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/chart_options.tsx @@ -47,7 +47,7 @@ function ChartOptions({ ); const setValueAxis = useCallback( - (paramName, value) => { + (paramName: 'valueAxis', value: string) => { changeValueAxis(index, paramName, value); }, [changeValueAxis, index] diff --git a/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/y_extents.tsx b/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/y_extents.tsx index 5b37ae97a196..e8baea3ed4da 100644 --- a/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/y_extents.tsx +++ b/src/plugins/vis_types/xy/public/editor/components/options/metrics_axes/y_extents.tsx @@ -10,7 +10,7 @@ import React, { useEffect, useCallback } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { NumberInputOption } from '@kbn/vis-default-editor-plugin/public'; +import { NumberInputOption, NumberInputOptionProps } from '@kbn/vis-default-editor-plugin/public'; import { Scale, ScaleType } from '../../../../types'; import { SetScale } from './value_axis_options'; @@ -54,7 +54,7 @@ function YExtents({ scale, setScale, setMultipleValidity }: YExtentsProps) { const isValid = !errors.length; - const setExtents = useCallback( + const setExtents = useCallback['setValue']>( (paramName, value) => { setScale(paramName, value === '' ? null : value); }, diff --git a/src/plugins/vis_types/xy/public/editor/components/options/point_series/point_series.tsx b/src/plugins/vis_types/xy/public/editor/components/options/point_series/point_series.tsx index f38471d2ae24..fe997ead61eb 100644 --- a/src/plugins/vis_types/xy/public/editor/components/options/point_series/point_series.tsx +++ b/src/plugins/vis_types/xy/public/editor/components/options/point_series/point_series.tsx @@ -46,7 +46,10 @@ export function PointSeriesOptions(props: ValidationVisOptionsProps) const [hadAutoLegendSize] = useState(() => legendSize === LegendSize.AUTO); - const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]); + const handleLegendSizeChange = useCallback( + (size?: LegendSize) => setValue('legendSize', size), + [setValue] + ); return ( <> diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx index 2ffe694e37b5..7b92509ed53c 100644 --- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx +++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx @@ -16,7 +16,7 @@ interface CounterParams { } export class SelfChangingEditor extends React.Component> { - onCounterChange = (ev: any) => { + onCounterChange = (ev: React.ChangeEvent) => { this.props.setValue('counter', parseInt(ev.target.value, 10)); }; diff --git a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts index 8e7adb504ebe..1eac63022d6d 100644 --- a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts +++ b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts @@ -8,6 +8,7 @@ import path from 'path'; import expect from '@kbn/expect'; +import { byIdAscComparator } from '@kbn/core-saved-objects-import-export-server-internal/src/export/utils'; import { PluginFunctionalProviderContext } from '../../services'; const fixturePaths = { @@ -47,11 +48,13 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide .expect(200) .then((resp) => { expect( - resp.body.saved_objects.map((obj: any) => ({ - id: obj.id, - type: obj.type, - hidden: obj.meta.hiddenType, - })) + resp.body.saved_objects + .map((obj: any) => ({ + id: obj.id, + type: obj.type, + hidden: obj.meta.hiddenType, + })) + .sort(byIdAscComparator) ).to.eql([ { id: 'obj_1', diff --git a/test/tsconfig.json b/test/tsconfig.json index b03067c0440a..9f9f062a1649 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -78,5 +78,6 @@ "@kbn/default-nav-analytics", "@kbn/default-nav-management", "@kbn/default-nav-devtools", + "@kbn/core-saved-objects-import-export-server-internal", ] } diff --git a/x-pack/examples/testing_embedded_lens/public/app.tsx b/x-pack/examples/testing_embedded_lens/public/app.tsx index c3d4d103a9a4..9aa6a40fe20c 100644 --- a/x-pack/examples/testing_embedded_lens/public/app.tsx +++ b/x-pack/examples/testing_embedded_lens/public/app.tsx @@ -470,7 +470,7 @@ export const App = (props: { const currentSO = useRef(initialAttributes); const [currentValid, saveValidSO] = useState(initialAttributes); const switchChartPreset = useCallback( - (newIndex) => { + (newIndex: number) => { const newChart = charts[newIndex]; const newAttributes = JSON.stringify(newChart.attributes, null, 2); currentSO.current = newAttributes; @@ -694,7 +694,7 @@ export const App = (props: { ({ value: i, text: id }))} value={undefined} - onChange={(e) => switchChartPreset(Number(e.target.value))} + onChange={(e) => switchChartPreset(+e.target.value)} aria-label="Load from a preset" prepend={'Load preset'} /> diff --git a/x-pack/packages/kbn-cloud-security-posture-common/index.ts b/x-pack/packages/kbn-cloud-security-posture-common/index.ts index f4d7ac2e34dd..66a98d5e398c 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/index.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/index.ts @@ -16,7 +16,8 @@ export type { BaseCspSetupBothPolicy, BaseCspSetupStatus, CspSetupStatus, - CspFinding, -} from './types'; +} from './types/status'; +export type { CspFinding } from './types/findings'; +export type { BenchmarksCisId } from './types/benchmark'; export * from './constants'; -export type { CspBenchmarkRuleMetadata, CspBenchmarkRulesStates } from './schema/rules'; +export { extractErrorMessage, buildMutedRulesFilter } from './utils/helpers'; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx b/x-pack/packages/kbn-cloud-security-posture-common/jest.config.js similarity index 64% rename from x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx rename to x-pack/packages/kbn-cloud-security-posture-common/jest.config.js index 92381ec3846b..d6f06d2bcc21 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx +++ b/x-pack/packages/kbn-cloud-security-posture-common/jest.config.js @@ -5,7 +5,8 @@ * 2.0. */ -export enum EventsViewType { - osqueryView = 'osquery-results-view', - responseActionsView = 'response-actions-results-view', -} +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/x-pack/packages/kbn-cloud-security-posture-common'], +}; diff --git a/x-pack/packages/kbn-cloud-security-posture-common/schema/rules.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules.ts deleted file mode 100644 index 67bb37e4e170..000000000000 --- a/x-pack/packages/kbn-cloud-security-posture-common/schema/rules.ts +++ /dev/null @@ -1,48 +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 { TypeOf, schema } from '@kbn/config-schema'; -import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../constants'; - -export type CspBenchmarkRuleMetadata = TypeOf; - -export const cspBenchmarkRuleMetadataSchema = schema.object({ - audit: schema.string(), - benchmark: schema.object({ - name: schema.string(), - posture_type: schema.maybe( - schema.oneOf([schema.literal(CSPM_POLICY_TEMPLATE), schema.literal(KSPM_POLICY_TEMPLATE)]) - ), - id: schema.string(), - version: schema.string(), - rule_number: schema.maybe(schema.string()), - }), - default_value: schema.maybe(schema.string()), - description: schema.string(), - id: schema.string(), - impact: schema.maybe(schema.string()), - name: schema.string(), - profile_applicability: schema.string(), - rationale: schema.string(), - references: schema.maybe(schema.string()), - rego_rule_id: schema.string(), - remediation: schema.string(), - section: schema.string(), - tags: schema.arrayOf(schema.string()), - version: schema.string(), -}); - -export const ruleStateAttributes = schema.object({ - muted: schema.boolean(), - benchmark_id: schema.string(), - benchmark_version: schema.string(), - rule_number: schema.string(), - rule_id: schema.string(), -}); - -export const rulesStates = schema.recordOf(schema.string(), ruleStateAttributes); - -export type CspBenchmarkRulesStates = TypeOf; diff --git a/x-pack/plugins/observability_solution/investigate/public/esql_widget/create_esql_widget.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/index.ts similarity index 50% rename from x-pack/plugins/observability_solution/investigate/public/esql_widget/create_esql_widget.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/index.ts index f3226afd1419..b8b927b3d1c5 100644 --- a/x-pack/plugins/observability_solution/investigate/public/esql_widget/create_esql_widget.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/index.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { createWidgetFactory } from '../create_widget'; -import { ESQL_WIDGET_NAME } from './constants'; -import type { EsqlWidgetParameters } from './types'; - -export const createEsqlWidget = createWidgetFactory(ESQL_WIDGET_NAME); +export * as rulesV1 from './v1'; +export * as rulesV2 from './v2'; +export * as rulesV3 from './v3'; +export * as rulesV4 from './v4'; +export * as rulesV5 from './v5'; diff --git a/x-pack/plugins/observability_solution/investigate/public/esql_widget/constants.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/latest.ts similarity index 86% rename from x-pack/plugins/observability_solution/investigate/public/esql_widget/constants.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/latest.ts index 068d4b49fcf8..b56fab649ade 100644 --- a/x-pack/plugins/observability_solution/investigate/public/esql_widget/constants.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/latest.ts @@ -5,4 +5,4 @@ * 2.0. */ -export const ESQL_WIDGET_NAME = 'esql'; +export * from './v5'; diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v1.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v1.ts similarity index 100% rename from x-pack/plugins/cloud_security_posture/common/types/rules/v1.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v1.ts diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v2.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v2.ts similarity index 100% rename from x-pack/plugins/cloud_security_posture/common/types/rules/v2.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v2.ts diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v3.ts similarity index 73% rename from x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v3.ts index 7c0a536de79a..a00bf1a8077e 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v3.ts @@ -6,8 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; - -import { cspBenchmarkRuleMetadataSchema } from '@kbn/cloud-security-posture-common/schema'; +import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../../constants'; export const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25; @@ -15,8 +14,36 @@ export const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25; export type FindCspBenchmarkRuleRequest = TypeOf; +export type CspBenchmarkRuleMetadata = TypeOf; + export type CspBenchmarkRule = TypeOf; +export const cspBenchmarkRuleMetadataSchema = schema.object({ + audit: schema.string(), + benchmark: schema.object({ + name: schema.string(), + posture_type: schema.maybe( + schema.oneOf([schema.literal(CSPM_POLICY_TEMPLATE), schema.literal(KSPM_POLICY_TEMPLATE)]) + ), + id: schema.string(), + version: schema.string(), + rule_number: schema.maybe(schema.string()), + }), + default_value: schema.maybe(schema.string()), + description: schema.string(), + id: schema.string(), + impact: schema.maybe(schema.string()), + name: schema.string(), + profile_applicability: schema.string(), + rationale: schema.string(), + references: schema.maybe(schema.string()), + rego_rule_id: schema.string(), + remediation: schema.string(), + section: schema.string(), + tags: schema.arrayOf(schema.string()), + version: schema.string(), +}); + export const cspBenchmarkRuleSchema = schema.object({ metadata: cspBenchmarkRuleMetadataSchema, }); diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v4.ts similarity index 86% rename from x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v4.ts index 231fb4c65a9b..4f05a15f555b 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v4.ts @@ -6,11 +6,15 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; -import { ruleStateAttributes, rulesStates } from '@kbn/cloud-security-posture-common/schema'; -import { BenchmarksCisId } from '../latest'; +import { BenchmarksCisId } from '../../types/benchmark'; import { DEFAULT_BENCHMARK_RULES_PER_PAGE } from './v3'; -export type { cspBenchmarkRuleSchema, CspBenchmarkRule, FindCspBenchmarkRuleResponse } from './v3'; +export type { + cspBenchmarkRuleMetadataSchema, + CspBenchmarkRuleMetadata, + cspBenchmarkRuleSchema, + CspBenchmarkRule, + FindCspBenchmarkRuleResponse, +} from './v3'; export type FindCspBenchmarkRuleRequest = TypeOf; @@ -22,6 +26,8 @@ export type CspBenchmarkRulesBulkActionRequestSchema = TypeOf< export type RuleStateAttributes = TypeOf; +export type CspBenchmarkRulesStates = TypeOf; + export type CspSettings = TypeOf; export const findCspBenchmarkRuleRequestSchema = schema.object({ @@ -137,6 +143,16 @@ export interface CspBenchmarkRulesBulkActionResponse { message: string; } +const ruleStateAttributes = schema.object({ + muted: schema.boolean(), + benchmark_id: schema.string(), + benchmark_version: schema.string(), + rule_number: schema.string(), + rule_id: schema.string(), +}); + +const rulesStates = schema.recordOf(schema.string(), ruleStateAttributes); + export const cspSettingsSchema = schema.object({ rules: rulesStates, }); diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v5.ts b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v5.ts similarity index 93% rename from x-pack/plugins/cloud_security_posture/common/types/rules/v5.ts rename to x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v5.ts index 1d70528d457e..6f30ed446531 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/rules/v5.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/schema/rules/v5.ts @@ -7,13 +7,20 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { DEFAULT_BENCHMARK_RULES_PER_PAGE } from './v3'; -export type { cspBenchmarkRuleSchema, CspBenchmarkRule, FindCspBenchmarkRuleResponse } from './v3'; +export type { + cspBenchmarkRuleMetadataSchema, + CspBenchmarkRuleMetadata, + cspBenchmarkRuleSchema, + CspBenchmarkRule, + FindCspBenchmarkRuleResponse, +} from './v3'; export type { PageUrlParams, rulesToUpdate, CspBenchmarkRulesBulkActionRequestSchema, CspBenchmarkRulesBulkActionResponse, RuleStateAttributes, + CspBenchmarkRulesStates, cspSettingsSchema, CspSettings, BulkActionBenchmarkRulesResponse, diff --git a/x-pack/packages/kbn-cloud-security-posture-common/tsconfig.json b/x-pack/packages/kbn-cloud-security-posture-common/tsconfig.json index 1eb47d23c154..17961df58625 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/tsconfig.json +++ b/x-pack/packages/kbn-cloud-security-posture-common/tsconfig.json @@ -16,5 +16,7 @@ ], "kbn_references": [ "@kbn/config-schema", + "@kbn/data-views-plugin", + "@kbn/i18n", ] } diff --git a/x-pack/packages/kbn-cloud-security-posture-common/schema/index.ts b/x-pack/packages/kbn-cloud-security-posture-common/types/benchmark.ts similarity index 73% rename from x-pack/packages/kbn-cloud-security-posture-common/schema/index.ts rename to x-pack/packages/kbn-cloud-security-posture-common/types/benchmark.ts index 981633d2a3fa..ed661879558e 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/schema/index.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/types/benchmark.ts @@ -4,5 +4,4 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -export { ruleStateAttributes, cspBenchmarkRuleMetadataSchema, rulesStates } from './rules'; +export type BenchmarksCisId = 'cis_k8s' | 'cis_azure' | 'cis_aws' | 'cis_eks' | 'cis_gcp'; diff --git a/x-pack/packages/kbn-cloud-security-posture-common/types.ts b/x-pack/packages/kbn-cloud-security-posture-common/types/findings.ts similarity index 54% rename from x-pack/packages/kbn-cloud-security-posture-common/types.ts rename to x-pack/packages/kbn-cloud-security-posture-common/types/findings.ts index 7a9d5fee09c8..8a7a563fb26c 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/types.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/types/findings.ts @@ -4,46 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { EcsDataStream, EcsEvent } from '@elastic/ecs'; -import type { CspBenchmarkRuleMetadata } from './schema/rules'; - -export type CspStatusCode = - | 'indexed' // latest findings index exists and has results - | 'indexing' // index timeout was not surpassed since installation, assumes data is being indexed - | 'unprivileged' // user lacks privileges for the latest findings index - | 'index-timeout' // index timeout was surpassed since installation - | 'not-deployed' // no healthy agents were deployed - | 'not-installed' // number of installed csp integrations is 0; - | 'waiting_for_results'; // have healthy agents but no findings at all, assumes data is being indexed for the 1st time - -export type IndexStatus = - | 'not-empty' // Index contains documents - | 'empty' // Index doesn't contain documents (or doesn't exist) - | 'unprivileged'; // User doesn't have access to query the index - -export interface IndexDetails { - index: string; - status: IndexStatus; -} - -export interface BaseCspSetupBothPolicy { - status: CspStatusCode; - installedPackagePolicies: number; - healthyAgents: number; -} - -export interface BaseCspSetupStatus { - indicesDetails: IndexDetails[]; - latestPackageVersion: string; - cspm: BaseCspSetupBothPolicy; - kspm: BaseCspSetupBothPolicy; - vuln_mgmt: BaseCspSetupBothPolicy; - isPluginInitialized: boolean; - installedPackageVersion?: string | undefined; - hasMisconfigurationsFindings?: boolean; -} -export type CspSetupStatus = BaseCspSetupStatus; +/* + * 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 type { EcsDataStream, EcsEvent } from '@elastic/ecs'; +import type { CspBenchmarkRuleMetadata } from '../schema/rules/latest'; export interface CspFinding { '@timestamp': string; diff --git a/x-pack/packages/kbn-cloud-security-posture-common/types/status.ts b/x-pack/packages/kbn-cloud-security-posture-common/types/status.ts new file mode 100644 index 000000000000..92ad6ee126b8 --- /dev/null +++ b/x-pack/packages/kbn-cloud-security-posture-common/types/status.ts @@ -0,0 +1,51 @@ +/* + * 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. + */ + +/* + * 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. + */ + +export type CspStatusCode = + | 'indexed' // latest findings index exists and has results + | 'indexing' // index timeout was not surpassed since installation, assumes data is being indexed + | 'unprivileged' // user lacks privileges for the latest findings index + | 'index-timeout' // index timeout was surpassed since installation + | 'not-deployed' // no healthy agents were deployed + | 'not-installed' // number of installed csp integrations is 0; + | 'waiting_for_results'; // have healthy agents but no findings at all, assumes data is being indexed for the 1st time + +export type IndexStatus = + | 'not-empty' // Index contains documents + | 'empty' // Index doesn't contain documents (or doesn't exist) + | 'unprivileged'; // User doesn't have access to query the index + +export interface IndexDetails { + index: string; + status: IndexStatus; +} + +export interface BaseCspSetupBothPolicy { + status: CspStatusCode; + installedPackagePolicies: number; + healthyAgents: number; +} + +export interface BaseCspSetupStatus { + indicesDetails: IndexDetails[]; + latestPackageVersion: string; + cspm: BaseCspSetupBothPolicy; + kspm: BaseCspSetupBothPolicy; + vuln_mgmt: BaseCspSetupBothPolicy; + isPluginInitialized: boolean; + installedPackageVersion?: string | undefined; + hasMisconfigurationsFindings?: boolean; +} + +export type CspSetupStatus = BaseCspSetupStatus; diff --git a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts new file mode 100644 index 000000000000..7e5f4f1d8120 --- /dev/null +++ b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts @@ -0,0 +1,141 @@ +/* + * 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 { extractErrorMessage, defaultErrorMessage, buildMutedRulesFilter } from './helpers'; + +const fallbackMessage = 'thisIsAFallBackMessage'; + +describe('test helper methods', () => { + describe('extractErrorMessage Test', () => { + it('should return error message if input is instance of Error', () => { + const errorMessage = 'thisIsInstanceOfErrorMessage'; + const error = new Error(errorMessage); + const extractedErrorMessage = extractErrorMessage(error, fallbackMessage); + + expect(extractedErrorMessage).toMatch(errorMessage); + }); + + it('should return string if input is string', () => { + const error: string = 'thisIsAString'; + const extractedErrorMessage = extractErrorMessage(error, fallbackMessage); + + expect(extractedErrorMessage).toMatch(error); + }); + + it('should return fallbackMessage is input is not string nor instance of Error', () => { + const error: number = 12345; + const extractedErrorMessage = extractErrorMessage(error, fallbackMessage); + + expect(extractedErrorMessage).toMatch(fallbackMessage); + }); + + it('should return default message when input is not string nor instance of Error and fallbackMessage is not provided', () => { + const error: number = 12345; + const extractedErrorMessage = extractErrorMessage(error); + + expect(extractedErrorMessage).toMatch(defaultErrorMessage); + }); + }); + + describe('buildMutedRulesFilter Test', () => { + it('should return an empty array if no rules are muted', () => { + const rulesStates = { + rule1: { + muted: false, + benchmark_id: '1', + benchmark_version: '1.0', + rule_number: '1', + rule_id: '11', + }, + rule2: { + muted: false, + benchmark_id: '2', + benchmark_version: '1.0', + rule_number: '2', + rule_id: '22', + }, + }; + + expect(buildMutedRulesFilter(rulesStates)).toEqual([]); + }); + + it('should return the correct query for a single muted rule', () => { + const rulesStates = { + rule1: { + muted: true, + benchmark_id: '1', + benchmark_version: '1.0', + rule_number: '1', + rule_id: '11', + }, + rule2: { + muted: false, + benchmark_id: '2', + benchmark_version: '1.0', + rule_number: '2', + rule_id: '22', + }, + }; + + const expectedQuery = [ + { + bool: { + must: [ + { term: { 'rule.benchmark.id': '1' } }, + { term: { 'rule.benchmark.version': '1.0' } }, + { term: { 'rule.benchmark.rule_number': '1' } }, + ], + }, + }, + ]; + + expect(buildMutedRulesFilter(rulesStates)).toEqual(expectedQuery); + }); + + it('should return the correct queries for multiple muted rules', () => { + const rulesStates = { + rule1: { + muted: true, + benchmark_id: '1', + benchmark_version: '1.0', + rule_number: '1', + rule_id: '11', + }, + rule2: { + muted: true, + benchmark_id: '2', + benchmark_version: '1.0', + rule_number: '2', + rule_id: '22', + }, + }; + + const expectedQuery = [ + { + bool: { + must: [ + { term: { 'rule.benchmark.id': '1' } }, + { term: { 'rule.benchmark.version': '1.0' } }, + { term: { 'rule.benchmark.rule_number': '1' } }, + ], + }, + }, + { + bool: { + must: [ + { term: { 'rule.benchmark.id': '2' } }, + { term: { 'rule.benchmark.version': '1.0' } }, + { term: { 'rule.benchmark.rule_number': '2' } }, + ], + }, + }, + ]; + + expect(buildMutedRulesFilter(rulesStates)).toEqual(expectedQuery); + }); + }); +}); diff --git a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts new file mode 100644 index 000000000000..7c26c6177813 --- /dev/null +++ b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts @@ -0,0 +1,43 @@ +/* + * 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 { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types'; +import { i18n } from '@kbn/i18n'; +import type { CspBenchmarkRulesStates } from '../schema/rules/latest'; + +export const defaultErrorMessage = i18n.translate('xpack.csp.common.utils.helpers.unknownError', { + defaultMessage: 'Unknown Error', +}); + +export const extractErrorMessage = (e: unknown, fallbackMessage?: string): string => { + if (e instanceof Error) return e.message; + if (typeof e === 'string') return e; + + return fallbackMessage ?? defaultErrorMessage; +}; + +export const buildMutedRulesFilter = ( + rulesStates: CspBenchmarkRulesStates +): QueryDslQueryContainer[] => { + const mutedRules = Object.fromEntries( + Object.entries(rulesStates).filter(([key, value]) => value.muted === true) + ); + + const mutedRulesFilterQuery = Object.keys(mutedRules).map((key) => { + const rule = mutedRules[key]; + return { + bool: { + must: [ + { term: { 'rule.benchmark.id': rule.benchmark_id } }, + { term: { 'rule.benchmark.version': rule.benchmark_version } }, + { term: { 'rule.benchmark.rule_number': rule.rule_number } }, + ], + }, + }; + }); + + return mutedRulesFilterQuery; +}; diff --git a/x-pack/packages/kbn-cloud-security-posture/index.ts b/x-pack/packages/kbn-cloud-security-posture/index.ts index a0e4ba8dbc1b..bb40ae57eca2 100644 --- a/x-pack/packages/kbn-cloud-security-posture/index.ts +++ b/x-pack/packages/kbn-cloud-security-posture/index.ts @@ -6,3 +6,4 @@ */ export * from './type'; +export { showErrorToast } from './src/utils/show_error_toast'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_csp_setup_status_api.ts similarity index 84% rename from x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts rename to x-pack/packages/kbn-cloud-security-posture/src/hooks/use_csp_setup_status_api.ts index 003f84177228..f77e1e5c12c8 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts +++ b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_csp_setup_status_api.ts @@ -6,16 +6,17 @@ */ import { useQuery, type UseQueryOptions } from '@tanstack/react-query'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { CoreStart } from '@kbn/core/public'; import { STATUS_API_CURRENT_VERSION, STATUS_ROUTE_PATH } from '@kbn/cloud-security-posture-common'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-common'; -import { useKibana } from '../hooks/use_kibana'; const getCspSetupStatusQueryKey = 'csp_status_key'; export const useCspSetupStatusApi = ( options?: UseQueryOptions ) => { - const { http } = useKibana().services; + const { http } = useKibana().services; return useQuery( [getCspSetupStatusQueryKey], () => http.get(STATUS_ROUTE_PATH, { version: STATUS_API_CURRENT_VERSION }), diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_get_benchmark_rules_state_api.ts b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_get_benchmark_rules_state_api.ts similarity index 81% rename from x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_get_benchmark_rules_state_api.ts rename to x-pack/packages/kbn-cloud-security-posture/src/hooks/use_get_benchmark_rules_state_api.ts index cf79ef80b119..06270d9bc710 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_get_benchmark_rules_state_api.ts +++ b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_get_benchmark_rules_state_api.ts @@ -10,13 +10,14 @@ import { CSP_GET_BENCHMARK_RULES_STATE_API_CURRENT_VERSION, CSP_GET_BENCHMARK_RULES_STATE_ROUTE_PATH, } from '@kbn/cloud-security-posture-common'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; -import { useKibana } from '../../../common/hooks/use_kibana'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { CoreStart } from '@kbn/core/public'; export const getRuleStatesKey = ['get_rules_state_key']; export const useGetCspBenchmarkRulesStatesApi = () => { - const { http } = useKibana().services; + const { http } = useKibana().services; return useQuery(getRuleStatesKey, () => http.get(CSP_GET_BENCHMARK_RULES_STATE_ROUTE_PATH, { version: CSP_GET_BENCHMARK_RULES_STATE_API_CURRENT_VERSION, diff --git a/x-pack/plugins/cloud_security_posture/public/common/utils/show_error_toast.ts b/x-pack/packages/kbn-cloud-security-posture/src/utils/show_error_toast.ts similarity index 90% rename from x-pack/plugins/cloud_security_posture/public/common/utils/show_error_toast.ts rename to x-pack/packages/kbn-cloud-security-posture/src/utils/show_error_toast.ts index 75316d9495b2..060ae8c3b69e 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/utils/show_error_toast.ts +++ b/x-pack/packages/kbn-cloud-security-posture/src/utils/show_error_toast.ts @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import type { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; -import { extractErrorMessage } from '../../../common/utils/helpers'; +import { extractErrorMessage } from '@kbn/cloud-security-posture-common'; const SEARCH_FAILED_TEXT = i18n.translate( 'xpack.csp.findings.findingsErrorToast.searchFailedTitle', diff --git a/x-pack/packages/kbn-cloud-security-posture/tsconfig.json b/x-pack/packages/kbn-cloud-security-posture/tsconfig.json index a2652215c4e7..152c3fe8a8b2 100644 --- a/x-pack/packages/kbn-cloud-security-posture/tsconfig.json +++ b/x-pack/packages/kbn-cloud-security-posture/tsconfig.json @@ -33,5 +33,8 @@ "@kbn/es-query", "@kbn/cloud-plugin", "@kbn/spaces-plugin", + "@kbn/kibana-react-plugin", + "@kbn/cloud-security-posture-common", + "@kbn/i18n", ] } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx index 01f4049fb67b..b23f85519a08 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo, useState } from 'react'; -import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; +import { EuiComboBox, EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; import * as i18n from './translations'; @@ -49,7 +49,9 @@ export const ModelSelector: React.FC = React.memo( ); // Callback for when user types to create a new model - const onCreateOption = useCallback( + const onCreateOption = useCallback< + NonNullable['onCreateOption']> + >( (searchValue, flattenedOptions = []) => { if (!searchValue || !searchValue.trim().toLowerCase()) { return; @@ -58,8 +60,7 @@ export const ModelSelector: React.FC = React.memo( const normalizedSearchValue = searchValue.trim().toLowerCase(); const optionExists = flattenedOptions.findIndex( - (option: EuiComboBoxOptionOption) => - option.label.trim().toLowerCase() === normalizedSearchValue + (option) => option.label.trim().toLowerCase() === normalizedSearchValue ) !== -1; const newOption = { diff --git a/x-pack/packages/ml/inference_integration_flyout/components/flyout_layout.tsx b/x-pack/packages/ml/inference_integration_flyout/components/flyout_layout.tsx index a859b1d95103..22c904e63561 100644 --- a/x-pack/packages/ml/inference_integration_flyout/components/flyout_layout.tsx +++ b/x-pack/packages/ml/inference_integration_flyout/components/flyout_layout.tsx @@ -51,7 +51,7 @@ export const InferenceFlyout: React.FC = ({ }, [inferenceEndpointError]); const onChangingInferenceEndpoint = useCallback( - (value) => { + (value: any) => { setInferenceEndpointId(value); onInferenceEndpointChange(value); }, diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx index 38cf611b4bdd..f6f3ea0f4d9d 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx @@ -104,7 +104,7 @@ export const LogRateAnalysisResultsTable: FC = groupFilter !== undefined ); - const onChange = useCallback((tableSettings) => { + const onChange = useCallback((tableSettings: any) => { if (tableSettings.page) { const { index, size } = tableSettings.page; setPageIndex(index); diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx index 905ac53b149c..d69a0fec7200 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx @@ -247,7 +247,7 @@ export const LogRateAnalysisResultsGroupsTable: FC { + const onChange = useCallback((tableSettings: any) => { if (tableSettings.page) { const { index, size } = tableSettings.page; setPageIndex(index); diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx index cd69f972c675..e74f3117d55f 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx @@ -9,6 +9,7 @@ import moment from 'moment'; import { FIELD_TYPES, Form, + FormSubmitHandler, getUseField, useForm, useFormData, @@ -136,7 +137,7 @@ export const CreateMaintenanceWindowForm = React.memo>( async (formData, isValid) => { if (!isValid || scopedQueryErrors.length !== 0) { return; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx index dd396057e372..7e474859981e 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/maintenance_windows_list.tsx @@ -29,7 +29,7 @@ import { MaintenanceWindow, } from '../../../../common'; import { StatusFilter } from './status_filter'; -import { TableActionsPopover } from './table_actions_popover'; +import { TableActionsPopover, TableActionsPopoverProps } from './table_actions_popover'; import { useFinishMaintenanceWindow } from '../../../hooks/use_finish_maintenance_window'; import { useArchiveMaintenanceWindow } from '../../../hooks/use_archive_maintenance_window'; import { useFinishAndArchiveMaintenanceWindow } from '../../../hooks/use_finish_and_archive_maintenance_window'; @@ -115,13 +115,13 @@ export const MaintenanceWindowsList = React.memo( }; const { euiTheme } = useEuiTheme(); const { navigateToEditMaintenanceWindows } = useEditMaintenanceWindowsNavigation(); - const onEdit = useCallback( + const onEdit = useCallback( (id) => navigateToEditMaintenanceWindows(id), [navigateToEditMaintenanceWindows] ); const { mutate: finishMaintenanceWindow, isLoading: isLoadingFinish } = useFinishMaintenanceWindow(); - const onCancel = useCallback( + const onCancel = useCallback( (id) => finishMaintenanceWindow(id, { onSuccess: () => refreshData() }), [finishMaintenanceWindow, refreshData] ); diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/table_actions_popover.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/table_actions_popover.tsx index ffe0509c1fd3..c91f518f6976 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/table_actions_popover.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/table_actions_popover.tsx @@ -18,7 +18,7 @@ import { import * as i18n from '../translations'; import { MaintenanceWindowStatus } from '../../../../common'; -interface TableActionsPopoverProps { +export interface TableActionsPopoverProps { id: string; status: MaintenanceWindowStatus; onEdit: (id: string) => void; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/vis_dimension.tsx b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/vis_dimension.tsx index 89c3cf35a7c3..488abfcc80e0 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/vis_dimension.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/vis_dimension.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useEffect, useCallback } from 'react'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSelect } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSelect, EuiSelectProps } from '@elastic/eui'; import { DatatableColumn, ExpressionAstExpression } from '@kbn/expressions-plugin/common'; import { templateFromReactComponent } from '../../../public/lib/template_from_react_component'; import { ArgumentStrings } from '../../../i18n'; @@ -15,7 +15,7 @@ import { ResolvedArgProps, ResolvedColumns } from '../../../public/expression_ty const { VisDimension: strings } = ArgumentStrings; type VisDimensionArgInputProps = { - onValueChange: (value: ExpressionAstExpression) => void; + onValueChange: (value: ExpressionAstExpression | string) => void; argValue: ExpressionAstExpression; typeInstance: { options?: { @@ -30,14 +30,14 @@ const VisDimensionArgInput: React.FC = ({ onValueChange, resolved: { columns }, }) => { - const [value, setValue] = useState(argValue); + const [value, setValue] = useState(argValue); const confirm = typeInstance?.options?.confirm; useEffect(() => { setValue(argValue); }, [argValue]); - const onChange = useCallback( + const onChange = useCallback>( (ev) => { const onChangeFn = confirm ? setValue : onValueChange; const astObj: ExpressionAstExpression = { diff --git a/x-pack/plugins/canvas/kibana.jsonc b/x-pack/plugins/canvas/kibana.jsonc index 1f6a3bf5554b..f752f37443fe 100644 --- a/x-pack/plugins/canvas/kibana.jsonc +++ b/x-pack/plugins/canvas/kibana.jsonc @@ -12,7 +12,6 @@ "canvas" ], "requiredPlugins": [ - "bfetch", "charts", "data", "dataViews", diff --git a/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx b/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx index 053cda9dd03f..f2abceff1f67 100644 --- a/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx +++ b/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx @@ -59,14 +59,18 @@ const ArgTemplateFormComponent: React.FunctionComponent = mountedArgumentRef.current = undefined; }); - const onMount = useCallback((ref) => { - if (!mountedArgumentRef.current && ref) { - mountedArgumentRef.current = ref; - } - }, []); + const onMount = useCallback( + (ref: UpdatePropsRef | null) => { + if (!mountedArgumentRef.current && ref) { + mountedArgumentRef.current = ref; + } + }, + [] + ); const renderTemplate = useCallback( - (domNode) => template && template(domNode, argumentProps, updatedHandlers, onMount), + (domNode: HTMLElement) => + template && template(domNode, argumentProps, updatedHandlers, onMount), [argumentProps, onMount, template, updatedHandlers] ); diff --git a/x-pack/plugins/canvas/public/components/var_config/var_value_field.tsx b/x-pack/plugins/canvas/public/components/var_config/var_value_field.tsx index 24b9a82e32e5..6b91497fa0f6 100644 --- a/x-pack/plugins/canvas/public/components/var_config/var_value_field.tsx +++ b/x-pack/plugins/canvas/public/components/var_config/var_value_field.tsx @@ -48,7 +48,7 @@ export const VarValueField: FC = ({ type, value, onChange }) => { ]; const onNumberChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const floatVal = parseFloat(e.target.value); const varValue = isNaN(floatVal) ? '' : floatVal; onChange(varValue); diff --git a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx index 7cc077203c73..1e604a6deb85 100644 --- a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx +++ b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx @@ -74,7 +74,7 @@ export const Workpad: FC = (props) => { ); const getAnimation = useCallback( - (pageNumber) => { + (pageNumber: number) => { if (!transition || !transition.name) { return null; } @@ -94,7 +94,7 @@ export const Workpad: FC = (props) => { const onTransitionEnd = useCallback(() => setTransition(null), [setTransition]); const setFullscreenWithEffect = useCallback( - (fullscreen) => { + (fullscreen: boolean) => { setFullscreen(fullscreen); if (fullscreen === true) { trackCanvasUiMetric( diff --git a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx index c14e54d8e854..64e0c259cd04 100644 --- a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx @@ -21,8 +21,11 @@ const strings = { export const WorkpadColorPicker = (props: Props) => { const dispatch = useDispatch(); - const onAddColor = useCallback((payload) => dispatch(addColor(payload)), [dispatch]); - const onRemoveColor = useCallback((payload) => dispatch(removeColor(payload)), [dispatch]); + const onAddColor = useCallback((payload: string) => dispatch(addColor(payload)), [dispatch]); + const onRemoveColor = useCallback( + (payload: string) => dispatch(removeColor(payload)), + [dispatch] + ); const colors = useSelector(getWorkpadColors); return ( diff --git a/x-pack/plugins/canvas/public/expression_types/datasource.tsx b/x-pack/plugins/canvas/public/expression_types/datasource.tsx index a7d5cd4e7a2b..f7bd89200cfd 100644 --- a/x-pack/plugins/canvas/public/expression_types/datasource.tsx +++ b/x-pack/plugins/canvas/public/expression_types/datasource.tsx @@ -61,12 +61,12 @@ const DatasourceWrapperComponent: React.FunctionComponent { + const onMount = useCallback((ref: UpdatePropsRef | null) => { datasourceRef.current = ref ?? undefined; }, []); const callRenderFn = useCallback( - (domNode) => { + (domNode: HTMLDivElement) => { const { template } = spec; if (!template) { return null; diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index 495dea5873f9..5f385ce5f079 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -27,7 +27,6 @@ import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { Start as InspectorStart } from '@kbn/inspector-plugin/public'; -import { BfetchPublicSetup } from '@kbn/bfetch-plugin/public'; import { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; @@ -53,7 +52,6 @@ export interface CanvasSetupDeps { expressions: ExpressionsSetup; home?: HomePublicPluginSetup; usageCollection?: UsageCollectionSetup; - bfetch: BfetchPublicSetup; charts: ChartsPluginSetup; uiActions: UiActionsSetup; } diff --git a/x-pack/plugins/canvas/public/setup_expressions.ts b/x-pack/plugins/canvas/public/setup_expressions.ts index 655daef80f85..848fb9a12b0c 100644 --- a/x-pack/plugins/canvas/public/setup_expressions.ts +++ b/x-pack/plugins/canvas/public/setup_expressions.ts @@ -21,7 +21,7 @@ export const setupExpressions = async ({ coreSetup: CoreSetup; setupPlugins: CanvasSetupDeps; }) => { - const { expressions, bfetch } = setupPlugins; + const { expressions } = setupPlugins; const loadServerFunctionWrappers = async () => { if (!cached) { @@ -29,7 +29,6 @@ export const setupExpressions = async ({ const serverFunctionList = await coreSetup.http.get(API_ROUTE_FUNCTIONS, { version: '1', }); - const batchedFunction = bfetch.batchedFunction({ url: API_ROUTE_FUNCTIONS }); const { serialize } = serializeProvider(expressions.getTypes()); // For every sever-side function, register a client-side @@ -43,7 +42,10 @@ export const setupExpressions = async ({ const fn = () => ({ ...serverFunctionList[functionName], fn: (input: any, args: any) => { - return batchedFunction({ functionName, args, context: serialize(input) }); + return coreSetup.http.post(API_ROUTE_FUNCTIONS, { + body: JSON.stringify({ functionName, args, context: serialize(input) }), + version: '1', + }); }, }); diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts index 36a6fbbd0e3e..074d29ec977f 100644 --- a/x-pack/plugins/canvas/server/plugin.ts +++ b/x-pack/plugins/canvas/server/plugin.ts @@ -11,7 +11,6 @@ import { PluginStart as DataPluginStart, } from '@kbn/data-plugin/server'; import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server'; -import { BfetchServerSetup } from '@kbn/bfetch-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import { HomeServerPluginSetup } from '@kbn/home-plugin/server'; import { EmbeddableSetup } from '@kbn/embeddable-plugin/server'; @@ -33,7 +32,6 @@ interface PluginsSetup { embeddable: EmbeddableSetup; features: FeaturesPluginSetup; home: HomeServerPluginSetup; - bfetch: BfetchServerSetup; data: DataPluginSetup; reporting?: ReportingServerPluginSetup; usageCollection?: UsageCollectionSetup; @@ -81,7 +79,6 @@ export class CanvasPlugin implements Plugin { initRoutes({ router: canvasRouter, expressions: expressionsSetup, - bfetch: plugins.bfetch, logger: this.logger, }); diff --git a/x-pack/plugins/canvas/server/routes/functions/functions.ts b/x-pack/plugins/canvas/server/routes/functions/functions.ts index 73036b35af05..3a8ff207fa00 100644 --- a/x-pack/plugins/canvas/server/routes/functions/functions.ts +++ b/x-pack/plugins/canvas/server/routes/functions/functions.ts @@ -6,6 +6,7 @@ */ import { serializeProvider } from '@kbn/expressions-plugin/common'; +import { schema } from '@kbn/config-schema'; import { RouteInitializerDeps } from '..'; import { API_ROUTE_FUNCTIONS } from '../../../common/lib/constants'; @@ -32,7 +33,43 @@ export function initializeGetFunctionsRoute(deps: RouteInitializerDeps) { } export function initializeBatchFunctionsRoute(deps: RouteInitializerDeps) { - const { bfetch, expressions } = deps; + const { router, expressions } = deps; + router.versioned + .post({ + path: API_ROUTE_FUNCTIONS, + access: 'internal', + }) + .addVersion( + { + version: '1', + validate: { + request: { + body: schema.object({ + functionName: schema.string(), + args: schema.object({}, { unknowns: 'allow' }), + context: schema.object({}, { unknowns: 'allow' }), + }), + }, + }, + }, + async (context, request, response) => { + const handlers = { + environment: 'server', + }; + const fnCall: FunctionCall = { + functionName: request.body.functionName, + args: request.body.args, + context: request.body.context, + }; + const result = await runFunction(handlers, fnCall); + if (typeof result === 'undefined') { + throw new Error(`Function ${fnCall.functionName} did not return anything.`); + } + return response.ok({ + body: result, + }); + } + ); async function runFunction(handlers: { environment: string }, fnCall: FunctionCall) { const { functionName, args, context } = fnCall; @@ -46,23 +83,4 @@ export function initializeBatchFunctionsRoute(deps: RouteInitializerDeps) { return result; } - - /** - * Register an endpoint that executes a batch of functions, and streams the - * results back using ND-JSON. - */ - bfetch.addBatchProcessingRoute(API_ROUTE_FUNCTIONS, (request) => { - return { - onBatchItem: async (fnCall: FunctionCall) => { - const handlers = { - environment: 'server', - }; - const result = await runFunction(handlers, fnCall); - if (typeof result === 'undefined') { - throw new Error(`Function ${fnCall.functionName} did not return anything.`); - } - return result; - }, - }; - }); } diff --git a/x-pack/plugins/canvas/server/routes/index.ts b/x-pack/plugins/canvas/server/routes/index.ts index 9b2d712b17c5..80dc1b56e3db 100644 --- a/x-pack/plugins/canvas/server/routes/index.ts +++ b/x-pack/plugins/canvas/server/routes/index.ts @@ -7,7 +7,6 @@ import { IRouter, Logger } from '@kbn/core/server'; import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server'; -import { BfetchServerSetup } from '@kbn/bfetch-plugin/server'; import { initCustomElementsRoutes } from './custom_elements'; import { initShareablesRoutes } from './shareables'; import { initWorkpadRoutes } from './workpad'; @@ -19,7 +18,6 @@ export interface RouteInitializerDeps { router: IRouter; logger: Logger; expressions: ExpressionsServerSetup; - bfetch: BfetchServerSetup; } export function initRoutes(deps: RouteInitializerDeps) { diff --git a/x-pack/plugins/canvas/server/routes/test_helpers.ts b/x-pack/plugins/canvas/server/routes/test_helpers.ts index 30d63576ed6f..ded9076909cb 100644 --- a/x-pack/plugins/canvas/server/routes/test_helpers.ts +++ b/x-pack/plugins/canvas/server/routes/test_helpers.ts @@ -10,13 +10,11 @@ import { loggingSystemMock, elasticsearchServiceMock, } from '@kbn/core/server/mocks'; -import { bfetchPluginMock } from '@kbn/bfetch-plugin/server/mocks'; import { expressionsPluginMock } from '@kbn/expressions-plugin/server/mocks'; export function getMockedRouterDeps() { const httpService = httpServiceMock.createSetupContract(); const elasticsearch = elasticsearchServiceMock.createSetup(); - const bfetch = bfetchPluginMock.createSetupContract(); const expressions = expressionsPluginMock.createSetupContract(); const router = httpService.createRouter(); @@ -24,7 +22,6 @@ export function getMockedRouterDeps() { router, expressions, elasticsearch, - bfetch, logger: loggingSystemMock.create().get(), }; } diff --git a/x-pack/plugins/canvas/tsconfig.json b/x-pack/plugins/canvas/tsconfig.json index 124d2c660e9f..85121b72c868 100644 --- a/x-pack/plugins/canvas/tsconfig.json +++ b/x-pack/plugins/canvas/tsconfig.json @@ -27,7 +27,6 @@ "kbn_references": [ { "path": "../../../src/setup_node_env/tsconfig.json" }, "@kbn/core", - "@kbn/bfetch-plugin", "@kbn/charts-plugin", "@kbn/data-plugin", "@kbn/share-plugin", diff --git a/x-pack/plugins/cases/public/components/actions/assignees/edit_assignees_selectable.tsx b/x-pack/plugins/cases/public/components/actions/assignees/edit_assignees_selectable.tsx index d3a4d9cbb06e..0d4bd261647d 100644 --- a/x-pack/plugins/cases/public/components/actions/assignees/edit_assignees_selectable.tsx +++ b/x-pack/plugins/cases/public/components/actions/assignees/edit_assignees_selectable.tsx @@ -198,7 +198,7 @@ const EditAssigneesSelectableComponent: React.FC = ({ ); const onSearchChange = useCallback( - (value) => { + (value: string) => { setSearchValue(value); onContentChange(value); }, diff --git a/x-pack/plugins/cases/public/components/actions/tags/edit_tags_selectable.tsx b/x-pack/plugins/cases/public/components/actions/tags/edit_tags_selectable.tsx index 17cf9939f814..947228ce9b13 100644 --- a/x-pack/plugins/cases/public/components/actions/tags/edit_tags_selectable.tsx +++ b/x-pack/plugins/cases/public/components/actions/tags/edit_tags_selectable.tsx @@ -120,10 +120,6 @@ const EditTagsSelectableComponent: React.FC = ({ [options, searchValue, state.items] ); - const onSearchChange = useCallback((value) => { - setSearchValue(value); - }, []); - return ( = ({ placeholder: i18n.SEARCH_PLACEHOLDER, isLoading, isClearable: !isLoading, - onChange: onSearchChange, + onChange: setSearchValue, value: searchValue, 'data-test-subj': 'cases-actions-tags-edit-selectable-search-input', }} diff --git a/x-pack/plugins/cases/public/components/add_comment/index.tsx b/x-pack/plugins/cases/public/components/add_comment/index.tsx index 009594df200f..c84f799b1c89 100644 --- a/x-pack/plugins/cases/public/components/add_comment/index.tsx +++ b/x-pack/plugins/cases/public/components/add_comment/index.tsx @@ -26,7 +26,7 @@ import { import { AttachmentType } from '../../../common/types/domain'; import { useCreateAttachments } from '../../containers/use_create_attachments'; import type { CaseUI } from '../../containers/types'; -import type { EuiMarkdownEditorRef } from '../markdown_editor'; +import type { MarkdownEditorRef } from '../markdown_editor'; import { MarkdownEditorForm } from '../markdown_editor'; import { getMarkdownEditorStorageKey } from '../markdown_editor/utils'; import { removeItemFromSessionStorage } from '../utils'; @@ -45,7 +45,7 @@ const initialCommentValue: AddCommentFormSchema = { export interface AddCommentRefObject { addQuote: (quote: string) => void; setComment: (newComment: string) => void; - editor: EuiMarkdownEditorRef | null; + editor: MarkdownEditorRef | null; } /* eslint-disable react/no-unused-prop-types */ @@ -65,7 +65,7 @@ export const AddComment = React.memo( { id, caseId, onCommentPosted, onCommentSaving, showLoading = true, statusActionButton }, ref ) => { - const editorRef = useRef(null); + const editorRef = useRef(null); const [focusOnContext, setFocusOnContext] = useState(false); const { permissions, owner } = useCasesContext(); const { isLoading, mutate: createAttachments } = useCreateAttachments(); @@ -85,7 +85,7 @@ export const AddComment = React.memo( const { setFieldValue, reset, submit } = form; const [{ comment }] = useFormData<{ comment: string }>({ form, watch: [fieldName] }); - const addQuote = useCallback( + const addQuote = useCallback( (quote) => { const addCarrots = quote.replace(new RegExp('\r?\n', 'g'), '\n> '); const val = `> ${addCarrots} \n\n`; @@ -95,7 +95,7 @@ export const AddComment = React.memo( [comment, setFieldValue] ); - const setComment = useCallback( + const setComment = useCallback( (newComment) => { setFieldValue(fieldName, newComment); }, diff --git a/x-pack/plugins/cases/public/components/all_cases/nav_buttons.tsx b/x-pack/plugins/cases/public/components/all_cases/nav_buttons.tsx index 29b0607ec62a..310340f0366e 100644 --- a/x-pack/plugins/cases/public/components/all_cases/nav_buttons.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/nav_buttons.tsx @@ -27,7 +27,7 @@ export const NavButtons: FunctionComponent = ({ actionsErrors }) => { const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation(); const { euiTheme } = useEuiTheme(); const navigateToCreateCaseClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); navigateToCreateCase(); }, diff --git a/x-pack/plugins/cases/public/components/all_cases/search.tsx b/x-pack/plugins/cases/public/components/all_cases/search.tsx index 265c42470cdb..542ebf9e0c51 100644 --- a/x-pack/plugins/cases/public/components/all_cases/search.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/search.tsx @@ -22,7 +22,7 @@ const TableSearchComponent: React.FC = ({ const [search, setSearch] = useState(filterOptionsSearch); const onSearch = useCallback( - (newSearch) => { + (newSearch: string) => { const trimSearch = newSearch.trim(); setSearch(trimSearch); onFilterOptionsChange({ search: trimSearch }); diff --git a/x-pack/plugins/cases/public/components/all_cases/table.tsx b/x-pack/plugins/cases/public/components/all_cases/table.tsx index c2b429f4789e..c95059660b3e 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table.tsx @@ -59,7 +59,7 @@ export const CasesTable: FunctionComponent = ({ const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation(); const { euiTheme } = useEuiTheme(); const navigateToCreateCaseClick = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); if (goToCreateCase != null) { goToCreateCase(); diff --git a/x-pack/plugins/cases/public/components/app/routes.tsx b/x-pack/plugins/cases/public/components/app/routes.tsx index 501cd665ff24..ee2c82777dbf 100644 --- a/x-pack/plugins/cases/public/components/app/routes.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.tsx @@ -28,6 +28,7 @@ import { NoPrivilegesPage } from '../no_privileges'; import * as i18n from './translations'; import { useReadonlyHeader } from './use_readonly_header'; import type { CaseViewProps } from '../case_view/types'; +import type { CreateCaseFormProps } from '../create/form'; const CaseViewLazy: React.FC = lazy(() => import('../case_view')); @@ -45,7 +46,7 @@ const CasesRoutesComponent: React.FC = ({ const { navigateToCaseView } = useCaseViewNavigation(); useReadonlyHeader(); - const onCreateCaseSuccess = useCallback( + const onCreateCaseSuccess: CreateCaseFormProps['onSuccess'] = useCallback( async ({ id }) => navigateToCaseView({ detailName: id }), [navigateToCaseView] ); diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx index adc2b41f6ce6..add85202d0e5 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx @@ -73,7 +73,7 @@ export const CaseViewPage = React.memo( }, [isLoading, refreshRef, refreshCaseViewPage]); const onSubmitTitle = useCallback( - (newTitle) => + (newTitle: string) => onUpdateField({ key: 'title', value: newTitle, diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx index d0e5cefa458a..6e945ef83627 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx @@ -25,6 +25,7 @@ import { useGetSupportedActionConnectors } from '../../../containers/configure/u import type { CaseSeverity, CaseStatuses } from '../../../../common/types/domain'; import type { CaseUICustomField, UseFetchAlertData } from '../../../../common/ui/types'; import type { CaseUI } from '../../../../common'; +import type { EditConnectorProps } from '../../edit_connector'; import { EditConnector } from '../../edit_connector'; import type { CasesNavigation } from '../../links'; import { StatusActionButton } from '../../status/button'; @@ -115,12 +116,12 @@ export const CaseViewActivity = ({ ); const onSubmitTags = useCallback( - (newTags) => onUpdateField({ key: 'tags', value: newTags }), + (newTags: string[]) => onUpdateField({ key: 'tags', value: newTags }), [onUpdateField] ); const onSubmitCategory = useCallback( - (newCategory) => onUpdateField({ key: 'category', value: newCategory }), + (newCategory: string | null) => onUpdateField({ key: 'category', value: newCategory }), [onUpdateField] ); @@ -142,7 +143,7 @@ export const CaseViewActivity = ({ const { isLoading: isLoadingAllAvailableConnectors, data: supportedActionConnectors } = useGetSupportedActionConnectors(); - const onSubmitConnector = useCallback( + const onSubmitConnector = useCallback( (connector) => { onUpdateField({ key: 'connector', diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_files.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_files.tsx index 85cd4685a41f..25f6929fbb81 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_files.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_files.tsx @@ -57,7 +57,7 @@ export const CaseViewFiles = ({ caseData }: CaseViewFilesProps) => { ); const onSearchChange = useCallback( - (newSearch) => { + (newSearch: string) => { const trimSearch = newSearch.trim(); if (!isEqual(trimSearch, filteringOptions.searchTerm)) { setFilteringOptions({ diff --git a/x-pack/plugins/cases/public/components/case_view/components/custom_fields.tsx b/x-pack/plugins/cases/public/components/case_view/components/custom_fields.tsx index 32d03bac8dc8..c30e2b1767ee 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/custom_fields.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/custom_fields.tsx @@ -33,7 +33,7 @@ const CustomFieldsComponent: React.FC = ({ ); const onSubmitCustomField = useCallback( - (customFieldToAdd) => { + (customFieldToAdd: CaseUICustomField) => { onSubmit(customFieldToAdd); }, [onSubmit] diff --git a/x-pack/plugins/cases/public/components/case_view/components/edit_category.tsx b/x-pack/plugins/cases/public/components/case_view/components/edit_category.tsx index f4992f96d985..460fa364bc4d 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/edit_category.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/edit_category.tsx @@ -28,7 +28,7 @@ import { RemovableItem } from '../../removable_item/removable_item'; export interface EditCategoryProps { isLoading: boolean; - onSubmit: (category?: string | null) => void; + onSubmit: (category: string | null) => void; category?: string | null; } diff --git a/x-pack/plugins/cases/public/components/description/index.tsx b/x-pack/plugins/cases/public/components/description/index.tsx index 78440cf9b7f1..6599bc3ef43c 100644 --- a/x-pack/plugins/cases/public/components/description/index.tsx +++ b/x-pack/plugins/cases/public/components/description/index.tsx @@ -21,7 +21,7 @@ import { getMarkdownEditorStorageKey } from '../markdown_editor/utils'; import * as i18n from '../user_actions/translations'; import { useCasesContext } from '../cases_context/use_cases_context'; import { useLensDraftComment } from '../markdown_editor/plugins/lens/use_lens_draft_comment'; -import type { EditableMarkdownRefObject, EuiMarkdownEditorRef } from '../markdown_editor'; +import type { EditableMarkdownRefObject, MarkdownEditorRef } from '../markdown_editor'; import { EditableMarkdown, ScrollableMarkdown } from '../markdown_editor'; import type { CaseUI } from '../../containers/types'; import type { OnUpdateFields } from '../case_view/types'; @@ -30,7 +30,7 @@ import { schema } from './schema'; const DESCRIPTION_ID = 'description'; export interface DescriptionMarkdownRefObject extends EditableMarkdownRefObject { - editor: EuiMarkdownEditorRef | null; + editor: MarkdownEditorRef | null; } export interface DescriptionProps { caseData: CaseUI; diff --git a/x-pack/plugins/cases/public/components/files/add_file.tsx b/x-pack/plugins/cases/public/components/files/add_file.tsx index 449e9bf26992..7b91879834a7 100644 --- a/x-pack/plugins/cases/public/components/files/add_file.tsx +++ b/x-pack/plugins/cases/public/components/files/add_file.tsx @@ -31,6 +31,7 @@ import { useCasesContext } from '../cases_context/use_cases_context'; import * as i18n from './translations'; import { useRefreshCaseViewPage } from '../case_view/use_on_refresh_case_view_page'; import { deleteFileAttachments } from '../../containers/api'; +import type { ServerError } from '../../types'; interface AddFileProps { caseId: string; @@ -47,7 +48,7 @@ const AddFileComponent: React.FC = ({ caseId }) => { const showModal = () => setIsModalVisible(true); const onError = useCallback( - (error) => { + (error: Error | ServerError) => { showErrorToast(error, { title: i18n.FAILED_UPLOAD, }); diff --git a/x-pack/plugins/cases/public/components/filter_popover/index.tsx b/x-pack/plugins/cases/public/components/filter_popover/index.tsx index 60b796476149..142a8aac8833 100644 --- a/x-pack/plugins/cases/public/components/filter_popover/index.tsx +++ b/x-pack/plugins/cases/public/components/filter_popover/index.tsx @@ -62,7 +62,7 @@ export const FilterPopoverComponent = ({ const setIsPopoverOpenCb = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); const toggleSelectedGroupCb = useCallback( - (option) => onSelectedOptionsChanged(toggleSelectedGroup(option, selectedOptions)), + (option: string) => onSelectedOptionsChanged(toggleSelectedGroup(option, selectedOptions)), [selectedOptions, onSelectedOptionsChanged] ); diff --git a/x-pack/plugins/cases/public/components/header_page/index.tsx b/x-pack/plugins/cases/public/components/header_page/index.tsx index 60aa4a9160cf..1901700fe428 100644 --- a/x-pack/plugins/cases/public/components/header_page/index.tsx +++ b/x-pack/plugins/cases/public/components/header_page/index.tsx @@ -56,7 +56,7 @@ const HeaderPageComponent: React.FC = ({ const xsFontSize = useEuiFontSize('xs').fontSize; const navigateToAllCasesClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { if (e) { e.preventDefault(); } diff --git a/x-pack/plugins/cases/public/components/links/index.tsx b/x-pack/plugins/cases/public/components/links/index.tsx index f09a9f852a28..cc6e29da8008 100644 --- a/x-pack/plugins/cases/public/components/links/index.tsx +++ b/x-pack/plugins/cases/public/components/links/index.tsx @@ -44,7 +44,7 @@ const CaseDetailsLinkComponent: React.FC = ({ }) => { const { getCaseViewUrl, navigateToCaseView } = useCaseViewNavigation(); const navigateToCaseViewClick = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToCaseView({ detailName }); }, @@ -83,7 +83,7 @@ const ConfigureCaseButtonComponent: React.FC = ({ const { getConfigureCasesUrl, navigateToConfigureCases } = useConfigureCasesNavigation(); const navigateToConfigureCasesClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); navigateToConfigureCases(); }, diff --git a/x-pack/plugins/cases/public/components/markdown_editor/editable_markdown_renderer.tsx b/x-pack/plugins/cases/public/components/markdown_editor/editable_markdown_renderer.tsx index bd91d219ee87..0353c7491d00 100644 --- a/x-pack/plugins/cases/public/components/markdown_editor/editable_markdown_renderer.tsx +++ b/x-pack/plugins/cases/public/components/markdown_editor/editable_markdown_renderer.tsx @@ -50,7 +50,7 @@ const EditableMarkDownRenderer = forwardRef< const { submit, setFieldValue, isValid: isFormValid } = form; const setComment = useCallback( - (newComment) => { + (newComment: string) => { setFieldValue(fieldName, newComment); }, [setFieldValue, fieldName] diff --git a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/use_lens_draft_comment.ts b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/use_lens_draft_comment.ts index 95e558ca1f79..23c4a66fa4e5 100644 --- a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/use_lens_draft_comment.ts +++ b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/use_lens_draft_comment.ts @@ -11,6 +11,7 @@ import { first } from 'rxjs'; import { useKibana } from '../../../../common/lib/kibana'; import { DRAFT_COMMENT_STORAGE_ID } from './constants'; import { VISUALIZATION } from './translations'; +import type { MarkdownEditorRef } from '../../editor'; interface DraftComment { commentId: string; @@ -51,9 +52,11 @@ export const useLensDraftComment = () => { fetchDraftComment(); }, [currentAppId$, embeddable, storage]); - const openLensModal = useCallback(({ editorRef }) => { + const openLensModal = useCallback(({ editorRef }: { editorRef: MarkdownEditorRef }) => { if (editorRef && editorRef.textarea && editorRef.toolbar) { - const lensPluginButton = editorRef.toolbar?.querySelector(`[aria-label="${VISUALIZATION}"]`); + const lensPluginButton = editorRef.toolbar?.querySelector( + `[aria-label="${VISUALIZATION}"]` + ); if (lensPluginButton) { lensPluginButton.click(); } diff --git a/x-pack/plugins/cases/public/components/recent_cases/filters/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/filters/index.tsx index 5478f5b91882..1d7c22eccb68 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/filters/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/filters/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { EuiSelectOption } from '@elastic/eui'; +import type { EuiSelectOption, EuiSelectProps } from '@elastic/eui'; import { EuiSelect } from '@elastic/eui'; import React, { useCallback } from 'react'; @@ -50,7 +50,7 @@ export const RecentCasesFilters = React.memo<{ }; }); - const onChange = useCallback( + const onChange = useCallback>( (e) => { setFilterBy(e.target.value as FilterMode); }, diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index 28c632f843d7..55df7a6c9ac4 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -48,7 +48,7 @@ const RecentCasesComponent = React.memo(({ maxCasesToShow }: RecentCasesProps) = useState('recentlyCreated'); const navigateToAllCasesClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); navigateToAllCases(); }, diff --git a/x-pack/plugins/cases/public/components/recent_cases/no_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/no_cases/index.tsx index d284c99af76d..5fc24e8655ee 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/no_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/no_cases/index.tsx @@ -23,7 +23,7 @@ const NoCasesComponent = ({ recentCasesFilterBy }: NoCasesComp) => { const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation(); const navigateToCreateCaseClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); navigateToCreateCase(); }, diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx index 92a24b615e38..a83fa9883671 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx @@ -24,7 +24,7 @@ export const useCreateCaseModal = ({ onCaseCreated }: UseCreateCaseModalProps) = const closeModal = useCallback(() => setIsModalOpen(false), []); const openModal = useCallback(() => setIsModalOpen(true), []); const onSuccess = useCallback( - async (theCase) => { + async (theCase: CaseUI) => { onCaseCreated(theCase); closeModal(); }, diff --git a/x-pack/plugins/cases/public/components/use_push_to_service/callout/callout.tsx b/x-pack/plugins/cases/public/components/use_push_to_service/callout/callout.tsx index c94fbb826df4..a3326b3cb90f 100644 --- a/x-pack/plugins/cases/public/components/use_push_to_service/callout/callout.tsx +++ b/x-pack/plugins/cases/public/components/use_push_to_service/callout/callout.tsx @@ -36,7 +36,7 @@ const CallOutComponent = ({ const { permissions } = useCasesContext(); const handleCallOut = useCallback( - (e) => handleButtonClick(e, id, type), + (e: React.MouseEvent) => handleButtonClick(e, id, type), [handleButtonClick, id, type] ); diff --git a/x-pack/plugins/cases/public/components/use_push_to_service/callout/index.tsx b/x-pack/plugins/cases/public/components/use_push_to_service/callout/index.tsx index 07f4ab2768c0..f311044e835a 100644 --- a/x-pack/plugins/cases/public/components/use_push_to_service/callout/index.tsx +++ b/x-pack/plugins/cases/public/components/use_push_to_service/callout/index.tsx @@ -36,7 +36,7 @@ const CaseCallOutComponent = ({ }: CaseCallOutProps) => { const { navigateToConfigureCases } = useConfigureCasesNavigation(); const handleCallOut = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); // if theres connectors open dropdown editor // if no connectors, redirect to create case page diff --git a/x-pack/plugins/cases/public/components/user_actions/comment/alert_event.tsx b/x-pack/plugins/cases/public/components/user_actions/comment/alert_event.tsx index 94f9d290e375..42e5e6b9d442 100644 --- a/x-pack/plugins/cases/public/components/user_actions/comment/alert_event.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/comment/alert_event.tsx @@ -29,7 +29,7 @@ interface MultipleAlertsProps extends SingleAlertProps { const RuleLink: React.FC = memo( ({ onRuleDetailsClick, getRuleDetailsHref, ruleId, ruleName, loadingAlertData, actionId }) => { const onLinkClick = useCallback( - (ev) => { + (ev: React.MouseEvent) => { ev.preventDefault(); if (onRuleDetailsClick) onRuleDetailsClick(ruleId, ev); }, diff --git a/x-pack/plugins/cases/public/components/user_actions/comment/host_isolation_event.tsx b/x-pack/plugins/cases/public/components/user_actions/comment/host_isolation_event.tsx index a638c1a69b30..66e7c65f8695 100644 --- a/x-pack/plugins/cases/public/components/user_actions/comment/host_isolation_event.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/comment/host_isolation_event.tsx @@ -31,7 +31,7 @@ const HostIsolationCommentEventComponent: React.FC = ({ const endpointDetailsHref = href ? href(endpoints[0].endpointId) : ''; const onLinkClick = useCallback( - (ev) => { + (ev: React.MouseEvent) => { ev.preventDefault(); if (onClick) onClick(endpoints[0].endpointId, ev); }, diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx index af2d7c0fd1cd..1c782973dd0e 100644 --- a/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx +++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_response/index.tsx @@ -139,7 +139,7 @@ export const ControlGeneralViewResponse = ({ }, [closePopover, onDuplicate, response]); const onChangeMatches = useCallback( - (options) => { + (options: any) => { response.match = options.map((option: EuiComboBoxOptionOption) => option.value); onResponseChange(response, index); @@ -148,7 +148,7 @@ export const ControlGeneralViewResponse = ({ ); const onChangeExcludes = useCallback( - (options) => { + (options: any) => { response.exclude = options.map((option: EuiComboBoxOptionOption) => option.value); if (response.exclude?.length === 0) { diff --git a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx index 4511aa71f056..05820541fd02 100644 --- a/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx +++ b/x-pack/plugins/cloud_defend/public/components/control_general_view_selector/index.tsx @@ -24,6 +24,7 @@ import { EuiFlexItem, EuiText, EuiCheckbox, + EuiCheckboxProps, } from '@elastic/eui'; import { useStyles } from './styles'; import { @@ -69,7 +70,7 @@ const BooleanCondition = ({ onRemoveCondition, }: BooleanConditionProps) => { const value = selector[prop as keyof Selector] as boolean; - const onChange = useCallback( + const onChange = useCallback( (e) => { onChangeBooleanCondition(prop, e.target.checked); }, diff --git a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx index 4dc47b8b5263..6d1262afa135 100644 --- a/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx +++ b/x-pack/plugins/cloud_defend/public/components/control_yaml_view/index.tsx @@ -43,7 +43,7 @@ export const ControlYamlView = ({ policy, onChange, show }: ViewDeps) => { const currentModel = useConfigModel(configuration); // not all validations can be done via json-schema - const validateAdditional = useCallback((value) => { + const validateAdditional = useCallback((value: any) => { const errors: string[] = []; const { selectors, responses } = getSelectorsAndResponsesFromYaml(value); @@ -125,7 +125,7 @@ export const ControlYamlView = ({ policy, onChange, show }: ViewDeps) => { ]); const onYamlChange = useCallback( - (value) => { + (value: any) => { if (show && input?.vars) { input.vars.configuration.value = value; diff --git a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx index 0c7455118394..b842453382b6 100644 --- a/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx +++ b/x-pack/plugins/cloud_defend/public/components/policy_settings/index.tsx @@ -16,6 +16,7 @@ import { EuiFormRow, EuiFieldText, EuiHorizontalRule, + EuiSwitchProps, } from '@elastic/eui'; import { INPUT_CONTROL } from '../../../common/constants'; import { getInputFromPolicy } from '../../../common/utils/helpers'; @@ -27,7 +28,7 @@ export const PolicySettings = ({ policy, onChange }: SettingsDeps) => { const [policyHasErrors, setPolicyHasErrors] = useState(false); const controlInput = getInputFromPolicy(policy, INPUT_CONTROL); const controlEnabled = !!controlInput?.enabled; - const onToggleEnabled = useCallback( + const onToggleEnabled = useCallback( (e) => { if (controlInput) { controlInput.enabled = e.target.checked; diff --git a/x-pack/plugins/cloud_security_posture/common/types/benchmarks/v2.ts b/x-pack/plugins/cloud_security_posture/common/types/benchmarks/v2.ts index efcdd38f4e9b..d0619d4a72dd 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/benchmarks/v2.ts +++ b/x-pack/plugins/cloud_security_posture/common/types/benchmarks/v2.ts @@ -7,12 +7,11 @@ // Optionally, re-export the entire set of types. Interfaces and types declared after this will override v1 declarations. import { schema } from '@kbn/config-schema'; +import type { BenchmarksCisId } from '@kbn/cloud-security-posture-common'; import type { BenchmarkScore } from './v1'; export type { BenchmarkScore } from './v1'; -export type BenchmarksCisId = 'cis_k8s' | 'cis_azure' | 'cis_aws' | 'cis_eks' | 'cis_gcp'; - export interface Benchmark { id: BenchmarksCisId; name: string; diff --git a/x-pack/plugins/cloud_security_posture/common/types/index.ts b/x-pack/plugins/cloud_security_posture/common/types/index.ts index c59071d11425..144a2d2e9afd 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/index.ts +++ b/x-pack/plugins/cloud_security_posture/common/types/index.ts @@ -5,22 +5,8 @@ * 2.0. */ -export * as rulesV1 from './rules/v1'; -export * as rulesV2 from './rules/v2'; -export * as rulesV3 from './rules/v3'; -export * as rulesV4 from './rules/v4'; -export * as rulesV5 from './rules/v5'; - export * as benchmarkV1 from './benchmarks/v1'; export * as benchmarkV2 from './benchmarks/v2'; // Explicit export of everything from latest -export type { - CspBenchmarkRule, - FindCspBenchmarkRuleRequest, - FindCspBenchmarkRuleResponse, - BenchmarkScore, - Benchmark, - GetBenchmarkResponse, - BenchmarkRuleSelectParams, -} from './latest'; +export type { BenchmarkScore, Benchmark, GetBenchmarkResponse } from './latest'; diff --git a/x-pack/plugins/cloud_security_posture/common/types/latest.ts b/x-pack/plugins/cloud_security_posture/common/types/latest.ts index 32006fe5b5ae..7844ef6e36f1 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/latest.ts +++ b/x-pack/plugins/cloud_security_posture/common/types/latest.ts @@ -5,5 +5,4 @@ * 2.0. */ -export * from './rules/v5'; export * from './benchmarks/v2'; diff --git a/x-pack/plugins/cloud_security_posture/common/types_old.ts b/x-pack/plugins/cloud_security_posture/common/types_old.ts index b5e399e4e639..c6531605bc32 100644 --- a/x-pack/plugins/cloud_security_posture/common/types_old.ts +++ b/x-pack/plugins/cloud_security_posture/common/types_old.ts @@ -5,7 +5,7 @@ * 2.0. */ import { type TypeOf } from '@kbn/config-schema'; -import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import type { CspFinding } from '@kbn/cloud-security-posture-common'; import { SUPPORTED_CLOUDBEAT_INPUTS, SUPPORTED_POLICY_TEMPLATES } from './constants'; diff --git a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts index fa514fe0fc2a..2e859ae314cb 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { convertRuleTagsToMatchAllKQL, convertRuleTagsToMatchAnyKQL, diff --git a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts index 4ae838529095..ae888cde81c2 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common/schema/rules/latest'; const CSP_RULE_TAG = 'Cloud Security'; const CSP_RULE_TAG_USE_CASE = 'Use Case: Configuration Audit'; diff --git a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts index 950803c2c65c..90e11734d72c 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts @@ -6,7 +6,7 @@ */ import { Truthy } from 'lodash'; -import type { BaseCspSetupStatus } from '@kbn/cloud-security-posture-common'; +import type { BaseCspSetupStatus, BenchmarksCisId } from '@kbn/cloud-security-posture-common'; import { NewPackagePolicy, NewPackagePolicyInput, @@ -15,6 +15,8 @@ import { PackagePolicyInput, UpdatePackagePolicy, } from '@kbn/fleet-plugin/common'; +import type { BenchmarkRuleSelectParams } from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import type { BenchmarkRuleSelectParams as BenchmarkRuleSelectParamsV4 } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, CLOUDBEAT_VANILLA, @@ -31,8 +33,6 @@ import type { AzureCredentialsType, RuleSection, } from '../types_old'; -import type { BenchmarkRuleSelectParams, BenchmarksCisId } from '../types/latest'; -import type { BenchmarkRuleSelectParams as BenchmarkRuleSelectParamsV1 } from '../types/rules/v4'; /** * @example @@ -44,13 +44,6 @@ export const isNonNullable = (v: T): v is NonNullable => export const truthy = (value: T): value is Truthy => !!value; -export const extractErrorMessage = (e: unknown, defaultMessage = 'Unknown Error'): string => { - if (e instanceof Error) return e.message; - if (typeof e === 'string') return e; - - return defaultMessage; // TODO: i18n -}; - export const getBenchmarkFilter = (type: BenchmarkId, section?: RuleSection): string => `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id: "${type}"${ section @@ -236,7 +229,7 @@ export const getCloudProviderNameFromAbbreviation = (cloudProvider: string) => { export const getBenchmarkFilterQuery = ( benchmarkId: BenchmarkId, benchmarkVersion?: string, - selectParams?: BenchmarkRuleSelectParamsV1 + selectParams?: BenchmarkRuleSelectParamsV4 ): string => { const baseQuery = `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id:${benchmarkId} AND ${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.version:"v${benchmarkVersion}"`; const sectionQuery = selectParams?.section diff --git a/x-pack/plugins/cloud_security_posture/common/utils/rules_states.ts b/x-pack/plugins/cloud_security_posture/common/utils/rules_states.ts index 9a142729e410..e2351d3ddcaa 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/rules_states.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/rules_states.ts @@ -4,31 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; - -export const buildMutedRulesFilter = ( - rulesStates: CspBenchmarkRulesStates -): QueryDslQueryContainer[] => { - const mutedRules = Object.fromEntries( - Object.entries(rulesStates).filter(([key, value]) => value.muted === true) - ); - - const mutedRulesFilterQuery = Object.keys(mutedRules).map((key) => { - const rule = mutedRules[key]; - return { - bool: { - must: [ - { term: { 'rule.benchmark.id': rule.benchmark_id } }, - { term: { 'rule.benchmark.version': rule.benchmark_version } }, - { term: { 'rule.benchmark.rule_number': rule.rule_number } }, - ], - }, - }; - }); - - return mutedRulesFilterQuery; -}; export const buildRuleKey = (benchmarkId: string, benchmarkVersion: string, ruleNumber: string) => { return `${benchmarkId};${benchmarkVersion};${ruleNumber}`; diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.test.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.test.ts index 6207885b60ab..af488c4bb81b 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.test.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.test.ts @@ -7,8 +7,8 @@ import { useBenchmarkDynamicValues } from './use_benchmark_dynamic_values'; import { renderHook } from '@testing-library/react-hooks/dom'; +import type { BenchmarksCisId } from '@kbn/cloud-security-posture-common'; import { useCspIntegrationLink } from '../navigation/use_csp_integration_link'; -import { BenchmarksCisId } from '../../../common/types/benchmarks/v2'; jest.mock('../navigation/use_csp_integration_link'); diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.ts index 7f9a2b5fd35f..7540b96797a1 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_benchmark_dynamic_values.ts @@ -7,8 +7,8 @@ import { i18n } from '@kbn/i18n'; import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '@kbn/cloud-security-posture-common'; +import type { BenchmarksCisId } from '@kbn/cloud-security-posture-common'; import { useCspIntegrationLink } from '../navigation/use_csp_integration_link'; -import { BenchmarksCisId } from '../../../common/types/benchmarks/v2'; type BenchmarkDynamicNames = | { diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_cloud_posture_data_table/use_cloud_posture_data_table.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_cloud_posture_data_table/use_cloud_posture_data_table.ts index ae8ddb48488c..acd63279bdcc 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_cloud_posture_data_table/use_cloud_posture_data_table.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_cloud_posture_data_table/use_cloud_posture_data_table.ts @@ -59,7 +59,7 @@ export const useCloudPostureDataTable = ({ const { pageSize, setPageSize } = usePageSize(paginationLocalStorageKey); const onChangeItemsPerPage = useCallback( - (newPageSize) => { + (newPageSize: any) => { setPageSize(newPageSize); setUrlQuery({ pageIndex: 0, @@ -81,7 +81,7 @@ export const useCloudPostureDataTable = ({ }, [setUrlQuery]); const onChangePage = useCallback( - (newPageIndex) => { + (newPageIndex: any) => { setUrlQuery({ pageIndex: newPageIndex, }); @@ -90,7 +90,7 @@ export const useCloudPostureDataTable = ({ ); const onSort = useCallback( - (sort) => { + (sort: any) => { setUrlQuery({ sort, }); @@ -99,7 +99,7 @@ export const useCloudPostureDataTable = ({ ); const setTableOptions = useCallback( - ({ page, sort }) => { + ({ page, sort }: any) => { setPageSize(page.size); setUrlQuery({ sort, @@ -119,7 +119,7 @@ export const useCloudPostureDataTable = ({ }); const handleUpdateQuery = useCallback( - (query) => { + (query: any) => { setUrlQuery({ ...query, pageIndex: 0 }); }, [setUrlQuery] diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx index 22fc6b4ae65f..9e2275c62e31 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx @@ -24,7 +24,7 @@ import { NoDataPage } from '@kbn/kibana-react-plugin/public'; const chance = new Chance(); -jest.mock('../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../common/api/use_license_management_locator_api'); jest.mock('../common/hooks/use_is_subscription_status_valid'); jest.mock('../common/navigation/use_csp_integration_link'); diff --git a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx index 7590e998cd0c..d62f86651f93 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx @@ -39,7 +39,7 @@ import { } from '../../../common/constants'; import { useParams } from 'react-router-dom'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { usePackagePolicyList } from '../../common/api/use_package_policy_list'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { @@ -67,7 +67,7 @@ jest.mock('react-router-dom', () => ({ integration: undefined, }), })); -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_package_policy_list'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); jest.mock('../../common/api/use_license_management_locator_api'); diff --git a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx index 096c6f0e8aae..9c8f2da45f8e 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx @@ -22,6 +22,7 @@ import { i18n } from '@kbn/i18n'; import { css } from '@emotion/react'; import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '@kbn/cloud-security-posture-common'; import type { IndexDetails, CspStatusCode } from '@kbn/cloud-security-posture-common'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { FullSizeCenteredPage } from '../full_size_centered_page'; import { useCISIntegrationPoliciesLink } from '../../common/navigation/use_navigate_to_cis_integration_policies'; import { @@ -30,7 +31,6 @@ import { NO_FINDINGS_STATUS_TEST_SUBJ, } from '../test_subjects'; import { CloudPosturePage, PACKAGE_NOT_INSTALLED_TEST_SUBJECT } from '../cloud_posture_page'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import type { PostureTypes } from '../../../common/types_old'; import noDataIllustration from '../../assets/illustrations/no_data_illustration.svg'; import { useCspIntegrationLink } from '../../common/navigation/use_csp_integration_link'; diff --git a/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx b/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx index a15cf0aacd6f..074e75915a5b 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx @@ -22,10 +22,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { css } from '@emotion/react'; import type { IndexDetails } from '@kbn/cloud-security-posture-common'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { VULN_MGMT_POLICY_TEMPLATE } from '../../common/constants'; import { FullSizeCenteredPage } from './full_size_centered_page'; import { CloudPosturePage } from './cloud_posture_page'; -import { useCspSetupStatusApi } from '../common/api/use_setup_status_api'; import { NO_VULNERABILITIES_STATUS_TEST_SUBJ, CNVM_NOT_INSTALLED_ACTION_SUBJ, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx index f625470fb08c..e11095bb622f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx @@ -14,13 +14,13 @@ import { TestProvider } from '../../test/test_provider'; import { Benchmarks } from './benchmarks'; import * as TEST_SUBJ from './test_subjects'; import { useCspBenchmarkIntegrationsV2 } from './use_csp_benchmark_integrations'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useCspIntegrationLink } from '../../common/navigation/use_csp_integration_link'; import { ERROR_STATE_TEST_SUBJECT } from './benchmarks_table'; import { useLicenseManagementLocatorApi } from '../../common/api/use_license_management_locator_api'; jest.mock('./use_csp_benchmark_integrations'); -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_license_management_locator_api'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); jest.mock('../../common/navigation/use_csp_integration_link'); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx index 13b475031781..dd6b8ce45318 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx @@ -21,6 +21,8 @@ import { FormattedMessage } from '@kbn/i18n-react'; import useDebounce from 'react-use/lib/useDebounce'; import { i18n } from '@kbn/i18n'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; +import { extractErrorMessage } from '@kbn/cloud-security-posture-common'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../../common/constants'; import { CloudPosturePageTitle } from '../../components/cloud_posture_page_title'; import { CloudPosturePage } from '../../components/cloud_posture_page'; @@ -29,7 +31,7 @@ import { useCspBenchmarkIntegrationsV2, UseCspBenchmarkIntegrationsProps, } from './use_csp_benchmark_integrations'; -import { extractErrorMessage, getBenchmarkCisName } from '../../../common/utils/helpers'; +import { getBenchmarkCisName } from '../../../common/utils/helpers'; import * as TEST_SUBJ from './test_subjects'; import { LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY, @@ -37,7 +39,6 @@ import { } from '../../common/constants'; import { usePageSize } from '../../common/hooks/use_page_size'; import { useKibana } from '../../common/hooks/use_kibana'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { NoFindingsStates } from '../../components/no_findings_states'; const SEARCH_DEBOUNCE_MS = 300; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx index 2da4cc06ddd5..ea08ce039814 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx @@ -21,9 +21,10 @@ import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { generatePath } from 'react-router-dom'; +import type { BenchmarksCisId } from '@kbn/cloud-security-posture-common'; import { FINDINGS_GROUPING_OPTIONS } from '../../common/constants'; import { useNavigateFindings } from '../../common/hooks/use_navigate_findings'; -import type { BenchmarkScore, Benchmark, BenchmarksCisId } from '../../../common/types/latest'; +import type { BenchmarkScore, Benchmark } from '../../../common/types/latest'; import * as TEST_SUBJ from './test_subjects'; import { isCommonError } from '../../components/cloud_posture_page'; import { FullSizeCenteredPage } from '../../components/full_size_centered_page'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx index 46b0e5961208..11d7a71118ea 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx @@ -12,7 +12,7 @@ import type { BaseCspSetupStatus, CspStatusCode } from '@kbn/cloud-security-post import { render, screen } from '@testing-library/react'; import { TestProvider } from '../../test/test_provider'; import { ComplianceDashboard, getDefaultTab } from '.'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useLicenseManagementLocatorApi } from '../../common/api/use_license_management_locator_api'; import { useKspmStatsApi, useCspmStatsApi } from '../../common/api/use_stats_api'; import { @@ -36,7 +36,7 @@ import { ComplianceDashboardDataV2 } from '../../../common/types_old'; import { cloudPosturePages } from '../../common/navigation/constants'; import { MemoryRouter } from 'react-router-dom'; -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_stats_api'); jest.mock('../../common/api/use_license_management_locator_api'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx index 1629a000d5e6..16037fa20476 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx @@ -15,6 +15,7 @@ import { Route, Routes } from '@kbn/shared-ux-router'; import { Redirect, useHistory, useLocation } from 'react-router-dom'; import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '@kbn/cloud-security-posture-common'; import type { BaseCspSetupStatus } from '@kbn/cloud-security-posture-common'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { NO_FINDINGS_STATUS_TEST_SUBJ } from '../../components/test_subjects'; import { useCspIntegrationLink } from '../../common/navigation/use_csp_integration_link'; import type { PosturePolicyTemplate, ComplianceDashboardDataV2 } from '../../../common/types_old'; @@ -35,7 +36,6 @@ import { CLOUD_POSTURE_DASHBOARD_PAGE_HEADER, } from './test_subjects'; import { useCspmStatsApi, useKspmStatsApi } from '../../common/api/use_stats_api'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { NoFindingsStates } from '../../components/no_findings_states'; import { SummarySection } from './dashboard_sections/summary_section'; import { BenchmarksSection } from './dashboard_sections/benchmarks_section'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.tsx index f17a8039db88..3f088e799239 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { Redirect, useLocation } from 'react-router-dom'; import { Routes, Route } from '@kbn/shared-ux-router'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { CDR_MISCONFIGURATIONS_DATA_VIEW_ID_PREFIX } from '../../../common/constants'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { NoFindingsStates } from '../../components/no_findings_states'; import { CloudPosturePage, defaultLoadingRenderer } from '../../components/cloud_posture_page'; import { useDataView } from '../../common/api/use_data_view'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_grouped_findings.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_grouped_findings.tsx index 532998f0f712..75234c0495f5 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_grouped_findings.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_grouped_findings.tsx @@ -11,8 +11,8 @@ import { GenericBuckets, GroupingQuery, RootAggregation } from '@kbn/grouping/sr import { useQuery } from '@tanstack/react-query'; import { lastValueFrom } from 'rxjs'; import { CDR_MISCONFIGURATIONS_INDEX_PATTERN } from '@kbn/cloud-security-posture-common'; +import { showErrorToast } from '@kbn/cloud-security-posture'; import { useKibana } from '../../../common/hooks/use_kibana'; -import { showErrorToast } from '../../../common/utils/show_error_toast'; // Elasticsearch returns `null` when a sub-aggregation cannot be computed type NumberOrNull = number | null; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings.ts index 5a77337ba171..f8cd0238ef0b 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings.ts @@ -11,18 +11,18 @@ import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-ty import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { buildDataTableRecord } from '@kbn/discover-utils'; import { EsHitRecord } from '@kbn/discover-utils/types'; -import { MAX_FINDINGS_TO_LOAD } from '@kbn/cloud-security-posture-common'; +import { showErrorToast } from '@kbn/cloud-security-posture'; +import { MAX_FINDINGS_TO_LOAD, buildMutedRulesFilter } from '@kbn/cloud-security-posture-common'; import { CDR_MISCONFIGURATIONS_INDEX_PATTERN, LATEST_FINDINGS_RETENTION_POLICY, } from '@kbn/cloud-security-posture-common'; -import type { CspBenchmarkRulesStates, CspFinding } from '@kbn/cloud-security-posture-common'; +import type { CspFinding } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import type { FindingsBaseEsQuery } from '@kbn/cloud-security-posture'; +import { useGetCspBenchmarkRulesStatesApi } from '@kbn/cloud-security-posture/src/hooks/use_get_benchmark_rules_state_api'; import { useKibana } from '../../../common/hooks/use_kibana'; import { getAggregationCount, getFindingsCountAggQuery } from '../utils/utils'; -import { showErrorToast } from '../../../common/utils/show_error_toast'; -import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api'; -import { buildMutedRulesFilter } from '../../../../common/utils/rules_states'; interface UseFindingsOptions extends FindingsBaseEsQuery { sort: string[][]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx index d94f063933b0..cc409fb95024 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx @@ -15,7 +15,11 @@ import { } from '@kbn/grouping/src'; import { useMemo } from 'react'; import { buildEsQuery, Filter } from '@kbn/es-query'; -import { LATEST_FINDINGS_RETENTION_POLICY } from '@kbn/cloud-security-posture-common'; +import { + LATEST_FINDINGS_RETENTION_POLICY, + buildMutedRulesFilter, +} from '@kbn/cloud-security-posture-common'; +import { useGetCspBenchmarkRulesStatesApi } from '@kbn/cloud-security-posture/src/hooks/use_get_benchmark_rules_state_api'; import { FINDINGS_GROUPING_OPTIONS, LOCAL_STORAGE_FINDINGS_GROUPING_KEY, @@ -36,8 +40,6 @@ import { } from './constants'; import { useCloudSecurityGrouping } from '../../../components/cloud_security_grouping'; import { getFilters } from '../utils/get_filters'; -import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api'; -import { buildMutedRulesFilter } from '../../../../common/utils/rules_states'; const getTermAggregation = (key: keyof FindingsGroupingAggregation, field: string) => ({ [key]: { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts index 289c6c2cb153..0ce1b7d09e89 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts @@ -7,7 +7,7 @@ import { HttpSetup } from '@kbn/core/public'; import { LATEST_FINDINGS_RETENTION_POLICY } from '@kbn/cloud-security-posture-common'; -import { CspBenchmarkRule } from '../../../../common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { FINDINGS_INDEX_PATTERN } from '../../../../common/constants'; import { createDetectionRule } from '../../../common/api/create_detection_rule'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx index f8d91d525023..b3995e405ba7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx @@ -10,11 +10,11 @@ import { EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { Redirect, useHistory, useLocation, matchPath } from 'react-router-dom'; import { Routes, Route } from '@kbn/shared-ux-router'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { Configurations } from '../configurations'; import { cloudPosturePages, findingsNavigation } from '../../common/navigation/constants'; import { LOCAL_STORAGE_FINDINGS_LAST_SELECTED_TAB_KEY } from '../../common/constants'; import { VULNERABILITIES_INDEX_NAME, FINDINGS_INDEX_NAME } from '../../../common/constants'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { getStatusForIndexName } from '../../../common/utils/helpers'; import { Vulnerabilities } from '../vulnerabilities'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx index 365af617b7f2..f404b6a82d21 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx @@ -10,6 +10,7 @@ import { generatePath, Link, type RouteComponentProps } from 'react-router-dom'; import { EuiButtonEmpty, EuiFlexGroup, EuiPageHeader, EuiSpacer, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; +import type { PageUrlParams } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CloudPosturePageTitle } from '../../components/cloud_posture_page_title'; import { RulesContainer } from './rules_container'; import { cloudPosturePages } from '../../common/navigation/constants'; @@ -18,7 +19,6 @@ import { useSecuritySolutionContext } from '../../application/security_solution_ import { useCspBenchmarkIntegrationsV2 } from '../benchmarks/use_csp_benchmark_integrations'; import { CISBenchmarkIcon } from '../../components/cis_benchmark_icon'; import { getBenchmarkCisName } from '../../../common/utils/helpers'; -import { PageUrlParams } from '../../../common/types/latest'; export const Rules = ({ match: { params } }: RouteComponentProps) => { const benchmarksInfo = useCspBenchmarkIntegrationsV2(); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx index 642aff1ef267..ff427e780945 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx @@ -12,16 +12,16 @@ import { render, screen } from '@testing-library/react'; import { QueryClient } from '@tanstack/react-query'; import { TestProvider } from '../../test/test_provider'; import { type RouteComponentProps } from 'react-router-dom'; -import { PageUrlParams } from '../../../common/types/latest'; +import type { PageUrlParams } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; import { coreMock } from '@kbn/core/public/mocks'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useCspIntegrationLink } from '../../common/navigation/use_csp_integration_link'; import { useLicenseManagementLocatorApi } from '../../common/api/use_license_management_locator_api'; import { useCspBenchmarkIntegrationsV2 } from '../benchmarks/use_csp_benchmark_integrations'; import * as TEST_SUBJECTS from './test_subjects'; -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_license_management_locator_api'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); jest.mock('../../common/navigation/use_csp_integration_link'); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index d81b834f9c93..4718dbae911a 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -13,7 +13,7 @@ import { useFindCspBenchmarkRule } from './use_csp_benchmark_rules'; import * as TEST_SUBJECTS from './test_subjects'; import { Chance } from 'chance'; import { TestProvider } from '../../test/test_provider'; -import type { CspBenchmarkRule } from '../../../common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { useParams } from 'react-router-dom'; import { coreMock } from '@kbn/core/public/mocks'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx index c134e405f8a3..1b1af9aab429 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx @@ -8,9 +8,14 @@ import React, { useState, useMemo, useEffect } from 'react'; import compareVersions from 'compare-versions'; import { EuiSpacer } from '@elastic/eui'; import { useParams, useHistory, generatePath } from 'react-router-dom'; +import type { + CspBenchmarkRule, + PageUrlParams, + RuleStateAttributes, +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import { extractErrorMessage } from '@kbn/cloud-security-posture-common'; import { benchmarksNavigation } from '../../common/navigation/constants'; import { buildRuleKey } from '../../../common/utils/rules_states'; -import { extractErrorMessage } from '../../../common/utils/helpers'; import { RulesTable } from './rules_table'; import { RulesTableHeader } from './rules_table_header'; import { useFindCspBenchmarkRule, type RulesQuery } from './use_csp_benchmark_rules'; @@ -18,11 +23,6 @@ import * as TEST_SUBJECTS from './test_subjects'; import { RuleFlyout } from './rules_flyout'; import { LOCAL_STORAGE_PAGE_SIZE_RULES_KEY } from '../../common/constants'; import { usePageSize } from '../../common/hooks/use_page_size'; -import type { - CspBenchmarkRule, - PageUrlParams, - RuleStateAttributes, -} from '../../../common/types/latest'; import { useCspGetRulesStates } from './use_csp_rules_state'; import { RulesCounters } from './rules_counters'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx index b47b55149743..70d1d951b50b 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx @@ -7,7 +7,7 @@ import type { HttpSetup } from '@kbn/core/public'; import React from 'react'; -import { CspBenchmarkRule } from '../../../common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { getFindingsDetectionRuleSearchTags } from '../../../common/utils/detection_rules'; import { DetectionRuleCounter } from '../../components/detection_rule_counter'; import { createDetectionRuleFromBenchmarkRule } from '../configurations/utils/create_detection_rule_from_benchmark'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx index 0bafc004a5e1..7447d82d251e 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx @@ -23,7 +23,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { HttpSetup } from '@kbn/core/public'; -import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { getRuleList } from '../configurations/findings_flyout/rule_tab'; import { getRemediationList } from '../configurations/findings_flyout/overview_tab'; import * as TEST_SUBJECTS from './test_subjects'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx index cd205bb7f6b7..6c28df502e5f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { act, renderHook } from '@testing-library/react-hooks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { RuleStateAttributes } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { useChangeCspRuleState, createRulesWithUpdatedState, @@ -17,7 +18,6 @@ import { CSP_RULES_STATES_QUERY_KEY } from './use_csp_rules_state'; import { BENCHMARK_INTEGRATION_QUERY_KEY_V2 } from '../benchmarks/use_csp_benchmark_integrations'; import { CSPM_STATS_QUERY_KEY, KSPM_STATS_QUERY_KEY } from '../../common/api'; import { CSP_BENCHMARK_RULES_BULK_ACTION_ROUTE_PATH } from '../../../common/constants'; -import { RuleStateAttributes } from '../../../common/types/rules/v4'; const initialRules = { rule_1: { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.tsx index 9b616062b005..e57060363694 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.tsx @@ -10,13 +10,13 @@ import { toMountPoint } from '@kbn/react-kibana-mount'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n as kbnI18n } from '@kbn/i18n'; +import type { + CspBenchmarkRulesBulkActionResponse, + RuleStateAttributes, +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_RULES_STATES_QUERY_KEY } from './use_csp_rules_state'; import { CSPM_STATS_QUERY_KEY, KSPM_STATS_QUERY_KEY } from '../../common/api'; import { BENCHMARK_INTEGRATION_QUERY_KEY_V2 } from '../benchmarks/use_csp_benchmark_integrations'; -import { - CspBenchmarkRulesBulkActionResponse, - RuleStateAttributes, -} from '../../../common/types/latest'; import { CSP_BENCHMARK_RULES_BULK_ACTION_ROUTE_PATH } from '../../../common/constants'; import { CloudSecurityPostureStartServices } from '../../types'; import { useKibana } from '../../common/hooks/use_kibana'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_benchmark_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_benchmark_rules.ts index fd8c5bf79493..8c62485bf4a8 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_benchmark_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_benchmark_rules.ts @@ -8,7 +8,7 @@ import { useQuery } from '@tanstack/react-query'; import { FindCspBenchmarkRuleRequest, FindCspBenchmarkRuleResponse, -} from '../../../common/types/latest'; +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { useKibana } from '../../common/hooks/use_kibana'; import { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules_state.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules_state.ts index 640dc9227448..e6535d90006e 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules_state.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules_state.ts @@ -7,7 +7,7 @@ import { useQuery } from '@tanstack/react-query'; import { CSP_GET_BENCHMARK_RULES_STATE_ROUTE_PATH } from '@kbn/cloud-security-posture-common'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { useKibana } from '../../common/hooks/use_kibana'; export const CSP_RULES_STATES_QUERY_KEY = ['csp_rules_states_v1']; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_grouped_vulnerabilities.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_grouped_vulnerabilities.tsx index 79cb2aad7e60..50e712612302 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_grouped_vulnerabilities.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_grouped_vulnerabilities.tsx @@ -10,9 +10,9 @@ import type { IKibanaSearchResponse } from '@kbn/search-types'; import { GenericBuckets, GroupingQuery, RootAggregation } from '@kbn/grouping/src'; import { useQuery } from '@tanstack/react-query'; import { lastValueFrom } from 'rxjs'; +import { showErrorToast } from '@kbn/cloud-security-posture'; import { LATEST_VULNERABILITIES_INDEX_PATTERN } from '../../../../common/constants'; import { useKibana } from '../../../common/hooks/use_kibana'; -import { showErrorToast } from '../../../common/utils/show_error_toast'; // Elasticsearch returns `null` when a sub-aggregation cannot be computed type NumberOrNull = number | null; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities.tsx index 3b1d3a156f30..aa1603fc9e98 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities.tsx @@ -17,7 +17,7 @@ import { import { buildDataTableRecord } from '@kbn/discover-utils'; import { EsHitRecord } from '@kbn/discover-utils/types'; import { MAX_FINDINGS_TO_LOAD } from '@kbn/cloud-security-posture-common'; -import { FindingsBaseEsQuery } from '@kbn/cloud-security-posture'; +import { FindingsBaseEsQuery, showErrorToast } from '@kbn/cloud-security-posture'; import { VULNERABILITY_FIELDS } from '../../../common/constants'; import { CspVulnerabilityFinding } from '../../../../common/schemas'; import { @@ -25,7 +25,6 @@ import { LATEST_VULNERABILITIES_RETENTION_POLICY, } from '../../../../common/constants'; import { useKibana } from '../../../common/hooks/use_kibana'; -import { showErrorToast } from '../../../common/utils/show_error_toast'; import { getCaseInsensitiveSortScript } from '../utils/custom_sort_script'; type LatestFindingsRequest = IKibanaSearchRequest; type LatestFindingsResponse = IKibanaSearchResponse< diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx index 5940b022a0b9..6d3b2e5cf1b7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx @@ -6,9 +6,9 @@ */ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { CDR_VULNERABILITIES_DATA_VIEW_ID_PREFIX } from '../../../common/constants'; import { NoVulnerabilitiesStates } from '../../components/no_vulnerabilities_states'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { CloudPosturePage } from '../../components/cloud_posture_page'; import { findingsNavigation } from '../../common/navigation/constants'; import { useDataView } from '../../common/api/use_data_view'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilties.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilties.test.tsx index c9e13c15613a..59fa1cfa0ef9 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilties.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilties.test.tsx @@ -12,7 +12,7 @@ import { LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, VULN_MGMT_POLICY_TEMPLATE, } from '../../../common/constants'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useDataView } from '../../common/api/use_data_view'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; import { useCISIntegrationPoliciesLink } from '../../common/navigation/use_navigate_to_cis_integration_policies'; @@ -28,7 +28,7 @@ import { useLicenseManagementLocatorApi } from '../../common/api/use_license_man import { createStubDataView } from '@kbn/data-views-plugin/common/stubs'; jest.mock('../../common/api/use_data_view'); -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_license_management_locator_api'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); jest.mock('../../common/navigation/use_navigate_to_cis_integration_policies'); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.test.tsx index 6203adbb11d2..0d477ef77d83 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.test.tsx @@ -14,7 +14,7 @@ import { } from '../../../common/constants'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { discoverPluginMock } from '@kbn/discover-plugin/public/mocks'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; import { useCISIntegrationPoliciesLink } from '../../common/navigation/use_navigate_to_cis_integration_policies'; import { useCspIntegrationLink } from '../../common/navigation/use_csp_integration_link'; @@ -32,7 +32,7 @@ import { useVulnerabilityDashboardApi } from '../../common/api/use_vulnerability import { mockCnvmDashboardData } from './_mocks_/vulnerability_dashboard.mock'; jest.mock('../../common/api/use_data_view'); -jest.mock('../../common/api/use_setup_status_api'); +jest.mock('@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'); jest.mock('../../common/api/use_license_management_locator_api'); jest.mock('../../common/hooks/use_is_subscription_status_valid'); jest.mock('../../common/navigation/use_navigate_to_cis_integration_policies'); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.tsx index 33c1a5fdad4d..9ca46a8e3640 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_dashboard.tsx @@ -7,9 +7,9 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPageHeader, EuiSpacer } from '@elastic/eui'; +import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useVulnerabilityDashboardApi } from '../../common/api/use_vulnerability_dashboard_api'; import { VulnerabilityTrendGraph } from './vulnerability_trend_graph'; -import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { NoVulnerabilitiesStates } from '../../components/no_vulnerabilities_states'; import { VULNERABILITY_DASHBOARD_CONTAINER, diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/muted_rules_stats_collector.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/muted_rules_stats_collector.ts index 63fc68caff47..e5acf7b992e2 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/muted_rules_stats_collector.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/muted_rules_stats_collector.ts @@ -10,8 +10,8 @@ import { SavedObjectsClientContract, } from '@kbn/core-saved-objects-api-server'; import type { Logger } from '@kbn/core/server'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; -import { CspBenchmarkRule } from '../../../../common/types/latest'; import { getCspBenchmarkRulesStatesHandler } from '../../../routes/benchmark_rules/get_states/v1'; import { MutedRulesStats } from './types'; diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index f3a019214914..b373b6d80c5e 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -24,6 +24,10 @@ import type { TaskManagerSetupContract, TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; +import type { + CspBenchmarkRule, + CspSettings, +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { isCspPackage } from '../common/utils/helpers'; import { isSubscriptionAllowed } from '../common/utils/subscription'; import { cleanupCredentials } from '../common/utils/helpers'; @@ -47,7 +51,6 @@ import { } from './tasks/findings_stats_task'; import { registerCspmUsageCollector } from './lib/telemetry/collectors/register'; import { CloudSecurityPostureConfig } from './config'; -import { CspBenchmarkRule, CspSettings } from '../common/types/latest'; export class CspPlugin implements diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts index 63a9201b1f26..5ac233f5be0f 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts @@ -9,8 +9,8 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { CspBenchmarkRulesBulkActionRequestSchema, cspBenchmarkRulesBulkActionRequestSchema, - CspBenchmarkRulesBulkActionResponse, -} from '../../../../common/types/rules/v4'; +} from '@kbn/cloud-security-posture-common/schema/rules/v4'; +import type { CspBenchmarkRulesBulkActionResponse } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { CspRouter } from '../../../types'; import { CSP_BENCHMARK_RULES_BULK_ACTION_ROUTE_PATH } from '../../../../common/constants'; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts index e733f6cc9600..ce70dfb7bfc4 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts @@ -6,14 +6,14 @@ */ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import type { FindResult, RulesClient } from '@kbn/alerting-plugin/server'; import type { RuleParams } from '@kbn/alerting-plugin/server/application/rule/types'; import type { CspBenchmarkRule, RulesToUpdate, CspSettings, -} from '../../../../common/types/rules/v4'; +} from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { convertRuleTagsToMatchAllKQL, generateBenchmarkRuleTags, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts index ce68e094c0ba..24aa7106e170 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts @@ -7,6 +7,10 @@ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { Logger } from '@kbn/core/server'; import type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { + BulkActionBenchmarkRulesResponse, + RulesToUpdate, +} from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { buildRuleKey } from '../../../../common/utils/rules_states'; import { getBenchmarkRules, @@ -14,10 +18,6 @@ import { setRulesStates, updateBenchmarkRulesStates, } from './utils'; -import type { - BulkActionBenchmarkRulesResponse, - RulesToUpdate, -} from '../../../../common/types/rules/v4'; const muteStatesMap = { mute: true, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.test.ts index a2814e4b48ff..0ce455ae35ce 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.test.ts @@ -5,8 +5,8 @@ * 2.0. */ +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { getSortedCspBenchmarkRulesTemplates } from './utils'; -import { CspBenchmarkRule } from '../../../../common/types/latest'; describe('getSortedCspBenchmarkRules', () => { it('sorts by metadata.benchmark.rule_number, invalid semantic version still should still get sorted and empty values should be sorted last', () => { diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.ts index c1b481b01f2c..3e4373ad8fed 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/find.ts @@ -9,15 +9,11 @@ import { FindCspBenchmarkRuleRequest, FindCspBenchmarkRuleResponse, findCspBenchmarkRuleRequestSchema, -} from '../../../../common/types/latest'; -import { - FindCspBenchmarkRuleRequest as FindCspBenchmarkRuleRequestV1, - findCspBenchmarkRuleRequestSchema as findCspBenchmarkRuleRequestSchemaV1, -} from '../../../../common/types/rules/v3'; -import { - FindCspBenchmarkRuleRequest as FindCspBenchmarkRuleRequestV2, - findCspBenchmarkRuleRequestSchema as findCspBenchmarkRuleRequestSchemaV2, -} from '../../../../common/types/rules/v4'; +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import { findCspBenchmarkRuleRequestSchema as findCspBenchmarkRuleRequestSchemaV1 } from '@kbn/cloud-security-posture-common/schema/rules/v3'; +import type { FindCspBenchmarkRuleRequest as FindCspBenchmarkRuleRequestV1 } from '@kbn/cloud-security-posture-common/schema/rules/v3'; +import { findCspBenchmarkRuleRequestSchema as findCspBenchmarkRuleRequestSchemaV2 } from '@kbn/cloud-security-posture-common/schema/rules/v4'; +import type { FindCspBenchmarkRuleRequest as FindCspBenchmarkRuleRequestV2 } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { FIND_CSP_BENCHMARK_RULE_ROUTE_PATH } from '../../../../common/constants'; import { CspRouter } from '../../../types'; import { findBenchmarkRuleHandler as findRuleHandlerV1 } from './v1'; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/utils.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/utils.ts index f118ed0e8c56..17e4f44fd10e 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/utils.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/utils.ts @@ -8,11 +8,10 @@ import semverValid from 'semver/functions/valid'; import semverCompare from 'semver/functions/compare'; import { NewPackagePolicy } from '@kbn/fleet-plugin/common'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../benchmarks/benchmarks'; import { getBenchmarkFromPackagePolicy } from '../../../../common/utils/helpers'; -import type { CspBenchmarkRule } from '../../../../common/types/latest'; - export const getSortedCspBenchmarkRulesTemplates = ( cspBenchmarkRules: CspBenchmarkRule[], sortDirection: 'asc' | 'desc' diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v1.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v1.ts index a1d5668ba8c2..c8db792e6a9b 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v1.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v1.ts @@ -5,14 +5,14 @@ * 2.0. */ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { getBenchmarkFilter } from '../../../../common/utils/helpers'; -import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; -import { getBenchmarkIdFromPackagePolicyId, getSortedCspBenchmarkRulesTemplates } from './utils'; -import type { CspBenchmarkRule } from '../../../../common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import type { FindCspBenchmarkRuleRequest, FindCspBenchmarkRuleResponse, -} from '../../../../common/types/rules/v3'; +} from '@kbn/cloud-security-posture-common/schema/rules/v3'; +import { getBenchmarkFilter } from '../../../../common/utils/helpers'; +import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; +import { getBenchmarkIdFromPackagePolicyId, getSortedCspBenchmarkRulesTemplates } from './utils'; export const findBenchmarkRuleHandler = async ( soClient: SavedObjectsClientContract, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v2.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v2.ts index e7db9544b7dd..858463e94fa5 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v2.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v2.ts @@ -6,14 +6,14 @@ */ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { getBenchmarkFilterQuery } from '../../../../common/utils/helpers'; -import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; - import type { CspBenchmarkRule, FindCspBenchmarkRuleRequest, FindCspBenchmarkRuleResponse, -} from '../../../../common/types/rules/v4'; +} from '@kbn/cloud-security-posture-common/schema/rules/v4'; +import { getBenchmarkFilterQuery } from '../../../../common/utils/helpers'; +import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; + import { getSortedCspBenchmarkRulesTemplates } from './utils'; export const findBenchmarkRuleHandler = async ( diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v3.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v3.ts index c3b77a1a38ac..f1797c067375 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v3.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/find/v3.ts @@ -6,14 +6,14 @@ */ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { getBenchmarkFilterQueryV2 } from '../../../../common/utils/helpers'; -import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; - import type { CspBenchmarkRule, FindCspBenchmarkRuleRequest, FindCspBenchmarkRuleResponse, -} from '../../../../common/types/latest'; +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import { getBenchmarkFilterQueryV2 } from '../../../../common/utils/helpers'; +import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../../common/constants'; + import { getSortedCspBenchmarkRulesTemplates } from './utils'; export const findBenchmarkRuleHandler = async ( diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/get_states.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/get_states.ts index 44dd77cc6705..6099921efdc6 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/get_states.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/get_states.ts @@ -7,7 +7,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { CSP_GET_BENCHMARK_RULES_STATE_ROUTE_PATH } from '@kbn/cloud-security-posture-common'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CspRouter } from '../../../types'; import { getCspBenchmarkRulesStatesHandler } from './v1'; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/v1.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/v1.ts index 1c7ddccf91bb..e6c2e90cd988 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/v1.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/get_states/v1.ts @@ -10,13 +10,13 @@ import { } from '@kbn/core-saved-objects-api-server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common'; -import { CspSettings } from '../../../../common/types/rules/v4'; +import { buildMutedRulesFilter } from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import type { CspSettings } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { INTERNAL_CSP_SETTINGS_SAVED_OBJECT_ID, INTERNAL_CSP_SETTINGS_SAVED_OBJECT_TYPE, } from '../../../../common/constants'; -import { buildMutedRulesFilter } from '../../../../common/utils/rules_states'; export const createCspSettingObject = async (soClient: SavedObjectsClientContract) => { return soClient.create( diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/utilities.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/utilities.ts index d7ce82da9d98..166349d863fb 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/utilities.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/utilities.ts @@ -7,9 +7,9 @@ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../../common/constants'; -import { CspBenchmarkRule } from '../../../common/types/latest'; import { BenchmarkId } from '../../../common/types_old'; import { getBenchmarkFilter } from '../../../common/utils/helpers'; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/v2.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/v2.ts index 55e32fdb45a8..327a2da76f33 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/v2.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/v2.ts @@ -9,12 +9,13 @@ import { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types'; import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, LATEST_FINDINGS_INDEX_DEFAULT_NS, } from '../../../common/constants'; -import { CspBenchmarkRule, Benchmark } from '../../../common/types/latest'; +import { Benchmark } from '../../../common/types/latest'; import { getClusters } from '../compliance_dashboard/get_clusters'; import { getStats } from '../compliance_dashboard/get_stats'; import { getSafePostureTypeRuntimeMapping } from '../../../common/runtime_mappings/get_safe_posture_type_runtime_mapping'; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_benchmark_rule.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_benchmark_rule.ts index ebf90aa50009..dc8c93ae4bc9 100644 --- a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_benchmark_rule.ts +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_benchmark_rule.ts @@ -7,7 +7,7 @@ import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; import { SavedObjectsType } from '@kbn/core/server'; -import { rulesV1, rulesV2, rulesV3 } from '../../common/types'; +import { rulesV1, rulesV2, rulesV3 } from '@kbn/cloud-security-posture-common/schema/rules'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '../../common/constants'; import { cspBenchmarkRuleMigrations } from './migrations'; import { cspBenchmarkRuleSavedObjectMapping } from './mappings'; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_settings.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_settings.ts index f1c61df75b4f..676828367f63 100644 --- a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_settings.ts +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_settings.ts @@ -7,7 +7,7 @@ import { SavedObjectsType } from '@kbn/core/server'; import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; -import { cspSettingsSchema } from '../../common/types/rules/v4'; +import { cspSettingsSchema } from '@kbn/cloud-security-posture-common/schema/rules/v4'; import { cspSettingsSavedObjectMapping } from './mappings'; import { INTERNAL_CSP_SETTINGS_SAVED_OBJECT_TYPE } from '../../common/constants'; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_benchmark_rule.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_benchmark_rule.ts index e440342d2083..942f2a2fc648 100644 --- a/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_benchmark_rule.ts +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_benchmark_rule.ts @@ -10,7 +10,7 @@ import { SavedObjectUnsanitizedDoc, SavedObjectMigrationContext, } from '@kbn/core/server'; -import { rulesV1, rulesV2, rulesV3 } from '../../../common/types'; +import { rulesV1, rulesV2, rulesV3 } from '@kbn/cloud-security-posture-common/schema/rules'; function migrateCspBenchmarkRuleToV840( doc: SavedObjectUnsanitizedDoc, diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/new_package_policy.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/new_package_policy.yaml index 956f51a8016f..ef22c197c5b4 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/new_package_policy.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/new_package_policy.yaml @@ -47,6 +47,7 @@ properties: - enabled policy_id: type: string + nullable: true deprecated: true policy_ids: type: array diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/package_policy_request.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/package_policy_request.yaml index 7e820c75bf4c..871bc8b6d1ae 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/package_policy_request.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/package_policy_request.yaml @@ -16,11 +16,17 @@ properties: type: string description: The package policy namespace. Leave blank to inherit the agent policy's namespace. example: 'customnamespace' + output_id: + type: string + description: Output ID to send package data to + example: 'output-id' + nullable: true policy_id: type: string description: Agent policy ID where that package policy will be added example: 'agent-policy-id' deprecated: true + nullable: true policy_ids: type: array items: diff --git a/x-pack/plugins/fleet/common/services/simplified_package_policy_helper.ts b/x-pack/plugins/fleet/common/services/simplified_package_policy_helper.ts index 8d616bf4cae1..14c7b3888f77 100644 --- a/x-pack/plugins/fleet/common/services/simplified_package_policy_helper.ts +++ b/x-pack/plugins/fleet/common/services/simplified_package_policy_helper.ts @@ -41,7 +41,7 @@ export type SimplifiedInputs = Record< export interface SimplifiedPackagePolicy { id?: string; - policy_id?: string; + policy_id?: string | null; policy_ids: string[]; output_id?: string; namespace: string; diff --git a/x-pack/plugins/fleet/common/types/models/package_policy.ts b/x-pack/plugins/fleet/common/types/models/package_policy.ts index a6db753d1a1c..1e456f3e4d21 100644 --- a/x-pack/plugins/fleet/common/types/models/package_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/package_policy.ts @@ -78,8 +78,8 @@ export interface NewPackagePolicy { namespace?: string; enabled: boolean; is_managed?: boolean; - /** @deprecated */ - policy_id?: string; + /** @deprecated Nullable to allow user to clear existing policy id */ + policy_id?: string | null; policy_ids: string[]; // Nullable to allow user to reset to default outputs output_id?: string | null; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts index 8b74a3142fa9..4aa2e367e04e 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts @@ -61,7 +61,7 @@ export type PostDeletePackagePoliciesResponse = Array<{ name?: string; success: boolean; package?: PackagePolicyPackage; - policy_id?: string; + policy_id?: string | null; policy_ids?: string[]; output_id?: string; // Support generic errors diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index ab640d8f26a0..5fa286098002 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -18,9 +18,12 @@ import { CONFIRM_MODAL } from '../screens/navigation'; import { request } from './common'; export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: false }) => { + cy.intercept('/api/fleet/agent_status?*').as('agentStatus'); + cy.getBySel(ADD_INTEGRATION_POLICY_BTN).click(); if (useExistingPolicy) { cy.getBySel(EXISTING_HOSTS_TAB).click(); + cy.wait('@agentStatus'); } else { // speeding up creating with unchecking system and agent integration cy.getBySel(AGENT_POLICY_SYSTEM_MONITORING_CHECKBOX).uncheck({ force: true }); @@ -33,7 +36,8 @@ export const addIntegration = ({ useExistingPolicy } = { useExistingPolicy: fals force: true, }); } - cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); + cy.getBySel(CREATE_PACKAGE_POLICY_SAVE_BTN).should('be.enabled').click(); + // sometimes agent is assigned to default policy, sometimes not cy.getBySel(CONFIRM_MODAL.CONFIRM_BUTTON).click(); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx index bb4e39b265f0..a52c2b488139 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_validation.tsx @@ -38,20 +38,20 @@ export const agentPolicyFormValidation = ( errors.namespace = [namespaceValidation.error]; } - if (agentPolicy.unenroll_timeout && agentPolicy.unenroll_timeout < 0) { + if (agentPolicy.unenroll_timeout !== undefined && agentPolicy.unenroll_timeout <= 0) { errors.unenroll_timeout = [ , ]; } - if (agentPolicy.inactivity_timeout && agentPolicy.inactivity_timeout < 0) { + if (agentPolicy.inactivity_timeout !== undefined && agentPolicy.inactivity_timeout <= 0) { errors.inactivity_timeout = [ , ]; } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.test.tsx index acd3eca55993..1ac5e8c17cb5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.test.tsx @@ -55,4 +55,16 @@ describe('ConfirmDeployAgentPolicyModal', () => { 'Agent policies that will be updated to remove this integration policy:Agent policy 3' ); }); + + it('should render no agent policies message when not adding/removing agent policies', () => { + testRenderer = createFleetTestRendererMock(); + render({ + agentCount: 0, + agentPolicies: [], + agentPoliciesToRemove: [], + }); + const calloutText = renderResult.getByTestId('confirmNoPoliciesCallout').textContent; + expect(calloutText).toContain('No agent policies selected'); + expect(calloutText).toContain('This integration will not be added to any agent policies.'); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.tsx index 9c6aa70ee1ac..e7a1494fdc01 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/confirm_deploy_modal.tsx @@ -27,7 +27,46 @@ export const ConfirmDeployAgentPolicyModal: React.FunctionComponent<{ agentPoliciesToAdd = [], agentPoliciesToRemove = [], }) => { - return ( + return agentPolicies.length === 0 && agentPoliciesToRemove.length === 0 ? ( + + } + onCancel={onCancel} + onConfirm={onConfirm} + cancelButtonText={ + + } + confirmButtonText={ + + } + buttonColor="primary" + > + +
+ +
+
+
+ ) : ( { await act(async () => { const select = renderResult.container.querySelector('[data-test-subj="agentPolicySelect"]'); expect((select as any)?.value).toEqual(''); - - expect(renderResult.getByText('At least one agent policy is required.')).toBeVisible(); }); }); @@ -179,8 +177,6 @@ describe('step select agent policy', () => { '[data-test-subj="agentPolicyMultiSelect"]' ); expect((select as any)?.value).toEqual(undefined); - - expect(renderResult.getByText('At least one agent policy is required.')).toBeVisible(); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_select_agent_policy.tsx index ecfd18ef9aac..eb5eb9a34b44 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_select_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_select_agent_policy.tsx @@ -101,19 +101,23 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ updateAgentPolicies([]); } }; - if (isLoading || selectedPolicyIds.length === 0) { + if (isLoading || isFirstLoad) { return; } + const agentPolicyIds = agentPolicies.map((policy) => policy.id); const agentPoliciesHaveAllSelectedIds = selectedPolicyIds.every((id) => - agentPolicies.map((policy) => policy.id).includes(id) + agentPolicyIds.includes(id) ); - if (agentPolicies.length === 0 || !agentPoliciesHaveAllSelectedIds) { + if ( + (agentPolicies.length === 0 && selectedPolicyIds.length !== 0) || + !agentPoliciesHaveAllSelectedIds + ) { fetchAgentPolicyInfo(); } else if (agentPoliciesHaveAllSelectedIds && selectedPolicyIds.length < agentPolicies.length) { setSelectedAgentPolicyError(undefined); updateAgentPolicies(agentPolicies.filter((policy) => selectedPolicyIds.includes(policy.id))); } - }, [selectedPolicyIds, agentPolicies, updateAgentPolicies, isLoading]); + }, [selectedPolicyIds, agentPolicies, updateAgentPolicies, isLoading, isFirstLoad]); // Try to select default agent policy useEffect(() => { @@ -152,9 +156,11 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ // Bubble up any issues with agent policy selection useEffect(() => { - if (selectedPolicyIds.length > 0 && !selectedAgentPolicyError) { + if (!selectedAgentPolicyError) { setHasAgentPolicyError(false); - } else setHasAgentPolicyError(true); + } else { + setHasAgentPolicyError(true); + } }, [selectedAgentPolicyError, selectedPolicyIds, setHasAgentPolicyError]); const onChange = useCallback( @@ -237,16 +243,9 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ /> ) : null } - isInvalid={Boolean( - selectedPolicyIds.length === 0 || someNewAgentPoliciesHaveLimitedPackage - )} + isInvalid={Boolean(someNewAgentPoliciesHaveLimitedPackage)} error={ - selectedPolicyIds.length === 0 ? ( - - ) : someNewAgentPoliciesHaveLimitedPackage ? ( + someNewAgentPoliciesHaveLimitedPackage ? ( { ).toContain('Agent policy 1'); }); - it('should display dropdown without preselected value when Existing hosts selected with mulitple agent policies', () => { + it('should display dropdown without preselected value when Existing hosts selected with mulitple agent policies', async () => { (useGetAgentPolicies as jest.MockedFunction).mockReturnValue({ data: { items: [ @@ -174,8 +174,9 @@ describe('StepSelectHosts', () => { fireEvent.click(renderResult.getByText('Existing hosts').closest('button')!); }); - waitFor(() => { - expect(renderResult.getByText('At least one agent policy is required.')).toBeInTheDocument(); + await act(async () => { + const select = renderResult.container.querySelector('[data-test-subj="agentPolicySelect"]'); + expect((select as any)?.value).toEqual(''); }); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/hooks/navigation.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/hooks/navigation.tsx index c97392dce6ae..8b9ca7886d23 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/hooks/navigation.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/hooks/navigation.tsx @@ -8,7 +8,8 @@ import { useCallback, useMemo, useEffect, useRef } from 'react'; import type { ApplicationStart } from '@kbn/core-application-browser'; -import { PLUGIN_ID } from '../../../../constants'; +import { PLUGIN_ID, INTEGRATIONS_PLUGIN_ID } from '../../../../constants'; +import { pkgKeyFromPackageInfo } from '../../../../services'; import { useStartServices, useLink, useIntraAppState } from '../../../../hooks'; import type { CreatePackagePolicyRouteState, @@ -35,7 +36,7 @@ export const useCancelAddPackagePolicy = (params: UseCancelParams) => { const { getHref } = useLink(); const cancelClickHandler = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { if (routeState?.onCancelNavigateTo) { ev.preventDefault(); navigateToApp(...routeState.onCancelNavigateTo); @@ -86,10 +87,14 @@ export const useOnSaveNavigate = (params: UseOnSaveNavigateParams) => { if (!doOnSaveNavigation.current) { return; } - const packagePolicyPath = getPath('policy_details', { - policyId: packagePolicy.policy_ids[0], // TODO navigates to first policy - }); - + const hasNoAgentPolicies = packagePolicy.policy_ids.length === 0; + const packagePolicyPath = hasNoAgentPolicies + ? getPath('integration_details_policies', { + pkgkey: pkgKeyFromPackageInfo(packagePolicy.package!), + }) + : getPath('policy_details', { + policyId: packagePolicy.policy_ids[0], // TODO navigates to first policy + }); const [onSaveNavigateTo, onSaveQueryParams]: [ Parameters, CreatePackagePolicyRouteState['onSaveQueryParams'] @@ -97,7 +102,7 @@ export const useOnSaveNavigate = (params: UseOnSaveNavigateParams) => { ? [routeState.onSaveNavigateTo, routeState?.onSaveQueryParams] : [ [ - PLUGIN_ID, + hasNoAgentPolicies ? INTEGRATIONS_PLUGIN_ID : PLUGIN_ID, { path: packagePolicyPath, }, @@ -123,7 +128,15 @@ export const useOnSaveNavigate = (params: UseOnSaveNavigateParams) => { navigateToApp(...onSaveNavigateTo); } }, - [packagePolicy.policy_ids, getPath, navigateToApp, routeState, queryParamsPolicyId] + [ + packagePolicy.policy_ids, + packagePolicy.package, + getPath, + routeState?.onSaveNavigateTo, + routeState?.onSaveQueryParams, + queryParamsPolicyId, + navigateToApp, + ] ); return onSaveNavigate; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx index 697731f74472..f624bd5c843a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx @@ -26,6 +26,7 @@ import { sendCreatePackagePolicy, sendBulkInstallPackages, sendGetPackagePolicies, + useMultipleAgentPolicies, } from '../../../../../hooks'; import { isVerificationError, packageToPackagePolicy } from '../../../../../services'; import { @@ -154,6 +155,8 @@ export function useOnSubmit({ const { notifications } = useStartServices(); const confirmForceInstall = useConfirmForceInstall(); const spaceSettings = useSpaceSettingsContext(); + const { canUseMultipleAgentPolicies } = useMultipleAgentPolicies(); + // only used to store the resulting package policy once saved const [savedPackagePolicy, setSavedPackagePolicy] = useState(); // Form state @@ -184,14 +187,10 @@ export function useOnSubmit({ if (isEqual(updatedAgentPolicies, agentPolicies)) { return; } - if (updatedAgentPolicies.length > 0) { - setAgentPolicies(updatedAgentPolicies); - if (packageInfo) { - setHasAgentPolicyError(false); - } - } else { - setHasAgentPolicyError(true); - setAgentPolicies([]); + + setAgentPolicies(updatedAgentPolicies); + if (packageInfo) { + setHasAgentPolicyError(false); } // eslint-disable-next-line no-console @@ -235,18 +234,17 @@ export function useOnSubmit({ ? validationHasErrors(newValidationResults) : false; const hasAgentPolicy = - newPackagePolicy.policy_ids.length > 0 && newPackagePolicy.policy_ids[0] !== ''; - if ( - hasPackage && - (hasAgentPolicy || selectedPolicyTab === SelectedPolicyTab.NEW) && - !hasValidationErrors - ) { + (newPackagePolicy.policy_ids.length > 0 && newPackagePolicy.policy_ids[0] !== '') || + selectedPolicyTab === SelectedPolicyTab.NEW; + const isOrphaningPolicy = + canUseMultipleAgentPolicies && newPackagePolicy.policy_ids.length === 0; + if (hasPackage && (hasAgentPolicy || isOrphaningPolicy) && !hasValidationErrors) { setFormState('VALID'); } else { setFormState('INVALID'); } }, - [packagePolicy, setFormState, updatePackagePolicyValidation, selectedPolicyTab] + [packagePolicy, updatePackagePolicyValidation, selectedPolicyTab, canUseMultipleAgentPolicies] ); // Initial loading of package info @@ -315,7 +313,8 @@ export function useOnSubmit({ return; } if ( - agentCount !== 0 && + (agentCount !== 0 || + (agentPolicies.length === 0 && selectedPolicyTab !== SelectedPolicyTab.NEW)) && !(isAgentlessIntegration(packageInfo) || isAgentlessPackagePolicy(packagePolicy)) && formState !== 'CONFIRM' ) { @@ -401,7 +400,7 @@ export function useOnSubmit({ setSavedPackagePolicy(data!.item); const promptForAgentEnrollment = - !(agentCount && agentPolicies.length > 0) && + (createdPolicy || (agentPolicies.length > 0 && !agentCount)) && !isAgentlessConfigured && hasFleetAddAgentsPrivileges; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index 99ed5592ac3a..7a8cfe4e956a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -218,7 +218,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ ); const updateSelectedPolicyTab = useCallback( - (selectedTab) => { + (selectedTab: any) => { setSelectedPolicyTab(selectedTab); setPolicyValidation(selectedTab, newAgentPolicy); }, @@ -498,7 +498,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ }> - {formState === 'CONFIRM' && agentPolicies.length > 0 && ( + {formState === 'CONFIRM' && ( 0) { + const { data, error: agentPolicyError } = await sendBulkGetAgentPolicies( + packagePolicyData!.item.policy_ids + ); - if (agentPolicyError) { - throw agentPolicyError; - } + if (agentPolicyError) { + throw agentPolicyError; + } - setAgentPolicies(data?.items ?? []); + setAgentPolicies(data?.items ?? []); + } const { data: upgradePackagePolicyDryRunData, error: upgradePackagePolicyDryRunError } = await sendUpgradePackagePolicyDryRun([packagePolicyId]); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx index 5acd854a76f0..1041c9151031 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx @@ -28,7 +28,7 @@ interface Params { packageInfo?: PackageInfo; existingAgentPolicies: AgentPolicy[]; setHasAgentPolicyError: (hasError: boolean) => void; - updatePackagePolicy: (data: { policy_ids: string[] }) => void; + updatePackagePolicy: (fields: Partial) => void; agentPolicies: AgentPolicy[]; setAgentPolicies: (agentPolicies: AgentPolicy[]) => void; isLoadingData: boolean; @@ -96,20 +96,12 @@ export function usePackagePolicySteps({ if (!isLoadingData && isEqual(updatedAgentPolicies, agentPolicies)) { return; } - if (updatedAgentPolicies.length > 0) { - setAgentPolicies(updatedAgentPolicies); - updatePackagePolicy({ - policy_ids: updatedAgentPolicies.map((policy) => policy.id), - }); - if (packageInfo) { - setHasAgentPolicyError(false); - } - } else { - setHasAgentPolicyError(true); - setAgentPolicies([]); - updatePackagePolicy({ - policy_ids: [], - }); + setAgentPolicies(updatedAgentPolicies); + updatePackagePolicy({ + policy_ids: updatedAgentPolicies.map((policy) => policy.id), + }); + if (packageInfo) { + setHasAgentPolicyError(false); } // eslint-disable-next-line no-console diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index 8150a61b93fb..841c2184894f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -6,7 +6,6 @@ */ import React, { useState, useEffect, useCallback, useMemo, memo } from 'react'; -import { isEmpty } from 'lodash'; import { useRouteMatch } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -250,7 +249,10 @@ export const EditPackagePolicyForm = memo<{ return; } if ( - (agentCount !== 0 || agentPoliciesToAdd.length > 0 || agentPoliciesToRemove.length > 0) && + (agentCount !== 0 || + agentPolicies.length === 0 || + agentPoliciesToAdd.length > 0 || + agentPoliciesToRemove.length > 0) && !hasAgentlessAgentPolicy && formState !== 'CONFIRM' ) { @@ -485,7 +487,7 @@ export const EditPackagePolicyForm = memo<{ {isLoadingData ? ( - ) : loadingError || isEmpty(existingAgentPolicies) || !packageInfo ? ( + ) : loadingError || !packageInfo ? ( = memo(({ agentStatus, showInactive }) => { - const agentStatuses = useMemo(() => { - return AGENT_STATUSES.filter((status) => - showInactive ? true : status !== 'inactive' && status !== 'unenrolled' - ); - }, [showInactive]); - +}> = memo(({ agentStatus }) => { return ( - {agentStatuses.map((status) => ( + {AGENT_STATUSES.map((status) => ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx index a6375bec6a39..bcac45801be0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx @@ -19,7 +19,6 @@ import type { SelectionMode } from './types'; export const AgentTableHeader: React.FunctionComponent<{ agentStatus?: { [k in SimplifiedAgentStatus]: number }; - showInactive: boolean; totalAgents: number; selectableAgents: number; managedAgentsOnCurrentPage: number; @@ -38,7 +37,6 @@ export const AgentTableHeader: React.FunctionComponent<{ setSelectionMode, selectedAgents, setSelectedAgents, - showInactive, clearFilters, isUsingFilter, }) => { @@ -69,9 +67,7 @@ export const AgentTableHeader: React.FunctionComponent<{ ) : null} - {agentStatus && ( - - )} + {agentStatus && }
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index 84884569071c..c1e1f83f4910 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -168,10 +168,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { setSortOrder(sort!.direction); }; - const showInactive = useMemo(() => { - return selectedStatus.some((status) => status === 'inactive' || status === 'unenrolled'); - }, [selectedStatus]); - const renderActions = (agent: Agent) => { const agentPolicy = typeof agent.policy_id === 'string' ? agentPoliciesIndexedById[agent.policy_id] : undefined; @@ -435,7 +431,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { {/* Agent total, bulk actions and status bar */} = ({ }, [value, onChange]); const onDragEndHandler = useCallback( - ({ source, destination }) => { + ({ source, destination }: any) => { if (source && destination) { const items = euiDragDropReorder(value, source.index, destination.index); const sourceErrors = indexedErrors[source.index]; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx index 695047288e29..fa45e0969c60 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/hooks/use_confirm_modal.tsx @@ -71,7 +71,7 @@ export const ConfirmModalProvider: React.FunctionComponent<{ children?: React.Re onConfirm: () => {}, }); - const showModal = useCallback(({ title, description, onConfirm, onCancel, options }) => { + const showModal = useCallback(({ title, description, onConfirm, onCancel, options }: any) => { setIsVisible(true); setModal({ title, diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx index 1b75311418ca..b475c4d39d76 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/package_policies.tsx @@ -74,17 +74,6 @@ const IntegrationDetailsLink = memo<{ ); }); -const AgentPolicyNotFound = () => ( - - -   - - -); - export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps) => { const { search } = useLocation(); const history = useHistory(); @@ -235,7 +224,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps defaultMessage: 'Agent policies', }), truncateText: true, - render(id, { agentPolicies, packagePolicy }) { + render(ids, { agentPolicies, packagePolicy }) { return agentPolicies.length > 0 ? ( canShowMultiplePoliciesCell ? ( ) + ) : ids.length === 0 ? ( + + + ) : ( - + + +   + + ); }, }, @@ -282,7 +285,14 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps }), render({ agentPolicies, packagePolicy }: InMemoryPackagePolicyAndAgentPolicy) { if (agentPolicies.length === 0) { - return null; + return ( + + + + ); } const agentPolicy = agentPolicies[0]; // TODO: handle multiple agent policies const canAddAgentsForPolicy = policyHasFleetServer(agentPolicy) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/persona.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/persona.tsx index c2a7e1530cbf..aa1bbcc3dc83 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/persona.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/persona.tsx @@ -17,7 +17,7 @@ const MIN_WIDTH: CSSProperties = { minWidth: 0 }; export const Persona = memo( ({ name, className, 'data-test-subj': dataTestSubj, title, ...otherAvatarProps }) => { const getTestId = useCallback( - (suffix) => { + (suffix: any) => { if (dataTestSubj) { return `${dataTestSubj}-${suffix}`; } diff --git a/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.test.tsx b/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.test.tsx index 50e930820767..afb7df056cc4 100644 --- a/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.test.tsx +++ b/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.test.tsx @@ -151,16 +151,24 @@ describe('ManageAgentPoliciesModal', () => { }); }); - it('should display callout and disable confirm if policy is removed', async () => { + it('should display callout and allow to submit if all policies are removed', async () => { const results = render(); await act(async () => { results.getByTestId('comboBoxClearButton').click(); }); - expect(results.getByText('Confirm').getAttribute('disabled')).toBeDefined(); + expect(results.getByText('Confirm').getAttribute('disabled')).toBeNull(); expect(results.getByTestId('confirmRemovePoliciesCallout')).toBeInTheDocument(); expect(results.getByTestId('confirmRemovePoliciesCallout').textContent).toContain( 'Test policy will no longer use this integration.' ); + + await act(async () => { + results.getByText('Confirm').click(); + }); + expect(usePackagePolicyWithRelatedData('', {}).savePackagePolicy).toHaveBeenCalledWith({ + policy_id: undefined, + policy_ids: [], + }); }); }); diff --git a/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.tsx b/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.tsx index 26e9421ed86f..7677ba493134 100644 --- a/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.tsx +++ b/x-pack/plugins/fleet/public/components/manage_agent_policies_modal.tsx @@ -70,6 +70,11 @@ export const ManageAgentPoliciesModal: React.FunctionComponent = ({ setIsSubmitting(true); const { error } = await savePackagePolicy({ policy_ids: selectedPolicyIds, + ...(selectedPolicyIds.length === 0 + ? { + policy_id: undefined, + } + : {}), }); setIsSubmitting(false); if (!error) { @@ -138,11 +143,7 @@ export const ManageAgentPoliciesModal: React.FunctionComponent = ({ /> } buttonColor="primary" - confirmButtonDisabled={ - selectedPolicyIds.length === 0 || - isSubmitting || - isEqual(initialPolicyIds, selectedPolicyIds) - } + confirmButtonDisabled={isSubmitting || isEqual(initialPolicyIds, selectedPolicyIds)} data-test-subj="manageAgentPoliciesModal" > diff --git a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx index a41b3e265826..90e680c2ff84 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx @@ -12,7 +12,7 @@ import { act, fireEvent } from '@testing-library/react'; import type { AgentPolicy, InMemoryPackagePolicy } from '../types'; import { createIntegrationsTestRendererMock } from '../mock'; -import { useMultipleAgentPolicies, useStartServices } from '../hooks'; +import { useMultipleAgentPolicies, useStartServices, useLink } from '../hooks'; import { PackagePolicyActionsMenu } from './package_policy_actions_menu'; @@ -203,10 +203,34 @@ describe('PackagePolicyActionsMenu', () => { const { utils } = renderMenu({ agentPolicies, packagePolicy }); await act(async () => { const editButton = utils.getByTestId('PackagePolicyActionsEditItem'); + expect(editButton).not.toHaveAttribute('disabled'); + expect(editButton).toHaveAttribute('href'); + expect(useLink().getHref as jest.Mock).toHaveBeenCalledWith('edit_integration', { + policyId: 'some-uuid1', + packagePolicyId: 'some-uuid2', + }); expect(editButton).toHaveAttribute( 'href', '/mock/app/fleet/policies/some-uuid1/edit-integration/some-uuid2' ); }); }); + + it('Should show Edit integration with correct href when there is no agent policy', async () => { + const packagePolicy = createMockPackagePolicy({ + policy_ids: [], + }); + const { utils } = renderMenu({ + agentPolicies: [], + packagePolicy, + }); + await act(async () => { + const editButton = utils.getByTestId('PackagePolicyActionsEditItem'); + expect(editButton).not.toHaveAttribute('disabled'); + expect(editButton).toHaveAttribute('href'); + expect(useLink().getHref as jest.Mock).toHaveBeenCalledWith('integration_policy_edit', { + packagePolicyId: 'some-uuid2', + }); + }); + }); }); diff --git a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx index 0eb0000af4fa..fcebfcb2f247 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.tsx @@ -52,6 +52,7 @@ export const PackagePolicyActionsMenu: React.FunctionComponent<{ const isManaged = Boolean(packagePolicy.is_managed); const agentPolicyIsManaged = Boolean(agentPolicy?.is_managed); + const isOrphanedPolicy = !agentPolicy && packagePolicy.policy_ids.length === 0; const isAddAgentVisible = showAddAgent && agentPolicy && !agentPolicyIsManaged; @@ -92,12 +93,18 @@ export const PackagePolicyActionsMenu: React.FunctionComponent<{ : []), ; @@ -170,59 +167,6 @@ describe('When calling package policy', () => { appContextService.stop(); }); - describe('Create api handler', () => { - const getCreateKibanaRequest = ( - newData?: typeof CreatePackagePolicyRequestSchema.body - ): KibanaRequest< - undefined, - typeof CreatePackagePolicyRequestSchema.query, - typeof CreatePackagePolicyRequestSchema.body - > => { - return httpServerMock.createKibanaRequest< - undefined, - typeof CreatePackagePolicyRequestSchema.query, - typeof CreatePackagePolicyRequestSchema.body - >({ - path: routeConfig.path, - method: 'post', - body: newData || {}, - query: { format: 'simplified' }, - }); - }; - - const newPolicy = { - name: 'endpoint-1', - description: 'desc', - enabled: true, - policy_ids: [], - inputs: [], - namespace: 'default', - package: { name: 'endpoint', title: 'Elastic Endpoint', version: '0.5.0' }, - }; - - beforeEach(() => { - jest.spyOn(licenseService, 'hasAtLeast').mockClear(); - // @ts-ignore - const postMock = routerMock.versioned.post.mock; - // @ts-ignore - routeConfig = postMock.calls.find(([{ path }]) => - path.startsWith(PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN) - )!; - routeHandler = postMock.results[0].value.addVersion.mock.calls[0][1]; - }); - - it('should throw if no policy_id or policy_ids is provided', async () => { - const request = getCreateKibanaRequest(newPolicy as any); - await createPackagePolicyHandler(context, request as any, response); - expect(response.customError).toHaveBeenCalledWith({ - statusCode: 400, - body: { - message: 'Either policy_id or policy_ids must be provided', - }, - }); - }); - }); - describe('Update api handler', () => { const getUpdateKibanaRequest = ( newData?: typeof UpdatePackagePolicyRequestSchema.body diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index 5cc00ef014cd..3bc2f79d6afd 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -243,10 +243,6 @@ export const createPackagePolicyHandler: FleetRequestHandler< const spaceId = fleetContext.spaceId; try { - if (!newPolicy.policy_id && (!newPolicy.policy_ids || newPolicy.policy_ids.length === 0)) { - throw new PackagePolicyRequestError('Either policy_id or policy_ids must be provided'); - } - let newPackagePolicy: NewPackagePolicy; if (isSimplifiedCreatePackagePolicyRequest(newPolicy)) { if (!pkg) { @@ -390,7 +386,8 @@ export const updatePackagePolicyHandler: FleetRequestHandler< name: restOfBody.name ?? packagePolicy.name, description: restOfBody.description ?? packagePolicy.description, namespace: restOfBody.namespace ?? packagePolicy?.namespace, - policy_id: restOfBody.policy_id ?? packagePolicy.policy_id, + policy_id: + restOfBody.policy_id === undefined ? packagePolicy.policy_id : restOfBody.policy_id, enabled: 'enabled' in restOfBody ? restOfBody.enabled ?? packagePolicy.enabled @@ -406,10 +403,6 @@ export const updatePackagePolicyHandler: FleetRequestHandler< } newData.inputs = alignInputsAndStreams(newData.inputs); - if (newData.policy_ids && newData.policy_ids.length === 0) { - throw new PackagePolicyRequestError('At least one agent policy id must be provided'); - } - if ( newData.policy_ids && !isEmpty(packagePolicy.policy_ids) && diff --git a/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts b/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts index 311bfeb339f2..9d68dde10a13 100644 --- a/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts @@ -86,6 +86,19 @@ describe('Package Policy Utils', () => { ); }); + it('should throw if no enterprise license and no policy_ids is provided', async () => { + jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(false); + jest + .spyOn(appContextService, 'getExperimentalFeatures') + .mockReturnValue({ enableReusableIntegrationPolicies: true } as any); + + await expect( + preflightCheckPackagePolicy(soClient, { ...testPolicy, policy_ids: [] }) + ).rejects.toThrowError( + 'Reusable integration policies are only available with an Enterprise license' + ); + }); + it('should throw if enterprise license and multiple policy_ids is provided but no feature flag', async () => { jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true); jest @@ -107,6 +120,16 @@ describe('Package Policy Utils', () => { ).resolves.not.toThrow(); }); + it('should not throw if enterprise license and no policy_ids is provided', async () => { + jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true); + jest + .spyOn(appContextService, 'getExperimentalFeatures') + .mockReturnValue({ enableReusableIntegrationPolicies: true } as any); + await expect( + preflightCheckPackagePolicy(soClient, { ...testPolicy, policy_ids: [] }) + ).resolves.not.toThrow(); + }); + it('should throw if no valid license and output_id is provided', async () => { jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(false); diff --git a/x-pack/plugins/fleet/server/services/package_policies/utils.ts b/x-pack/plugins/fleet/server/services/package_policies/utils.ts index 61ff380fec55..0d76fc307c74 100644 --- a/x-pack/plugins/fleet/server/services/package_policies/utils.ts +++ b/x-pack/plugins/fleet/server/services/package_policies/utils.ts @@ -76,10 +76,11 @@ export async function preflightCheckPackagePolicy( soClient: SavedObjectsClientContract, packagePolicy: PackagePolicy | NewPackagePolicy ) { - // If package policy has multiple agent policies, check if they can be used + // If package policy has multiple agent policies IDs, or no agent policies (orphaned integration policy) + // check if user can use multiple agent policies feature const { canUseReusablePolicies, errorMessage: canUseMultipleAgentPoliciesErrorMessage } = canUseMultipleAgentPolicies(); - if ((packagePolicy.policy_ids ?? []).length > 1 && !canUseReusablePolicies) { + if (!canUseReusablePolicies && packagePolicy.policy_ids.length !== 1) { throw new PackagePolicyMultipleAgentPoliciesError(canUseMultipleAgentPoliciesErrorMessage); } diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index a53334c893fe..f23ed5836afe 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -415,9 +415,16 @@ class PackagePolicyClientImpl implements PackagePolicyClient { } keepPolicyIdInSync(packagePolicy: NewPackagePolicy): void { + if (packagePolicy.policy_ids) { + if (packagePolicy.policy_ids.length === 0 && packagePolicy.policy_id !== undefined) { + packagePolicy.policy_id = null; + } + } else { + packagePolicy.policy_ids = []; + } if (packagePolicy.policy_id && !packagePolicy.policy_ids?.[0]) { packagePolicy.policy_ids = [packagePolicy.policy_id]; - } else if (!packagePolicy.policy_id) { + } else if (!packagePolicy.policy_id && packagePolicy.policy_ids[0]) { packagePolicy.policy_id = packagePolicy.policy_ids[0]; } } @@ -891,6 +898,8 @@ class PackagePolicyClientImpl implements PackagePolicyClient { } if (!oldPackagePolicy) { throw new PackagePolicyNotFoundError('Package policy not found'); + } else { + this.keepPolicyIdInSync(oldPackagePolicy); } if ( @@ -1021,16 +1030,19 @@ class PackagePolicyClientImpl implements PackagePolicyClient { } } } - // Bump revision of associated agent policy - logger.debug(`Bumping revision of associated agent policies ${packagePolicy.policy_ids}`); + + // Bump revision of all associated agent policies (old and new) + const associatedPolicyIds = new Set([...oldPackagePolicy.policy_ids, ...newPolicy.policy_ids]); + logger.debug(`Bumping revision of associated agent policies ${associatedPolicyIds}`); const bumpPromises = []; - for (const policyId of packagePolicy.policy_ids) { + for (const policyId of associatedPolicyIds) { bumpPromises.push( agentPolicyService.bumpRevision(soClient, esClient, policyId, { user: options?.user, }) ); } + const assetRemovePromise = removeOldAssets({ soClient, pkgName: newPolicy.package!.name, @@ -1060,6 +1072,7 @@ class PackagePolicyClientImpl implements PackagePolicyClient { error: Error | SavedObjectError; }>; }> { + const logger = appContextService.getLogger(); const savedObjectType = await getPackagePolicySavedObjectType(); for (const packagePolicy of packagePolicyUpdates) { auditLoggingService.writeCustomSoAuditLog({ @@ -1081,7 +1094,7 @@ class PackagePolicyClientImpl implements PackagePolicyClient { const allSecretsToDelete: PolicySecretReference[] = []; const packageInfosandAssetsMap = await getPkgInfoAssetsMap({ - logger: appContextService.getLogger(), + logger, packageInfos: [...packageInfos.values()], savedObjectsClient: soClient, }); @@ -1103,6 +1116,8 @@ class PackagePolicyClientImpl implements PackagePolicyClient { const oldPackagePolicy = oldPackagePolicies.find((p) => p.id === id); if (!oldPackagePolicy) { throw new PackagePolicyNotFoundError('Package policy not found'); + } else { + this.keepPolicyIdInSync(oldPackagePolicy); } let secretReferences: PolicySecretReference[] | undefined; @@ -1188,10 +1203,13 @@ class PackagePolicyClientImpl implements PackagePolicyClient { policiesToUpdate ); - const agentPolicyIds = new Set(packagePolicyUpdates.flatMap((p) => p.policy_ids)); - - const bumpPromise = pMap(agentPolicyIds, async (agentPolicyId) => { - // Bump revision of associated agent policy + // Bump revision of all associated agent policies (old and new) + const associatedPolicyIds = new Set([ + ...packagePolicyUpdates.flatMap((p) => p.policy_ids), + ...oldPackagePolicies.flatMap((p) => p.policy_ids), + ]); + logger.debug(`Bumping revision of associated agent policies ${associatedPolicyIds}`); + const bumpPromise = pMap(associatedPolicyIds, async (agentPolicyId) => { await agentPolicyService.bumpRevision(soClient, esClient, agentPolicyId, { user: options?.user, }); @@ -1787,16 +1805,6 @@ class PackagePolicyClientImpl implements PackagePolicyClient { })), } as NewPackagePolicyInput; }); - let agentPolicyId; - // fallback to first agent policy id in case no policy_id is specified, BWC with 8.0 - if (!newPolicy.policy_id && !newPolicy.policy_ids[0]) { - const { items: agentPolicies } = await agentPolicyService.list(soClient, { - perPage: 1, - }); - if (agentPolicies.length > 0) { - agentPolicyId = agentPolicies[0].id; - } - } newPackagePolicy = { ...newPP, name: newPolicy.name, @@ -1807,8 +1815,8 @@ class PackagePolicyClientImpl implements PackagePolicyClient { ...newPP.package!, experimental_data_stream_features: newPolicy.package?.experimental_data_stream_features, }, - policy_id: newPolicy.policy_id ?? agentPolicyId, - policy_ids: newPolicy.policy_ids ?? [agentPolicyId], + policy_id: newPolicy.policy_id ?? undefined, + policy_ids: newPolicy.policy_ids ?? undefined, output_id: newPolicy.output_id, inputs: newPolicy.inputs[0]?.streams ? newPolicy.inputs : inputs, vars: newPolicy.vars || newPP.vars, @@ -2592,7 +2600,7 @@ function _enforceFrozenVars( export interface NewPackagePolicyWithId extends NewPackagePolicy { id?: string; - policy_id?: string; + policy_id?: string | null; version?: string; } diff --git a/x-pack/plugins/fleet/server/types/models/package_policy.ts b/x-pack/plugins/fleet/server/types/models/package_policy.ts index c80cb45c84ff..e105bc82b27d 100644 --- a/x-pack/plugins/fleet/server/types/models/package_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/package_policy.ts @@ -96,7 +96,7 @@ const PackagePolicyBaseSchema = { name: schema.string(), description: schema.maybe(schema.string()), namespace: schema.maybe(PackagePolicyNamespaceSchema), - policy_id: schema.maybe(schema.string()), + policy_id: schema.nullable(schema.maybe(schema.string())), policy_ids: schema.maybe(schema.arrayOf(schema.string())), output_id: schema.nullable(schema.maybe(schema.string())), enabled: schema.boolean(), @@ -221,7 +221,7 @@ export const SimplifiedPackagePolicyPreconfiguredSchema = SimplifiedPackagePolic export const SimplifiedCreatePackagePolicyRequestBodySchema = SimplifiedPackagePolicyBaseSchema.extends({ - policy_id: schema.maybe(schema.string()), + policy_id: schema.nullable(schema.maybe(schema.string())), policy_ids: schema.maybe(schema.arrayOf(schema.string())), force: schema.maybe(schema.boolean()), package: schema.object({ diff --git a/x-pack/plugins/fleet/server/types/so_attributes.ts b/x-pack/plugins/fleet/server/types/so_attributes.ts index ef39759b206f..1bb954cf990d 100644 --- a/x-pack/plugins/fleet/server/types/so_attributes.ts +++ b/x-pack/plugins/fleet/server/types/so_attributes.ts @@ -119,7 +119,7 @@ export interface PackagePolicySOAttributes { created_at: string; created_by: string; inputs: PackagePolicyInput[]; - policy_id?: string; + policy_id?: string | null; policy_ids: string[]; // Nullable to allow user to reset to default outputs output_id?: string | null; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_json_editor.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_json_editor.tsx index 94d370082ca7..751f4fb546c7 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_json_editor.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_json_editor.tsx @@ -18,7 +18,7 @@ export const DocumentFieldsJsonEditor = ({ defaultValue }: Props) => { const dispatch = useDispatch(); const defaultValueRef = useRef(defaultValue); const onUpdate = useCallback( - ({ data, isValid }) => + ({ data, isValid }: any) => dispatch({ type: 'fieldsJsonEditor.update', value: { json: data.format(), isValid }, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx index 9edef3e800a9..1c236ea7e78d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx @@ -98,7 +98,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( ); const onDescriptionChange = useCallback( - (nextDescription) => { + (nextDescription: any) => { let nextOptions: Record; if (!nextDescription) { const { description: _description, ...restOptions } = processor.options; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/drag_and_drop_text_list.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/drag_and_drop_text_list.tsx index ea9f460a5899..915054b053ba 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/drag_and_drop_text_list.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/drag_and_drop_text_list.tsx @@ -78,7 +78,7 @@ function DragAndDropTextListComponent({ const [firstItemId] = useState(() => uuidv4()); const onDragEnd = useCallback( - ({ source, destination }) => { + ({ source, destination }: any) => { if (source && destination) { onMove(source.index, destination.index); } diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/xjson_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/xjson_editor.tsx index 73aff739b1ee..5134df09ac93 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/xjson_editor.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/field_components/xjson_editor.tsx @@ -28,7 +28,7 @@ export const XJsonEditor: FunctionComponent = ({ field, editorProps }) => const { xJson, setXJson, convertToJson } = useXJsonMode(value); const onChange = useCallback( - (s) => { + (s: any) => { setXJson(s); setValue(convertToJson(s)); }, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processor_form.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processor_form.container.tsx index ff34c88a7179..e6a47c52657e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processor_form.container.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processor_form.container.tsx @@ -74,7 +74,7 @@ export const ProcessorFormContainer: FunctionComponent = ({ }, [processor, unsavedFormState]); const formSerializer = useCallback( - (formState) => { + (formState: any) => { return { type: formState.type, fields: formState.customOptions diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processors_tree/processors_tree.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processors_tree/processors_tree.tsx index 1dd2bec15845..9e5281ea4a85 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processors_tree/processors_tree.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processors_tree/processors_tree.tsx @@ -61,7 +61,7 @@ export const ProcessorsTree: FunctionComponent = memo((props) => { onAction({ type: 'cancelMove' }); } }; - const cancelMoveClickListener = (ev: any) => { + const cancelMoveClickListener = () => { onAction({ type: 'cancelMove' }); }; // Give the browser a chance to flush any click events including the click diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx index fc731f6be078..6d5cc2b582e8 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx @@ -152,7 +152,7 @@ export const DocumentsTab: FunctionComponent = ({ const { getFormData, reset } = form; const onAddDocumentHandler = useCallback( - (document) => { + (document: any) => { const { documents: existingDocuments = [] } = getFormData(); reset({ defaultValue: { documents: [...existingDocuments, document] } }); diff --git a/x-pack/plugins/integration_assistant/__jest__/fixtures/ecs_mapping.ts b/x-pack/plugins/integration_assistant/__jest__/fixtures/ecs_mapping.ts index e0c2054a49e8..514012761e8d 100644 --- a/x-pack/plugins/integration_assistant/__jest__/fixtures/ecs_mapping.ts +++ b/x-pack/plugins/integration_assistant/__jest__/fixtures/ecs_mapping.ts @@ -452,6 +452,8 @@ export const ecsTestState = { results: { test: 'testresults' }, samplesFormat: 'testsamplesFormat', ecsVersion: 'testversion', + chunkMapping: { test1: 'test1' }, + useFinalMapping: false, currentMapping: { test1: 'test1' }, lastExecutedChain: 'testchain', rawSamples: ['{"test1": "test1"}'], diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.test.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.test.ts index f3a51c80a524..346947cd1a38 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { FakeLLM } from '@langchain/core/utils/testing'; -import { handleDuplicates } from './duplicates'; -import type { EcsMappingState } from '../../types'; -import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; import { ActionsClientChatOpenAI, ActionsClientSimpleChatModel, } from '@kbn/langchain/server/language_models'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; +import type { EcsMappingState } from '../../types'; +import { handleDuplicates } from './duplicates'; const model = new FakeLLM({ response: '{ "message": "ll callback later."}', diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.ts index 5c66168fc0bf..2d59bd1c241d 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/duplicates.ts @@ -6,9 +6,9 @@ */ import { JsonOutputParser } from '@langchain/core/output_parsers'; -import type { EcsNodeParams } from './types'; import type { EcsMappingState } from '../../types'; import { ECS_DUPLICATES_PROMPT } from './prompts'; +import type { EcsNodeParams } from './types'; export async function handleDuplicates({ state, @@ -16,13 +16,18 @@ export async function handleDuplicates({ }: EcsNodeParams): Promise> { const outputParser = new JsonOutputParser(); const ecsDuplicatesGraph = ECS_DUPLICATES_PROMPT.pipe(model).pipe(outputParser); + const usesFinalMapping = state?.useFinalMapping; + const mapping = usesFinalMapping ? state.finalMapping : state.currentMapping; - const currentMapping = await ecsDuplicatesGraph.invoke({ + const result = await ecsDuplicatesGraph.invoke({ ecs: state.ecs, - current_mapping: JSON.stringify(state.currentMapping, null, 2), + current_mapping: JSON.stringify(mapping, null, 2), ex_answer: state.exAnswer, duplicate_fields: state.duplicateFields, }); - return { currentMapping, lastExecutedChain: 'duplicateFields' }; + return { + [usesFinalMapping ? 'finalMapping' : 'currentMapping']: result, + lastExecutedChain: 'duplicateFields', + }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/graph.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/graph.ts index 86b0561a22e4..f9bc48960762 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/graph.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/graph.ts @@ -5,16 +5,16 @@ * 2.0. */ -import { END, START, StateGraph, Send } from '@langchain/langgraph'; +import { END, Send, START, StateGraph } from '@langchain/langgraph'; import type { EcsMappingState } from '../../types'; -import type { EcsGraphParams, EcsBaseNodeParams } from './types'; -import { modelInput, modelOutput, modelSubOutput } from './model'; import { handleDuplicates } from './duplicates'; import { handleInvalidEcs } from './invalid'; import { handleEcsMapping } from './mapping'; import { handleMissingKeys } from './missing'; -import { handleValidateMappings } from './validate'; +import { modelInput, modelMergedInputFromSubGraph, modelOutput, modelSubOutput } from './model'; import { graphState } from './state'; +import type { EcsBaseNodeParams, EcsGraphParams } from './types'; +import { handleValidateMappings } from './validate'; const handleCreateMappingChunks = async ({ state }: EcsBaseNodeParams) => { // Cherrypick a shallow copy of state to pass to subgraph @@ -44,7 +44,7 @@ function chainRouter({ state }: EcsBaseNodeParams): string { return 'invalidEcsFields'; } if (!state.finalized) { - return 'modelSubOutput'; + return 'modelOutput'; } return END; } @@ -69,7 +69,7 @@ async function getEcsSubGraph({ model }: EcsGraphParams) { duplicateFields: 'handleDuplicates', missingKeys: 'handleMissingKeys', invalidEcsFields: 'handleInvalidEcs', - modelSubOutput: 'modelSubOutput', + modelOutput: 'modelSubOutput', }) .addEdge('modelSubOutput', END); @@ -85,12 +85,29 @@ export async function getEcsGraph({ model }: EcsGraphParams) { }) .addNode('modelInput', (state: EcsMappingState) => modelInput({ state })) .addNode('modelOutput', (state: EcsMappingState) => modelOutput({ state })) + .addNode('handleValidation', (state: EcsMappingState) => handleValidateMappings({ state })) + .addNode('handleDuplicates', (state: EcsMappingState) => handleDuplicates({ state, model })) + .addNode('handleMissingKeys', (state: EcsMappingState) => handleMissingKeys({ state, model })) + .addNode('handleInvalidEcs', (state: EcsMappingState) => handleInvalidEcs({ state, model })) + .addNode('handleMergedSubGraphResponse', (state: EcsMappingState) => + modelMergedInputFromSubGraph({ state }) + ) .addNode('subGraph', subGraph) .addEdge(START, 'modelInput') - .addEdge('subGraph', 'modelOutput') + .addEdge('subGraph', 'handleMergedSubGraphResponse') + .addEdge('handleDuplicates', 'handleValidation') + .addEdge('handleMissingKeys', 'handleValidation') + .addEdge('handleInvalidEcs', 'handleValidation') + .addEdge('handleMergedSubGraphResponse', 'handleValidation') .addConditionalEdges('modelInput', (state: EcsMappingState) => handleCreateMappingChunks({ state }) ) + .addConditionalEdges('handleValidation', (state: EcsMappingState) => chainRouter({ state }), { + duplicateFields: 'handleDuplicates', + missingKeys: 'handleMissingKeys', + invalidEcsFields: 'handleInvalidEcs', + modelOutput: 'modelOutput', + }) .addEdge('modelOutput', END); const compiledEcsGraph = workflow.compile(); diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.test.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.test.ts index ad10aa5b030d..0986452d171a 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { FakeLLM } from '@langchain/core/utils/testing'; -import { handleInvalidEcs } from './invalid'; -import type { EcsMappingState } from '../../types'; -import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; import { ActionsClientChatOpenAI, ActionsClientSimpleChatModel, } from '@kbn/langchain/server/language_models'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; +import type { EcsMappingState } from '../../types'; +import { handleInvalidEcs } from './invalid'; const model = new FakeLLM({ response: '{ "message": "ll callback later."}', diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.ts index 4b050fac3ccf..5440b5bc9b12 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/invalid.ts @@ -5,9 +5,9 @@ * 2.0. */ import { JsonOutputParser } from '@langchain/core/output_parsers'; -import type { EcsNodeParams } from './types'; import type { EcsMappingState } from '../../types'; import { ECS_INVALID_PROMPT } from './prompts'; +import type { EcsNodeParams } from './types'; export async function handleInvalidEcs({ state, @@ -15,14 +15,19 @@ export async function handleInvalidEcs({ }: EcsNodeParams): Promise> { const outputParser = new JsonOutputParser(); const ecsInvalidEcsGraph = ECS_INVALID_PROMPT.pipe(model).pipe(outputParser); + const usesFinalMapping = state?.useFinalMapping; + const mapping = usesFinalMapping ? state.finalMapping : state.currentMapping; - const currentMapping = await ecsInvalidEcsGraph.invoke({ + const result = await ecsInvalidEcsGraph.invoke({ ecs: state.ecs, - current_mapping: JSON.stringify(state.currentMapping, null, 2), + current_mapping: JSON.stringify(mapping, null, 2), ex_answer: state.exAnswer, combined_samples: state.combinedSamples, invalid_ecs_fields: state.invalidEcsFields, }); - return { currentMapping, lastExecutedChain: 'invalidEcs' }; + return { + [usesFinalMapping ? 'finalMapping' : 'currentMapping']: result, + lastExecutedChain: 'invalidEcs', + }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/mapping.test.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/mapping.test.ts index 92954b83863b..3e8bf31fc1eb 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/mapping.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/mapping.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { FakeLLM } from '@langchain/core/utils/testing'; -import { handleEcsMapping } from './mapping'; -import type { EcsMappingState } from '../../types'; -import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; import { ActionsClientChatOpenAI, ActionsClientSimpleChatModel, } from '@kbn/langchain/server/language_models'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; +import type { EcsMappingState } from '../../types'; +import { handleEcsMapping } from './mapping'; const model = new FakeLLM({ response: '{ "message": "ll callback later."}', diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.test.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.test.ts index 35fbc51bbb2e..dc24226e5442 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { FakeLLM } from '@langchain/core/utils/testing'; -import { handleMissingKeys } from './missing'; -import type { EcsMappingState } from '../../types'; -import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; import { ActionsClientChatOpenAI, ActionsClientSimpleChatModel, } from '@kbn/langchain/server/language_models'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import { ecsTestState } from '../../../__jest__/fixtures/ecs_mapping'; +import type { EcsMappingState } from '../../types'; +import { handleMissingKeys } from './missing'; const model = new FakeLLM({ response: '{ "message": "ll callback later."}', diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.ts index 649c9a5d1fac..0c22af98a41b 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/missing.ts @@ -6,9 +6,9 @@ */ import { JsonOutputParser } from '@langchain/core/output_parsers'; -import { EcsNodeParams } from './types'; import { EcsMappingState } from '../../types'; import { ECS_MISSING_KEYS_PROMPT } from './prompts'; +import { EcsNodeParams } from './types'; export async function handleMissingKeys({ state, @@ -16,14 +16,19 @@ export async function handleMissingKeys({ }: EcsNodeParams): Promise> { const outputParser = new JsonOutputParser(); const ecsMissingGraph = ECS_MISSING_KEYS_PROMPT.pipe(model).pipe(outputParser); + const usesFinalMapping = state?.useFinalMapping; + const mapping = usesFinalMapping ? state.finalMapping : state.currentMapping; - const currentMapping = await ecsMissingGraph.invoke({ + const result = await ecsMissingGraph.invoke({ ecs: state.ecs, - current_mapping: JSON.stringify(state.currentMapping, null, 2), + current_mapping: JSON.stringify(mapping, null, 2), ex_answer: state.exAnswer, combined_samples: state.combinedSamples, missing_keys: state?.missingKeys, }); - return { currentMapping, lastExecutedChain: 'missingKeys' }; + return { + [usesFinalMapping ? 'finalMapping' : 'currentMapping']: result, + lastExecutedChain: 'missingKeys', + }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/model.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/model.ts index 44508bca4ff1..67dbc747152f 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/model.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/model.ts @@ -4,17 +4,27 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { EcsMappingState } from '../../types'; import { prefixSamples } from '../../util/samples'; +import { mergeAndChunkSamples } from './chunk'; import { ECS_EXAMPLE_ANSWER, ECS_FIELDS } from './constants'; import { createPipeline } from './pipeline'; -import { mergeAndChunkSamples } from './chunk'; -import type { EcsMappingState } from '../../types'; import type { EcsBaseNodeParams } from './types'; export function modelSubOutput({ state }: EcsBaseNodeParams): Partial { return { - lastExecutedChain: 'ModelSubOutput', - finalMapping: state.currentMapping, + lastExecutedChain: 'modelSubOutput', + chunkMapping: state.currentMapping, + }; +} + +export function modelMergedInputFromSubGraph({ + state, +}: EcsBaseNodeParams): Partial { + return { + lastExecutedChain: 'modelMergedInputFromSubGraph', + useFinalMapping: true, + finalMapping: state.chunkMapping, }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/pipeline.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/pipeline.ts index 35c1fb4d31f4..7a1357216954 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/pipeline.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/pipeline.ts @@ -163,7 +163,7 @@ function generateProcessors(ecsMapping: object, samples: object, basePath: strin export function createPipeline(state: EcsMappingState): IngestPipeline { const samples = JSON.parse(state.combinedSamples); - const processors = generateProcessors(state.currentMapping, samples); + const processors = generateProcessors(state.finalMapping, samples); // Retrieve all source field names from convert processors to populate single remove processor: const fieldsToRemove = processors .map((p: any) => p.convert?.field) diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/prompts.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/prompts.ts index 4e5e4794d5b8..5df21295c8e2 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/prompts.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/prompts.ts @@ -166,10 +166,17 @@ Here is some context for you to reference for your task, read it carefully as yo {duplicate_fields} - + +Go through each ECS field in the above list of duplicate fields step by step and and modify the current mapping following this process: +1. For each duplicate ECS field there is 2 or more source fields that has target set to the same ECS field, identify which of these it is. +2. For each of the source fields that has the same target set, choose only one of them to have the target set to the ECS field, for the rest you should either find another matching ECS field or set the source to be null. +3. Make sure that all of the ECS fields mentioned in the duplicate fields above have been resolved and return the updated current mapping object. + To resolve the duplicate mappings, go through each key and value defined in the duplicate fields, and modify the current mapping step by step, and ensure they follow these guidelines: -- Multiple keys should not have the same value (ECS field it will be mapped to). If multiple keys do have the same value then always choose the best match for the ECS field, while the other duplicates should have their value changed to null. +- Only focus on ECS fields reported as duplicate fields, do not modify any other fields. +- For all fields that are marked duplicate, when the best target is choosen, remember to set the value of the source field to null. +- The value "target" should not have a null value, but rather the source object itself should be set to null, use the existing current mapping for reference. - Do not respond with anything except the updated current mapping JSON object enclosed with 3 backticks (\`). See example response below. diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/state.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/state.ts index 35a307f1de93..079f35a4cc1b 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/state.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/state.ts @@ -16,7 +16,7 @@ export const graphState: StateGraphArgs['channels'] = { }, chunkSize: { value: (x: number, y?: number) => y ?? x, - default: () => 10, + default: () => 25, }, lastExecutedChain: { value: (x: string, y?: string) => y ?? x, @@ -58,10 +58,18 @@ export const graphState: StateGraphArgs['channels'] = { value: (x: object, y?: object) => y ?? x, default: () => ({}), }, - finalMapping: { + chunkMapping: { reducer: merge, default: () => ({}), }, + finalMapping: { + value: (x: object, y?: object) => y ?? x, + default: () => ({}), + }, + useFinalMapping: { + value: (x: boolean, y?: boolean) => y ?? x, + default: () => false, + }, currentPipeline: { value: (x: object, y?: object) => y ?? x, default: () => ({}), diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.test.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.test.ts index 052c0d6bf11b..20074bc4f104 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { findInvalidEcsFields, processMapping } from './validate'; +import { findDuplicateFields, findInvalidEcsFields, processMapping } from './validate'; describe('Testing ecs handler', () => { it('processMapping()', async () => { @@ -90,3 +90,35 @@ describe('findInvalidEcsFields', () => { expect(invalid.length).toBe(1); }); }); + +describe('findDuplicateFields', () => { + it('duplicates: samples with duplicates', async () => { + const finalMapping = { + teleport_log: { + audit: { + ei: null, + event: { + target: 'event.action', + confidence: 0.9, + type: 'string', + date_formats: [], + }, + uid: { + target: 'event.action', + confidence: 0.8, + type: 'string', + date_formats: [], + }, + }, + }, + }; + const samples = [ + '{"teleport_log":{"audit":{"ei":0,"event":"user.login","uid":"8c815e54-c83b-43d7-b578-2bcf5b6775fa","code":"T1000W","time":"2024-05-09T20:58:57.77Z","cluster_name":"teleport.ericbeahan.com","user":"root","success":false,"error":"invalid username, password or second factor","method":"local","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36","addr.remote":"136.32.177.60:52457"}}}', + '{"teleport_log":{"audit":{"ei":0,"event":"user.login","uid":"6bf237a0-2753-418d-b01b-2d82ebf42636","code":"T1000W","time":"2024-05-09T21:00:22.747Z","cluster_name":"teleport.ericbeahan.com","user":"teleport-admin","success":false,"error":"invalid username, password or second factor","method":"local","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36","addr.remote":"136.32.177.60:52818"}}}', + ]; + const duplicates = findDuplicateFields(samples, finalMapping); + expect(duplicates).toStrictEqual([ + "One or more samples have matching fields for ECS field 'event.action': teleport_log.audit.event, teleport_log.audit.uid", + ]); + }); +}); diff --git a/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.ts b/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.ts index 0a22ef4bc0fd..87005e3553e9 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/ecs/validate.ts @@ -6,6 +6,7 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ECS_FULL } from '../../../common/ecs'; +import { mergeSamples } from '../../util/samples'; import { ECS_RESERVED } from './constants'; import type { EcsBaseNodeParams } from './types'; @@ -89,7 +90,7 @@ function getValueFromPath(obj: AnyObject, path: string[]): unknown { return path.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : null), obj); } -function findDuplicateFields(prefixedSamples: string[], ecsMapping: AnyObject): string[] { +export function findDuplicateFields(prefixedSamples: string[], ecsMapping: AnyObject): string[] { const parsedSamples = prefixedSamples.map((sample) => JSON.parse(sample)); const results: string[] = []; const output: Record = {}; @@ -148,9 +149,13 @@ export function findInvalidEcsFields(currentMapping: AnyObject): string[] { } export function handleValidateMappings({ state }: EcsBaseNodeParams): AnyObject { - const missingKeys = findMissingFields(state?.combinedSamples, state?.currentMapping); - const duplicateFields = findDuplicateFields(state?.prefixedSamples, state?.currentMapping); - const invalidEcsFields = findInvalidEcsFields(state?.currentMapping); + const usesFinalMapping = state?.useFinalMapping; + const mapping = usesFinalMapping ? state.finalMapping : state.currentMapping; + const samples = usesFinalMapping ? mergeSamples(state.prefixedSamples) : state.combinedSamples; + + const missingKeys = findMissingFields(samples, mapping); + const duplicateFields = findDuplicateFields(state?.prefixedSamples, mapping); + const invalidEcsFields = findInvalidEcsFields(mapping); return { missingKeys, duplicateFields, diff --git a/x-pack/plugins/integration_assistant/server/types.ts b/x-pack/plugins/integration_assistant/server/types.ts index d6fa5652c44b..44af5afcd10e 100644 --- a/x-pack/plugins/integration_assistant/server/types.ts +++ b/x-pack/plugins/integration_assistant/server/types.ts @@ -5,13 +5,13 @@ * 2.0. */ -import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { - ActionsClientChatOpenAI, ActionsClientBedrockChatModel, - ActionsClientSimpleChatModel, + ActionsClientChatOpenAI, ActionsClientGeminiChatModel, + ActionsClientSimpleChatModel, } from '@kbn/langchain/server'; +import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { SamplesFormat } from '../common'; export interface IntegrationAssistantPluginSetup { @@ -76,6 +76,8 @@ export interface EcsMappingState { finalized: boolean; currentMapping: object; finalMapping: object; + chunkMapping: object; + useFinalMapping: boolean; currentPipeline: object; duplicateFields: string[]; missingKeys: string[]; diff --git a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/index.tsx b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/index.tsx index e907e0dc9dbe..57d3e3288d61 100644 --- a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/index.tsx +++ b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/index.tsx @@ -86,7 +86,7 @@ export const ContainerNameWidget = ({ sortDirection ); - const onTableChange = useCallback(({ sort = {} }) => { + const onTableChange = useCallback(({ sort = {} }: any) => { // @ts-ignore const { field: sortingField, direction: sortingDirection } = sort; diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 3f12c6f63ca9..da99d693539b 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -8,9 +8,9 @@ import { cloneDeep, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; -import { isOfAggregateQueryType } from '@kbn/es-query'; +import { AggregateQuery, isOfAggregateQueryType, Query } from '@kbn/es-query'; import { useStore } from 'react-redux'; -import { TopNavMenuData } from '@kbn/navigation-plugin/public'; +import { TopNavMenuData, TopNavMenuProps } from '@kbn/navigation-plugin/public'; import { getEsQueryConfig } from '@kbn/data-plugin/public'; import type { DataView, DataViewSpec } from '@kbn/data-views-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; @@ -803,7 +803,9 @@ export const LensTopNavMenu = ({ startServices, ]); - const onQuerySubmitWrapped = useCallback( + const onQuerySubmitWrapped = useCallback< + Required>['onQuerySubmit'] + >( (payload) => { const { dateRange, query: newQuery } = payload; const currentRange = data.query.timefilter.timefilter.getTime(); @@ -819,7 +821,7 @@ export const LensTopNavMenu = ({ } if (newQuery) { if (!isEqual(newQuery, query)) { - dispatchSetState({ query: newQuery }); + dispatchSetState({ query: newQuery as Query }); // check if query is text-based (esql etc) and switchAndCleanDatasource if (isOfAggregateQueryType(newQuery) && !isOnTextBasedMode) { setIsOnTextBasedMode(true); @@ -846,14 +848,16 @@ export const LensTopNavMenu = ({ ] ); - const onSavedWrapped = useCallback( + const onSavedWrapped = useCallback>['onSaved']>( (newSavedQuery) => { dispatchSetState({ savedQuery: newSavedQuery }); }, [dispatchSetState] ); - const onSavedQueryUpdatedWrapped = useCallback( + const onSavedQueryUpdatedWrapped = useCallback< + Required>['onSavedQueryUpdated'] + >( (newSavedQuery) => { // If the user tries to load the same saved query that is already loaded, // we will receive the same object reference which was previously frozen diff --git a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts index 5b6712ed2386..fa9268c0374e 100644 --- a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts +++ b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts @@ -15,6 +15,7 @@ import { TimeRange, EsQueryConfig, isOfQueryType, + AggregateQuery, } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { RecursiveReadonly } from '@kbn/utility-types'; @@ -203,7 +204,7 @@ type QueryLanguage = 'lucene' | 'kuery'; * extra filter pill. */ export function combineQueryAndFilters( - query: Query | Query[] | undefined, + query: Query | Query[] | AggregateQuery | undefined, filters: Filter[], meta: LayerMetaInfo, dataViews: DataViewBase[] | undefined, diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx index ba047564a1f0..c666c23d667c 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx @@ -241,7 +241,7 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({ [layerFields] ); - const onOverrideFieldGroupDetails = useCallback((groupName) => { + const onOverrideFieldGroupDetails = useCallback((groupName: string) => { if (groupName === FieldsGroupNames.AvailableFields) { return { helpText: i18n.translate('xpack.lens.indexPattern.allFieldsLabelHelp', { diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx index b551ac967eea..98086df2e5ba 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx @@ -48,9 +48,9 @@ import { getReferencedField, hasField } from '../pure_utils'; import { fieldIsInvalid, getSamplingValue, isSamplingValueEnabled } from '../utils'; import { BucketNestingEditor } from './bucket_nesting_editor'; import type { FormBasedLayer } from '../types'; -import { FormatSelector } from './format_selector'; +import { FormatSelector, FormatSelectorProps } from './format_selector'; import { ReferenceEditor } from './reference_editor'; -import { TimeScaling } from './time_scaling'; +import { TimeScaling, TimeScalingProps } from './time_scaling'; import { Filtering } from './filtering'; import { ReducedTimeRange } from './reduced_time_range'; import { AdvancedOptions } from './advanced_options'; @@ -144,7 +144,8 @@ export function DimensionEditor(props: DimensionEditorProps) { const { euiTheme } = useEuiTheme(); const updateLayer = useCallback( - (newLayer) => setState((prevState) => mergeLayer({ state: prevState, layerId, newLayer })), + (newLayer: Partial) => + setState((prevState) => mergeLayer({ state: prevState, layerId, newLayer })), [layerId, setState] ); @@ -843,7 +844,7 @@ export function DimensionEditor(props: DimensionEditorProps) { updateLayer({ ...layer, // clean up the incomplete column data for the referenced id - incompleteColumns: { ...layer.incompleteColumns, [referenceId]: null }, + incompleteColumns: { ...layer.incompleteColumns, [referenceId]: undefined }, }); }} onDeleteColumn={() => { @@ -993,7 +994,7 @@ export function DimensionEditor(props: DimensionEditorProps) { const ButtonGroupContent = showQuickFunctions ? quickFunctions : customParamEditor; - const onFormatChange = useCallback( + const onFormatChange = useCallback( (newFormat) => { updateLayer( updateColumnParam({ @@ -1098,7 +1099,7 @@ export function DimensionEditor(props: DimensionEditorProps) { * Advanced options can cause side effects on other columns (i.e. formulas) * so before updating the layer the full insertOrReplaceColumn needs to be performed */ - const updateAdvancedOption = useCallback( + const updateAdvancedOption = useCallback( (newLayer) => { if (selectedColumn) { setStateWrapper( diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx index e79ead1e5536..c4585a51e6b0 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx @@ -9,6 +9,7 @@ import { isEqual } from 'lodash'; import type { Query } from '@kbn/es-query'; import { validateQuery, FilterQueryInput } from '@kbn/visualization-ui-components'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { FilterQueryInputProps } from '@kbn/visualization-ui-components/components/query_input/filter_query_input'; import { LENS_APP_NAME } from '../../../../common/constants'; import { GenericIndexPatternColumn, operationDefinitionMap } from '../operations'; import type { FormBasedLayer } from '../types'; @@ -44,7 +45,7 @@ export function Filtering({ helpMessage: string | null; }) { const inputFilter = selectedColumn.filter; - const onChange = useCallback( + const onChange = useCallback( (query) => { const { isValid } = validateQuery(query, indexPattern); if (isValid && !isEqual(inputFilter, query)) { diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx index 08972b236240..0e978e439a70 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx @@ -17,6 +17,7 @@ import { EuiFormLabel, EuiLink, useEuiTheme, + EuiComboBoxOptionOption, } from '@elastic/eui'; import { useDebouncedValue } from '@kbn/visualization-utils'; import { useKibana } from '@kbn/kibana-react-plugin/public'; @@ -227,7 +228,7 @@ export function FormatSelector(props: FormatSelectorProps) { ); const onChangeWrapped = useCallback( - (choices) => { + (choices: Array>) => { if (choices.length === 0) { return; } diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx index 003407649622..5cf3bde50bec 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx @@ -54,17 +54,14 @@ export function setTimeScaling( }; } -export function TimeScaling({ - selectedColumn, - columnId, - layer, - updateLayer, -}: { +export interface TimeScalingProps { selectedColumn: GenericIndexPatternColumn; columnId: string; layer: FormBasedLayer; updateLayer: (newLayer: FormBasedLayer) => void; -}) { +} + +export function TimeScaling({ selectedColumn, columnId, layer, updateLayer }: TimeScalingProps) { const selectedOperation = operationDefinitionMap[selectedColumn.operationType]; if (!selectedOperation.timeScalingMode || selectedOperation.timeScalingMode === 'disabled') { diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx index ad9a1067dcae..7896f1f2950b 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiFieldNumber, EuiRange } from '@elastic/eui'; +import { EuiFieldNumber, EuiRange, EuiRangeProps } from '@elastic/eui'; import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { AggFunctionsMapping } from '@kbn/data-plugin/public'; @@ -344,7 +344,7 @@ export const percentileOperation: OperationDefinition< const step = isInline ? 1 : 0.0001; const upperBound = isInline ? 99 : 99.9999; const onChange = useCallback( - (value) => { + (value?: string) => { if ( !isValidNumber(value, isInline, upperBound, step, ALLOWED_DECIMAL_DIGITS) || Number(value) === currentColumn.params.percentile @@ -384,7 +384,12 @@ export const percentileOperation: OperationDefinition< ALLOWED_DECIMAL_DIGITS ); - const handleInputChange = useCallback( + const handleInputChange = useCallback>( + (e) => handleInputChangeWithoutValidation(String(e.currentTarget.value)), + [handleInputChangeWithoutValidation] + ); + + const handleRangeChange = useCallback>( (e) => handleInputChangeWithoutValidation(String(e.currentTarget.value)), [handleInputChangeWithoutValidation] ); @@ -420,7 +425,7 @@ export const percentileOperation: OperationDefinition< min={step} max={upperBound} step={step} - onChange={handleInputChange} + onChange={handleRangeChange} showInput aria-label={percentileLabel} /> diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx index 575bcc2ec0ed..a7d8896ea050 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx @@ -185,7 +185,7 @@ export const percentileRanksOperation: OperationDefinition< defaultMessage: 'Percentile ranks value', }); const onChange = useCallback( - (value) => { + (value?: string) => { if (!isValidNumber(value, isInline) || Number(value) === currentColumn.params.value) { return; } diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.tsx index 715889b896ce..6b2b2166c02b 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.tsx @@ -167,7 +167,7 @@ export const staticValueOperation: OperationDefinition< paramEditorCustomProps, }) { const onChange = useCallback( - (newValue) => { + (newValue?: string) => { // even if debounced it's triggering for empty string with the previous valid value if ( currentColumn.params.value === newValue || diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx index 2a88a7202964..960aeea67b23 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx @@ -16,7 +16,7 @@ import { } from '@kbn/visualization-ui-components'; import { useDebouncedValue } from '@kbn/visualization-utils'; import { IndexPattern } from '../../../../../types'; -import { FieldSelect } from '../../../dimension_panel/field_select'; +import { FieldChoiceWithOperationType, FieldSelect } from '../../../dimension_panel/field_select'; import type { TermsIndexPatternColumn } from './types'; import type { OperationSupportMatrix } from '../../../dimension_panel'; import { supportedTypes } from './constants'; @@ -72,7 +72,7 @@ export function FieldInputs({ }); const onFieldSelectChange = useCallback( - (choice, index = 0) => { + (choice: FieldChoiceWithOperationType, index = 0) => { const fields = [...localValues]; if (indexPattern.getFieldByName(choice.field)) { diff --git a/x-pack/plugins/lens/public/datasources/form_based/types.ts b/x-pack/plugins/lens/public/datasources/form_based/types.ts index 5abec15c31d6..1241429cf785 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/types.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/types.ts @@ -53,7 +53,7 @@ export interface FormBasedLayer { indexPatternId: string; linkToLayers?: string[]; // Partial columns represent the temporary invalid states - incompleteColumns?: Record; + incompleteColumns?: Record; sampling?: number; ignoreGlobalFilters?: boolean; } diff --git a/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx index bda5df0e3488..fd61c0d06345 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx @@ -24,6 +24,7 @@ import { GetCustomFieldType, useGroupedFields, } from '@kbn/unified-field-list'; +import { OverrideFieldGroupDetails } from '@kbn/unified-field-list/src/types'; import type { DatasourceDataPanelProps } from '../../../types'; import type { TextBasedPrivateState } from '../types'; import { getStateFromAggregateQuery } from '../utils'; @@ -83,7 +84,7 @@ export function TextBasedDataPanel({ [layerFields] ); - const onOverrideFieldGroupDetails = useCallback((groupName) => { + const onOverrideFieldGroupDetails = useCallback((groupName) => { if (groupName === FieldsGroupNames.AvailableFields) { return { helpText: i18n.translate('xpack.lens.indexPattern.allFieldsForTextBasedLabelHelp', { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx index aa3315972b71..4218eb6426d2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx @@ -13,6 +13,7 @@ import { DropTargetSwapDuplicateCombine, Draggable, Droppable, + DroppableProps, } from '@kbn/dom-drag-drop'; import { isDraggedField } from '../../../../utils'; import { @@ -125,11 +126,11 @@ export function DraggableDimensionButton({ ); const registerNewButtonRefMemoized = useCallback( - (el) => registerNewButtonRef(target.columnId, el), + (el: HTMLDivElement | null) => registerNewButtonRef(target.columnId, el), [registerNewButtonRef, target.columnId] ); - const handleOnDrop = useCallback( + const handleOnDrop = useCallback>( (source, selectedDropType) => onDrop(source, value, selectedDropType), [value, onDrop] ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx index f8562a161c2a..836365effc3d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useMemo, useState, useEffect } from 'react'; +import React, { useCallback, useMemo, useState, useEffect } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { @@ -14,6 +14,7 @@ import { DropType, DropTargetSwapDuplicateCombine, Droppable, + DroppableProps, } from '@kbn/dom-drag-drop'; import { EmptyDimensionButton as EmptyDimensionButtonInner } from '@kbn/visualization-ui-components'; import { css } from '@emotion/react'; @@ -167,7 +168,7 @@ export function EmptyDimensionButton({ [newColumnId, target, nextLabel, canDuplicate] ); - const handleOnDrop = React.useCallback( + const handleOnDrop = useCallback>( (source, selectedDropType) => onDrop(source, value, selectedDropType), [value, onDrop] ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 5f66bd2e838c..e83323a36fad 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -23,7 +23,7 @@ import { import { AddLayerFunction, DragDropOperation, Visualization } from '../../../types'; import { LayerPanel } from './layer_panel'; import { generateId } from '../../../id_generator'; -import { ConfigPanelWrapperProps } from './types'; +import { ConfigPanelWrapperProps, LayerPanelProps } from './types'; import { useFocusUpdate } from './use_focus_update'; import { setLayerDefaultDimension, @@ -245,10 +245,9 @@ export function LayerPanels( setNextFocusedLayerId(layerId); }; - const registerLibraryAnnotationGroupFunction = useCallback( - (groupInfo) => dispatchLens(registerLibraryAnnotationGroup(groupInfo)), - [dispatchLens] - ); + const registerLibraryAnnotationGroupFunction = useCallback< + LayerPanelProps['registerLibraryAnnotationGroup'] + >((groupInfo) => dispatchLens(registerLibraryAnnotationGroup(groupInfo)), [dispatchLens]); const hideAddLayerButton = query && isOfAggregateQueryType(query); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index cad1dd351c3c..2847af1ca437 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -91,7 +91,7 @@ export function LayerPanel(props: LayerPanelProps) { const settingsPanelRef = useRef(null); const registerLayerRef = useCallback( - (el) => registerNewLayerRef(layerId, el), + (el: HTMLDivElement | null) => registerNewLayerRef(layerId, el), [layerId, registerNewLayerRef] ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/use_focus_update.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/use_focus_update.tsx index 7065c37c1daf..4a6234a7cf6b 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/use_focus_update.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/use_focus_update.tsx @@ -35,7 +35,7 @@ export function useFocusUpdate(ids: string[]) { } }, [ids, refsById, nextFocusedId]); - const registerNewRef = useCallback((id, el) => { + const registerNewRef = useCallback((id: string, el: HTMLElement | null) => { if (el) { setRefsById((refs) => { return new Map(refs.set(id, el)); @@ -44,7 +44,7 @@ export function useFocusUpdate(ids: string[]) { }, []); const removeRef = useCallback( - (id) => { + (id: string) => { if (ids.length <= 1) { return setNextFocusedId(id); } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index e0736b149fcb..d5173998dc46 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -97,7 +97,7 @@ export function EditorFrame(props: EditorFrameProps) { ); const dropOntoWorkspace = useCallback( - (field) => { + (field: DragDropIdentifier) => { const suggestion = getSuggestionForField.current!(field); if (suggestion) { trackUiCounterEvents('drop_onto_workspace'); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index faa617f081d8..7baf35c4eb14 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -162,7 +162,7 @@ interface PreventableEvent { export type Simplify = { [KeyType in keyof T]: T[KeyType] } & {}; -interface LensBaseEmbeddableInput extends EmbeddableInput { +export interface LensBaseEmbeddableInput extends EmbeddableInput { filters?: Filter[]; query?: Query; timeRange?: TimeRange; diff --git a/x-pack/plugins/lens/public/shared_components/axis/ticks/axis_ticks_settings.tsx b/x-pack/plugins/lens/public/shared_components/axis/ticks/axis_ticks_settings.tsx index 1ac1c84f7063..8f47307d19d3 100644 --- a/x-pack/plugins/lens/public/shared_components/axis/ticks/axis_ticks_settings.tsx +++ b/x-pack/plugins/lens/public/shared_components/axis/ticks/axis_ticks_settings.tsx @@ -33,7 +33,7 @@ export const AxisTicksSettings: React.FunctionComponent updateTicksVisibilityState, }) => { const onTicksStatusChange = useCallback( - (visible) => updateTicksVisibilityState(visible, axis), + (visible: boolean) => updateTicksVisibilityState(visible, axis), [axis, updateTicksVisibilityState] ); diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx index 9c3823c434a2..83249f86ffa7 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx @@ -183,13 +183,13 @@ export const DatatableComponent = (props: DatatableRenderProps) => { ); const onChangeItemsPerPage = useCallback( - (pageSize) => onEditAction({ action: 'pagesize', size: pageSize }), + (pageSize: number) => onEditAction({ action: 'pagesize', size: pageSize }), [onEditAction] ); // active page isn't persisted, so we manage this state locally const onChangePage = useCallback( - (pageIndex) => { + (pageIndex: number) => { setPagination((_pagination) => { if (_pagination) { return { pageSize: _pagination?.pageSize, pageIndex }; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.tsx index b27dc0305c68..be5a81ef33dc 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.tsx @@ -24,9 +24,9 @@ export function DataTableToolbar(props: VisualizationToolbarProps { const rowHeightLines = @@ -45,7 +45,7 @@ export function DataTableToolbar(props: VisualizationToolbarProps { + (newRowHeightLines: number, heightLinesProperty: string) => { setState({ ...state, [heightLinesProperty]: newRowHeightLines, diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/axis_settings_popover.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/axis_settings_popover.tsx index 47178886dc53..1bf00cb0afb6 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/axis_settings_popover.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/axis_settings_popover.tsx @@ -245,7 +245,7 @@ export const AxisSettingsPopover: React.FunctionComponent { + (newExtent: AxisExtentConfig | undefined) => { if (setExtent && newExtent && !isEqual(newExtent, extent)) { const { errorMsg } = validateExtent(hasBarOrAreaOnAxis, newExtent, scale); if (axis === 'x' || newExtent.mode !== 'custom' || !errorMsg) { diff --git a/x-pack/plugins/ml/common/util/group_color_utils.ts b/x-pack/plugins/ml/common/util/group_color_utils.ts index 3c2398a18684..77d16b8aaad5 100644 --- a/x-pack/plugins/ml/common/util/group_color_utils.ts +++ b/x-pack/plugins/ml/common/util/group_color_utils.ts @@ -24,7 +24,7 @@ const COLORS = [ euiVars.euiColorPrimary, ]; -const colorMap: Record = {}; +const colorMap: Record = Object.create(null); export function tabColor(name: string): string { if (colorMap[name] === undefined) { diff --git a/x-pack/plugins/ml/public/alerting/anomaly_detection_rule/ml_anomaly_alert_trigger.tsx b/x-pack/plugins/ml/public/alerting/anomaly_detection_rule/ml_anomaly_alert_trigger.tsx index 2f36f3f687ca..7404646db719 100644 --- a/x-pack/plugins/ml/public/alerting/anomaly_detection_rule/ml_anomaly_alert_trigger.tsx +++ b/x-pack/plugins/ml/public/alerting/anomaly_detection_rule/ml_anomaly_alert_trigger.tsx @@ -199,7 +199,6 @@ const MlAnomalyAlertTrigger: FC = ({ errors={Array.isArray(errors.jobSelection) ? errors.jobSelection : []} shouldUseDropdownJobCreate /> - = ({ alertParams={resultParams} maxNumberOfBuckets={maxNumberOfBuckets} /> - = ({ onChange={useCallback(onAlertParamChange('includeInterim'), [])} /> - { + onChange={useCallback((update: any) => { Object.keys(update).forEach((k) => { setRuleParams(k, update[k as keyof MlAnomalyDetectionAlertAdvancedSettings]); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [])} /> - - - ); diff --git a/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx b/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx index 4e8d88f8b33e..54d25e9fcb30 100644 --- a/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx +++ b/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx @@ -125,13 +125,11 @@ const AnomalyDetectionJobsHealthRuleTrigger: FC = ({ } shouldUseDropdownJobCreate /> - - { + onChange={useCallback((update: any) => { const callback = onAlertParamChange('excludeJobs'); if (isPopulatedObject(update)) { callback(update); @@ -151,9 +149,7 @@ const AnomalyDetectionJobsHealthRuleTrigger: FC = ({ options={excludeJobsOptions} shouldUseDropdownJobCreate /> - - { const useUserTimeSettings = useUiSettings().get(ANOMALY_DETECTION_ENABLE_TIME_RANGE); const userTimeSettings = useUiSettings().get(ANOMALY_DETECTION_DEFAULT_TIME_RANGE); const createLinkWithUserDefaults = useCallback( - (location, jobList) => { + (location: any, jobList: any) => { const resultsUrl = mlJobService.createResultsUrlForJobs( jobList, location, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_data_grid.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_data_grid.ts index 8ed2b2fd3b2a..5a8d29422a9d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_data_grid.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_data_grid.ts @@ -36,20 +36,20 @@ export const useExplorationDataGrid = ( }), [pageUrlState.pageSize, pageUrlState.pageIndex] ); - dataGrid.setPagination = useCallback( + dataGrid.setPagination = useCallback( (u) => { setPageUrlState({ ...u }); }, [setPageUrlState] ); dataGrid.onChangePage = useCallback( - (pageIndex) => { + (pageIndex: number) => { setPageUrlState({ pageIndex }); }, [setPageUrlState] ); dataGrid.onChangeItemsPerPage = useCallback( - (pageSize) => { + (pageSize: number) => { setPageUrlState({ pageSize }); }, [setPageUrlState] diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/feature_importance/decision_path_chart.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/feature_importance/decision_path_chart.tsx index 954b85ce2793..2805563eeb7f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/feature_importance/decision_path_chart.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/feature_importance/decision_path_chart.tsx @@ -122,7 +122,7 @@ export const DecisionPathChart = ({ ); // if regression, guarantee up to num_precision significant digits without having it in scientific notation // if classification, hide the numeric values since we only want to show the path - const tickFormatter = useCallback((d) => formatSingleValue(d, '').toString(), []); + const tickFormatter = useCallback((d: any) => formatSingleValue(d, '').toString(), []); return (
diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/total_feature_importance_summary/feature_importance_summary.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/total_feature_importance_summary/feature_importance_summary.tsx index e4c1b92433b8..9e7371580b12 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/total_feature_importance_summary/feature_importance_summary.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/total_feature_importance_summary/feature_importance_summary.tsx @@ -200,7 +200,7 @@ export const FeatureImportanceSummaryPanel: FC Number(d.toPrecision(3)).toString(), []); + const tickFormatter = useCallback((d: any) => Number(d.toPrecision(3)).toString(), []); // do not expand by default if no feature importance data const noDataCallOut = useMemo(() => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx index 19d4d3a55f73..9cf363660445 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx @@ -100,7 +100,7 @@ export const DataFrameAnalyticsList: FC = ({ const searchQueryText = pageState.queryText ?? ''; const setSearchQueryText = useCallback( - (value) => { + (value: any) => { updatePageState({ queryText: value }); }, [updatePageState] diff --git a/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts b/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts index 8d710e0a83b6..faa2b009c131 100644 --- a/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts +++ b/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts @@ -224,7 +224,7 @@ export const useExplorerData = (): [Partial | undefined, (d: any) const explorerData$ = useMemo(() => loadExplorerData$.pipe(switchMap(loadExplorerData)), []); const explorerData = useObservable(explorerData$); - const update = useCallback((c) => { + const update = useCallback((c: any) => { loadExplorerData$.next(c); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx b/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx index 2b164985f022..ae12b8b1fa4a 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx @@ -465,7 +465,7 @@ export const AnomalyTimeline: FC = React.memo( { + onChange={useCallback((update: any) => { setSeverityUpdate(update); }, [])} /> diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.tsx b/x-pack/plugins/ml/public/application/explorer/explorer.tsx index 23a4cbed76bb..65b862bc548e 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer.tsx @@ -232,7 +232,7 @@ export const Explorer: FC = ({ ); const onPanelWidthChange = useCallback( - (newSizes) => { + (newSizes: any) => { setAnomalyExplorerPanelState({ mainPage: { size: newSizes.mainPage, diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 93b6daac5081..deb7c9d2cc65 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -255,7 +255,7 @@ export function registerAnomalyDetectionAlertType({ spaceId, rule, }: ExecutorOptions) => { - const fakeRequest = {} as KibanaRequest; + const fakeRequest = Object.create(null) as KibanaRequest; const alertingService = mlSharedServices.alertingServiceProvider( services.savedObjectsClient, fakeRequest diff --git a/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts index b311a637eb2d..7d50f99a4212 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts @@ -266,7 +266,7 @@ export function registerJobsMonitoringRuleType({ throw new AlertsClientError(); } - const fakeRequest = {} as KibanaRequest; + const fakeRequest = Object.create(null) as KibanaRequest; const { getTestsResults } = mlServicesProviders.jobsHealthServiceProvider( services.savedObjectsClient, fakeRequest, diff --git a/x-pack/plugins/ml/server/lib/capabilities/__mocks__/ml_capabilities.ts b/x-pack/plugins/ml/server/lib/capabilities/__mocks__/ml_capabilities.ts index ebc90c1f208a..a27556faa645 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/__mocks__/ml_capabilities.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/__mocks__/ml_capabilities.ts @@ -13,7 +13,7 @@ import { } from '../../../../common/types/capabilities'; export function getAdminCapabilities() { - const caps: any = {}; + const caps: any = Object.create(null); Object.keys(adminMlCapabilities).forEach((k) => { caps[k] = true; }); @@ -21,7 +21,7 @@ export function getAdminCapabilities() { } export function getUserCapabilities() { - const caps: any = {}; + const caps: any = Object.create(null); Object.keys(userMlCapabilities).forEach((k) => { caps[k] = true; }); diff --git a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts index 868a1c570922..c36e569a6eb3 100644 --- a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts +++ b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts @@ -65,8 +65,8 @@ const cardinalityCheckProvider = (client: IScopedClusterClient) => { const { detectors, influencers, bucket_span: bucketSpan } = analysisConfig; - let overallCardinality = {}; - let maxBucketCardinality = {}; + let overallCardinality = Object.create(null); + let maxBucketCardinality = Object.create(null); // Get fields required for the model memory estimation const overallCardinalityFields: Set = detectors.reduce( diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts index f959683b6ae8..4e112a2ff313 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts @@ -228,7 +228,7 @@ export class AnalyticsManager { private async getInitialElementsModelRoot(modelId: string): Promise { const resultElements = []; const modelElements = []; - const details: any = {}; + const details: any = Object.create(null); let data: estypes.MlTrainedModelConfig | estypes.MlDataframeAnalyticsSummary | undefined; // fetch model data and create model elements data = this.findTrainedModel(modelId); @@ -296,7 +296,7 @@ export class AnalyticsManager { ): Promise { const resultElements = []; const modelElements = []; - const details: any = {}; + const details: any = Object.create(null); const data = this.findJob(jobId); const nextLinkId = data?.source?.index[0]; @@ -351,7 +351,7 @@ export class AnalyticsManager { try { await this.initData(); // Create first node for incoming analyticsId or modelId - let initialData: InitialElementsReturnType = {} as InitialElementsReturnType; + let initialData: InitialElementsReturnType = Object.create(null) as InitialElementsReturnType; const job = analyticsId === undefined ? undefined : this.findJob(analyticsId); if (analyticsId !== undefined && job !== undefined) { const jobCreateTime = job.create_time!; diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 07eebe6aaa66..d54976a37ecd 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -355,7 +355,7 @@ export class DataRecognizer { const jobs: ModuleJob[] = []; const datafeeds: ModuleDatafeed[] = []; - const kibana: KibanaObjects = {}; + const kibana: KibanaObjects = Object.create(null); // load all of the job configs if (isModule(module)) { const tempJobs: ModuleJob[] = module.jobs.map((j) => ({ @@ -595,7 +595,7 @@ export class DataRecognizer { } public async dataRecognizerJobsExist(moduleId: string): Promise { - const results = {} as JobExistResult; + const results = Object.create(null) as JobExistResult; // Load the module with the specified ID and check if the jobs // in the module have been created. @@ -851,7 +851,7 @@ export class DataRecognizer { start?: number, end?: number ): Promise<{ [key: string]: DatafeedResponse }> { - const results = {} as { [key: string]: DatafeedResponse }; + const results = Object.create(null) as { [key: string]: DatafeedResponse }; for (const datafeed of datafeeds) { results[datafeed.id] = await this._startDatafeed(datafeed, start, end); } @@ -957,7 +957,9 @@ export class DataRecognizer { // creates an empty results object, // listing each job/datafeed/savedObject with a save success boolean private _createResultsTemplate(moduleConfig: Module): DataRecognizerConfigResponse { - const results: DataRecognizerConfigResponse = {} as DataRecognizerConfigResponse; + const results: DataRecognizerConfigResponse = Object.create( + null + ) as DataRecognizerConfigResponse; const reducedConfig = { jobs: moduleConfig.jobs, datafeeds: moduleConfig.datafeeds, @@ -982,7 +984,7 @@ export class DataRecognizer { if (Array.isArray(reducedConfig[i])) { createResultsItems(reducedConfig[i] as any[], results, i); } else { - results[i] = {} as any; + results[i] = Object.create(null); Object.keys(reducedConfig[i]).forEach((k) => { createResultsItems((reducedConfig[i] as Module['kibana'])[k] as any[], results[i], k); }); @@ -1174,7 +1176,7 @@ export class DataRecognizer { ); if (!job.config.analysis_limits) { - job.config.analysis_limits = {} as AnalysisLimits; + job.config.analysis_limits = Object.create(null) as AnalysisLimits; } job.config.analysis_limits.model_memory_limit = modelMemoryLimit; @@ -1206,7 +1208,7 @@ export class DataRecognizer { // so set the jobs mml to be the max if (!job.config.analysis_limits) { - job.config.analysis_limits = {} as AnalysisLimits; + job.config.analysis_limits = Object.create(null) as AnalysisLimits; } job.config.analysis_limits.model_memory_limit = maxMml; diff --git a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts index 720a39193b9a..fa84a271e84b 100644 --- a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts @@ -246,7 +246,7 @@ export class DataVisualizer { ): Promise { // Batch up fields by type, getting stats for multiple fields at a time. const batches: Field[][] = []; - const batchedFields: { [key: string]: Field[][] } = {}; + const batchedFields: { [key: string]: Field[][] } = Object.create(null); each(fields, (field) => { if (field.fieldName === undefined) { // undefined fieldName is used for a document count request. @@ -584,7 +584,7 @@ export class DataVisualizer { { maxRetries: 0 } ); - const buckets: { [key: string]: number } = {}; + const buckets: { [key: string]: number } = Object.create(null); const dataByTimeBucket: Array<{ key: string; doc_count: number }> = get( body, ['aggregations', 'eventRate', 'buckets'], @@ -628,7 +628,7 @@ export class DataVisualizer { () => (count += PERCENTILE_SPACING) ); - const aggs: { [key: string]: any } = {}; + const aggs: { [key: string]: any } = Object.create(null); fields.forEach((field, i) => { const safeFieldName = getSafeAggregationName(field.fieldName, i); aggs[`${safeFieldName}_field_stats`] = { @@ -757,7 +757,7 @@ export class DataVisualizer { const size = 0; const filterCriteria = buildBaseFilterCriteria(timeFieldName, earliestMs, latestMs, query); - const aggs: Aggs = {}; + const aggs: Aggs = Object.create(null); fields.forEach((field, i) => { const safeFieldName = getSafeAggregationName(field.fieldName, i); const top = { @@ -839,7 +839,7 @@ export class DataVisualizer { const size = 0; const filterCriteria = buildBaseFilterCriteria(timeFieldName, earliestMs, latestMs, query); - const aggs: Aggs = {}; + const aggs: Aggs = Object.create(null); fields.forEach((field, i) => { const safeFieldName = getSafeAggregationName(field.fieldName, i); aggs[`${safeFieldName}_field_stats`] = { @@ -910,7 +910,7 @@ export class DataVisualizer { const size = 0; const filterCriteria = buildBaseFilterCriteria(timeFieldName, earliestMs, latestMs, query); - const aggs: Aggs = {}; + const aggs: Aggs = Object.create(null); fields.forEach((field, i) => { const safeFieldName = getSafeAggregationName(field.fieldName, i); aggs[`${safeFieldName}_value_count`] = { diff --git a/x-pack/plugins/ml/server/models/fields_service/fields_service.ts b/x-pack/plugins/ml/server/models/fields_service/fields_service.ts index cba34e2cbb8e..a7e1812888c2 100644 --- a/x-pack/plugins/ml/server/models/fields_service/fields_service.ts +++ b/x-pack/plugins/ml/server/models/fields_service/fields_service.ts @@ -146,7 +146,7 @@ export function fieldsServiceProvider({ asCurrentUser }: IScopedClusterClient) { mustCriteria.push(query); } - const runtimeMappings: any = {}; + const runtimeMappings: any = Object.create(null); const aggs = fieldsToAgg.reduce( (obj, field) => { if ( diff --git a/x-pack/plugins/ml/server/models/filter/filter_manager.ts b/x-pack/plugins/ml/server/models/filter/filter_manager.ts index 84f5ae9d7e5a..3aed4b80a792 100644 --- a/x-pack/plugins/ml/server/models/filter/filter_manager.ts +++ b/x-pack/plugins/ml/server/models/filter/filter_manager.ts @@ -77,7 +77,7 @@ export class FilterManager { ]); // Build a map of filter_ids against jobs and detectors using that filter. - let filtersInUse: FiltersInUse = {}; + let filtersInUse: FiltersInUse = Object.create(null); if (results[JOBS] && (results[JOBS] as estypes.MlGetJobsResponse).jobs) { filtersInUse = this.buildFiltersInUse((results[JOBS] as estypes.MlGetJobsResponse).jobs); } @@ -136,7 +136,7 @@ export class FilterManager { buildFiltersInUse(jobsList: Job[]) { // Build a map of filter_ids against jobs and detectors using that filter. - const filtersInUse: FiltersInUse = {}; + const filtersInUse: FiltersInUse = Object.create(null); jobsList.forEach((job) => { const detectors = job.analysis_config.detectors; detectors.forEach((detector) => { diff --git a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts index 43125551e833..52f2f9b0cada 100644 --- a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts +++ b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts @@ -89,7 +89,7 @@ export function jobAuditMessagesProvider( gte = `now-${from}`; } - let timeFilter = {}; + let timeFilter = Object.create(null); if (from !== null) { timeFilter = { range: { diff --git a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts index 50400054a4e0..5c2c44c326c8 100644 --- a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts +++ b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts @@ -41,7 +41,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie return acc; }, {} as { [id: string]: boolean }); - const results: Results = {}; + const results: Results = Object.create(null); async function doStart(datafeedId: string): Promise<{ started: boolean; error?: string }> { if (doStartsCalled[datafeedId] === false) { @@ -114,7 +114,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie } async function stopDatafeeds(datafeedIds: string[]) { - const results: Results = {}; + const results: Results = Object.create(null); for (const datafeedId of datafeedIds) { try { diff --git a/x-pack/plugins/ml/server/models/job_service/groups.ts b/x-pack/plugins/ml/server/models/job_service/groups.ts index cdb5d373393b..06641fff9795 100644 --- a/x-pack/plugins/ml/server/models/job_service/groups.ts +++ b/x-pack/plugins/ml/server/models/job_service/groups.ts @@ -22,8 +22,8 @@ export function groupsProvider(mlClient: MlClient) { const calMngr = new CalendarManager(mlClient); async function getAllGroups() { - const groups: { [id: string]: Group } = {}; - const jobIds: { [id: string]: undefined | null } = {}; + const groups: { [id: string]: Group } = Object.create(null); + const jobIds: { [id: string]: undefined | null } = Object.create(null); const [body, calendars] = await Promise.all([mlClient.getJobs(), calMngr.getAllCalendars()]); const { jobs } = body; @@ -70,7 +70,7 @@ export function groupsProvider(mlClient: MlClient) { } async function updateGroups(jobs: UpdateGroupsRequest['jobs']) { - const results: Results = {}; + const results: Results = Object.create(null); for (const job of jobs) { const { jobId, groups } = job; try { diff --git a/x-pack/plugins/ml/server/models/job_service/jobs.ts b/x-pack/plugins/ml/server/models/job_service/jobs.ts index d9cebc84bb74..7e29fe896615 100644 --- a/x-pack/plugins/ml/server/models/job_service/jobs.ts +++ b/x-pack/plugins/ml/server/models/job_service/jobs.ts @@ -89,7 +89,7 @@ export function jobsProvider( deleteUserAnnotations = false, deleteAlertingRules = false ) { - const results: Results = {}; + const results: Results = Object.create(null); const datafeedIds = await getDatafeedIdsByJobId(); if (deleteAlertingRules && rulesClient) { @@ -149,7 +149,7 @@ export function jobsProvider( } async function closeJobs(jobIds: string[]) { - const results: Results = {}; + const results: Results = Object.create(null); for (const jobId of jobIds) { try { await mlClient.closeJob({ job_id: jobId }); @@ -185,7 +185,7 @@ export function jobsProvider( } async function resetJobs(jobIds: string[], deleteUserAnnotations = false) { - const results: ResetJobsResponse = {}; + const results: ResetJobsResponse = Object.create(null); for (const jobId of jobIds) { try { // @ts-expect-error @elastic-elasticsearch resetJob response incorrect, missing task @@ -229,7 +229,7 @@ export function jobsProvider( async function jobsSummary(jobIds: string[] = []) { const fullJobsList: CombinedJobWithStats[] = await createFullJobsList(); const fullJobsIds = fullJobsList.map((job) => job.job_id); - let auditMessagesByJob: { [id: string]: AuditMessage } = {}; + let auditMessagesByJob: { [id: string]: AuditMessage } = Object.create(null); // even if there are errors getting the audit messages, we still want to show the full list try { @@ -309,12 +309,12 @@ export function jobsProvider( async function jobsWithTimerange() { const fullJobsList = await createFullJobsList(); - const jobsMap: { [id: string]: string[] } = {}; + const jobsMap: { [id: string]: string[] } = Object.create(null); const jobs = fullJobsList.map((job) => { jobsMap[job.job_id] = job.groups || []; const hasDatafeed = isPopulatedObject(job.datafeed_config); - const timeRange: { to?: number; from?: number } = {}; + const timeRange: { to?: number; from?: number } = Object.create(null); const dataCounts = job.data_counts; if (dataCounts !== undefined) { @@ -378,9 +378,9 @@ export function jobsProvider( async function createFullJobsList(jobIds: string[] = []) { const jobs: CombinedJobWithStats[] = []; - const groups: { [jobId: string]: string[] } = {}; - const datafeeds: { [id: string]: DatafeedWithStats } = {}; - const calendarsByJobId: { [jobId: string]: string[] } = {}; + const groups: { [jobId: string]: string[] } = Object.create(null); + const datafeeds: { [id: string]: DatafeedWithStats } = Object.create(null); + const calendarsByJobId: { [jobId: string]: string[] } = Object.create(null); const globalCalendars: string[] = []; const jobIdsString = jobIds.join(); @@ -583,7 +583,7 @@ export function jobsProvider( jobIds: string[] = [], allSpaces: boolean = false ): Promise { - const results: JobsExistResponse = {}; + const results: JobsExistResponse = Object.create(null); for (const jobId of jobIds) { try { if (jobId === '') { @@ -669,7 +669,7 @@ export function jobsProvider( jobs: Array<{ job: Job; datafeed: Datafeed }>, authHeader: AuthorizationHeader ) { - const results: BulkCreateResults = {}; + const results: BulkCreateResults = Object.create(null); await Promise.all( jobs.map(async ({ job, datafeed }) => { results[job.job_id] = { job: { success: false }, datafeed: { success: false } }; diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts index 6a439a3711c6..d95808bef1bc 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts @@ -69,7 +69,7 @@ export function newJobLineChartProvider({ asCurrentUser }: IScopedClusterClient) function processSearchResults(resp: any, fields: string[]): ProcessedResults { const aggregationsByTime = get(resp, ['aggregations', 'times', 'buckets'], []); - const tempResults: Record = {}; + const tempResults: Record = Object.create(null); fields.forEach((f, i) => (tempResults[i] = [])); aggregationsByTime.forEach((dataForTime: any) => { @@ -166,7 +166,10 @@ function getSearchJsonFromConfig( json.body.query = query; - const aggs: Record> = {}; + const aggs: Record< + number, + Record + > = Object.create(null); aggFieldNamePairs.forEach(({ agg, field }, i) => { if (field !== null && field !== EVENT_RATE_FIELD_ID) { diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts index 03daf69a3813..de450ea697ea 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts @@ -75,7 +75,7 @@ export function newJobPopulationChartProvider({ asCurrentUser }: IScopedClusterC function processSearchResults(resp: any, fields: string[]): ProcessedResults { const aggregationsByTime = get(resp, ['aggregations', 'times', 'buckets'], []); - const tempResults: Record = {}; + const tempResults: Record = Object.create(null); fields.forEach((f, i) => (tempResults[i] = [])); aggregationsByTime.forEach((dataForTime: any) => { @@ -188,7 +188,7 @@ function getPopulationSearchJsonFromConfig( json.body.query = query; - const aggs: any = {}; + const aggs: any = Object.create(null); aggFieldNamePairs.forEach(({ agg, field, by }, i) => { if (field === EVENT_RATE_FIELD_ID) { diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts index 6cfd84740385..74065222a529 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts @@ -125,7 +125,7 @@ class FieldsService { // the _indexPattern will be replaced with a comma separated list // of index patterns from all of the rollup jobs public async getData(includeNested: boolean = false): Promise { - let rollupFields: RollupFields = {}; + let rollupFields: RollupFields = Object.create(null); if (this._isRollup) { const rollupService = await rollupServiceProvider( @@ -159,7 +159,7 @@ class FieldsService { function combineAllRollupFields( rollupConfigs: estypes.RollupGetRollupCapsRollupCapabilitySummary[] ): RollupFields { - const rollupFields: RollupFields = {}; + const rollupFields: RollupFields = Object.create(null); rollupConfigs.forEach((conf) => { Object.keys(conf.fields).forEach((fieldName) => { if (rollupFields[fieldName] === undefined) { diff --git a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts index f31f708100d4..98fb5ce52e24 100644 --- a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts @@ -23,7 +23,7 @@ callAs.search.mockResponse({ hits: { total: { value: 1, relation: ES_CLIENT_TOTAL_HITS_RELATION.EQ } }, }); -const authHeader: AuthorizationHeader = {}; +const authHeader: AuthorizationHeader = Object.create(null); const mlClusterClient = { asCurrentUser: callAs, diff --git a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts index 8b6f1d1fa049..8d14417a1d38 100644 --- a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts +++ b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts @@ -227,7 +227,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu esSearchRequest.query!.bool!.minimum_should_match = shouldCriteria.length / 2; } - esSearchRequest.aggs!.byTime.aggs = {}; + esSearchRequest.aggs!.byTime.aggs = Object.create(null); if (metricFieldName !== undefined && metricFieldName !== '' && metricFunction) { const metricAgg: any = { @@ -258,7 +258,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu } esSearchRequest.aggs!.byTime.aggs = tempAggs; } else { - esSearchRequest.aggs!.byTime.aggs.metric = metricAgg; + esSearchRequest.aggs!.byTime.aggs!.metric = metricAgg; } } else { // if metricFieldName is not defined, it's probably a variation of the non zero count function @@ -465,9 +465,9 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu return { records: [], errors: undefined }; } // Aggregate by job, detector, and analysis fields (partition, by, over). - const aggregatedData: Record = {}; + const aggregatedData: Record = Object.create(null); - const jobsErrorMessage: Record = {}; + const jobsErrorMessage: Record = Object.create(null); each(anomalyRecords, (record) => { // Check if we can plot a chart for this record, depending on whether the source data // is chartable, and if model plot is enabled for the job. @@ -516,13 +516,13 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu } const jobId = record.job_id; if (aggregatedData[jobId] === undefined) { - aggregatedData[jobId] = {}; + aggregatedData[jobId] = Object.create(null); } const detectorsForJob = aggregatedData[jobId]; const detectorIndex = record.detector_index; if (detectorsForJob[detectorIndex] === undefined) { - detectorsForJob[detectorIndex] = {}; + detectorsForJob[detectorIndex] = Object.create(null); } // TODO - work out how best to display results from detectors with just an over field. @@ -534,11 +534,11 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu const groupsForDetector = detectorsForJob[detectorIndex]; if (groupsForDetector[firstFieldName] === undefined) { - groupsForDetector[firstFieldName] = {}; + groupsForDetector[firstFieldName] = Object.create(null); } const valuesForGroup: Record = groupsForDetector[firstFieldName]; if (valuesForGroup[firstFieldValue] === undefined) { - valuesForGroup[firstFieldValue] = {}; + valuesForGroup[firstFieldValue] = Object.create(null); } const dataForGroupValue = valuesForGroup[firstFieldValue]; @@ -568,12 +568,12 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu if (secondFieldName !== undefined && secondFieldValue !== undefined) { if (dataForGroupValue[secondFieldName] === undefined) { - dataForGroupValue[secondFieldName] = {}; + dataForGroupValue[secondFieldName] = Object.create(null); } const splitsForGroup = dataForGroupValue[secondFieldName]; if (splitsForGroup[secondFieldValue] === undefined) { - splitsForGroup[secondFieldValue] = {}; + splitsForGroup[secondFieldValue] = Object.create(null); } const dataForSplitValue = splitsForGroup[secondFieldValue]; @@ -604,7 +604,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu }); // Group job id by error message instead of by job: - const errorMessages: Record> | undefined = {}; + const errorMessages: Record> = Object.create(null); Object.keys(jobsErrorMessage).forEach((jobId) => { const msg = jobsErrorMessage[jobId]; if (errorMessages[msg] === undefined) { @@ -907,13 +907,13 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu handleError = (errorMsg: string, jobId: string) => { // Group the jobIds by the type of error message if (!errorMessages) { - errorMessages = {}; + errorMessages = Object.create(null); } - if (errorMessages[errorMsg]) { - errorMessages[errorMsg].add(jobId); + if (errorMessages![errorMsg]) { + errorMessages![errorMsg].add(jobId); } else { - errorMessages[errorMsg] = new Set([jobId]); + errorMessages![errorMsg] = new Set([jobId]); } }; } @@ -1408,7 +1408,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu const dataByJobId = get(resp, ['aggregations', 'jobs', 'buckets'], []); each(dataByJobId, (dataForJob: any) => { const jobId: string = dataForJob.key; - const resultsForTime: Record = {}; + const resultsForTime: Record = Object.create(null); const dataByTime = get(dataForJob, ['times', 'buckets'], []); each(dataByTime, (dataForTime: any) => { const time: string = dataForTime.key; @@ -1543,7 +1543,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu typeof metricFunction === 'string' ) { // @ts-ignore - body.aggs.sample.aggs.byTime.aggs.entities.aggs = {}; + body.aggs.sample.aggs.byTime.aggs.entities.aggs = Object.create(null); const metricAgg = { [metricFunction]: { diff --git a/x-pack/plugins/ml/server/models/results_service/results_service.ts b/x-pack/plugins/ml/server/models/results_service/results_service.ts index 0a732cf45a94..bbf9c4def472 100644 --- a/x-pack/plugins/ml/server/models/results_service/results_service.ts +++ b/x-pack/plugins/ml/server/models/results_service/results_service.ts @@ -54,7 +54,7 @@ interface Influencer { * @param source */ export function getTypicalAndActualValues(source: MlAnomalyRecordDoc) { - const result: { actual?: number[]; typical?: number[] } = {}; + const result: { actual?: number[]; typical?: number[] } = Object.create(null); const functionDescription = source.function_description || ''; const causes = source.causes || []; @@ -254,9 +254,9 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust (item: any) => item.entityName === 'mlcategory' ); if (categoryAnomalies.length > 0) { - tableData.examplesByJobId = {}; + tableData.examplesByJobId = Object.create(null); - const categoryIdsByJobId: { [key: string]: any } = {}; + const categoryIdsByJobId: { [key: string]: any } = Object.create(null); categoryAnomalies.forEach((anomaly) => { if (categoryIdsByJobId[anomaly.jobId] === undefined) { categoryIdsByJobId[anomaly.jobId] = []; @@ -420,7 +420,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust ['aggregations', 'byJobId', 'buckets'], [] ); - const timestampByJobId: { [key: string]: number | undefined } = {}; + const timestampByJobId: { [key: string]: number | undefined } = Object.create(null); bucketsByJobId.forEach((bucket) => { timestampByJobId[bucket.key] = bucket.maxTimestamp.value; }); @@ -446,7 +446,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust [jobId] ); - const examplesByCategoryId: { [key: string]: any } = {}; + const examplesByCategoryId: { [key: string]: any } = Object.create(null); // @ts-expect-error incorrect search response type if (body.hits.total.value > 0) { body.hits.hits.forEach((hit: any) => { diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index e408c2a719fb..0229f9e9bba5 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -668,7 +668,7 @@ export function dataFrameAnalyticsRoutes( routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response }) => { try { const { analyticsIds, allSpaces } = request.body; - const results: { [id: string]: { exists: boolean } } = {}; + const results: { [id: string]: { exists: boolean } } = Object.create(null); for (const id of analyticsIds) { try { const body = allSpaces diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index 2f3e402e05be..b0197c19aa5f 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -617,7 +617,8 @@ export function trainedModelsRoutes( try { const { deploymentId, modelId } = request.params; - const results: Record = {}; + const results: Record = + Object.create(null); for (const id of deploymentId.split(',')) { try { diff --git a/x-pack/plugins/ml/server/saved_objects/checks.ts b/x-pack/plugins/ml/server/saved_objects/checks.ts index 1985115d6ebf..f8e1827c78a8 100644 --- a/x-pack/plugins/ml/server/saved_objects/checks.ts +++ b/x-pack/plugins/ml/server/saved_objects/checks.ts @@ -404,7 +404,7 @@ export function checksFactory( .reduce((acc, cur) => { const type = cur.type; if (acc[type] === undefined) { - acc[type] = {}; + acc[type] = Object.create(null); } acc[type][cur.jobId] = cur.namespaces; return acc; diff --git a/x-pack/plugins/ml/server/saved_objects/service.ts b/x-pack/plugins/ml/server/saved_objects/service.ts index eed08b2a74d6..e6c32f2bc653 100644 --- a/x-pack/plugins/ml/server/saved_objects/service.ts +++ b/x-pack/plugins/ml/server/saved_objects/service.ts @@ -75,7 +75,7 @@ export function mlSavedObjectServiceFactory( currentSpaceOnly: boolean = true ) { await isMlReady(); - const filterObject: JobObjectFilter = {}; + const filterObject: JobObjectFilter = Object.create(null); if (jobType !== undefined) { filterObject.type = jobType; @@ -225,7 +225,7 @@ export function mlSavedObjectServiceFactory( async function getAllJobObjectsForAllSpaces(jobType?: JobType, jobId?: string) { await isMlReady(); - const filterObject: JobObjectFilter = {}; + const filterObject: JobObjectFilter = Object.create(null); if (jobType !== undefined) { filterObject.type = jobType; @@ -359,7 +359,7 @@ export function mlSavedObjectServiceFactory( return {}; } - const results: SavedObjectResult = {}; + const results: SavedObjectResult = Object.create(null); const jobs = await _getJobObjects(jobType); const jobObjectIdMap = new Map(); const jobObjectsToUpdate: Array<{ type: string; id: string }> = []; @@ -463,7 +463,7 @@ export function mlSavedObjectServiceFactory( async function _getTrainedModelObjects(modelId?: string, currentSpaceOnly: boolean = true) { await isMlReady(); - const filterObject: TrainedModelObjectFilter = {}; + const filterObject: TrainedModelObjectFilter = Object.create(null); if (modelId !== undefined) { filterObject.model_id = modelId; @@ -725,7 +725,7 @@ export function mlSavedObjectServiceFactory( if (modelIds.length === 0 || (spacesToAdd.length === 0 && spacesToRemove.length === 0)) { return {}; } - const results: SavedObjectResult = {}; + const results: SavedObjectResult = Object.create(null); const models = await _getTrainedModelObjects(); const trainedModelObjectIdMap = new Map(); const objectsToUpdate: Array<{ type: string; id: string }> = []; diff --git a/x-pack/plugins/ml/server/saved_objects/sync.ts b/x-pack/plugins/ml/server/saved_objects/sync.ts index cb8713f03acd..f96233debf9a 100644 --- a/x-pack/plugins/ml/server/saved_objects/sync.ts +++ b/x-pack/plugins/ml/server/saved_objects/sync.ts @@ -61,7 +61,7 @@ export function syncSavedObjectsFactory( if (job.checks.savedObjectExits === false) { const type = 'anomaly-detector'; if (results.savedObjectsCreated[type] === undefined) { - results.savedObjectsCreated[type] = {}; + results.savedObjectsCreated[type] = Object.create(null); } if (simulate === true) { results.savedObjectsCreated[type]![job.jobId] = { success: true }; @@ -88,7 +88,7 @@ export function syncSavedObjectsFactory( if (job.checks.savedObjectExits === false) { const type = 'data-frame-analytics'; if (results.savedObjectsCreated[type] === undefined) { - results.savedObjectsCreated[type] = {}; + results.savedObjectsCreated[type] = Object.create(null); } if (simulate === true) { results.savedObjectsCreated[type]![job.jobId] = { success: true }; @@ -119,7 +119,7 @@ export function syncSavedObjectsFactory( const { modelId } = model; const type = 'trained-model'; if (results.savedObjectsCreated[type] === undefined) { - results.savedObjectsCreated[type] = {}; + results.savedObjectsCreated[type] = Object.create(null); } if (simulate === true) { results.savedObjectsCreated[type]![modelId] = { success: true }; @@ -161,7 +161,7 @@ export function syncSavedObjectsFactory( if (job.checks.jobExists === false) { const type = 'anomaly-detector'; if (results.savedObjectsDeleted[type] === undefined) { - results.savedObjectsDeleted[type] = {}; + results.savedObjectsDeleted[type] = Object.create(null); } if (simulate === true) { results.savedObjectsDeleted[type]![job.jobId] = { success: true }; @@ -191,7 +191,7 @@ export function syncSavedObjectsFactory( if (job.checks.jobExists === false) { const type = 'data-frame-analytics'; if (results.savedObjectsDeleted[type] === undefined) { - results.savedObjectsDeleted[type] = {}; + results.savedObjectsDeleted[type] = Object.create(null); } if (simulate === true) { results.savedObjectsDeleted[type]![job.jobId] = { success: true }; @@ -225,7 +225,7 @@ export function syncSavedObjectsFactory( const { modelId, namespaces } = model; const type = 'trained-model'; if (results.savedObjectsDeleted[type] === undefined) { - results.savedObjectsDeleted[type] = {}; + results.savedObjectsDeleted[type] = Object.create(null); } if (simulate === true) { @@ -265,7 +265,7 @@ export function syncSavedObjectsFactory( adJobsById[job.jobId].datafeedId !== job.datafeedId) ) { if (results.datafeedsAdded[type] === undefined) { - results.datafeedsAdded[type] = {}; + results.datafeedsAdded[type] = Object.create(null); } // add datafeed id for jobs where the datafeed exists but the id is missing from the saved object // or if the datafeed id in the saved object is not the same as the one attached to the job in es @@ -298,7 +298,7 @@ export function syncSavedObjectsFactory( job.datafeedId !== undefined ) { if (results.datafeedsRemoved[type] === undefined) { - results.datafeedsRemoved[type] = {}; + results.datafeedsRemoved[type] = Object.create(null); } // remove datafeed id for jobs where the datafeed no longer exists but the id is populated in the saved object if (simulate === true) { diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_table.ts b/x-pack/plugins/monitoring/public/application/hooks/use_table.ts index af1a71f95aa2..11f76bb577b1 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_table.ts +++ b/x-pack/plugins/monitoring/public/application/hooks/use_table.ts @@ -72,7 +72,7 @@ export function useTable(storageKey: string) { ); const updateTotalItemCount = useCallback( - (num) => { + (num: any) => { // only update pagination state if different if (num === pagination.totalItemCount) return; setPagination({ diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx index 206b43cad457..b89bb112e56f 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx @@ -145,7 +145,7 @@ export const LogStashPipelinePage: React.FC = ({ clusters }) => }, [detailVertexId, getPageData]); const onChangePipelineHash = useCallback( - (hash) => { + (hash: any) => { window.location.hash = getSafeForExternalLink(`#/logstash/pipelines/${pipelineId}/${hash}`); }, [pipelineId] diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx index e606c5c2e163..a5d0df3b0553 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx @@ -71,7 +71,7 @@ export function AlertsOverview() { }, [serviceName, environment]); const onKueryChange = useCallback( - (value) => push(history, { query: { kuery: value } }), + (value: any) => push(history, { query: { kuery: value } }), [history] ); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/correlations_table.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/correlations_table.tsx index 670521bb6086..ea79b1ef198b 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/correlations_table.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/correlations_table.tsx @@ -69,7 +69,7 @@ export function CorrelationsTable({ }, [pageIndex, pageSize, significantTerms]); const onChange = useCallback( - (tableSettings) => { + (tableSettings: any) => { const { index, size } = tableSettings.page; setPageIndex(index); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/failed_transactions_correlations.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/failed_transactions_correlations.tsx index 9149be49e298..d02eed810acd 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/failed_transactions_correlations.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/failed_transactions_correlations.tsx @@ -331,7 +331,7 @@ export function FailedTransactionsCorrelations({ onFilter }: { onFilter: () => v useState('normalizedScore'); const [sortDirection, setSortDirection] = useState('desc'); - const onTableChange = useCallback(({ sort }) => { + const onTableChange = useCallback(({ sort }: any) => { const { field: currentSortField, direction: currentSortDirection } = sort; setSortField(currentSortField); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/latency_correlations.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/latency_correlations.tsx index 1183338b0f4b..8144dbd54841 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/correlations/latency_correlations.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/correlations/latency_correlations.tsx @@ -249,7 +249,7 @@ export function LatencyCorrelations({ onFilter }: { onFilter: () => void }) { const [sortField, setSortField] = useState('correlation'); const [sortDirection, setSortDirection] = useState('desc'); - const onTableChange = useCallback(({ sort }) => { + const onTableChange = useCallback(({ sort }: any) => { const { field: currentSortField, direction: currentSortDirection } = sort; setSortField(currentSortField); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/location_stats.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/location_stats.tsx index b59246cf27e1..47451fac265c 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/location_stats.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/location_stats.tsx @@ -88,7 +88,7 @@ export function MobileLocationStats({ const previousPeriod = locationStatsData?.previousPeriod; const getComparisonValueFormatter = useCallback( - ({ currentPeriodValue, previousPeriodValue }) => { + ({ currentPeriodValue, previousPeriodValue }: any) => { const comparisonDiffValue = calculateDiffPercentageAndFormat( currentPeriodValue, previousPeriodValue diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/stats.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/stats.tsx index f71da0cf8abd..59f6020d61c3 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/stats.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/mobile/service_overview/stats/stats.tsx @@ -49,7 +49,7 @@ export function MobileStats({ start, end, kuery }: { start: string; end: string; ); const getComparisonValueFormatter = useCallback( - (value) => { + (value: any) => { return ( {value && comparisonEnabled diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_dashboards/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_dashboards/index.tsx index db8a2c1bac8c..458a2e647cc2 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_dashboards/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_dashboards/index.tsx @@ -124,7 +124,7 @@ export function ServiceDashboards({ checkForEntities = false }: { checkForEntiti }, [dataView, serviceName, environment, kuery, dashboard, rangeFrom, rangeTo, currentDashboard]); const getLocatorParams = useCallback( - (params) => { + (params: any) => { return { serviceName, dashboardId: params.dashboardId, diff --git a/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/header/add_to_case_action.tsx b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/header/add_to_case_action.tsx index 8f91ee3c87cd..4a3693de8265 100644 --- a/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/header/add_to_case_action.tsx +++ b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/header/add_to_case_action.tsx @@ -45,7 +45,7 @@ export function AddToCaseAction({ } = kServices; const getToastText = useCallback( - (theCase) => + (theCase: any) => toMountPoint( { + (isLoading: any) => { const timeLoaded = Date.now(); setChartTimeRangeContext?.({ diff --git a/x-pack/plugins/observability_solution/exploratory_view/public/context/date_picker_context.tsx b/x-pack/plugins/observability_solution/exploratory_view/public/context/date_picker_context.tsx index 33d57611d139..598cb9f956f1 100644 --- a/x-pack/plugins/observability_solution/exploratory_view/public/context/date_picker_context.tsx +++ b/x-pack/plugins/observability_solution/exploratory_view/public/context/date_picker_context.tsx @@ -108,7 +108,7 @@ export function DatePickerContextProvider({ children }: { children: React.ReactE ); const updateRefreshInterval = useCallback( - ({ interval, isPaused }) => { + ({ interval, isPaused }: any) => { updateUrl({ refreshInterval: interval, refreshPaused: isPaused }); data.query.timefilter.timefilter.setRefreshInterval({ value: interval, pause: isPaused }); setLastUpdated(Date.now()); diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/expression.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/expression.tsx index f89cd7e77876..89579ac74a32 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/expression.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/expression.tsx @@ -128,7 +128,7 @@ export const Expressions: React.FC = (props) => { const { metricsView } = useMetricsDataViewContext(); const updateParams = useCallback( - (id, e: InventoryMetricConditions) => { + (id: any, e: InventoryMetricConditions) => { const exp = ruleParams.criteria ? ruleParams.criteria.slice() : []; exp[id] = e; setRuleParams('criteria', exp); @@ -492,7 +492,7 @@ export const ExpressionRow: FC> = (props) ); const updateThreshold = useCallback( - (t) => { + (t: any) => { if (t.join() !== expression.threshold.join()) { setRuleParams(expressionId, { ...expression, threshold: t }); } @@ -501,7 +501,7 @@ export const ExpressionRow: FC> = (props) ); const updateWarningThreshold = useCallback( - (t) => { + (t: any) => { if (t.join() !== expression.warningThreshold?.join()) { setRuleParams(expressionId, { ...expression, warningThreshold: t }); } diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx index 33f63fe6a49c..f821d7510b3b 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -218,7 +218,7 @@ const useCriteriaState = ( onUpdateCriteria: (criteria: PartialCountCriteriaType) => void ) => { const updateCriterion = useCallback( - (idx, criterionParams) => { + (idx: any, criterionParams: any) => { const nextCriteria = criteria.map((criterion, index) => { return idx === index ? { ...criterion, ...criterionParams } : criterion; }); @@ -233,7 +233,7 @@ const useCriteriaState = ( }, [criteria, defaultCriterion, onUpdateCriteria]); const removeCriterion = useCallback( - (idx) => { + (idx: any) => { const nextCriteria = criteria.filter((_criterion, index) => { return index !== idx; }); diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index a38eed49ee82..85935143da39 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -193,7 +193,7 @@ export const Editor: React.FC { + (thresholdParams: any) => { const nextThresholdParams = { ...ruleParams.count, ...thresholdParams }; setRuleParams('count', nextThresholdParams); }, diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression.tsx index 4855d71274e9..42eb0daa7806 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression.tsx @@ -81,7 +81,7 @@ export const Expressions: React.FC = (props) => { }, [metadata]); const updateParams = useCallback( - (id, e: MetricExpression) => { + (id: any, e: MetricExpression) => { const exp = ruleParams.criteria ? ruleParams.criteria.slice() : []; exp[id] = e; setRuleParams('criteria', exp); diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx index cca94d10e953..48371bebb256 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/expression_row.tsx @@ -118,13 +118,13 @@ export const ExpressionRow = ({ ); const convertThreshold = useCallback( - (enteredThreshold) => + (enteredThreshold: any) => isMetricPct ? enteredThreshold.map((v: number) => pctToDecimal(v)) : enteredThreshold, [isMetricPct] ); const updateThreshold = useCallback( - (enteredThreshold) => { + (enteredThreshold: any) => { const t = convertThreshold(enteredThreshold); if (t.join() !== expression.threshold.join()) { setRuleParams(expressionId, { ...expression, threshold: t }); @@ -134,7 +134,7 @@ export const ExpressionRow = ({ ); const updateWarningThreshold = useCallback( - (enteredThreshold) => { + (enteredThreshold: any) => { const t = convertThreshold(enteredThreshold); if (t.join() !== expression.warningThreshold?.join()) { setRuleParams(expressionId, { ...expression, warningThreshold: t }); @@ -165,7 +165,7 @@ export const ExpressionRow = ({ ]); const handleCustomMetricChange = useCallback( - (exp) => { + (exp: any) => { setRuleParams(expressionId, exp); }, [expressionId, setRuleParams] diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/actions/save_dashboard_modal.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/actions/save_dashboard_modal.tsx index cda931e81a3f..87ff45ef2173 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/actions/save_dashboard_modal.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/actions/save_dashboard_modal.tsx @@ -91,7 +91,7 @@ export function SaveDashboardModal({ () => setAssetNameFiltersEnabled(!assetNameEnabled), [assetNameEnabled] ); - const onSelect = useCallback((newSelection) => setSelectedDashboard(newSelection), []); + const onSelect = useCallback((newSelection: any) => setSelectedDashboard(newSelection), []); const onClickSave = useCallback( async function () { diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/dashboards.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/dashboards.tsx index 2c7aaeafa687..0178d478a85b 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/dashboards.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/dashboards/dashboards.tsx @@ -165,7 +165,7 @@ export function Dashboards() { ]); const getLocatorParams = useCallback( - (params, isFlyoutView) => { + (params: any, isFlyoutView: any) => { const searchParams = new URLSearchParams(location.search); const tableProperties = searchParams.get('tableProperties'); const flyoutParams = diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/table.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/table.tsx index 4d4d2e4c0558..fedf54a2d10a 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/table.tsx @@ -126,7 +126,7 @@ export const Table = ({ loading, rows, onSearchChange, search, showActionsColumn ); const searchBarOnChange = useCallback( - ({ queryText, error }) => { + ({ queryText, error }: any) => { if (error) { setSearchError(error); } else { diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes.tsx index d11aab9307ab..e7666a7f4191 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes.tsx @@ -110,7 +110,7 @@ export const Processes = () => { }, []); const searchBarOnChange = useCallback( - ({ query, queryText, error: queryError }) => { + ({ query, queryText, error: queryError }: any) => { if (queryError) { setSearchQueryError(queryError); } else { diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes_table.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes_table.tsx index 87d4d7d9b5aa..6d432910c20b 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes_table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/processes/processes_table.tsx @@ -66,7 +66,7 @@ function useSortableProperties( return { updateSortableProperties: useCallback( - (property) => { + (property: any) => { sortableProperties.sortOn(property); callback(omit(sortableProperties.getSortedProperty(), 'getValue')); }, diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/profiling/profiling.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/profiling/profiling.tsx index c31c79f02463..709d249616f2 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/profiling/profiling.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/profiling/profiling.tsx @@ -49,7 +49,7 @@ export function Profiling() { ); const onSearchSubmit = useCallback( - ({ dateRange: range, query }) => { + ({ dateRange: range, query }: any) => { setDateRange(range); setCustomKuery(query); }, diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx index 7550f81112c0..0751ad3b897f 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx @@ -19,7 +19,7 @@ export const AnalyzeInMlButton: React.FunctionComponent<{ } = useKibanaContextForPlugin(); const handleClick = useCallback( - (e) => { + (e: React.MouseEvent) => { if (!href || !shouldHandleLinkEvent(e)) return; application.navigateToUrl(href); }, diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_datepicker.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_datepicker.tsx index db2f90fc52df..097f2fbf755d 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_datepicker.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_datepicker.tsx @@ -6,7 +6,13 @@ */ import React, { useCallback } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker, EuiButton } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiSuperDatePicker, + EuiButton, + OnTimeChangeProps, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; interface LogDatepickerProps { @@ -27,7 +33,7 @@ export const LogDatepicker: React.FC = ({ onStopStreaming, }) => { const handleTimeChange = useCallback( - ({ start, end, isInvalid }) => { + ({ start, end, isInvalid }: OnTimeChangeProps) => { if (onUpdateDateRange && !isInvalid) { onUpdateDateRange({ startDateExpression: start, endDateExpression: end }); } diff --git a/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx index 4e344808c04e..fca61d349ce3 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx @@ -357,7 +357,7 @@ export const AnomaliesTable = ({ setSearch(e.target.value); }, []); - const changeJobType = useCallback((selectedOptions) => { + const changeJobType = useCallback((selectedOptions: any) => { setSelectedJobType(selectedOptions); setJobType(selectedOptions[0].id); }, []); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/analyze_dataset_in_ml_action.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/analyze_dataset_in_ml_action.tsx index a0ee944e5efb..088f54a14997 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/analyze_dataset_in_ml_action.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/analyze_dataset_in_ml_action.tsx @@ -47,7 +47,7 @@ export const AnalyzeCategoryDatasetInMlAction: React.FunctionComponent<{ ); const handleClick = useCallback( - (e) => { + (e: React.MouseEvent) => { if (!viewAnomalyInMachineLearningLink || !shouldHandleLinkEvent(e)) return; application.navigateToUrl(viewAnomalyInMachineLearningLink); }, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx index f119a08cbd10..784867239131 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui'; +import { Criteria, EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; import React, { useMemo, useCallback } from 'react'; @@ -14,6 +14,7 @@ import useSet from 'react-use/lib/useSet'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { + categoriesSortRT, LogEntryCategory, LogEntryCategoryDataset, LogEntryCategoryHistogram, @@ -51,8 +52,10 @@ export const TopCategoriesTable = euiStyled( }, [sortOptions]); const handleTableChange = useCallback( - ({ sort = {} }) => { - changeSortOptions(sort); + ({ sort }: Criteria) => { + if (categoriesSortRT.is(sort)) { + changeSortOptions(sort); + } }, [changeSortOptions] ); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx index ad5601846f33..6c545beb4b9c 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx @@ -139,7 +139,7 @@ export const LogEntryExampleMessage: React.FunctionComponent = ({ }); const handleMlLinkClick = useCallback( - (e) => { + (e: React.MouseEvent) => { if (!viewAnomalyInMachineLearningLink || !shouldHandleLinkEvent(e)) return; application.navigateToUrl(viewAnomalyInMachineLearningLink); }, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/table.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/table.tsx index e3f7767662a0..a0c8eb762e9f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/sections/anomalies/table.tsx @@ -6,42 +6,44 @@ */ import { + Criteria, EuiBasicTable, EuiBasicTableColumn, - EuiIcon, + EuiButtonIcon, EuiFlexGroup, EuiFlexItem, - EuiButtonIcon, + EuiIcon, EuiSpacer, RIGHT_ALIGNMENT, } from '@elastic/eui'; -import moment from 'moment'; import { i18n } from '@kbn/i18n'; +import moment from 'moment'; import React, { useCallback, useMemo } from 'react'; import useSet from 'react-use/lib/useSet'; -import { TimeRange } from '../../../../../../common/time/time_range'; import { + anomaliesSortRT, AnomalyType, - getFriendlyNameForPartitionId, formatOneDecimalPlace, + getFriendlyNameForPartitionId, isCategoryAnomaly, } from '../../../../../../common/log_analysis'; +import { TimeRange } from '../../../../../../common/time/time_range'; import { RowExpansionButton } from '../../../../../components/basic_table'; -import { AnomaliesTableExpandedRow } from './expanded_row'; +import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper'; import { AnomalySeverityIndicator } from '../../../../../components/logging/log_analysis_results/anomaly_severity_indicator'; import { RegularExpressionRepresentation } from '../../../../../components/logging/log_analysis_results/category_expression'; import { useKibanaUiSetting } from '../../../../../hooks/use_kibana_ui_setting'; import { - Page, + ChangePaginationOptions, + ChangeSortOptions, FetchNextPage, FetchPreviousPage, - ChangeSortOptions, - ChangePaginationOptions, - SortOptions, - PaginationOptions, LogEntryAnomalies, + Page, + PaginationOptions, + SortOptions, } from '../../use_log_entry_anomalies_results'; -import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper'; +import { AnomaliesTableExpandedRow } from './expanded_row'; interface TableItem { id: string; @@ -146,8 +148,10 @@ export const AnomaliesTable: React.FunctionComponent<{ ); const handleTableChange = useCallback( - ({ sort = {} }) => { - changeSortOptions(sort); + ({ sort }: Criteria) => { + if (anomaliesSortRT.is(sort)) { + changeSortOptions(sort); + } }, [changeSortOptions] ); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/log_columns_configuration_panel.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/log_columns_configuration_panel.tsx index 97fd485fac24..931219dc0bce 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/log_columns_configuration_panel.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/log_columns_configuration_panel.tsx @@ -57,7 +57,7 @@ export const LogColumnsConfigurationPanel = React.memo<{ ); const moveLogColumn = useCallback( - (sourceIndex, destinationIndex) => { + (sourceIndex: number, destinationIndex: number) => { logColumnsFormElement.updateValue((logColumns) => { if (destinationIndex >= 0 && sourceIndex <= logColumnsFormElement.value.length - 1) { const newLogColumns = [...logColumnsFormElement.value]; @@ -189,6 +189,8 @@ const TimestampLogColumnConfigurationPanel: React.FunctionComponent< id="xpack.infra.sourceConfiguration.timestampLogColumnDescription" defaultMessage="This system field shows the log entry's time as determined by the {timestampSetting} field setting." values={{ + // this is a settings key and should not be translated + // eslint-disable-next-line @kbn/i18n/strings_should_be_translated_with_i18n timestampSetting: timestamp, }} /> diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_logs_content.tsx index 7184b0c9ecf3..d40014ed4468 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page_logs_content.tsx @@ -13,10 +13,12 @@ import { LogEntryFlyout, LogEntryStreamItem, ScrollableLogTextStreamView, + UpdatedDateRange, useLogHighlightsStateContext, useLogPositionStateContext, useLogStreamContext, useLogViewContext, + VisibleInterval, WithSummary, WithSummaryProps, } from '@kbn/logs-shared-plugin/public'; @@ -173,11 +175,11 @@ export const StreamPageLogsContent = React.memo<{ const [, { setContextEntry }] = useViewLogInProviderContext(); const handleDateRangeExtension = useCallback( - (newDateRange) => { + (newDateRange: UpdatedDateRange) => { updateDateRange(newDateRange); if ( - 'startDateExpression' in newDateRange && + newDateRange.startDateExpression != null && isValidDatemath(newDateRange.startDateExpression) ) { fetchPreviousEntries({ @@ -185,7 +187,10 @@ export const StreamPageLogsContent = React.memo<{ extendTo: datemathToEpochMillis(newDateRange.startDateExpression)!, }); } - if ('endDateExpression' in newDateRange && isValidDatemath(newDateRange.endDateExpression)) { + if ( + newDateRange.endDateExpression != null && + isValidDatemath(newDateRange.endDateExpression) + ) { fetchNextEntries({ force: true, extendTo: datemathToEpochMillis(newDateRange.endDateExpression)!, @@ -196,7 +201,7 @@ export const StreamPageLogsContent = React.memo<{ ); const handlePagination = useCallback( - (params) => { + (params: VisibleInterval) => { reportVisiblePositions(params); if (!params.fromScroll) { return; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx index 92c57e945991..7b81056b32b8 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx @@ -27,6 +27,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import React, { SyntheticEvent, useState, useCallback, useEffect } from 'react'; import { first, last } from 'lodash'; +import { EuiRangeProps, EuiSelectProps } from '@elastic/eui'; import type { WaffleLegendOptions } from '../../hooks/use_waffle_options'; import { type InfraWaffleMapBounds, @@ -148,17 +149,17 @@ export const LegendControls = ({ setPopoverState(false); }, [autoBounds, boundsOverride, options]); - const handleStepsChange = useCallback( + const handleStepsChange = useCallback>( (e) => { - const steps = parseInt(e.target.value, 10); + const steps = parseInt((e.target as HTMLInputElement).value, 10); setLegendOptions((previous) => ({ ...previous, steps })); }, [setLegendOptions] ); - const handlePaletteChange = useCallback( + const handlePaletteChange = useCallback>( (e) => { - const palette = e.target.value; + const palette = e.target.value as WaffleLegendOptions['palette']; setLegendOptions((previous) => ({ ...previous, palette })); }, [setLegendOptions] diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx index 582c52a969ac..9a24e0b0cd0e 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/aggregation.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback } from 'react'; import { xor } from 'lodash'; +import { EuiSelectProps } from '@elastic/eui'; import { MetricsExplorerAggregation } from '../../../../../common/http_api/metrics_explorer'; import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; import { @@ -56,7 +57,7 @@ export const MetricsExplorerAggregationPicker = ({ options, onChange }: Props) = }), }; - const handleChange = useCallback( + const handleChange = useCallback>( (e) => { const aggregation = (metricsExplorerAggregationRT.is(e.target.value) && e.target.value) || 'avg'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx index abd82b4e74a9..01471fab526a 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/chart_options.tsx @@ -15,6 +15,7 @@ import { EuiForm, EuiFormRow, EuiSwitch, + EuiSwitchProps, } from '@elastic/eui'; import { MetricsExplorerChartOptions as ChartOptions, @@ -111,7 +112,7 @@ export const MetricsExplorerChartOptions = ({ chartOptions, onChange }: Props) = [chartOptions, onChange] ); - const handleStackChange = useCallback( + const handleStackChange = useCallback( (e) => { onChange({ ...chartOptions, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx index 4e2764d9222e..c493d2922359 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metrics_explorer/components/metrics.tsx @@ -60,7 +60,7 @@ export const MetricsExplorerMetrics = ({ options, onChange, autoFocus = false }: ); const handleChange = useCallback( - (selectedOptions) => { + (selectedOptions: any) => { onChange( selectedOptions.map((opt: SelectedOption, index: number) => ({ aggregation: options.aggregation, diff --git a/x-pack/plugins/observability_solution/investigate/common/index.ts b/x-pack/plugins/observability_solution/investigate/common/index.ts index 541e2d7206bf..47b5ad6ed231 100644 --- a/x-pack/plugins/observability_solution/investigate/common/index.ts +++ b/x-pack/plugins/observability_solution/investigate/common/index.ts @@ -4,11 +4,5 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -export type { - Investigation, - InvestigateWidget, - InvestigateWidgetCreate, - InvestigationNote, -} from './types'; export { mergePlainObjects } from './utils/merge_plain_objects'; diff --git a/x-pack/plugins/observability_solution/investigate/common/types.ts b/x-pack/plugins/observability_solution/investigate/common/types.ts index 8a2bba966ed7..55eab5836ce5 100644 --- a/x-pack/plugins/observability_solution/investigate/common/types.ts +++ b/x-pack/plugins/observability_solution/investigate/common/types.ts @@ -5,47 +5,9 @@ * 2.0. */ -import type { DeepPartial } from 'utility-types'; - export interface GlobalWidgetParameters { timeRange: { from: string; to: string; }; } - -export interface Investigation { - id: string; - createdAt: number; - title: string; - items: InvestigateWidget[]; - notes: InvestigationNote[]; - parameters: GlobalWidgetParameters; -} - -export interface InvestigationNote { - id: string; - createdAt: number; - createdBy: string; - content: string; -} - -export interface InvestigateWidget< - TParameters extends Record = {}, - TData extends Record = {} -> { - id: string; - createdAt: number; - createdBy: string; - title: string; - type: string; - parameters: GlobalWidgetParameters & TParameters; - data: TData; -} - -export type InvestigateWidgetCreate = {}> = Pick< - InvestigateWidget, - 'title' | 'type' -> & { - parameters: DeepPartial & TParameters; -}; diff --git a/x-pack/plugins/observability_solution/investigate/public/create_widget.ts b/x-pack/plugins/observability_solution/investigate/public/create_widget.ts deleted file mode 100644 index 697202ac42d2..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/create_widget.ts +++ /dev/null @@ -1,35 +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 { DeepPartial } from 'utility-types'; -import { InvestigateWidgetCreate } from '../common'; -import { GlobalWidgetParameters } from '../common/types'; - -type MakePartial, K extends keyof T> = Omit & - DeepPartial>; - -type PredefinedKeys = 'type'; - -export type WidgetFactory> = < - T extends MakePartial, PredefinedKeys> ->( - widgetCreate: T -) => Pick, PredefinedKeys> & - Omit & { parameters: T['parameters'] & DeepPartial }; - -export function createWidgetFactory>( - type: string -): WidgetFactory { - const createWidget: WidgetFactory = (widgetCreate) => { - return { - type, - ...widgetCreate, - }; - }; - - return createWidget; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/esql_widget/types.ts b/x-pack/plugins/observability_solution/investigate/public/esql_widget/types.ts deleted file mode 100644 index 764daedc9c5e..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/esql_widget/types.ts +++ /dev/null @@ -1,34 +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 type { IconType } from '@elastic/eui'; -import type { Ast } from '@kbn/interpreter'; - -// copied over from the Lens plugin to prevent dependency hell -type TableChangeType = 'initial' | 'unchanged' | 'reduced' | 'extended' | 'reorder' | 'layers'; - -interface Suggestion { - visualizationId: string; - datasourceState?: V; - datasourceId?: string; - columns: number; - score: number; - title: string; - visualizationState: T; - previewExpression?: Ast | string; - previewIcon: IconType; - hide?: boolean; - // flag to indicate if the visualization is incomplete - incomplete?: boolean; - changeType: TableChangeType; - keptLayerIds: string[]; -} - -export interface EsqlWidgetParameters { - esql: string; - suggestion?: Suggestion; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/create_new_investigation.ts b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/create_new_investigation.ts deleted file mode 100644 index af6227e55211..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/create_new_investigation.ts +++ /dev/null @@ -1,47 +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'; -import { GetInvestigationResponse } from '@kbn/investigation-shared'; -import { v4 } from 'uuid'; -import type { Investigation } from '../../../common'; - -export function createNewInvestigation(): Investigation { - return { - id: v4(), - createdAt: new Date().getTime(), - title: i18n.translate('xpack.investigate.newInvestigationTitle', { - defaultMessage: 'New investigation', - }), - items: [], - notes: [], - parameters: { - timeRange: { - from: new Date(Date.now() - 15 * 60 * 1000).toISOString(), - to: new Date().toISOString(), - }, - }, - }; -} - -export function fromInvestigationResponse( - investigationData: GetInvestigationResponse -): Investigation { - return { - id: investigationData.id, - createdAt: investigationData.createdAt, - title: investigationData.title, - items: [], - notes: investigationData.notes, - parameters: { - timeRange: { - from: new Date(investigationData.params.timeRange.from).toISOString(), - to: new Date(investigationData.params.timeRange.to).toISOString(), - }, - }, - }; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/index.tsx b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/index.tsx deleted file mode 100644 index fd3c50cdb80a..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/index.tsx +++ /dev/null @@ -1,166 +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 type { AuthenticatedUser, NotificationsStart } from '@kbn/core/public'; -import { i18n } from '@kbn/i18n'; -import { GetInvestigationResponse } from '@kbn/investigation-shared'; -import { pull } from 'lodash'; -import React, { useMemo, useRef, useState } from 'react'; -import useObservable from 'react-use/lib/useObservable'; -import { v4 } from 'uuid'; -import type { GlobalWidgetParameters } from '../..'; -import type { InvestigateWidget, InvestigateWidgetCreate } from '../../../common'; -import type { WidgetDefinition } from '../../types'; -import { createNewInvestigation, fromInvestigationResponse } from './create_new_investigation'; -import { StatefulInvestigation, createInvestigationStore } from './investigation_store'; - -export type RenderableInvestigateWidget = InvestigateWidget & { - loading: boolean; - element: React.ReactNode; -}; - -export type RenderableInvestigation = Omit & { - items: RenderableInvestigateWidget[]; -}; - -export interface UseInvestigationApi { - investigation?: StatefulInvestigation; - renderableInvestigation?: RenderableInvestigation; - copyItem: (id: string) => Promise; - deleteItem: (id: string) => Promise; - addItem: (options: InvestigateWidgetCreate) => Promise; - setGlobalParameters: (parameters: GlobalWidgetParameters) => Promise; - setTitle: (title: string) => Promise; -} - -function useInvestigationWithoutContext({ - user, - notifications, - widgetDefinitions, - investigationData, -}: { - user: AuthenticatedUser; - notifications: NotificationsStart; - widgetDefinitions: WidgetDefinition[]; - investigationData?: GetInvestigationResponse; -}): UseInvestigationApi { - const [investigationStore, _] = useState(() => - createInvestigationStore({ - user, - widgetDefinitions, - investigation: investigationData - ? fromInvestigationResponse(investigationData) - : createNewInvestigation(), - }) - ); - - const investigation$ = investigationStore.asObservable(); - const investigation = useObservable(investigation$)?.investigation; - - const addItem = async (widget: InvestigateWidgetCreate) => { - try { - const id = v4(); - await investigationStore.addItem(id, widget); - } catch (error) { - notifications.showErrorDialog({ - title: i18n.translate('xpack.investigate.failedToAddWidget', { - defaultMessage: 'Failed to add widget', - }), - error, - }); - } - }; - - const deleteItem = async (id: string) => { - return investigationStore.deleteItem(id); - }; - - const widgetComponentsById = useRef< - Record> - >({}); - - const itemsWithContext = useMemo(() => { - const unusedComponentIds = Object.keys(widgetComponentsById); - - const nextItemsWithContext = - investigation?.items.map((item) => { - let Component = widgetComponentsById.current[item.id]; - if (!Component) { - const id = item.id; - const widgetDefinition = widgetDefinitions.find( - (definition) => definition.type === item.type - )!; - - Component = widgetComponentsById.current[id] = (props) => { - return <>{widgetDefinition?.render({ widget: props.widget })}; - }; - } - - pull(unusedComponentIds, item.id); - - return { - ...item, - Component, - }; - }) ?? []; - - unusedComponentIds.forEach((id) => { - delete widgetComponentsById.current[id]; - }); - - return nextItemsWithContext; - }, [investigation?.items, widgetDefinitions]); - - const renderableInvestigation = useMemo(() => { - return investigation - ? { - ...investigation, - items: itemsWithContext.map((item) => { - const { Component, ...rest } = item; - return { - ...rest, - element: , - }; - }), - } - : undefined; - }, [investigation, itemsWithContext]); - - const { copyItem, setGlobalParameters, setTitle } = investigationStore; - - return { - addItem, - copyItem, - deleteItem, - investigation, - renderableInvestigation, - setGlobalParameters, - setTitle, - }; -} - -export function createUseInvestigation({ - notifications, - widgetDefinitions, -}: { - notifications: NotificationsStart; - widgetDefinitions: WidgetDefinition[]; -}) { - return ({ - user, - investigationData, - }: { - user: AuthenticatedUser; - investigationData?: GetInvestigationResponse; - }) => { - return useInvestigationWithoutContext({ - user, - notifications, - widgetDefinitions, - investigationData, - }); - }; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts deleted file mode 100644 index be2da347f995..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/investigation_store.ts +++ /dev/null @@ -1,152 +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 type { AuthenticatedUser } from '@kbn/security-plugin/common'; -import { MaybePromise } from '@kbn/utility-types'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { v4 } from 'uuid'; -import { InvestigateWidget } from '../../../common'; -import { - GlobalWidgetParameters, - InvestigateWidgetCreate, - Investigation, -} from '../../../common/types'; -import { WidgetDefinition } from '../../types'; -import { regenerateItem } from './regenerate_item'; - -export type StatefulInvestigateWidget = InvestigateWidget & { - loading: boolean; -}; - -export type StatefulInvestigation = Omit & { - items: StatefulInvestigateWidget[]; -}; - -interface InvestigationStore { - copyItem: (id: string) => Promise; - deleteItem: (id: string) => Promise; - addItem: (id: string, item: InvestigateWidgetCreate) => Promise; - asObservable: () => Observable<{ - investigation: StatefulInvestigation; - }>; - setGlobalParameters: (globalWidgetParameters: GlobalWidgetParameters) => Promise; - setTitle: (title: string) => Promise; - destroy: () => void; -} - -export function createInvestigationStore({ - investigation, - user, - widgetDefinitions, -}: { - investigation: Investigation; - user: AuthenticatedUser; - widgetDefinitions: WidgetDefinition[]; -}): InvestigationStore { - const controller = new AbortController(); - - const observable$ = new BehaviorSubject<{ investigation: StatefulInvestigation }>({ - investigation: { - ...investigation, - items: investigation.items.map((item) => ({ ...item, loading: false })), - }, - }); - - async function updateInvestigationInPlace( - cb: (prevInvestigation: StatefulInvestigation) => MaybePromise - ) { - observable$.next({ investigation: await cb(observable$.value.investigation) }); - } - - const asObservable = observable$.asObservable(); - - return { - addItem: (itemId, item) => { - return updateInvestigationInPlace(async (prevInvestigation) => { - return { - ...prevInvestigation, - items: prevInvestigation.items.concat({ - ...(await regenerateItem({ - user, - widgetDefinitions, - signal: controller.signal, - widget: { - ...item, - id: itemId, - }, - globalWidgetParameters: prevInvestigation.parameters, - })), - loading: false, - }), - }; - }); - }, - copyItem: (itemId) => { - return updateInvestigationInPlace((prevInvestigation) => { - const itemToCopy = prevInvestigation.items.find((item) => item.id === itemId); - if (!itemToCopy) { - throw new Error('Cannot find item for id ' + itemId); - } - return { - ...prevInvestigation, - items: prevInvestigation.items.concat({ - ...itemToCopy, - id: v4(), - }), - }; - }); - }, - deleteItem: (itemId) => { - return updateInvestigationInPlace((prevInvestigation) => { - return { - ...prevInvestigation, - items: prevInvestigation.items.filter((item) => item.id !== itemId), - }; - }); - }, - asObservable: () => asObservable, - destroy: () => { - return controller.abort(); - }, - setGlobalParameters: async (parameters) => { - await updateInvestigationInPlace((prevInvestigation) => { - return { - ...prevInvestigation, - items: prevInvestigation.items.map((item) => { - return { ...item, loading: true }; - }), - }; - }); - - await updateInvestigationInPlace(async (prevInvestigation) => { - return { - ...prevInvestigation, - parameters, - items: await Promise.all( - prevInvestigation.items.map(async (item) => { - return { - ...(await regenerateItem({ - widget: item, - globalWidgetParameters: parameters, - signal: controller.signal, - user, - widgetDefinitions, - })), - loading: false, - }; - }) - ), - }; - }); - }, - setTitle: async (title: string) => { - return updateInvestigationInPlace((prevInvestigation) => { - return { ...prevInvestigation, title }; - }); - }, - }; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/regenerate_item.ts b/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/regenerate_item.ts deleted file mode 100644 index 7f7d6208ed9e..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/hooks/use_investigation/regenerate_item.ts +++ /dev/null @@ -1,52 +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 { AuthenticatedUser } from '@kbn/core-security-common'; -import { v4 } from 'uuid'; -import { InvestigateWidget, InvestigateWidgetCreate, mergePlainObjects } from '../../../common'; -import { GlobalWidgetParameters } from '../../../common/types'; -import { WidgetDefinition } from '../../types'; - -export async function regenerateItem({ - user, - widgetDefinitions, - signal, - widget, - globalWidgetParameters, -}: { - user: AuthenticatedUser; - widgetDefinitions: WidgetDefinition[]; - widget: InvestigateWidgetCreate | InvestigateWidget; - signal: AbortSignal; - globalWidgetParameters: GlobalWidgetParameters; -}): Promise { - const now = Date.now(); - - const definition = widgetDefinitions.find( - (currentDefinition) => currentDefinition.type === widget.type - ); - - if (!definition) { - throw new Error(`Definition for widget ${widget.type} not found`); - } - - const nextParameters = mergePlainObjects(widget.parameters, globalWidgetParameters); - - const widgetData = await definition.generate({ - parameters: nextParameters, - signal, - }); - - return { - createdAt: now, - id: v4(), - ...widget, - parameters: nextParameters, - data: widgetData, - createdBy: user.username, - }; -} diff --git a/x-pack/plugins/observability_solution/investigate/public/index.ts b/x-pack/plugins/observability_solution/investigate/public/index.ts index 2f55a27ef1c2..07493d836055 100644 --- a/x-pack/plugins/observability_solution/investigate/public/index.ts +++ b/x-pack/plugins/observability_solution/investigate/public/index.ts @@ -13,27 +13,16 @@ import type { InvestigateSetupDependencies, InvestigateStartDependencies, ConfigSchema, - OnWidgetAdd, } from './types'; -export type { InvestigatePublicSetup, InvestigatePublicStart, OnWidgetAdd }; +export type { InvestigatePublicSetup, InvestigatePublicStart }; -export { - type Investigation, - type InvestigateWidget, - type InvestigateWidgetCreate, - type GlobalWidgetParameters, -} from '../common/types'; +export { type GlobalWidgetParameters } from '../common/types'; export { mergePlainObjects } from '../common/utils/merge_plain_objects'; -export { createWidgetFactory } from './create_widget'; export { getEsFilterFromGlobalParameters } from './util/get_es_filters_from_global_parameters'; -export { ESQL_WIDGET_NAME } from './esql_widget/constants'; -export { createEsqlWidget } from './esql_widget/create_esql_widget'; -export type { EsqlWidgetParameters } from './esql_widget/types'; - export const plugin: PluginInitializer< InvestigatePublicSetup, InvestigatePublicStart, diff --git a/x-pack/plugins/observability_solution/investigate/public/investigation/item_definition_registry.ts b/x-pack/plugins/observability_solution/investigate/public/investigation/item_definition_registry.ts new file mode 100644 index 000000000000..6fcb8308e716 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate/public/investigation/item_definition_registry.ts @@ -0,0 +1,45 @@ +/* + * 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 { GlobalWidgetParameters } from '../../common/types'; + +export type ItemDefinitionData = Record; +export type ItemDefinitionParams = Record; + +export interface ItemDefinition< + Params extends ItemDefinitionParams = {}, + Data extends ItemDefinitionData = {} +> { + type: string; + generate: (option: { itemParams: Params; globalParams: GlobalWidgetParameters }) => Promise; + render: (option: { + data: Data; + itemParams: Params; + globalParams: GlobalWidgetParameters; + }) => React.ReactNode; +} + +export class ItemDefinitionRegistry { + private readonly definitions: ItemDefinition[] = []; + + constructor() {} + + public registerItem( + definition: ItemDefinition + ) { + // @ts-ignore TODO fix this type issue with generics + this.definitions.push(definition); + } + + public getItemDefinitions(): ItemDefinition[] { + return this.definitions; + } + + public getItemDefinitionByType(type: string): ItemDefinition | undefined { + return this.definitions.find((definition) => definition.type === type); + } +} diff --git a/x-pack/plugins/observability_solution/investigate/public/plugin.tsx b/x-pack/plugins/observability_solution/investigate/public/plugin.tsx index 887753446c4a..9429383d851a 100644 --- a/x-pack/plugins/observability_solution/investigate/public/plugin.tsx +++ b/x-pack/plugins/observability_solution/investigate/public/plugin.tsx @@ -4,17 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { - AuthenticatedUser, - CoreSetup, - CoreStart, - Plugin, - PluginInitializerContext, -} from '@kbn/core/public'; -import { GetInvestigationResponse } from '@kbn/investigation-shared'; -import type { Logger } from '@kbn/logging'; -import { useMemo } from 'react'; -import { createUseInvestigation } from './hooks/use_investigation'; +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; +import { + ItemDefinition, + ItemDefinitionData, + ItemDefinitionParams, + ItemDefinitionRegistry, +} from './investigation/item_definition_registry'; import type { ConfigSchema, InvestigatePublicSetup, @@ -22,7 +18,6 @@ import type { InvestigateSetupDependencies, InvestigateStartDependencies, } from './types'; -import { WidgetRegistry } from './widget_registry'; export class InvestigatePlugin implements @@ -33,57 +28,28 @@ export class InvestigatePlugin InvestigateStartDependencies > { - logger: Logger; - - widgetRegistry: WidgetRegistry = new WidgetRegistry(); + private itemDefinitionRegistry: ItemDefinitionRegistry = new ItemDefinitionRegistry(); - registrationPromises: Array> = []; + constructor(context: PluginInitializerContext) {} - constructor(context: PluginInitializerContext) { - this.logger = context.logger.get(); - } setup(coreSetup: CoreSetup, pluginsSetup: InvestigateSetupDependencies): InvestigatePublicSetup { return { - register: (callback) => { - const registrationPromise = Promise.race([ - callback(this.widgetRegistry.registerWidget), - new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error('Timed out running registration function')); - }, 30000); - }), - ]).catch((error) => { - this.logger.error( - new Error('Encountered an error during widget registration', { cause: error }) - ); - return Promise.resolve(); - }); - - this.registrationPromises.push(registrationPromise); + registerItemDefinition: < + Params extends ItemDefinitionParams, + Data extends ItemDefinitionData + >( + definition: ItemDefinition + ) => { + this.itemDefinitionRegistry.registerItem(definition); }, }; } start(coreStart: CoreStart, pluginsStart: InvestigateStartDependencies): InvestigatePublicStart { return { - getWidgetDefinitions: this.widgetRegistry.getWidgetDefinitions, - useInvestigation: ({ - user, - investigationData, - }: { - user: AuthenticatedUser; - investigationData?: GetInvestigationResponse; - }) => { - const widgetDefinitions = useMemo(() => this.widgetRegistry.getWidgetDefinitions(), []); - - return createUseInvestigation({ - notifications: coreStart.notifications, - widgetDefinitions, - })({ - user, - investigationData, - }); - }, + getItemDefinitions: () => this.itemDefinitionRegistry.getItemDefinitions(), + getItemDefinitionByType: (type: string) => + this.itemDefinitionRegistry.getItemDefinitionByType(type), }; } } diff --git a/x-pack/plugins/observability_solution/investigate/public/types.ts b/x-pack/plugins/observability_solution/investigate/public/types.ts index dc6eb8b62021..36a87759c271 100644 --- a/x-pack/plugins/observability_solution/investigate/public/types.ts +++ b/x-pack/plugins/observability_solution/investigate/public/types.ts @@ -6,54 +6,11 @@ */ /* eslint-disable @typescript-eslint/no-empty-interface*/ -import type { AuthenticatedUser } from '@kbn/core/public'; -import type { CompatibleJSONSchema } from '@kbn/observability-ai-assistant-plugin/public'; -import type { GetInvestigationResponse } from '@kbn/investigation-shared'; -import type { FromSchema } from 'json-schema-to-ts'; -import type { InvestigateWidget } from '../common'; -import type { GlobalWidgetParameters, InvestigateWidgetCreate } from '../common/types'; -import type { UseInvestigationApi } from './hooks/use_investigation'; - -export type OnWidgetAdd = (create: InvestigateWidgetCreate) => Promise; - -interface WidgetRenderOptions { - widget: TInvestigateWidget; -} - -export interface WidgetDefinition { - type: string; - description: string; - schema: CompatibleJSONSchema; - generate: (options: { - parameters: GlobalWidgetParameters; - signal: AbortSignal; - }) => Promise>; - render: (options: WidgetRenderOptions) => React.ReactNode; -} - -type RegisterWidgetOptions = Omit; - -type MaybeSchemaFrom = - {} & (TSchema extends CompatibleJSONSchema ? FromSchema : {}); - -type GenerateCallback< - TSchema extends CompatibleJSONSchema | undefined, - TData extends Record | undefined -> = (options: { - parameters: MaybeSchemaFrom & GlobalWidgetParameters; - signal: AbortSignal; -}) => Promise; - -export type RegisterWidget = < - TSchema extends CompatibleJSONSchema, - TData extends Record ->( - definition: Omit & { schema: TSchema }, - generateCallback: GenerateCallback, - renderCallback: ( - options: WidgetRenderOptions, TData>> - ) => React.ReactNode -) => void; +import { + ItemDefinition, + ItemDefinitionData, + ItemDefinitionParams, +} from './investigation/item_definition_registry'; export interface ConfigSchema {} @@ -62,13 +19,15 @@ export interface InvestigateSetupDependencies {} export interface InvestigateStartDependencies {} export interface InvestigatePublicSetup { - register: (callback: (registerWidget: RegisterWidget) => Promise) => void; + registerItemDefinition: < + Params extends ItemDefinitionParams = {}, + Data extends ItemDefinitionData = {} + >( + itemDefinition: ItemDefinition + ) => void; } export interface InvestigatePublicStart { - getWidgetDefinitions: () => WidgetDefinition[]; - useInvestigation: ({}: { - user: AuthenticatedUser; - investigationData?: GetInvestigationResponse; - }) => UseInvestigationApi; + getItemDefinitions: () => ItemDefinition[]; + getItemDefinitionByType: (type: string) => ItemDefinition | undefined; } diff --git a/x-pack/plugins/observability_solution/investigate/public/widget_registry.ts b/x-pack/plugins/observability_solution/investigate/public/widget_registry.ts deleted file mode 100644 index f76adf5a7250..000000000000 --- a/x-pack/plugins/observability_solution/investigate/public/widget_registry.ts +++ /dev/null @@ -1,26 +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 type { RegisterWidget, WidgetDefinition } from './types'; - -export class WidgetRegistry { - private readonly definitions: WidgetDefinition[] = []; - - constructor() {} - - registerWidget: RegisterWidget = (definition, generateCallback, renderCallback) => { - this.definitions.push({ - ...definition, - generate: generateCallback as WidgetDefinition['generate'], - render: renderCallback as WidgetDefinition['render'], - }); - }; - - getWidgetDefinitions = (): WidgetDefinition[] => { - return this.definitions; - }; -} diff --git a/x-pack/plugins/observability_solution/investigate/tsconfig.json b/x-pack/plugins/observability_solution/investigate/tsconfig.json index d48acf4a215a..e2e39f527c2e 100644 --- a/x-pack/plugins/observability_solution/investigate/tsconfig.json +++ b/x-pack/plugins/observability_solution/investigate/tsconfig.json @@ -14,14 +14,7 @@ "@kbn/core", "@kbn/logging", "@kbn/config-schema", - "@kbn/observability-ai-assistant-plugin", "@kbn/es-query", - "@kbn/interpreter", - "@kbn/security-plugin", - "@kbn/i18n", - "@kbn/utility-types", - "@kbn/core-security-common", - "@kbn/investigation-shared", ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc b/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc index 5b31cbc3973a..c7e860a04736 100644 --- a/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc @@ -21,9 +21,9 @@ "security", ], "requiredBundles": [ + "esql", "kibanaReact", "kibanaUtils", - "esql", "esqlDataGrid", ], "optionalPlugins": [], diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.stories.tsx b/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.stories.tsx deleted file mode 100644 index 072d25b1e552..000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.stories.tsx +++ /dev/null @@ -1,112 +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 { ComponentMeta, ComponentStoryObj } from '@storybook/react'; -import React, { useState } from 'react'; -import { v4 } from 'uuid'; -import { InvestigateWidgetGrid as Component, InvestigateWidgetGridItem } from '.'; -import { KibanaReactStorybookDecorator } from '../../../.storybook/storybook_decorator'; - -const meta: ComponentMeta = { - component: Component, - title: 'app/Organisms/InvestigateWidgetGrid', - decorators: [KibanaReactStorybookDecorator], -}; - -export default meta; - -function WithPersistedChanges(props: React.ComponentProps) { - const [items, setItems] = useState(props.items); - - return ( - { - setItems((prevItems) => - prevItems.concat({ - ...item, - id: v4(), - }) - ); - }} - onItemDelete={async (item) => { - setItems((prevItems) => prevItems.filter((currentItem) => currentItem.id !== item.id)); - }} - items={items} - /> - ); -} - -const defaultProps: ComponentStoryObj = { - args: {}, - render: (props) => ( -
- -
- ), -}; - -function createItem>(overrides: T) { - return { - ...overrides, - id: v4(), - columns: 4, - rows: 2, - description: '', - loading: false, - overrides: [], - }; -} - -export const InvestigateWidgetGridStory: ComponentStoryObj = { - ...defaultProps, - args: { - ...defaultProps.args, - items: [ - createItem({ - title: '1', - element: ( -
- This should not overflow -
- ), - columns: 4, - rows: 12, - }), - - createItem({ - title: '2', - element: <>TODO, - columns: 2, - rows: 3, - overrides: [ - { - id: v4(), - label: '4 hours earlier', - }, - { - id: v4(), - label: 'service.name:opbeans-java AND service.enviroment:(production OR development)', - }, - ], - }), - createItem({ - title: '3', - element: <>TODO, - columns: 2, - rows: 3, - }), - createItem({ - title: '4', - element: <>TODO, - columns: 4, - rows: 3, - }), - ], - }, - name: 'default', -}; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/styles.scss b/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/styles.scss deleted file mode 100644 index 5528e053f84a..000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/styles.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../../../../../src/plugins/dashboard/public/dashboard_container/dashboard_container'; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts index d2f6bc9060e4..62078d7d55bc 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts @@ -13,6 +13,9 @@ export const investigationKeys = { notes: ['investigation', 'notes'] as const, fetchNotes: (params: { investigationId: string }) => [...investigationKeys.notes, 'fetch', params] as const, + items: ['investigation', 'items'] as const, + fetchItems: (params: { investigationId: string }) => + [...investigationKeys.items, 'fetch', params] as const, }; export type InvestigationKeys = typeof investigationKeys; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_item.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_item.ts new file mode 100644 index 000000000000..a11b5d976fe0 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_add_investigation_item.ts @@ -0,0 +1,49 @@ +/* + * 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 { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { + CreateInvestigationItemParams, + CreateInvestigationItemResponse, +} from '@kbn/investigation-shared'; +import { useMutation } from '@tanstack/react-query'; +import { useKibana } from './use_kibana'; + +type ServerError = IHttpFetchError; + +export function useAddInvestigationItem() { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + return useMutation< + CreateInvestigationItemResponse, + ServerError, + { investigationId: string; item: CreateInvestigationItemParams }, + { investigationId: string } + >( + ['addInvestigationItem'], + ({ investigationId, item }) => { + const body = JSON.stringify(item); + return http.post( + `/api/observability/investigations/${investigationId}/items`, + { body, version: '2023-10-31' } + ); + }, + { + onSuccess: (response, {}) => { + toasts.addSuccess('Item saved'); + }, + onError: (error, {}, context) => { + toasts.addError(new Error(error.body?.message ?? 'An error occurred'), { title: 'Error' }); + }, + } + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_item.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_item.ts new file mode 100644 index 000000000000..41c19013e6b2 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_item.ts @@ -0,0 +1,44 @@ +/* + * 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 { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { useMutation } from '@tanstack/react-query'; +import { useKibana } from './use_kibana'; + +type ServerError = IHttpFetchError; + +export function useDeleteInvestigationItem() { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + return useMutation< + void, + ServerError, + { investigationId: string; itemId: string }, + { investigationId: string } + >( + ['deleteInvestigationItem'], + ({ investigationId, itemId }) => { + return http.delete( + `/api/observability/investigations/${investigationId}/items/${itemId}`, + { version: '2023-10-31' } + ); + }, + { + onSuccess: (response, {}) => { + toasts.addSuccess('Item deleted'); + }, + onError: (error, {}, context) => { + toasts.addError(new Error(error.body?.message ?? 'An error occurred'), { title: 'Error' }); + }, + } + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_note.ts index 136387372c58..aed3cc571ec9 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_note.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_delete_investigation_note.ts @@ -25,7 +25,7 @@ export function useDeleteInvestigationNote() { { investigationId: string; noteId: string }, { investigationId: string } >( - ['addInvestigationNote'], + ['deleteInvestigationNote'], ({ investigationId, noteId }) => { return http.delete( `/api/observability/investigations/${investigationId}/notes/${noteId}`, diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_items.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_items.ts new file mode 100644 index 000000000000..5cc253fc6c44 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_items.ts @@ -0,0 +1,76 @@ +/* + * 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 { + GetInvestigationItemsResponse, + InvestigationItemResponse, +} from '@kbn/investigation-shared'; +import { + QueryObserverResult, + RefetchOptions, + RefetchQueryFilters, + useQuery, +} from '@tanstack/react-query'; +import { investigationKeys } from './query_key_factory'; +import { useKibana } from './use_kibana'; + +export interface Params { + investigationId: string; + initialItems?: InvestigationItemResponse[]; +} + +export interface Response { + isInitialLoading: boolean; + isLoading: boolean; + isRefetching: boolean; + isSuccess: boolean; + isError: boolean; + refetch: ( + options?: (RefetchOptions & RefetchQueryFilters) | undefined + ) => Promise>; + data: GetInvestigationItemsResponse | undefined; +} + +export function useFetchInvestigationItems({ investigationId, initialItems }: Params): Response { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data, refetch } = useQuery( + { + queryKey: investigationKeys.fetchItems({ investigationId }), + queryFn: async ({ signal }) => { + return await http.get( + `/api/observability/investigations/${investigationId}/items`, + { version: '2023-10-31', signal } + ); + }, + initialData: initialItems, + refetchOnWindowFocus: false, + refetchInterval: 10 * 1000, + refetchIntervalInBackground: true, + onError: (error: Error) => { + toasts.addError(error, { + title: 'Something went wrong while fetching investigation items', + }); + }, + } + ); + + return { + data, + isInitialLoading, + isLoading, + isRefetching, + isSuccess, + isError, + refetch, + }; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/README.md b/x-pack/plugins/observability_solution/investigate_app/public/items/README.md new file mode 100644 index 000000000000..710c9fd3624e --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/README.md @@ -0,0 +1 @@ +This folder replaces widgets/ diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/register_embeddable_widget.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx similarity index 79% rename from x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/register_embeddable_widget.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx index 779fb9c5301b..e07c940c8ca5 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/register_embeddable_widget.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx @@ -6,16 +6,14 @@ */ import { EuiLoadingSpinner } from '@elastic/eui'; import { css } from '@emotion/css'; +import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public'; import type { GlobalWidgetParameters } from '@kbn/investigate-plugin/public'; import { useAbortableAsync } from '@kbn/observability-ai-assistant-plugin/public'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { v4 } from 'uuid'; -import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public'; -import { EMBEDDABLE_WIDGET_NAME } from '../../constants'; -import { useKibana } from '../../hooks/use_kibana'; -import { RegisterWidgetOptions } from '../register_widgets'; -import { EmbeddableWidgetParameters } from './types'; import { ErrorMessage } from '../../components/error_message'; +import { useKibana } from '../../hooks/use_kibana'; +import { Options } from '../register_items'; const embeddableClassName = css` height: 100%; @@ -24,7 +22,7 @@ const embeddableClassName = css` } `; -type Props = EmbeddableWidgetParameters & GlobalWidgetParameters; +type Props = EmbeddableItemParams & GlobalWidgetParameters; type ParentApi = ReturnType['getParentApi']>; @@ -155,40 +153,38 @@ function EmbeddableWidget(props: Props) { return ; } -export function registerEmbeddableWidget({ registerWidget }: RegisterWidgetOptions) { - registerWidget( - { - type: EMBEDDABLE_WIDGET_NAME, - description: 'Display a saved embeddable', - schema: { - type: 'object', - properties: { - type: { - type: 'string', - }, - config: { - type: 'object', - }, - savedObjectId: { - type: 'string', - }, - }, - required: ['type', 'config'], - } as const, - }, - async ({ parameters, signal }) => { +interface EmbeddableItemParams { + type: string; + config: Record; + savedObjectId?: string; +} + +export function registerEmbeddableItem({ + dependencies: { + setup: { investigate }, + }, + services, +}: Options) { + investigate.registerItemDefinition({ + type: 'esql', + generate: async (option: { + itemParams: EmbeddableItemParams; + globalParams: GlobalWidgetParameters; + }) => { return {}; }, - ({ widget }) => { + render: (option: { + itemParams: EmbeddableItemParams; + globalParams: GlobalWidgetParameters; + }) => { const parameters = { - type: widget.parameters.type, - config: widget.parameters.config, - savedObjectId: widget.parameters.savedObjectId, - timeRange: widget.parameters.timeRange, - query: widget.parameters.query, + type: option.itemParams.type, + config: option.itemParams.config, + savedObjectId: option.itemParams.savedObjectId, + timeRange: option.globalParams.timeRange, }; return ; - } - ); + }, + }); } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/esql_widget/get_date_histogram_results.ts b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/get_date_histogram_results.ts similarity index 100% rename from x-pack/plugins/observability_solution/investigate_app/public/widgets/esql_widget/get_date_histogram_results.ts rename to x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/get_date_histogram_results.ts diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/esql_widget/register_esql_widget.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx similarity index 80% rename from x-pack/plugins/observability_solution/investigate_app/public/widgets/esql_widget/register_esql_widget.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx index 84818c758ffe..1b62b5476f02 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/widgets/esql_widget/register_esql_widget.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx @@ -10,20 +10,16 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import type { ESQLSearchResponse } from '@kbn/es-types'; import { ESQLDataGrid } from '@kbn/esql-datagrid/public'; import { i18n } from '@kbn/i18n'; -import { - type EsqlWidgetParameters, - type GlobalWidgetParameters, -} from '@kbn/investigate-plugin/public'; +import { type GlobalWidgetParameters } from '@kbn/investigate-plugin/public'; import type { Suggestion } from '@kbn/lens-plugin/public'; import { useAbortableAsync } from '@kbn/observability-ai-assistant-plugin/public'; import React, { useMemo } from 'react'; import { ErrorMessage } from '../../components/error_message'; -import { ESQL_WIDGET_NAME } from '../../constants'; import { useKibana } from '../../hooks/use_kibana'; import { getDatatableFromEsqlResponse } from '../../utils/get_data_table_from_esql_response'; import { getEsFilterFromOverrides } from '../../utils/get_es_filter_from_overrides'; import { getLensAttrsForSuggestion } from '../../utils/get_lens_attrs_for_suggestion'; -import type { RegisterWidgetOptions } from '../register_widgets'; +import type { Options } from '../register_items'; import { getDateHistogramResults } from './get_date_histogram_results'; const lensClassName = css` @@ -45,6 +41,24 @@ interface Props { }; } +interface EsqlItemParams { + esql: string; + suggestion?: Suggestion; +} + +interface EsqlItemData { + dataView: DataView; + columns: ESQLSearchResponse['columns']; + values: ESQLSearchResponse['values']; + suggestion: Suggestion; + dateHistoResponse?: { + query: string; + columns: ESQLSearchResponse['columns']; + values: ESQLSearchResponse['values']; + groupingExpression: string; + }; +} + export function EsqlWidget({ suggestion, dataView, @@ -207,34 +221,21 @@ export function EsqlWidget({ ); } -export function registerEsqlWidget({ +export function registerEsqlItem({ dependencies: { setup: { investigate }, }, services, - registerWidget, -}: RegisterWidgetOptions) { - registerWidget( - { - type: ESQL_WIDGET_NAME, - description: 'Visualize an ES|QL query', - schema: { - type: 'object', - properties: { - esql: { - description: 'The ES|QL query', - type: 'string', - }, - }, - required: ['esql'], - } as const, - }, - async ({ parameters, signal }) => { - const { - esql: esqlQuery, - timeRange, - suggestion: suggestionFromParameters, - } = parameters as EsqlWidgetParameters & GlobalWidgetParameters; +}: Options) { + investigate.registerItemDefinition({ + type: 'esql', + generate: async (option: { + itemParams: EsqlItemParams; + globalParams: GlobalWidgetParameters; + }) => { + const controller = new AbortController(); + const { esql: esqlQuery, suggestion: suggestionFromParameters } = option.itemParams; + const { timeRange } = option.globalParams; const esql = await services.esql; @@ -252,7 +253,7 @@ export function registerEsqlWidget({ const mainResponse = await esql.queryWithMeta({ query: esqlQuery, - signal, + signal: controller.signal, filter: getFilter(), }); @@ -263,37 +264,36 @@ export function registerEsqlWidget({ columns: mainResponse.query.columns, esql, filter: getFilter(), - signal, + signal: controller.signal, suggestion, timeRange, }); return { - main: { - columns: mainResponse.query.columns, - values: mainResponse.query.values, - suggestion, - dataView: mainResponse.meta.dataView, - }, - dateHistogram: dateHistoResponse, + dataView: mainResponse.meta.dataView, + columns: mainResponse.query.columns, + values: mainResponse.query.values, + suggestion, + dateHistoResponse, }; }, - ({ widget }) => { - const { - main: { dataView, columns, values, suggestion }, - dateHistogram, - } = widget.data; + render: (option: { + itemParams: EsqlItemParams; + globalParams: GlobalWidgetParameters; + data: EsqlItemData; + }) => { + const { itemParams, data } = option; return ( ); - } - ); + }, + }); } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/register_widgets.ts b/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts similarity index 55% rename from x-pack/plugins/observability_solution/investigate_app/public/widgets/register_widgets.ts rename to x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts index fd2e2b972817..ff0304105a0b 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/widgets/register_widgets.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts @@ -5,22 +5,20 @@ * 2.0. */ -import type { RegisterWidget } from '@kbn/investigate-plugin/public/types'; import type { InvestigateAppServices } from '../services/types'; import type { InvestigateAppSetupDependencies, InvestigateAppStartDependencies } from '../types'; -import { registerEmbeddableWidget } from './embeddable_widget/register_embeddable_widget'; -import { registerEsqlWidget } from './esql_widget/register_esql_widget'; +import { registerEmbeddableItem } from './embeddable_item/register_embeddable_item'; +import { registerEsqlItem } from './esql_item/register_esql_item'; -export interface RegisterWidgetOptions { +export interface Options { dependencies: { setup: InvestigateAppSetupDependencies; start: InvestigateAppStartDependencies; }; services: InvestigateAppServices; - registerWidget: RegisterWidget; } -export function registerWidgets(options: RegisterWidgetOptions) { - registerEsqlWidget(options); - registerEmbeddableWidget(options); +export function registerItems(options: Options) { + registerEsqlItem(options); + registerEmbeddableItem(options); } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/add_investigation_item.tsx similarity index 93% rename from x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/index.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/add_investigation_item.tsx index 69f43ef51514..e4dcd2fe2000 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/index.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/add_investigation_item.tsx @@ -9,19 +9,20 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPanel, EuiTitle } fro import { css } from '@emotion/css'; import { TextBasedLangEditor } from '@kbn/esql/public'; import { i18n } from '@kbn/i18n'; -import { GlobalWidgetParameters, OnWidgetAdd } from '@kbn/investigate-plugin/public'; +import { GlobalWidgetParameters } from '@kbn/investigate-plugin/public'; +import { Item } from '@kbn/investigation-shared'; import React from 'react'; import { EsqlWidgetPreview } from './esql_widget_preview'; type Props = { - onWidgetAdd: OnWidgetAdd; + onItemAdd: (item: Item) => void; } & GlobalWidgetParameters; const emptyPreview = css` padding: 36px 0px 36px 0px; `; -export function AddObservationUI({ onWidgetAdd, timeRange }: Props) { +export function AddInvestigationItem({ onItemAdd: onItemAdd, timeRange }: Props) { const [isOpen, setIsOpen] = React.useState(false); const [query, setQuery] = React.useState({ esql: '' }); @@ -113,9 +114,9 @@ export function AddObservationUI({ onWidgetAdd, timeRange }: Props) { { + onItemAdd={(item) => { resetState(); - return onWidgetAdd(widget); + return onItemAdd(item); }} /> )} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/esql_widget_preview.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/esql_widget_preview.tsx similarity index 85% rename from x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/esql_widget_preview.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/esql_widget_preview.tsx index 2d1e1f150679..c865dfcf9182 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/add_observation_ui/esql_widget_preview.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/add_investigation_item/esql_widget_preview.tsx @@ -8,38 +8,33 @@ import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; import { css } from '@emotion/css'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { ESQLColumn, ESQLRow } from '@kbn/es-types'; -import { - ESQL_WIDGET_NAME, - GlobalWidgetParameters, - InvestigateWidgetCreate, - OnWidgetAdd, - createEsqlWidget, -} from '@kbn/investigate-plugin/public'; +import { GlobalWidgetParameters } from '@kbn/investigate-plugin/public'; +import { Item } from '@kbn/investigation-shared'; import type { Suggestion } from '@kbn/lens-plugin/public'; import { useAbortableAsync } from '@kbn/observability-ai-assistant-plugin/public'; import React, { useEffect, useMemo, useState } from 'react'; -import { useKibana } from '../../hooks/use_kibana'; -import { getEsFilterFromOverrides } from '../../utils/get_es_filter_from_overrides'; -import { getDateHistogramResults } from '../../widgets/esql_widget/get_date_histogram_results'; -import { EsqlWidget } from '../../widgets/esql_widget/register_esql_widget'; -import { ErrorMessage } from '../error_message'; -import { SuggestVisualizationList } from '../suggest_visualization_list'; +import { ErrorMessage } from '../../../../components/error_message'; +import { SuggestVisualizationList } from '../../../../components/suggest_visualization_list'; +import { useKibana } from '../../../../hooks/use_kibana'; +import { getDateHistogramResults } from '../../../../items/esql_item/get_date_histogram_results'; +import { EsqlWidget } from '../../../../items/esql_item/register_esql_item'; +import { getEsFilterFromOverrides } from '../../../../utils/get_es_filter_from_overrides'; -function getWidgetFromSuggestion({ +function getItemFromSuggestion({ query, suggestion, }: { query: string; suggestion: Suggestion; -}): InvestigateWidgetCreate { - return createEsqlWidget({ +}): Item { + return { title: suggestion.title, - type: ESQL_WIDGET_NAME, - parameters: { + type: 'esql', + params: { esql: query, suggestion, }, - }); + }; } function PreviewContainer({ children }: { children: React.ReactNode }) { @@ -64,11 +59,11 @@ function PreviewContainer({ children }: { children: React.ReactNode }) { export function EsqlWidgetPreview({ esqlQuery, - onWidgetAdd, + onItemAdd, timeRange, }: { esqlQuery: string; - onWidgetAdd: OnWidgetAdd; + onItemAdd: (item: Item) => void; } & GlobalWidgetParameters) { const { services: { esql }, @@ -199,7 +194,7 @@ export function EsqlWidgetPreview({ { - onWidgetAdd(getWidgetFromSuggestion({ query: esqlQuery, suggestion })); + onItemAdd(getItemFromSuggestion({ query: esqlQuery, suggestion })); }} loading={queryResult.loading} onMouseLeave={() => {}} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.stories.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.stories.tsx similarity index 90% rename from x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.stories.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.stories.tsx index 6111d0181ccb..54b13f1eea29 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.stories.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.stories.tsx @@ -9,8 +9,8 @@ import { Meta, StoryObj } from '@storybook/react'; import React from 'react'; import { v4 } from 'uuid'; import { GridItem as Component } from '.'; -import { extendProps } from '../../../.storybook/extend_props'; -import { KibanaReactStorybookDecorator } from '../../../.storybook/storybook_decorator'; +import { extendProps } from '../../../../../.storybook/extend_props'; +import { KibanaReactStorybookDecorator } from '../../../../../.storybook/storybook_decorator'; type Props = React.ComponentProps; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.tsx similarity index 95% rename from x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.tsx index 465f6f803edd..91f7a58b43b5 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/grid_item/index.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/grid_item/index.tsx @@ -7,8 +7,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; import { css } from '@emotion/css'; import React from 'react'; -import { useTheme } from '../../hooks/use_theme'; -import { InvestigateTextButton } from '../investigate_text_button'; +import { useTheme } from '../../../../hooks/use_theme'; +import { InvestigateTextButton } from '../../../../components/investigate_text_button'; export const GRID_ITEM_HEADER_HEIGHT = 40; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx index 8dfb18a753ac..83b61c331843 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.stories.tsx @@ -5,10 +5,11 @@ * 2.0. */ +import { mockAuthenticatedUser } from '@kbn/core-security-common/mocks'; import { ComponentMeta, ComponentStoryObj } from '@storybook/react'; import React from 'react'; -import { InvestigationDetails as Component } from '.'; import { KibanaReactStorybookDecorator } from '../../../../../.storybook/storybook_decorator'; +import { InvestigationDetails as Component } from './investigation_details'; const meta: ComponentMeta = { component: Component, @@ -20,7 +21,7 @@ export default meta; const defaultProps: ComponentStoryObj = { args: {}, - render: (props) => , + render: (props) => , }; export const InvestigateViewStory: ComponentStoryObj = { diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx deleted file mode 100644 index c1c77ef56454..000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/index.tsx +++ /dev/null @@ -1,121 +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 datemath from '@elastic/datemath'; -import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; -import { AuthenticatedUser } from '@kbn/security-plugin/common'; -import React from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { AddObservationUI } from '../../../../components/add_observation_ui'; -import { InvestigateSearchBar } from '../../../../components/investigate_search_bar'; -import { InvestigateWidgetGrid } from '../../../../components/investigate_widget_grid'; -import { useFetchInvestigation } from '../../../../hooks/use_fetch_investigation'; -import { useKibana } from '../../../../hooks/use_kibana'; -import { InvestigationNotes } from '../investigation_notes/investigation_notes'; - -function InvestigationDetailsWithUser({ - user, - investigationId, -}: { - user: AuthenticatedUser; - investigationId: string; -}) { - const { - dependencies: { - start: { investigate }, - }, - } = useKibana(); - // const widgetDefinitions = investigate.getWidgetDefinitions(); - const { data: investigationData } = useFetchInvestigation({ id: investigationId }); - - const { - addItem, - copyItem, - deleteItem, - investigation, - setGlobalParameters, - renderableInvestigation, - } = investigate.useInvestigation({ - user, - investigationData, - }); - - if (!investigation || !renderableInvestigation || !investigationData) { - return ; - } - - return ( - - - - - - { - const nextDateRange = { - from: datemath.parse(dateRange.from)!.toISOString(), - to: datemath.parse(dateRange.to)!.toISOString(), - }; - await setGlobalParameters({ - ...renderableInvestigation.parameters, - timeRange: nextDateRange, - }); - }} - /> - - - - { - return copyItem(copiedItem.id); - }} - onItemDelete={async (deletedItem) => { - return deleteItem(deletedItem.id); - }} - /> - - - - { - return addItem(widget); - }} - /> - - - - - - - - ); -} - -export function InvestigationDetails({ investigationId }: { investigationId: string }) { - const { - core: { security }, - } = useKibana(); - - const user = useAsync(() => { - return security.authc.getCurrentUser(); - }, [security]); - - return user.value ? ( - - ) : null; -} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/investigation_details.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/investigation_details.tsx new file mode 100644 index 000000000000..5f6e1ca4515d --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_details/investigation_details.tsx @@ -0,0 +1,38 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; +import { AuthenticatedUser } from '@kbn/security-plugin/common'; +import React from 'react'; +import { useFetchInvestigation } from '../../../../hooks/use_fetch_investigation'; +import { InvestigationItems } from '../investigation_items/investigation_items'; +import { InvestigationNotes } from '../investigation_notes/investigation_notes'; + +interface Props { + user: AuthenticatedUser; + investigationId: string; +} + +export function InvestigationDetails({ user, investigationId }: Props) { + const { data: investigation, isLoading } = useFetchInvestigation({ id: investigationId }); + + if (isLoading || !investigation) { + return ; + } + + return ( + + + + + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items/investigation_items.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items/investigation_items.tsx new file mode 100644 index 000000000000..dcc83eb96834 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items/investigation_items.tsx @@ -0,0 +1,91 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { GetInvestigationResponse, Item } from '@kbn/investigation-shared'; +import { pick } from 'lodash'; +import React from 'react'; +import { useAddInvestigationItem } from '../../../../hooks/use_add_investigation_item'; +import { useDeleteInvestigationItem } from '../../../../hooks/use_delete_investigation_item'; +import { useFetchInvestigationItems } from '../../../../hooks/use_fetch_investigation_items'; +import { useRenderItems } from '../../hooks/use_render_items'; +import { AddInvestigationItem } from '../add_investigation_item/add_investigation_item'; +import { InvestigationItemsList } from '../investigation_items_list/investigation_items_list'; +import { InvestigationSearchBar } from '../investigation_search_bar/investigation_search_bar'; + +export interface Props { + investigationId: string; + investigation: GetInvestigationResponse; +} + +export function InvestigationItems({ investigationId, investigation }: Props) { + const { data: items, refetch } = useFetchInvestigationItems({ + investigationId, + initialItems: investigation.items, + }); + const renderableItems = useRenderItems({ items, params: investigation.params }); + + const { mutateAsync: addInvestigationItem, isLoading: isAdding } = useAddInvestigationItem(); + const { mutateAsync: deleteInvestigationItem, isLoading: isDeleting } = + useDeleteInvestigationItem(); + + const onAddItem = async (item: Item) => { + await addInvestigationItem({ investigationId, item }); + refetch(); + }; + + const onDeleteItem = async (itemId: string) => { + await deleteInvestigationItem({ investigationId, itemId }); + refetch(); + }; + + return ( + + + { + // const nextDateRange = { + // from: datemath.parse(dateRange.from)!.toISOString(), + // to: datemath.parse(dateRange.to)!.toISOString(), + // }; + // await setGlobalParameters({ + // ...renderableInvestigation.parameters, + // timeRange: nextDateRange, + // }); + }} + /> + + + { + await onAddItem(pick(copiedItem, ['title', 'type', 'params'])); + }} + onItemDelete={async (deletedItem) => { + await onDeleteItem(deletedItem.id); + }} + /> + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items_list/investigation_items_list.tsx similarity index 75% rename from x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items_list/investigation_items_list.tsx index 41c3b3a3e8b6..8ec5bf3ffef9 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_widget_grid/index.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_items_list/investigation_items_list.tsx @@ -8,24 +8,19 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; +import { RenderedInvestigationItem } from '../../hooks/use_render_items'; import { GridItem } from '../grid_item'; -import './styles.scss'; - -export interface InvestigateWidgetGridItem { - id: string; - title: string; - element: React.ReactNode; - loading: boolean; -} interface InvestigateWidgetGridProps { - items: InvestigateWidgetGridItem[]; - onItemCopy: (item: InvestigateWidgetGridItem) => Promise; - onItemDelete: (item: InvestigateWidgetGridItem) => Promise; + items: RenderedInvestigationItem[]; + isLoading: boolean; + onItemCopy: (item: RenderedInvestigationItem) => Promise; + onItemDelete: (item: RenderedInvestigationItem) => Promise; } -export function InvestigateWidgetGrid({ +export function InvestigationItemsList({ items, + isLoading, onItemDelete, onItemCopy, }: InvestigateWidgetGridProps) { @@ -41,7 +36,7 @@ export function InvestigateWidgetGrid({ { return onItemCopy(item); }} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx index 0f03a9f374ac..8406ba8fe3f0 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_notes/investigation_notes.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { css } from '@emotion/css'; import { i18n } from '@kbn/i18n'; -import { InvestigationNote } from '@kbn/investigate-plugin/common'; +import { InvestigationNoteResponse, GetInvestigationResponse } from '@kbn/investigation-shared'; import React, { useState } from 'react'; import { useAddInvestigationNote } from '../../../../hooks/use_add_investigation_note'; import { useDeleteInvestigationNote } from '../../../../hooks/use_delete_investigation_note'; @@ -27,16 +27,16 @@ import { TimelineMessage } from './timeline_message'; export interface Props { investigationId: string; - initialNotes: InvestigationNote[]; + investigation: GetInvestigationResponse; } -export function InvestigationNotes({ investigationId, initialNotes }: Props) { +export function InvestigationNotes({ investigationId, investigation }: Props) { const theme = useTheme(); const [noteInput, setNoteInput] = useState(''); const { data: notes, refetch } = useFetchInvestigationNotes({ investigationId, - initialNotes, + initialNotes: investigation.notes, }); const { mutateAsync: addInvestigationNote, isLoading: isAdding } = useAddInvestigationNote(); const { mutateAsync: deleteInvestigationNote, isLoading: isDeleting } = @@ -70,7 +70,7 @@ export function InvestigationNotes({ investigationId, initialNotes }: Props) { - {notes?.map((currNote: InvestigationNote) => { + {notes?.map((currNote: InvestigationNoteResponse) => { return ( void; isDeleting: boolean; }) { diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_search_bar/index.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_search_bar/investigation_search_bar.tsx similarity index 93% rename from x-pack/plugins/observability_solution/investigate_app/public/components/investigate_search_bar/index.tsx rename to x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_search_bar/investigation_search_bar.tsx index 45519f2e799b..a6ad73bc67d0 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/investigate_search_bar/index.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/investigation_search_bar/investigation_search_bar.tsx @@ -8,7 +8,7 @@ import { css } from '@emotion/css'; import type { TimeRange } from '@kbn/es-query'; import { SearchBar } from '@kbn/unified-search-plugin/public'; import React from 'react'; -import { useKibana } from '../../hooks/use_kibana'; +import { useKibana } from '../../../../hooks/use_kibana'; const parentClassName = css` width: 100%; @@ -21,7 +21,7 @@ interface Props { onRefresh?: Required>['onRefresh']; } -export function InvestigateSearchBar({ +export function InvestigationSearchBar({ dateRangeFrom, dateRangeTo, onQuerySubmit, diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/hooks/use_render_items.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/hooks/use_render_items.tsx new file mode 100644 index 000000000000..dc2c1c029bcc --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/hooks/use_render_items.tsx @@ -0,0 +1,84 @@ +/* + * 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'; +import { GetInvestigationResponse, InvestigationItem } from '@kbn/investigation-shared'; +import React, { useEffect, useState } from 'react'; +import { useKibana } from '../../../hooks/use_kibana'; + +export type RenderedInvestigationItem = InvestigationItem & { + loading: boolean; + element: React.ReactNode; +}; + +export function useRenderItems({ + items, + params, +}: { + items?: InvestigationItem[]; + params: GetInvestigationResponse['params']; +}) { + const { + dependencies: { + start: { investigate }, + }, + } = useKibana(); + + const [renderableItems, setRenderableItems] = useState([]); + + useEffect(() => { + async function renderItems(currItems: InvestigationItem[]) { + return await Promise.all( + currItems.map(async (item) => { + const itemDefinition = investigate.getItemDefinitionByType(item.type); + if (!itemDefinition) { + return Promise.resolve({ + ...item, + loading: false, + element: ( +
+ {i18n.translate('xpack.investigateApp.renderableItems.div.notFoundLabel', { + defaultMessage: 'Not found for type {type}', + values: { type: item.type }, + })} +
+ ), + }); + } + + const globalParams = { + timeRange: { + from: new Date(params.timeRange.from).toISOString(), + to: new Date(params.timeRange.to).toISOString(), + }, + }; + + const data = await itemDefinition.generate({ + itemParams: item.params, + globalParams, + }); + + return Promise.resolve({ + ...item, + loading: false, + element: itemDefinition.render({ + data, + globalParams, + itemParams: item.params, + }), + }); + }) + ); + } + + if (items) { + renderItems(items).then((nextRenderableItems) => setRenderableItems(nextRenderableItems)); + } + }, [items, investigate, params]); + + return renderableItems; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx index 90af6b4591c6..8bce69ea125a 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/investigation_details_page.tsx @@ -11,23 +11,29 @@ import { alertOriginSchema } from '@kbn/investigation-shared'; import { ALERT_RULE_CATEGORY } from '@kbn/rule-data-utils/src/default_alerts_as_data'; import React from 'react'; import { useParams } from 'react-router-dom'; +import useAsync from 'react-use/lib/useAsync'; import { paths } from '../../../common/paths'; import { useFetchAlert } from '../../hooks/use_get_alert_details'; import { useFetchInvestigation } from '../../hooks/use_get_investigation_details'; import { useKibana } from '../../hooks/use_kibana'; -import { InvestigationDetails } from './components/investigation_details'; +import { InvestigationDetails } from './components/investigation_details/investigation_details'; import { InvestigationDetailsPathParams } from './types'; export function InvestigationDetailsPage() { const { core: { http: { basePath }, + security, }, dependencies: { start: { observabilityShared }, }, } = useKibana(); + const user = useAsync(() => { + return security.authc.getCurrentUser(); + }, [security]); + const { investigationId } = useParams(); const ObservabilityPageTemplate = observabilityShared.navigation.PageTemplate; @@ -44,6 +50,10 @@ export function InvestigationDetailsPage() { const { data: alertDetails } = useFetchAlert({ id: alertId }); + if (!user.value) { + return null; + } + if (isFetchInvestigationLoading) { return (

@@ -106,7 +116,7 @@ export function InvestigationDetailsPage() { ], }} > - + ); } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/plugin.tsx b/x-pack/plugins/observability_solution/investigate_app/public/plugin.tsx index 75b07099cbb6..abbe76256254 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/plugin.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/plugin.tsx @@ -125,28 +125,26 @@ export class InvestigateAppPlugin .getStartServices() .then(([, pluginsStart]) => pluginsStart); - pluginsSetup.investigate.register((registerWidget) => - Promise.all([ - pluginsStartPromise, - import('./widgets/register_widgets').then((m) => m.registerWidgets), - getCreateEsqlService(), - ]).then(([pluginsStart, registerWidgets, createEsqlService]) => { - registerWidgets({ - dependencies: { - setup: pluginsSetup, - start: pluginsStart, - }, - services: { - esql: createEsqlService({ - data: pluginsStart.data, - dataViews: pluginsStart.dataViews, - lens: pluginsStart.lens, - }), - }, - registerWidget, - }); - }) - ); + // new + Promise.all([ + pluginsStartPromise, + import('./items/register_items').then((m) => m.registerItems), + getCreateEsqlService(), + ]).then(([pluginsStart, registerItems, createEsqlService]) => { + registerItems({ + dependencies: { + setup: pluginsSetup, + start: pluginsStart, + }, + services: { + esql: createEsqlService({ + data: pluginsStart.data, + dataViews: pluginsStart.dataViews, + lens: pluginsStart.lens, + }), + }, + }); + }); return {}; } diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/create_embeddable_widget.ts b/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/create_embeddable_widget.ts deleted file mode 100644 index 61e99df8b28b..000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/create_embeddable_widget.ts +++ /dev/null @@ -1,13 +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 { createWidgetFactory } from '@kbn/investigate-plugin/public'; -import { EMBEDDABLE_WIDGET_NAME } from '../../constants'; -import { EmbeddableWidgetParameters } from './types'; - -export const createEmbeddableWidget = - createWidgetFactory(EMBEDDABLE_WIDGET_NAME); diff --git a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/types.ts b/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/types.ts deleted file mode 100644 index d3ecd0379c71..000000000000 --- a/x-pack/plugins/observability_solution/investigate_app/public/widgets/embeddable_widget/types.ts +++ /dev/null @@ -1,18 +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 type { InvestigateWidget, InvestigateWidgetCreate } from '@kbn/investigate-plugin/common'; - -export interface EmbeddableWidgetParameters { - type: string; - savedObjectId?: string; - config: Record; -} - -export type EmbeddableWidgetCreate = InvestigateWidgetCreate; - -export type EmbeddableWidget = InvestigateWidget; diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx index ffb188112254..952ee959e4a7 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx @@ -51,7 +51,7 @@ export const useLogEntryFlyout = (logViewReference: LogViewReference) => { }, []); const openLogEntryFlyout = useCallback( - (logEntryId) => { + (logEntryId: string | null | undefined) => { const { Provider: KibanaReactContextProvider } = createKibanaReactContext({ http, data, diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/index.ts b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/index.ts index c4507a2b4ebc..6468ea3d94d2 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/index.ts +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/index.ts @@ -17,3 +17,4 @@ export { LogEntryMessageColumn } from './log_entry_message_column'; export { LogEntryRowWrapper } from './log_entry_row_wrapper'; export { LogEntryTimestampColumn } from './log_entry_timestamp_column'; export { ScrollableLogTextStreamView } from './scrollable_log_text_stream_view'; +export type { UpdatedDateRange, VisibleInterval } from './scrollable_log_text_stream_view'; diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx index fdb0d6a88f8a..6fe7260e8c7e 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx @@ -28,6 +28,20 @@ import { LogDateRow } from './log_date_row'; import { LogEntry } from '../../../../common/log_entry'; import { LogColumnRenderConfiguration } from '../../../utils/log_column_render_configuration'; +export interface VisibleInterval { + pagesBeforeStart: number; + pagesAfterEnd: number; + startKey: TimeKey | null; + middleKey: TimeKey | null; + endKey: TimeKey | null; + fromScroll: boolean; +} + +export interface UpdatedDateRange { + startDateExpression?: string; + endDateExpression?: string; +} + export interface ScrollableLogTextStreamViewProps { columnConfigurations: LogColumnRenderConfiguration[]; items: StreamItem[]; @@ -41,14 +55,7 @@ export interface ScrollableLogTextStreamViewProps { lastLoadedTime?: Date; target: TimeKey | null; jumpToTarget: (target: TimeKey) => any; - reportVisibleInterval: (params: { - pagesBeforeStart: number; - pagesAfterEnd: number; - startKey: TimeKey | null; - middleKey: TimeKey | null; - endKey: TimeKey | null; - fromScroll: boolean; - }) => any; + reportVisibleInterval: (params: VisibleInterval) => any; reloadItems: () => void; onOpenLogEntryFlyout?: (logEntryId?: string) => void; setContextEntry?: (entry: LogEntry) => void; @@ -56,7 +63,7 @@ export interface ScrollableLogTextStreamViewProps { currentHighlightKey: UniqueTimeKey | null; startDateExpression: string; endDateExpression: string; - updateDateRange: (range: { startDateExpression?: string; endDateExpression?: string }) => void; + updateDateRange: (range: UpdatedDateRange) => void; startLiveStreaming: () => void; hideScrollbar?: boolean; } diff --git a/x-pack/plugins/observability_solution/logs_shared/public/index.ts b/x-pack/plugins/observability_solution/logs_shared/public/index.ts index 80b8dd363892..7a0f731b4a93 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/index.ts +++ b/x-pack/plugins/observability_solution/logs_shared/public/index.ts @@ -46,6 +46,10 @@ export { } from './components/logging/log_text_stream/log_entry_column'; export type { LogAIAssistantProps } from './components/log_ai_assistant/log_ai_assistant'; export type { LogStreamProps } from './components/log_stream/log_stream'; +export type { + UpdatedDateRange, + VisibleInterval, +} from './components/logging/log_text_stream/scrollable_log_text_stream_view'; export const WithSummary = dynamic(() => import('./containers/logs/log_summary/with_summary')); export const LogEntryFlyout = dynamic( diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/expression_row.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/expression_row.tsx index ffeaf3aef61c..d98b0a69d984 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/expression_row.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/expression_row.tsx @@ -73,13 +73,13 @@ export const ExpressionRow: React.FC = (props) => { ); const convertThreshold = useCallback( - (enteredThreshold) => + (enteredThreshold: any) => isMetricPct ? enteredThreshold.map((v: number) => pctToDecimal(v)) : enteredThreshold, [isMetricPct] ); const updateThreshold = useCallback( - (enteredThreshold) => { + (enteredThreshold: any) => { const t = convertThreshold(enteredThreshold); if (t.join() !== expression.threshold.join()) { setRuleParams(expressionId, { ...expression, threshold: t }); @@ -89,7 +89,7 @@ export const ExpressionRow: React.FC = (props) => { ); const handleCustomMetricChange = useCallback( - (exp) => { + (exp: any) => { setRuleParams(expressionId, exp); }, [expressionId, setRuleParams] diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx index bbbcb5905782..747abedfc0f3 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx @@ -219,7 +219,7 @@ export default function Expressions(props: Props) { ); const updateParams = useCallback( - (id, e: MetricExpression) => { + (id: any, e: MetricExpression) => { const ruleCriteria = ruleParams.criteria ? ruleParams.criteria.slice() : []; ruleCriteria[id] = e; setRuleParams('criteria', ruleCriteria); diff --git a/x-pack/plugins/observability_solution/observability/public/context/date_picker_context/date_picker_context.tsx b/x-pack/plugins/observability_solution/observability/public/context/date_picker_context/date_picker_context.tsx index b31b48456a56..3a7b3ed89b21 100644 --- a/x-pack/plugins/observability_solution/observability/public/context/date_picker_context/date_picker_context.tsx +++ b/x-pack/plugins/observability_solution/observability/public/context/date_picker_context/date_picker_context.tsx @@ -108,7 +108,7 @@ export function DatePickerContextProvider({ children }: { children: React.ReactE ); const updateRefreshInterval = useCallback( - ({ interval, isPaused }) => { + ({ interval, isPaused }: any) => { updateUrl({ refreshInterval: interval, refreshPaused: isPaused }); data.query.timefilter.timefilter.setRefreshInterval({ value: interval, pause: isPaused }); setLastUpdated(Date.now()); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts index 81b8a6ac5629..78c3d55e706e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/index.ts @@ -38,7 +38,6 @@ export { } from './conversation_complete'; export { - aiAssistantResponseLanguage, aiAssistantLogsIndexPattern, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, @@ -46,8 +45,6 @@ export { export { concatenateChatCompletionChunks } from './utils/concatenate_chat_completion_chunks'; -export { DEFAULT_LANGUAGE_OPTION, LANGUAGE_OPTIONS } from './ui_settings/language_options'; - export { isSupportedConnectorType } from './connectors'; export { ShortIdTable } from './utils/short_id_table'; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/language_options.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/language_options.ts deleted file mode 100644 index b4f89d512cd9..000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/language_options.ts +++ /dev/null @@ -1,165 +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. - */ - -/* eslint-disable @typescript-eslint/naming-convention */ -// Data taken from https://github.com/L-P/native-language-list/blob/master/data/langs.json -export const languages: { [key: string]: string } = { - af: 'Afrikaans', - ak: 'Akan', - am: '\u12a0\u121b\u122d\u129b', - ar: '\u0627\u0644\u0639\u0631\u0628\u064a\u0629', - as: '\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be', - az: 'az\u0259rbaycan', - be: '\u0431\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f', - bg: '\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438', - bm: 'bamanakan', - bn: '\u09ac\u09be\u0982\u09b2\u09be', - bo: '\u0f56\u0f7c\u0f51\u0f0b\u0f66\u0f90\u0f51\u0f0b', - br: 'brezhoneg', - bs: 'bosanski', - ca: 'catal\u00e0', - cs: '\u010de\u0161tina', - cy: 'Cymraeg', - da: 'dansk', - de: 'Deutsch', - de_AT: '\u00d6sterreichisches Deutsch', - de_CH: 'Schweizer Hochdeutsch', - dz: '\u0f62\u0fab\u0f7c\u0f44\u0f0b\u0f41', - ee: 'e\u028begbe', - el: '\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac', - en: 'English', - en_AU: 'Australian English', - en_CA: 'Canadian English', - en_GB: 'British English', - en_US: 'American English', - eo: 'esperanto', - es: 'espa\u00f1ol', - es_ES: 'espa\u00f1ol de Espa\u00f1a', - es_MX: 'espa\u00f1ol de M\u00e9xico', - et: 'eesti', - eu: 'euskara', - fa: '\u0641\u0627\u0631\u0633\u06cc', - ff: 'Pulaar', - fi: 'suomi', - fo: 'f\u00f8royskt', - fr: 'fran\u00e7ais', - fr_CA: 'fran\u00e7ais canadien', - fr_CH: 'fran\u00e7ais suisse', - fy: 'West-Frysk', - ga: 'Gaeilge', - gd: 'G\u00e0idhlig', - gl: 'galego', - gu: '\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0', - gv: 'Gaelg', - ha: 'Hausa', - he: '\u05e2\u05d1\u05e8\u05d9\u05ea', - hi: '\u0939\u093f\u0902\u0926\u0940', - hr: 'hrvatski', - hu: 'magyar', - hy: '\u0570\u0561\u0575\u0565\u0580\u0565\u0576', - id: 'Bahasa Indonesia', - ig: 'Igbo', - ii: '\ua188\ua320\ua259', - is: '\u00edslenska', - it: 'italiano', - ja: '\u65e5\u672c\u8a9e', - ka: '\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8', - ki: 'Gikuyu', - kk: '\u049b\u0430\u0437\u0430\u049b \u0442\u0456\u043b\u0456', - kl: 'kalaallisut', - km: '\u1781\u17d2\u1798\u17c2\u179a', - kn: '\u0c95\u0ca8\u0ccd\u0ca8\u0ca1', - ko: '\ud55c\uad6d\uc5b4', - ks: '\u06a9\u0672\u0634\u064f\u0631', - kw: 'kernewek', - ky: '\u043a\u044b\u0440\u0433\u044b\u0437\u0447\u0430', - lb: 'L\u00ebtzebuergesch', - lg: 'Luganda', - ln: 'ling\u00e1la', - lo: '\u0ea5\u0eb2\u0ea7', - lt: 'lietuvi\u0173', - lu: 'Tshiluba', - lv: 'latvie\u0161u', - mg: 'Malagasy', - mk: '\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438', - ml: '\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02', - mn: '\u043c\u043e\u043d\u0433\u043e\u043b', - mr: '\u092e\u0930\u093e\u0920\u0940', - ms: 'Bahasa Melayu', - mt: 'Malti', - my: '\u1017\u1019\u102c', - nb: 'norsk bokm\u00e5l', - nd: 'isiNdebele', - ne: '\u0928\u0947\u092a\u093e\u0932\u0940', - nl: 'Nederlands', - nl_BE: 'Vlaams', - nn: 'nynorsk', - no: 'norsk', - om: 'Oromoo', - or: '\u0b13\u0b21\u0b3c\u0b3f\u0b06', - os: '\u0438\u0440\u043e\u043d', - pa: '\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40', - pl: 'polski', - ps: '\u067e\u069a\u062a\u0648', - pt: 'portugu\u00eas', - pt_BR: 'portugu\u00eas do Brasil', - pt_PT: 'portugu\u00eas europeu', - qu: 'Runasimi', - rm: 'rumantsch', - rn: 'Ikirundi', - ro: 'rom\u00e2n\u0103', - ro_MD: 'moldoveneasc\u0103', - ru: '\u0440\u0443\u0441\u0441\u043a\u0438\u0439', - rw: 'Kinyarwanda', - se: 'davvis\u00e1megiella', - sg: 'S\u00e4ng\u00f6', - sh: 'Srpskohrvatski', - si: '\u0dc3\u0dd2\u0d82\u0dc4\u0dbd', - sk: 'sloven\u010dina', - sl: 'sloven\u0161\u010dina', - sn: 'chiShona', - so: 'Soomaali', - sq: 'shqip', - sr: '\u0441\u0440\u043f\u0441\u043a\u0438', - sv: 'svenska', - sw: 'Kiswahili', - ta: '\u0ba4\u0bae\u0bbf\u0bb4\u0bcd', - te: '\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41', - th: '\u0e44\u0e17\u0e22', - ti: '\u1275\u130d\u122d\u129b', - tl: 'Tagalog', - to: 'lea fakatonga', - tr: 'T\u00fcrk\u00e7e', - ug: '\u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5', - uk: '\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430', - ur: '\u0627\u0631\u062f\u0648', - uz: 'o\u02bbzbekcha', - vi: 'Ti\u1ebfng Vi\u1ec7t', - yi: '\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9', - yo: '\u00c8d\u00e8 Yor\u00f9b\u00e1', - zh: '\u4e2d\u6587', - zh_Hans: '\u7b80\u4f53\u4e2d\u6587', - zh_Hant: '\u7e41\u9ad4\u4e2d\u6587', - zu: 'isiZulu', -}; - -export const KIBANA_LOCALE_SETTING = { - value: 'locale_setting', - label: 'Kibana locale setting', -}; - -export const BROWSER_LANGUAGE_SETTING = { - value: 'browser_setting', - label: 'Browser language setting', -}; - -export const DEFAULT_LANGUAGE_OPTION = KIBANA_LOCALE_SETTING; -export const LANGUAGE_OPTIONS = [ - KIBANA_LOCALE_SETTING, - BROWSER_LANGUAGE_SETTING, - ...Object.entries(languages).map(([value, label]) => ({ value, label })), -]; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts index 4685befa9df2..eae50d1116a8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts @@ -7,7 +7,6 @@ // AI Assistant export const aiAssistantLogsIndexPattern = 'observability:aiAssistantLogsIndexPattern'; -export const aiAssistantResponseLanguage = 'observability:aiAssistantResponseLanguage'; export const aiAssistantSimulatedFunctionCalling = 'observability:aiAssistantSimulatedFunctionCalling'; export const aiAssistantSearchConnectorIndexPattern = diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_chat.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_chat.ts index 4d850118bb73..712b102c36f8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_chat.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_chat.ts @@ -21,7 +21,6 @@ import { import type { ObservabilityAIAssistantChatService, ObservabilityAIAssistantService } from '..'; import { useKibana } from './use_kibana'; import { useOnce } from './use_once'; -import { useUserPreferredLanguage } from './use_user_preferred_language'; export enum ChatState { Ready = 'ready', @@ -88,8 +87,6 @@ function useChatWithoutContext({ const abortControllerRef = useRef(new AbortController()); - const { getPreferredLanguage } = useUserPreferredLanguage(); - const onChatCompleteRef = useRef(onChatComplete); onChatCompleteRef.current = onChatComplete; @@ -164,7 +161,6 @@ function useChatWithoutContext({ disableFunctions: disableFunctions ?? false, signal: abortControllerRef.current.signal, conversationId, - responseLanguage: getPreferredLanguage(), }); function getPendingMessages() { @@ -263,7 +259,6 @@ function useChatWithoutContext({ disableFunctions, service, systemMessage, - getPreferredLanguage, ] ); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_user_preferred_language.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_user_preferred_language.ts deleted file mode 100644 index 16e4edbf8ceb..000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/hooks/use_user_preferred_language.ts +++ /dev/null @@ -1,62 +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'; -import { useCallback } from 'react'; -import { - DEFAULT_LANGUAGE_OPTION, - KIBANA_LOCALE_SETTING, - BROWSER_LANGUAGE_SETTING, - languages, -} from '../../common/ui_settings/language_options'; -import { aiAssistantResponseLanguage } from '../../common'; - -import { useKibana } from './use_kibana'; - -export type UseUserPreferredLanguageResult = ReturnType; - -export function useUserPreferredLanguage() { - const { - services: { uiSettings }, - } = useKibana(); - - const selectedLanguage = uiSettings.get( - aiAssistantResponseLanguage, - DEFAULT_LANGUAGE_OPTION.value - ); - - const getPreferredLanguage = useCallback(() => { - if (selectedLanguage === KIBANA_LOCALE_SETTING.value) { - return getLanguageFromKibanaSettings(); - } else if (selectedLanguage === BROWSER_LANGUAGE_SETTING.value) { - return getLanguageFromBrowserSetting(); - } else { - return languages[selectedLanguage] || 'English'; - } - }, [selectedLanguage]); - - return { selectedLanguage, getPreferredLanguage }; -} - -function getLanguageFromKibanaSettings() { - switch (i18n.getLocale()) { - case 'en': - return 'English'; - case 'zh-cn': - return '简体中文'; - case 'ja-jp': - return '日本語'; - case 'fr-fr': - return 'français'; - default: - return 'English'; - } -} - -function getLanguageFromBrowserSetting() { - return languages[navigator.language] || 'English'; -} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/index.ts index 81cee3036e9c..ab2dea089dcf 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/index.ts @@ -93,10 +93,8 @@ export type { } from './api'; export type { UseChatResult } from './hooks/use_chat'; -export { LANGUAGE_OPTIONS, DEFAULT_LANGUAGE_OPTION } from '../common/ui_settings/language_options'; export { - aiAssistantResponseLanguage, aiAssistantLogsIndexPattern, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx index 31907f54c49b..b5d85be11dfe 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/mock.tsx @@ -79,12 +79,6 @@ function createStartContract(): ObservabilityAIAssistantPublicStart { selectConnector: () => {}, reloadConnectors: () => {}, }), - useUserPreferredLanguage: () => ({ - LANGUAGE_OPTIONS: [{ label: 'English' }], - selectedLanguage: 'English', - setSelectedLanguage: () => {}, - getPreferredLanguage: () => 'English', - }), getContextualInsightMessages: () => [], createScreenContextAction: () => ({} as ScreenContextActionDefinition), }; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/plugin.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant/public/plugin.tsx index 2c2c68f407d8..fd2a60dcdfc3 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/plugin.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/plugin.tsx @@ -16,7 +16,6 @@ import { ObservabilityAIAssistantMultipaneFlyoutContext } from './context/observ import { ObservabilityAIAssistantProvider } from './context/observability_ai_assistant_provider'; import { useGenAIConnectorsWithoutContext } from './hooks/use_genai_connectors'; import { useObservabilityAIAssistantChatService } from './hooks/use_observability_ai_assistant_chat_service'; -import { useUserPreferredLanguage } from './hooks/use_user_preferred_language'; import { createUseChat } from './hooks/use_chat'; import { createService } from './service/create_service'; import { createScreenContextAction } from './utils/create_screen_context_action'; @@ -97,7 +96,6 @@ export class ObservabilityAIAssistantPlugin useChat: createUseChat({ notifications: coreStart.notifications, }), - useUserPreferredLanguage, ObservabilityAIAssistantMultipaneFlyoutContext, ObservabilityAIAssistantChatServiceContext, useObservabilityAIAssistantChatService, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts index 4665f9b7b486..59b3e7c9087d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.test.ts @@ -101,7 +101,6 @@ describe('complete', () => { persist: false, disableFunctions: false, signal: new AbortController().signal, - responseLanguage: 'orcish', ...params, }, requestCallback diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.ts index 90a8f16639ed..85f5f0397ff3 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/complete.ts @@ -42,7 +42,6 @@ export function complete( persist, disableFunctions, signal, - responseLanguage, instructions, }: { client: Pick; @@ -65,7 +64,6 @@ export function complete( disableFunctions, screenContexts, conversationId, - responseLanguage, instructions, }, }, @@ -131,7 +129,6 @@ export function complete( messages: initialMessages.concat(nextMessages), signal, persist, - responseLanguage, disableFunctions, instructions, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.test.ts index 6555c310b14f..6d0332602c86 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.test.ts @@ -229,38 +229,4 @@ describe('createChatService', () => { ).rejects.toEqual(expect.any(AbortError)); }); }); - - describe('complete', () => { - it("sends the user's preferred response language to the API", async () => { - respondWithChunks({ - chunks: [ - '{"id":"my-id","type":"chatCompletionChunk","message":{"content":"Some message"}}', - ], - }); - - const response$ = service.complete({ - connectorId: '', - getScreenContexts: () => [], - messages: [], - persist: false, - disableFunctions: false, - signal: new AbortController().signal, - responseLanguage: 'orcish', - }); - - await getConcatenatedMessage(response$); - - expect(clientSpy).toHaveBeenNthCalledWith( - 2, - 'POST /internal/observability_ai_assistant/chat/complete', - expect.objectContaining({ - params: expect.objectContaining({ - body: expect.objectContaining({ - responseLanguage: 'orcish', - }), - }), - }) - ); - }); - }); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts index db3c8b1f5bbf..fc8c06ef55f5 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/service/create_chat_service.ts @@ -214,7 +214,7 @@ export async function createChatService({ persist, disableFunctions, signal, - responseLanguage, + instructions, }) { return complete( @@ -227,7 +227,6 @@ export async function createChatService({ disableFunctions, signal, client, - responseLanguage, instructions, }, ({ params }) => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts index c00cf4805ff8..71a8a7e40274 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/types.ts @@ -29,7 +29,6 @@ import { ObservabilityAIAssistantMultipaneFlyoutContext } from './context/observ import { useChat } from './hooks/use_chat'; import type { UseGenAIConnectorsResult } from './hooks/use_genai_connectors'; import { useObservabilityAIAssistantChatService } from './hooks/use_observability_ai_assistant_chat_service'; -import type { UseUserPreferredLanguageResult } from './hooks/use_user_preferred_language'; import { createScreenContextAction } from './utils/create_screen_context_action'; /* eslint-disable @typescript-eslint/no-empty-interface*/ @@ -67,7 +66,6 @@ export interface ObservabilityAIAssistantChatService { except: string[]; }; signal: AbortSignal; - responseLanguage?: string; instructions?: AdHocInstruction[]; }) => Observable; getFunctions: (options?: { contexts?: string[]; filter?: string }) => FunctionDefinition[]; @@ -135,7 +133,6 @@ export interface ObservabilityAIAssistantPublicStart { useObservabilityAIAssistantChatService: typeof useObservabilityAIAssistantChatService; useGenAIConnectors: () => UseGenAIConnectorsResult; useChat: typeof useChat; - useUserPreferredLanguage: () => UseUserPreferredLanguageResult; getContextualInsightMessages: ({}: { message: string; instructions: string }) => Message[]; createScreenContextAction: typeof createScreenContextAction; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts index 03b3f4ccdc76..7d1409b29dde 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/index.ts @@ -19,7 +19,6 @@ export type { } from './types'; export { - aiAssistantResponseLanguage, aiAssistantLogsIndexPattern, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts index 73d8b0d1354e..d57051cf9fb6 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/chat/route.ts @@ -33,7 +33,6 @@ const chatCompleteBaseRt = t.type({ t.partial({ conversationId: t.string, title: t.string, - responseLanguage: t.string, disableFunctions: t.union([ toBooleanRt, t.type({ @@ -241,7 +240,6 @@ async function chatComplete( title, persist, screenContexts, - responseLanguage, instructions, disableFunctions, }, @@ -266,7 +264,6 @@ async function chatComplete( persist, signal, functionClient, - responseLanguage, instructions, simulateFunctionCalling, disableFunctions, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts index 33bd0ab49b1d..f5c6b79b2178 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts @@ -33,7 +33,7 @@ type ChunkDelta = CreateChatCompletionResponseChunk['choices'][number]['delta']; type LlmSimulator = ReturnType; -const EXPECTED_STORED_SYSTEM_MESSAGE = `system\n\nYou MUST respond in the users preferred language which is: English.`; +const EXPECTED_STORED_SYSTEM_MESSAGE = `system`; const nextTick = () => { return new Promise(process.nextTick); @@ -366,8 +366,8 @@ describe('Observability AI Assistant client', () => { last_updated: expect.any(String), token_count: { completion: 1, - prompt: 46, - total: 47, + prompt: 33, + total: 34, }, }, type: StreamingChatResponseEventType.ConversationCreate, @@ -423,8 +423,8 @@ describe('Observability AI Assistant client', () => { last_updated: expect.any(String), token_count: { completion: 6, - prompt: 230, - total: 236, + prompt: 210, + total: 216, }, }, type: StreamingChatResponseEventType.ConversationCreate, @@ -441,8 +441,8 @@ describe('Observability AI Assistant client', () => { title: 'An auto-generated title', token_count: { completion: 6, - prompt: 230, - total: 236, + prompt: 210, + total: 216, }, }, labels: {}, @@ -572,8 +572,8 @@ describe('Observability AI Assistant client', () => { last_updated: expect.any(String), token_count: { completion: 2, - prompt: 124, - total: 126, + prompt: 111, + total: 113, }, }, type: StreamingChatResponseEventType.ConversationUpdate, @@ -591,8 +591,8 @@ describe('Observability AI Assistant client', () => { title: 'My stored conversation', token_count: { completion: 2, - prompt: 124, - total: 126, + prompt: 111, + total: 113, }, }, labels: {}, @@ -1583,39 +1583,6 @@ describe('Observability AI Assistant client', () => { ); }); - it("Adds the user's preferred language to the system prompt", async () => { - client = createClient(); - const chatSpy = jest.spyOn(client, 'chat'); - - actionsClientMock.execute.mockImplementation(async () => { - return { - actionId: '', - status: 'ok', - data: createLlmSimulator().stream, - }; - }); - - client - .complete({ - connectorId: 'foo', - messages: [system('This is a system message'), user('A user message to cause completion')], - functionClient: functionClientMock, - signal: new AbortController().signal, - title: 'My predefined title', - persist: false, - responseLanguage: 'Orcish', - }) - .subscribe(() => {}); // To trigger call to chat - await nextTick(); - - const systemMessage = chatSpy.mock.calls[0][1].messages[0]; - - expect(systemMessage.message.role).toEqual(MessageRole.System); - expect(systemMessage.message.content).toEqual( - EXPECTED_STORED_SYSTEM_MESSAGE.replace('English', 'Orcish') - ); - }); - describe('when executing an action', () => { let completePromise: Promise; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts index 293d2da9c04b..45309911375d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts @@ -166,7 +166,6 @@ export class ObservabilityAIAssistantClient { instructions: adHocInstructions = [], messages: initialMessages, signal, - responseLanguage = 'English', persist, kibanaPublicUrl, isPublic, @@ -179,7 +178,6 @@ export class ObservabilityAIAssistantClient { signal: AbortSignal; functionClient: ChatFunctionClient; persist: boolean; - responseLanguage?: string; conversationId?: string; title?: string; isPublic?: boolean; @@ -195,13 +193,6 @@ export class ObservabilityAIAssistantClient { return new LangTracer(context.active()).startActiveSpan( 'complete', ({ tracer: completeTracer }) => { - if (responseLanguage) { - adHocInstructions.push({ - instruction_type: 'application_instruction', - text: `You MUST respond in the users preferred language which is: ${responseLanguage}.`, - }); - } - const isConversationUpdate = persist && !!predefinedConversationId; const conversationId = persist ? predefinedConversationId || v4() : ''; @@ -252,7 +243,6 @@ export class ObservabilityAIAssistantClient { switchMap((messages) => getGeneratedTitle({ messages, - responseLanguage, logger: this.dependencies.logger, chat: (name, chatParams) => { return this.chat(name, { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.test.ts index 02f5e5c29446..a8ddd5233132 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.test.ts @@ -38,9 +38,7 @@ describe('getGeneratedTitle', () => { }; } - function callGenerateTitle( - ...rest: [ChatEvent[]] | [{ responseLanguage?: string }, ChatEvent[]] - ) { + function callGenerateTitle(...rest: [ChatEvent[]] | [{}, ChatEvent[]]) { const options = rest.length === 1 ? {} : rest[0]; const chunks = rest.length === 1 ? rest[0] : rest[1]; @@ -119,27 +117,6 @@ describe('getGeneratedTitle', () => { expect(await testTitle(`"User's request for a title"`)).toEqual(`User's request for a title`); }); - it('mentions the given response language in the instruction', async () => { - const { chatSpy, title$ } = callGenerateTitle( - { - responseLanguage: 'Orcish', - }, - [ - createChatCompletionChunk({ - function_call: { - name: 'title_conversation', - arguments: JSON.stringify({ title: 'My title' }), - }, - }), - ] - ); - - await lastValueFrom(title$); - - const [, params] = chatSpy.mock.calls[0]; - expect(params.messages[0].message.content).toContain('Orcish'); - }); - it('handles partial updates', async () => { const { title$ } = callGenerateTitle([ createChatCompletionChunk({ diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts index 23440c30bdcc..79dac3c03604 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/get_generated_title.ts @@ -25,13 +25,11 @@ type ChatFunctionWithoutConnectorAndTokenCount = ( ) => Observable; export function getGeneratedTitle({ - responseLanguage, messages, chat, logger, tracer, }: { - responseLanguage?: string; messages: Message[]; chat: ChatFunctionWithoutConnectorAndTokenCount; logger: Pick; @@ -44,7 +42,7 @@ export function getGeneratedTitle({ '@timestamp': new Date().toString(), message: { role: MessageRole.System, - content: `You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you. Please create the title in ${responseLanguage}.`, + content: `You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you.`, }, }, { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts index 967ef4a96fbf..f972eb5742a9 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts @@ -10,44 +10,11 @@ import { UiSettingsParams } from '@kbn/core-ui-settings-common'; import { i18n } from '@kbn/i18n'; import { aiAssistantLogsIndexPattern, - aiAssistantResponseLanguage, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, } from '@kbn/observability-ai-assistant-plugin/common'; -import { - DEFAULT_LANGUAGE_OPTION, - LANGUAGE_OPTIONS, -} from '@kbn/observability-ai-assistant-plugin/common'; export const uiSettings: Record = { - [aiAssistantResponseLanguage]: { - category: ['observability'], - name: i18n.translate( - 'xpack.observabilityAiAssistantManagement.settingsPage.userPreferencesLabel', - { - defaultMessage: 'Response language', - } - ), - value: DEFAULT_LANGUAGE_OPTION.value, - description: i18n.translate( - 'xpack.observabilityAiAssistantManagement.settingsPage.selectYourLanguageLabel', - { - defaultMessage: - 'Select the language you wish the Assistant to use when generating responses.', - } - ), - - // Argument of type 'Type[]' is not assignable to parameter of type '[Type]'. - // @ts-expect-error - schema: schema.oneOf(LANGUAGE_OPTIONS.map((lang) => schema.literal(lang.value))), - type: 'select', - options: LANGUAGE_OPTIONS.map((lang) => lang.value), - optionLabels: LANGUAGE_OPTIONS.reduce( - (acc, { value, label }) => ({ ...acc, [value]: label }), - {} - ), - requiresPageReload: true, - }, [aiAssistantLogsIndexPattern]: { category: ['observability'], name: i18n.translate( diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx index 9b7022efc324..807bde0557d8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx @@ -9,10 +9,7 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; import { render } from '../../../helpers/test_helper'; import { SettingsTab } from './settings_tab'; -import { - aiAssistantLogsIndexPattern, - aiAssistantResponseLanguage, -} from '@kbn/observability-ai-assistant-plugin/server'; +import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/server'; import { uiSettings } from '../../../../common/ui_settings'; jest.mock('../../../hooks/use_app_context'); @@ -76,13 +73,6 @@ describe('SettingsTab', () => { target: { value: 'observability-ai-assistant-*' }, }); - fireEvent.change( - getByTestId(`management-settings-editField-${aiAssistantResponseLanguage}`), - { - target: { value: 'da' }, - } - ); - fireEvent.click(getByTestId('observabilityAiAssistantManagementBottomBarActionsButton')); await waitFor(() => expect(windowLocationReloadMock).toHaveBeenCalledTimes(1)); @@ -97,7 +87,6 @@ describe('SettingsTab', () => { aiAssistantLogsIndexPattern, 'observability-ai-assistant-*' ); - expect(settingsClientSet).toBeCalledWith(aiAssistantResponseLanguage, 'da'); }); }); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx index 4b30a568bd5e..5be8456954d6 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { BottomBarActions, useEditableSettings } from '@kbn/observability-shared-plugin/public'; import { aiAssistantLogsIndexPattern, - aiAssistantResponseLanguage, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, aiAssistantPreferredAIAssistantType, @@ -22,7 +21,6 @@ import { useKibana } from '../../../hooks/use_kibana'; const settingsKeys = [ aiAssistantLogsIndexPattern, - aiAssistantResponseLanguage, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, aiAssistantPreferredAIAssistantType, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx index 2882104dbcb9..7740a346ca99 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx @@ -34,7 +34,7 @@ describe('', () => { type: config.type, }} onChange={useCallback( - (code) => setConfig({ type: code.type as CodeEditorMode, value: code.value }), + (code: any) => setConfig({ type: code.type as CodeEditorMode, value: code.value }), [setConfig] )} readOnly={readOnly} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_history/monitor_history.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_history/monitor_history.tsx index 8420df9b15f8..fc151db70d1e 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_history/monitor_history.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_history/monitor_history.tsx @@ -35,7 +35,7 @@ export const MonitorHistory = () => { const statsColumns = statsWidth && statsWidth < STATS_WIDTH_SINGLE_COLUMN_THRESHOLD ? 1 : 2; const handleStatusChartBrushed = useCallback( - ({ fromUtc, toUtc }) => { + ({ fromUtc, toUtc }: any) => { updateUrlParams({ dateRangeStart: fromUtc, dateRangeEnd: toUtc }); }, [updateUrlParams] diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx index 78ac9dd2f663..cf2f6cb97d82 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx @@ -187,7 +187,7 @@ function DetailedFlyoutHeader({ configId={configId} selectedLocation={selectedLocation} onChange={useCallback( - (id, label) => { + (id: any, label: any) => { if (currentLocation !== label) setCurrentLocation(label, id); }, [currentLocation, setCurrentLocation] diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_chart_wrapper.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_chart_wrapper.tsx index ed5a6b73d411..4f155d56db83 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_chart_wrapper.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_chart_wrapper.tsx @@ -127,14 +127,14 @@ export const WaterfallChartWrapper: React.FC = ({ setShowCustomMarks={setShowCustomMarks} query={query} setQuery={setQuery} - renderTooltipItem={useCallback((tooltipProps) => { + renderTooltipItem={useCallback((tooltipProps: any) => { return {tooltipProps?.value}; }, [])} > `${Number(d).toFixed(0)} ms`, [])} domain={domain} - barStyleAccessor={useCallback(({ datum }) => { + barStyleAccessor={useCallback(({ datum }: any) => { if (!datum.config?.isHighlighted) { return { rect: { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_sidebar_item.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_sidebar_item.tsx index 60898420c84b..a5d26e33a9b5 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_sidebar_item.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/step_details_page/step_waterfall_chart/waterfall/waterfall_sidebar_item.tsx @@ -35,7 +35,7 @@ export const WaterfallSidebarItem = React.memo(function WaterfallSidebarItem({ } }, [buttonRef, index, onClick]); - const setRef = useCallback((ref) => setButtonRef(ref), [setButtonRef]); + const setRef = useCallback((ref: any) => setButtonRef(ref), [setButtonRef]); const isErrorStatusCode = (statusCode: number) => { const is400 = statusCode >= 400 && statusCode <= 499; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/test_now_mode/test_now_mode_flyout_container.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/test_now_mode/test_now_mode_flyout_container.tsx index b550cdbd2745..b710da8cfcba 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/test_now_mode/test_now_mode_flyout_container.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/test_now_mode/test_now_mode_flyout_container.tsx @@ -26,7 +26,7 @@ export function TestNowModeFlyoutContainer() { const flyoutOpenTestRun = useTestFlyoutOpen(); const onDone = useCallback( - (testRunId) => { + (testRunId: any) => { dispatch( manualTestRunUpdateAction({ testRunId, @@ -39,7 +39,7 @@ export function TestNowModeFlyoutContainer() { ); const handleFlyoutClose = useCallback( - (testRunId) => { + (testRunId: any) => { dispatch( manualTestRunUpdateAction({ testRunId, diff --git a/x-pack/plugins/observability_solution/synthetics/public/hooks/use_form_wrapped.tsx b/x-pack/plugins/observability_solution/synthetics/public/hooks/use_form_wrapped.tsx index 97a5d7433714..354f3f6e21c2 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/hooks/use_form_wrapped.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/hooks/use_form_wrapped.tsx @@ -41,7 +41,7 @@ export function useFormWrapped { + (name: any, ...registerArgs: any) => { const { ref, onChange, ...restOfRegister } = register(name, ...registerArgs); return { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx index 669d615dd647..2cde284fd7af 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx @@ -129,14 +129,14 @@ export const WaterfallChartWrapper: React.FC = ({ sidebarItems={sidebarItems} legendItems={legendItems} metadata={metadata} - renderTooltipItem={useCallback((tooltipProps) => { + renderTooltipItem={useCallback((tooltipProps: any) => { return {tooltipProps?.value}; }, [])} > `${Number(d).toFixed(0)} ms`, [])} domain={domain} - barStyleAccessor={useCallback(({ datum }) => { + barStyleAccessor={useCallback(({ datum }: any) => { if (!datum.config?.isHighlighted) { return { rect: { diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx index 193fe3312163..249edeaa8f3a 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx @@ -35,7 +35,7 @@ export const WaterfallSidebarItem = ({ } }, [buttonRef, index, onClick]); - const setRef = useCallback((ref) => setButtonRef(ref), [setButtonRef]); + const setRef = useCallback((ref: any) => setButtonRef(ref), [setButtonRef]); const isErrorStatusCode = (statusCode: number) => { const is400 = statusCode >= 400 && statusCode <= 499; diff --git a/x-pack/plugins/observability_solution/uptime/public/plugin.ts b/x-pack/plugins/observability_solution/uptime/public/plugin.ts index b02ee95e1203..b2558fe83e33 100644 --- a/x-pack/plugins/observability_solution/uptime/public/plugin.ts +++ b/x-pack/plugins/observability_solution/uptime/public/plugin.ts @@ -311,7 +311,7 @@ function setUptimeAppStatus( } else { const hasUptimePrivileges = coreStart.application.capabilities.uptime?.show; if (hasUptimePrivileges) { - const indexStatusPromise = UptimeDataHelper(coreStart).indexStatus('now-7d', 'now'); + const indexStatusPromise = UptimeDataHelper(coreStart).indexStatus('now-7d/d', 'now/d'); indexStatusPromise.then((indexStatus) => { if (indexStatus.indexExists) { registerUptimeRoutesWithNavigation(coreStart, pluginsStart); diff --git a/x-pack/plugins/observability_solution/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx b/x-pack/plugins/observability_solution/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx index 2c32df316efc..71738fbe246f 100644 --- a/x-pack/plugins/observability_solution/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx +++ b/x-pack/plugins/observability_solution/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx @@ -70,7 +70,7 @@ export function VisitorBreakdownChart({ ); const filterHandler = useCallback( - (event) => { + (event: any) => { onFilter(metric, event); }, [onFilter, metric] diff --git a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx index 6b9581249a07..3a53b3c2d9f1 100644 --- a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx +++ b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx @@ -78,10 +78,13 @@ const ActionResultsSummaryComponent: React.FC = ({ } }, [edges, error, expired]); - const renderAgentIdColumn = useCallback((agentId) => , []); - const renderRowsColumn = useCallback((rowsCount) => rowsCount ?? '-', []); + const renderAgentIdColumn = useCallback( + (agentId: any) => , + [] + ); + const renderRowsColumn = useCallback((rowsCount: any) => rowsCount ?? '-', []); const renderStatusColumn = useCallback( - (_, item) => { + (_: any, item: any) => { if (item.fields['error.skipped']) { return i18n.translate('xpack.osquery.liveQueryActionResults.table.skippedStatusText', { defaultMessage: 'skipped', diff --git a/x-pack/plugins/osquery/public/actions/actions_table.tsx b/x-pack/plugins/osquery/public/actions/actions_table.tsx index a6c66855f12c..a2b654b310c1 100644 --- a/x-pack/plugins/osquery/public/actions/actions_table.tsx +++ b/x-pack/plugins/osquery/public/actions/actions_table.tsx @@ -66,14 +66,14 @@ const ActionsTableComponent = () => { kuery: 'user_id: *', }); - const onTableChange = useCallback(({ page = {} }) => { + const onTableChange = useCallback(({ page = {} }: any) => { const { index, size } = page; setPageIndex(index); setPageSize(size); }, []); - const renderQueryColumn = useCallback((_, item) => { + const renderQueryColumn = useCallback((_: any, item: any) => { if (item._source.pack_name) { return ( @@ -96,22 +96,28 @@ const ActionsTableComponent = () => { ); }, []); - const renderAgentsColumn = useCallback((_, item) => <>{item.fields.agents?.length ?? 0}, []); + const renderAgentsColumn = useCallback( + (_: any, item: any) => <>{item.fields.agents?.length ?? 0}, + [] + ); - const renderCreatedByColumn = useCallback((userId) => (isArray(userId) ? userId[0] : '-'), []); + const renderCreatedByColumn = useCallback( + (userId: any) => (isArray(userId) ? userId[0] : '-'), + [] + ); const renderTimestampColumn = useCallback( - (_, item) => <>{formatDate(item.fields['@timestamp'][0])}, + (_: any, item: any) => <>{formatDate(item.fields['@timestamp'][0])}, [] ); const renderActionsColumn = useCallback( - (item) => , + (item: any) => , [] ); const handlePlayClick = useCallback( - (item) => () => { + (item: any) => () => { const packId = item._source.pack_id; if (packId) { @@ -152,7 +158,7 @@ const ActionsTableComponent = () => { [push] ); const renderPlayButton = useCallback( - (item, enabled) => { + (item: any, enabled: any) => { const playText = i18n.translate('xpack.osquery.liveQueryActions.table.runActionAriaLabel', { defaultMessage: 'Run query', }); @@ -174,7 +180,7 @@ const ActionsTableComponent = () => { const existingPackIds = useMemo(() => map(packsData?.data ?? [], 'id'), [packsData]); const isPlayButtonAvailable = useCallback( - (item) => { + (item: any) => { if (item.fields.pack_id?.length) { return ( existingPackIds.includes(item.fields.pack_id[0]) && @@ -260,7 +266,7 @@ const ActionsTableComponent = () => { ); const rowProps = useCallback( - (data) => ({ + (data: any) => ({ 'data-test-subj': `row-${data._source.action_id}`, }), [] diff --git a/x-pack/plugins/osquery/public/agent_policies/agents_policy_link.tsx b/x-pack/plugins/osquery/public/agent_policies/agents_policy_link.tsx index c471d9ffcd1b..722a0ee2073b 100644 --- a/x-pack/plugins/osquery/public/agent_policies/agents_policy_link.tsx +++ b/x-pack/plugins/osquery/public/agent_policies/agents_policy_link.tsx @@ -38,7 +38,7 @@ const AgentsPolicyLinkComponent: React.FC = ({ policyId } ); const handleClick = useCallback( - (event) => { + (event: any) => { if (!isModifiedEvent(event) && isLeftClickEvent(event)) { event.preventDefault(); diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index ff9b89f73543..913876e7019e 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -173,7 +173,7 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh } }, [agentList?.agents, agentList?.groups, agentList?.total, agentsFetched, searchValue]); - const renderOption = useCallback((option, searchVal, contentClassName) => { + const renderOption = useCallback((option: any, searchVal: any, contentClassName: any) => { const { label, value } = option; return value?.groupType === AGENT_GROUP_KEY.Agent ? ( diff --git a/x-pack/plugins/osquery/public/components/empty_state.tsx b/x-pack/plugins/osquery/public/components/empty_state.tsx index 18f5afe8eaf5..9a25443d4aaf 100644 --- a/x-pack/plugins/osquery/public/components/empty_state.tsx +++ b/x-pack/plugins/osquery/public/components/empty_state.tsx @@ -35,7 +35,7 @@ const OsqueryAppEmptyStateComponent = () => { ); const integrationClick = useCallback( - (event) => { + (event: any) => { if (!isModifiedEvent(event) && isLeftClickEvent(event)) { event.preventDefault(); diff --git a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx index 44ae6421a6c2..5c8141d5b8bb 100644 --- a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx +++ b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx @@ -30,7 +30,7 @@ const ManageIntegrationLinkComponent = () => { ); const integrationClick = useCallback( - (event) => { + (event: any) => { if (!isModifiedEvent(event) && isLeftClickEvent(event)) { event.preventDefault(); diff --git a/x-pack/plugins/osquery/public/fleet_integration/config_uploader.tsx b/x-pack/plugins/osquery/public/fleet_integration/config_uploader.tsx index 3d5b042769d8..67370b42fe01 100644 --- a/x-pack/plugins/osquery/public/fleet_integration/config_uploader.tsx +++ b/x-pack/plugins/osquery/public/fleet_integration/config_uploader.tsx @@ -75,7 +75,7 @@ const ConfigUploaderComponent: React.FC = ({ onChange }) => }; const handleInputChange = useCallback( - (inputFiles) => { + (inputFiles: any) => { if (!inputFiles.length) { return; } diff --git a/x-pack/plugins/osquery/public/fleet_integration/navigation_buttons.tsx b/x-pack/plugins/osquery/public/fleet_integration/navigation_buttons.tsx index 4da470270de7..bf6ce0dcc73e 100644 --- a/x-pack/plugins/osquery/public/fleet_integration/navigation_buttons.tsx +++ b/x-pack/plugins/osquery/public/fleet_integration/navigation_buttons.tsx @@ -14,7 +14,7 @@ import { useKibana, isModifiedEvent, isLeftClickEvent } from '../common/lib/kiba interface NavigationButtonsProps { isDisabled?: boolean; - agentPolicyId?: string | undefined; + agentPolicyId?: string | null; } const NavigationButtonsComponent: React.FC = ({ @@ -36,7 +36,7 @@ const NavigationButtonsComponent: React.FC = ({ ); const liveQueryClick = useCallback( - (event) => { + (event: any) => { if (!isModifiedEvent(event) && isLeftClickEvent(event)) { event.preventDefault(); navigateToApp(PLUGIN_ID, { @@ -54,7 +54,7 @@ const NavigationButtonsComponent: React.FC = ({ }); const packsClick = useCallback( - (event) => { + (event: any) => { if (!isModifiedEvent(event) && isLeftClickEvent(event)) { event.preventDefault(); navigateToApp(PLUGIN_ID, { diff --git a/x-pack/plugins/osquery/public/fleet_integration/osquery_managed_policy_create_import_extension.tsx b/x-pack/plugins/osquery/public/fleet_integration/osquery_managed_policy_create_import_extension.tsx index 8c41771b6f19..732c47fcdcfa 100644 --- a/x-pack/plugins/osquery/public/fleet_integration/osquery_managed_policy_create_import_extension.tsx +++ b/x-pack/plugins/osquery/public/fleet_integration/osquery_managed_policy_create_import_extension.tsx @@ -194,7 +194,7 @@ export const OsqueryManagedPolicyCreateImportExtension = React.memo< }, [getUrlForApp, policy?.policy_id]); const handleConfigUpload = useCallback( - (newConfig) => { + (newConfig: any) => { let currentPacks = {}; try { currentPacks = JSON.parse(config)?.packs; diff --git a/x-pack/plugins/osquery/public/form/results_type_field.tsx b/x-pack/plugins/osquery/public/form/results_type_field.tsx index 37fe9d9ceee3..43eb9b88ca82 100644 --- a/x-pack/plugins/osquery/public/form/results_type_field.tsx +++ b/x-pack/plugins/osquery/public/form/results_type_field.tsx @@ -74,7 +74,7 @@ const ResultsTypeFieldComponent: React.FC = ({ euiFieldPr }); const handleChange = useCallback( - (newValue) => { + (newValue: any) => { if (newValue === SNAPSHOT_OPTION.value) { onSnapshotChange(true); onRemovedChange(false); diff --git a/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx b/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx index 53281c794e3a..240cd6d24de0 100644 --- a/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx +++ b/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx @@ -41,7 +41,7 @@ const ViewResultsInLensActionComponent: React.FC = const { data: logsDataView } = useLogsDataView({ skip: !actionId, checkOnly: true }); const handleClick = useCallback( - (event) => { + (event: any) => { event.preventDefault(); if (logsDataView) { diff --git a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx index 23ef0524dbb1..462d3aa94d7f 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx @@ -82,7 +82,7 @@ const LiveQueryQueryFieldComponent: React.FC = ({ [resetField] ); - const handleToggle = useCallback((isOpen) => { + const handleToggle = useCallback((isOpen: any) => { const newState = isOpen ? 'open' : 'closed'; setAdvancedContentState(newState); }, []); diff --git a/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx b/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx index 73d66481d94f..4fe0993306c9 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx @@ -157,7 +157,7 @@ const PackQueriesStatusTableComponent: React.FC = ( } | null>(null); const handleQueryFlyoutOpen = useCallback( - (item) => () => { + (item: any) => () => { setQueryDetailsFlyoutOpen(item); }, [] @@ -179,7 +179,7 @@ const PackQueriesStatusTableComponent: React.FC = ( ); const renderQueryColumn = useCallback( - (query: string, item) => { + (query: string, item: any) => { const singleLine = removeMultilines(query); const content = singleLine.length > 55 ? `${singleLine.substring(0, 55)}...` : singleLine; @@ -201,7 +201,7 @@ const PackQueriesStatusTableComponent: React.FC = ( return ; }, []); - const renderAgentsColumn = useCallback((item) => { + const renderAgentsColumn = useCallback((item: any) => { if (!item.action_id) return; return ( @@ -214,14 +214,17 @@ const PackQueriesStatusTableComponent: React.FC = ( }, []); const renderDiscoverResultsAction = useCallback( - (item) => , + (item: any) => , [] ); - const renderLensResultsAction = useCallback((item) => , []); + const renderLensResultsAction = useCallback( + (item: any) => , + [] + ); const getHandleErrorsToggle = useCallback( - (item) => () => { + (item: any) => () => { setItemIdToExpandedRowMap((prevValue) => { const itemIdToExpandedRowMapValues = { ...prevValue }; if (itemIdToExpandedRowMapValues[item.id]) { @@ -252,7 +255,7 @@ const PackQueriesStatusTableComponent: React.FC = ( ); const renderToggleResultsAction = useCallback( - (item) => + (item: any) => item?.action_id && data?.length && data.length > 1 ? ( ([]); const handlePackChange = useCallback( - (newSelectedOptions) => { + (newSelectedOptions: any) => { if (!newSelectedOptions.length) { setSelectedOptions(newSelectedOptions); onChange([]); @@ -86,7 +86,7 @@ export const PacksComboBoxField = ({ ); const renderOption = useCallback( - ({ value: option }) => ( + ({ value: option }: any) => ( { + (type: any) => { setQueryType(type); }, [setQueryType] diff --git a/x-pack/plugins/osquery/public/packs/form/index.tsx b/x-pack/plugins/osquery/public/packs/form/index.tsx index fd9c114a0794..5b0bb73fd166 100644 --- a/x-pack/plugins/osquery/public/packs/form/index.tsx +++ b/x-pack/plugins/osquery/public/packs/form/index.tsx @@ -60,7 +60,7 @@ const PackFormComponent: React.FC = ({ }) => { const [shardsToggleState, setShardsToggleState] = useState('closed'); - const handleToggle = useCallback((isOpen) => { + const handleToggle = useCallback((isOpen: any) => { const newState = isOpen ? 'open' : 'closed'; setShardsToggleState(newState); }, []); diff --git a/x-pack/plugins/osquery/public/packs/form/pack_uploader.tsx b/x-pack/plugins/osquery/public/packs/form/pack_uploader.tsx index b9f9c914ed24..7ab3218a00b9 100644 --- a/x-pack/plugins/osquery/public/packs/form/pack_uploader.tsx +++ b/x-pack/plugins/osquery/public/packs/form/pack_uploader.tsx @@ -83,7 +83,7 @@ const OsqueryPackUploaderComponent: React.FC = ({ onCh }; const handleInputChange = useCallback( - (inputFiles) => { + (inputFiles: any) => { if (!inputFiles.length) { packName.current = ''; diff --git a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx index 3e62a5639e1f..f4f2f0729713 100644 --- a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx +++ b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx @@ -56,7 +56,7 @@ const QueriesFieldComponent: React.FC = ({ euiFieldProps }) = const handleHideEditFlyout = useCallback(() => setShowEditQueryFlyout(-1), []); const handleDeleteClick = useCallback( - (query) => { + (query: any) => { const streamIndex = findIndex(fieldValue, ['id', query.id]); if (streamIndex > -1) { @@ -67,7 +67,7 @@ const QueriesFieldComponent: React.FC = ({ euiFieldProps }) = ); const handleEditClick = useCallback( - (query) => { + (query: any) => { const streamIndex = findIndex(fieldValue, ['id', query.id]); setShowEditQueryFlyout(streamIndex); @@ -76,7 +76,7 @@ const QueriesFieldComponent: React.FC = ({ euiFieldProps }) = ); const handleEditQuery = useCallback( - (updatedQuery) => + (updatedQuery: any) => new Promise((resolve) => { if (showEditQueryFlyout >= 0) { update( @@ -114,7 +114,7 @@ const QueriesFieldComponent: React.FC = ({ euiFieldProps }) = ); const handleAddQuery = useCallback( - (newQuery) => + (newQuery: any) => new Promise((resolve) => { append(newQuery); handleHideAddFlyout(); @@ -132,7 +132,7 @@ const QueriesFieldComponent: React.FC = ({ euiFieldProps }) = }, [fieldValue, remove, tableSelectedItems]); const handlePackUpload = useCallback( - (parsedContent, uploadedPackName) => { + (parsedContent: any, uploadedPackName: any) => { replace( map(parsedContent.queries, (newQuery, newQueryId) => pickBy( diff --git a/x-pack/plugins/osquery/public/packs/form/shards/pack_type_selectable.tsx b/x-pack/plugins/osquery/public/packs/form/shards/pack_type_selectable.tsx index a64dc02cb028..ce64d990a5dc 100644 --- a/x-pack/plugins/osquery/public/packs/form/shards/pack_type_selectable.tsx +++ b/x-pack/plugins/osquery/public/packs/form/shards/pack_type_selectable.tsx @@ -50,7 +50,7 @@ const PackTypeSelectableComponent = ({ resetFormFields, }: PackTypeSelectableProps) => { const handleChange = useCallback( - (type) => { + (type: any) => { setPackType(type); if (resetFormFields) { resetFormFields(); diff --git a/x-pack/plugins/osquery/public/packs/form/shards/shards_form.tsx b/x-pack/plugins/osquery/public/packs/form/shards/shards_form.tsx index 8fbf05e3d7e7..c353512b66f6 100644 --- a/x-pack/plugins/osquery/public/packs/form/shards/shards_form.tsx +++ b/x-pack/plugins/osquery/public/packs/form/shards/shards_form.tsx @@ -39,7 +39,7 @@ const ShardsFormComponent = ({ }, [index, onDelete]); const buttonWrapperCss = useCallback( - ({ euiTheme }) => (index === 0 ? { marginTop: euiTheme.size.base } : {}), + ({ euiTheme }: any) => (index === 0 ? { marginTop: euiTheme.size.base } : {}), [index] ); diff --git a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx index f4f941a1254e..48f3024d499c 100644 --- a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx +++ b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx @@ -187,7 +187,7 @@ const ViewResultsInLensActionComponent: React.FC { + (event: any) => { event.preventDefault(); if (logsDataView?.id) { @@ -584,7 +584,7 @@ const PackQueriesStatusTableComponent: React.FC = ( Record> >({}); - const renderQueryColumn = useCallback((query: string, item) => { + const renderQueryColumn = useCallback((query: string, item: any) => { const singleLine = removeMultilines(query); const content = singleLine.length > 55 ? `${singleLine.substring(0, 55)}...` : singleLine; @@ -618,7 +618,7 @@ const PackQueriesStatusTableComponent: React.FC = ( ); const renderLastResultsColumn = useCallback( - (item) => ( + (item: any) => ( = ( [packName] ); const renderDocsColumn = useCallback( - (item) => ( + (item: any) => ( ), [packName] ); const renderAgentsColumn = useCallback( - (item) => ( + (item: any) => ( ), [packName] ); const renderErrorsColumn = useCallback( - (item) => ( + (item: any) => ( = ( ); const renderDiscoverResultsAction = useCallback( - (item) => , + (item: any) => , [packName] ); const renderLensResultsAction = useCallback( - (item) => , + (item: any) => , [packName] ); diff --git a/x-pack/plugins/osquery/public/packs/packs_table.tsx b/x-pack/plugins/osquery/public/packs/packs_table.tsx index 3574d4589175..aa0d6d205a62 100644 --- a/x-pack/plugins/osquery/public/packs/packs_table.tsx +++ b/x-pack/plugins/osquery/public/packs/packs_table.tsx @@ -86,18 +86,18 @@ const PacksTableComponent = () => { const { data, isLoading } = usePacks({}); const renderAgentPolicy = useCallback( - (agentPolicyIds) => , + (agentPolicyIds: any) => , [] ); const renderQueries = useCallback( - (queries) => <>{(queries && Object.keys(queries).length) ?? 0}, + (queries: any) => <>{(queries && Object.keys(queries).length) ?? 0}, [] ); - const renderActive = useCallback((_, item) => , []); + const renderActive = useCallback((_: any, item: any) => , []); - const renderUpdatedAt = useCallback((updatedAt, item) => { + const renderUpdatedAt = useCallback((updatedAt: any, item: any) => { if (!updatedAt) return '-'; const updatedBy = item.updated_by !== item.created_by ? ` @ ${item.updated_by}` : ''; @@ -122,7 +122,7 @@ const PacksTableComponent = () => { ); const renderPlayAction = useCallback( - (item, enabled) => { + (item: any, enabled: any) => { const playText = i18n.translate('xpack.osquery.packs.table.runActionAriaLabel', { defaultMessage: 'Run {packName}', values: { diff --git a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx index d1ca70f14b08..5cd399303337 100644 --- a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx @@ -139,7 +139,7 @@ const ECSComboboxFieldComponent: React.FC = ({ const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); const { ecsMappingArray: watchedEcsMapping } = watch(); const handleChange = useCallback( - (newSelectedOptions) => { + (newSelectedOptions: any) => { setSelected(newSelectedOptions); ECSField.onChange(newSelectedOptions[0]?.label ?? ''); }, @@ -148,7 +148,7 @@ const ECSComboboxFieldComponent: React.FC = ({ // TODO: Create own component for this. const renderOption = useCallback( - (option, searchValue, contentClassName) => ( + (option: any, searchValue: any, contentClassName: any) => ( = ({ const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); const renderOsqueryOption = useCallback( - (option, searchValue, contentClassName) => ( + (option: any, searchValue: any, contentClassName: any) => ( = ({ ); const handleKeyChange = useCallback( - (newSelectedOptions) => { + (newSelectedOptions: any) => { setSelected(newSelectedOptions); resultField.onChange( isArray(newSelectedOptions) @@ -438,7 +438,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ }, [ecsMappingArray, index, isLastItem, resultTypeField.value]); const onTypeChange = useCallback( - (newType) => { + (newType: any) => { if (newType !== resultTypeField.value) { resultTypeField.onChange(newType); resultField.onChange(newType === 'value' && isSingleSelection === false ? [] : ''); diff --git a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx index 751f53f91ece..1afe75f463d0 100644 --- a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx @@ -76,7 +76,7 @@ const QueryFlyoutComponent: React.FC = ({ }; const handleSetQueryValue = useCallback( - (savedQuery) => { + (savedQuery: any) => { if (savedQuery) { resetField('id', { defaultValue: savedQuery.id }); resetField('query', { defaultValue: savedQuery.query }); diff --git a/x-pack/plugins/osquery/public/packs/scheduled_query_errors_table.tsx b/x-pack/plugins/osquery/public/packs/scheduled_query_errors_table.tsx index 99b614a2c53f..7c7f1bee0fc5 100644 --- a/x-pack/plugins/osquery/public/packs/scheduled_query_errors_table.tsx +++ b/x-pack/plugins/osquery/public/packs/scheduled_query_errors_table.tsx @@ -37,7 +37,7 @@ const ViewErrorsInLogsActionComponent: React.FC = ( const navigateToApp = useKibana().services.application.navigateToApp; const handleClick = useCallback( - (event) => { + (event: any) => { const openInNewTab = !(!isModifiedEvent(event) && isLeftClickEvent(event)); event.preventDefault(); @@ -90,10 +90,13 @@ const ScheduledQueryErrorsTableComponent: React.FC , []); + const renderAgentIdColumn = useCallback( + (agentId: any) => , + [] + ); const renderLogsErrorsAction = useCallback( - (item) => ( + (item: any) => ( = ({ } = useKibana().services; const getFleetAppUrl = useCallback( - (agentId) => + (agentId: any) => getUrlForApp('fleet', { path: pagePathGetters.agent_details({ agentId })[1], }), @@ -118,7 +118,7 @@ const ResultsTableComponent: React.FC = ({ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 50 }); const onChangeItemsPerPage = useCallback( - (pageSize) => + (pageSize: any) => setPagination((currentPagination) => ({ ...currentPagination, pageSize, @@ -127,7 +127,7 @@ const ResultsTableComponent: React.FC = ({ [setPagination] ); const onChangePage = useCallback( - (pageIndex) => setPagination((currentPagination) => ({ ...currentPagination, pageIndex })), + (pageIndex: any) => setPagination((currentPagination) => ({ ...currentPagination, pageIndex })), [setPagination] ); diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/index.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/index.tsx index d1c78cf89de8..ce7cda4f71fe 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/index.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/index.tsx @@ -126,7 +126,7 @@ const EditSavedQueryPageComponent = () => { ); const handleSubmit = useCallback( - async (payload) => { + async (payload: any) => { await updateSavedQueryMutation.mutateAsync(payload); }, [updateSavedQueryMutation] diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx index e9fa1d34df20..8d6d180f46bd 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx @@ -157,7 +157,7 @@ const SavedQueriesPageComponent = () => { [permissions.runSavedQueries, permissions.writeLiveQueries] ); - const renderUpdatedAt = useCallback((updatedAt, item) => { + const renderUpdatedAt = useCallback((updatedAt: any, item: any) => { if (!updatedAt) return '-'; const updatedBy = item.updated_by !== item.created_by ? ` @ ${item.updated_by}` : ''; @@ -223,7 +223,7 @@ const SavedQueriesPageComponent = () => { [renderDescriptionColumn, renderEditAction, renderPlayAction, renderUpdatedAt] ); - const onTableChange = useCallback(({ page = {}, sort = {} }) => { + const onTableChange = useCallback(({ page = {}, sort = {} }: any) => { setPageIndex(page.index); setPageSize(page.size); setSortField(sort.field); diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/new/index.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/new/index.tsx index 4c8d2fa5d3a9..b06c27aeaf0b 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/new/index.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/new/index.tsx @@ -48,7 +48,7 @@ const NewSavedQueryPageComponent = () => { ); const handleSubmit = useCallback( - async (payload) => { + async (payload: any) => { await mutateAsync(payload); }, [mutateAsync] diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx index 690341fd2221..5a5e052362ee 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx @@ -67,7 +67,7 @@ const SavedQueriesDropdownComponent: React.FC = ({ ); const handleSavedQueryChange = useCallback( - (newSelectedOptions) => { + (newSelectedOptions: any) => { if (!newSelectedOptions.length) { onChange(null); setSelectedOptions(newSelectedOptions); @@ -87,7 +87,7 @@ const SavedQueriesDropdownComponent: React.FC = ({ ); const renderOption = useCallback( - ({ value }) => ( + ({ value }: any) => ( <> {value.id}
diff --git a/x-pack/plugins/osquery/public/timelines/add_to_timeline_button.tsx b/x-pack/plugins/osquery/public/timelines/add_to_timeline_button.tsx index 6a03317c486d..f59ccfee00ab 100644 --- a/x-pack/plugins/osquery/public/timelines/add_to_timeline_button.tsx +++ b/x-pack/plugins/osquery/public/timelines/add_to_timeline_button.tsx @@ -28,7 +28,7 @@ export const AddToTimelineButton = (props: AddToTimelineButtonProps) => { const queryIds = isArray(value) ? value : [value]; const TimelineIconComponent = useCallback( - (timelineComponentProps) => ( + (timelineComponentProps: any) => ( ), [iconProps] diff --git a/x-pack/plugins/saved_objects_tagging/public/components/edition_modal/utils.ts b/x-pack/plugins/saved_objects_tagging/public/components/edition_modal/utils.ts index e5b98b35a18a..773e8a40fab2 100644 --- a/x-pack/plugins/saved_objects_tagging/public/components/edition_modal/utils.ts +++ b/x-pack/plugins/saved_objects_tagging/public/components/edition_modal/utils.ts @@ -66,7 +66,7 @@ export const useIfMounted = () => { [] ); - const ifMounted = useCallback((func) => { + const ifMounted = useCallback((func?: () => void) => { if (isMounted.current && func) { func(); } diff --git a/x-pack/plugins/searchprofiler/public/application/app.tsx b/x-pack/plugins/searchprofiler/public/application/app.tsx index 321b2a167a38..08dd4b1db647 100644 --- a/x-pack/plugins/searchprofiler/public/application/app.tsx +++ b/x-pack/plugins/searchprofiler/public/application/app.tsx @@ -46,7 +46,7 @@ export const App = () => { ); const onHighlight = useCallback( - (value) => dispatch({ type: 'setHighlightDetails', value }), + (value: any) => dispatch({ type: 'setHighlightDetails', value }), [dispatch] ); diff --git a/x-pack/plugins/searchprofiler/public/application/components/profile_query_editor/profile_query_editor.tsx b/x-pack/plugins/searchprofiler/public/application/components/profile_query_editor/profile_query_editor.tsx index 574f8c7e18b6..577c3e530e8c 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/profile_query_editor/profile_query_editor.tsx +++ b/x-pack/plugins/searchprofiler/public/application/components/profile_query_editor/profile_query_editor.tsx @@ -77,7 +77,10 @@ export const ProfileQueryEditor = memo(() => { } }; - const onEditorReady = useCallback((editorInstance) => (editorRef.current = editorInstance), []); + const onEditorReady = useCallback( + (editorInstance: any) => (editorRef.current = editorInstance), + [] + ); const licenseEnabled = getLicenseStatus().valid; return ( diff --git a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx index 3de834c08829..084f8ca94215 100644 --- a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx @@ -17,7 +17,7 @@ export const useAssistantTelemetry = (): AssistantTelemetry => { const baseConversations = useBaseConversations(); const getAnonymizedConversationTitle = useCallback( - async (title) => { + async (title: string) => { // With persistent storage for conversation replacing id to title, because id is UUID now // and doesn't make any value for telemetry tracking return baseConversations[title] ? title : 'Custom'; diff --git a/x-pack/plugins/security_solution/public/attack_discovery/attack_discovery_panel/tabs/attack_discovery_tab/index.tsx b/x-pack/plugins/security_solution/public/attack_discovery/attack_discovery_panel/tabs/attack_discovery_tab/index.tsx index 23a63d0503db..a850ed1a5d41 100644 --- a/x-pack/plugins/security_solution/public/attack_discovery/attack_discovery_panel/tabs/attack_discovery_tab/index.tsx +++ b/x-pack/plugins/security_solution/public/attack_discovery/attack_discovery_panel/tabs/attack_discovery_tab/index.tsx @@ -11,7 +11,7 @@ import { css } from '@emotion/react'; import React, { useMemo } from 'react'; import { AttackChain } from '../../../attack/attack_chain'; -import { InvestigateInTimelineButton } from '../../../../common/components/event_details/table/investigate_in_timeline_button'; +import { InvestigateInTimelineButton } from '../../../../common/components/event_details/investigate_in_timeline_button'; import { buildAlertsKqlFilter } from '../../../../detections/components/alerts_table/actions'; import { getTacticMetadata } from '../../../helpers'; import { AttackDiscoveryMarkdownFormatter } from '../../../attack_discovery_markdown_formatter'; diff --git a/x-pack/plugins/security_solution/public/cases/pages/index.tsx b/x-pack/plugins/security_solution/public/cases/pages/index.tsx index 1ba63b8c4366..c873e48e4975 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/index.tsx @@ -44,7 +44,8 @@ const CaseContainerComponent: React.FC = () => { const { openFlyout } = useExpandableFlyoutApi(); const getDetectionsRuleDetailsHref = useCallback( - (ruleId) => detectionsFormatUrl(getRuleDetailsUrl(ruleId ?? '', detectionsUrlSearch)), + (ruleId: string | null | undefined) => + detectionsFormatUrl(getRuleDetailsUrl(ruleId ?? '', detectionsUrlSearch)), [detectionsFormatUrl, detectionsUrlSearch] ); diff --git a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx index 5c61900876aa..931c519ae9b5 100644 --- a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx @@ -26,7 +26,7 @@ import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental import { useTourContext } from '../../guided_onboarding_tour'; import { AlertsCasesTourSteps, SecurityStepId } from '../../guided_onboarding_tour/tour_config'; -type Props = EuiDataGridCellValueElementProps & { +export type RowActionProps = EuiDataGridCellValueElementProps & { columnHeaders: ColumnHeaderOptions[]; controlColumn: ControlColumnProps; data: TimelineItem; @@ -67,7 +67,7 @@ const RowActionComponent = ({ setEventsDeleted, width, refetch, -}: Props) => { +}: RowActionProps) => { const { data: timelineNonEcsData, ecs: ecsData, _id: eventId, _index: indexName } = data ?? {}; const { telemetry } = useKibana().services; const { openFlyout } = useExpandableFlyoutApi(); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx index 9a8762cee2c0..eca4c61f9cea 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx @@ -95,7 +95,7 @@ type RenderFunctionProp = ( state: DraggableStateSnapshot ) => React.ReactNode; -interface Props { +export interface DraggableWrapperProps { dataProvider: DataProvider; fieldType?: string; isAggregatable?: boolean; @@ -128,7 +128,7 @@ export const getStyle = ( }; }; -const DraggableOnWrapper: React.FC = React.memo( +const DraggableOnWrapper: React.FC = React.memo( ({ dataProvider, render, scopeId, truncate, hideTopN }) => { const [providerRegistered, setProviderRegistered] = useState(false); const isDisabled = dataProvider.id.includes(`-${ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID}-`); @@ -265,7 +265,7 @@ const DraggableOnWrapper: React.FC = React.memo( ); DraggableOnWrapper.displayName = 'DraggableOnWrapper'; -export const DraggableWrapper: React.FC = React.memo( +export const DraggableWrapper: React.FC = React.memo( ({ dataProvider, isDraggable = false, render, scopeId, truncate, hideTopN }) => { const content = useMemo( () => ( diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx index d0b1ce4eca21..586165893408 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx @@ -7,7 +7,7 @@ import { rgba } from 'polished'; import React, { useCallback } from 'react'; -import type { DraggableChildrenFn } from '@hello-pangea/dnd'; +import type { DraggableChildrenFn, DroppableProps } from '@hello-pangea/dnd'; import { Droppable } from '@hello-pangea/dnd'; import styled from 'styled-components'; @@ -99,7 +99,7 @@ export const DroppableWrapper = React.memo( render = null, renderClone, }) => { - const DroppableContent = useCallback( + const DroppableContent = useCallback( (provided, snapshot) => ( ( [field, id, name, queryValue, value] ); - const renderCallback = useCallback( + const renderCallback = useCallback( (dataProvider, _, snapshot) => snapshot.isDragging ? ( diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.test.ts b/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.test.ts deleted file mode 100644 index fc793df1025e..000000000000 --- a/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.test.ts +++ /dev/null @@ -1,95 +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 type { UseSummaryRowsProps } from './get_alert_summary_rows'; -import { useSummaryRows } from './get_alert_summary_rows'; -import { createAppRootMockRenderer, endpointAlertDataMock } from '../../mock/endpoint'; -import type { RenderHookResult } from '@testing-library/react-hooks/src/types'; -import type { AlertSummaryRow } from './helpers'; - -describe('useSummaryRows', () => { - let hookProps: UseSummaryRowsProps; - let renderHook: () => RenderHookResult; - - beforeEach(() => { - const appContextMock = createAppRootMockRenderer(); - - appContextMock.setExperimentalFlag({ - responseActionsSentinelOneV1Enabled: true, - responseActionsCrowdstrikeManualHostIsolationEnabled: true, - }); - - hookProps = { - data: endpointAlertDataMock.generateEndpointAlertDetailsItemData(), - browserFields: {}, - scopeId: 'scope-id', - eventId: 'event-id', - investigationFields: [], - }; - - renderHook = () => { - return appContextMock.renderHook(() => - useSummaryRows(hookProps) - ); - }; - }); - - it('returns summary rows for default event categories', () => { - const { result } = renderHook(); - - expect(result.current).toEqual( - expect.arrayContaining([ - expect.objectContaining({ title: 'host.name', description: expect.anything() }), - ]) - ); - }); - - it('excludes fields not related to the event source', () => { - const { result } = renderHook(); - - expect(result.current).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ - title: 'agent.id', - description: expect.anything(), - }), - ]) - ); - }); - - it('includes sentinel_one agent status field', () => { - hookProps.data = endpointAlertDataMock.generateSentinelOneAlertDetailsItemData(); - const { result } = renderHook(); - - expect(result.current).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - title: 'Agent status', - description: expect.objectContaining({ - values: ['abfe4a35-d5b4-42a0-a539-bd054c791769'], - }), - }), - ]) - ); - }); - - it('includes crowdstrike agent status field', () => { - hookProps.data = endpointAlertDataMock.generateCrowdStrikeAlertDetailsItemData(); - const { result } = renderHook(); - - expect(result.current).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - title: 'Agent status', - description: expect.objectContaining({ - values: ['abfe4a35-d5b4-42a0-a539-bd054c791769'], - }), - }), - ]) - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.tsx index 357e1230ebee..f591c3d48e0d 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/get_alert_summary_rows.tsx @@ -4,16 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useMemo } from 'react'; -import { find, isEmpty, uniqBy } from 'lodash/fp'; +import { find, uniqBy } from 'lodash/fp'; import { ALERT_RULE_PARAMETERS, ALERT_RULE_TYPE } from '@kbn/rule-data-utils'; import { EventCode, EventCategory } from '@kbn/securitysolution-ecs'; +import { i18n } from '@kbn/i18n'; import { SUPPORTED_AGENT_ID_ALERT_FIELDS } from '../../../../common/endpoint/service/response_actions/constants'; -import { isResponseActionsAlertAgentIdField } from '../../lib/endpoint'; -import { useAlertResponseActionsSupport } from '../../hooks/endpoint/use_alert_response_actions_support'; -import * as i18n from './translations'; -import type { BrowserFields } from '../../../../common/search_strategy/index_fields'; import { ALERTS_HEADERS_THRESHOLD_CARDINALITY, ALERTS_HEADERS_THRESHOLD_COUNT, @@ -31,17 +27,27 @@ import { AGENT_STATUS_FIELD_NAME, QUARANTINED_PATH_FIELD_NAME, } from '../../../timelines/components/timeline/body/renderers/constants'; -import type { AlertSummaryRow } from './helpers'; -import { getEnrichedFieldInfo } from './helpers'; -import type { EventSummaryField, EnrichedFieldInfo } from './types'; +import type { EventSummaryField } from './types'; import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy/timeline'; const THRESHOLD_TERMS_FIELD = `${ALERT_THRESHOLD_RESULT}.terms.field`; const THRESHOLD_TERMS_VALUE = `${ALERT_THRESHOLD_RESULT}.terms.value`; const THRESHOLD_CARDINALITY_FIELD = `${ALERT_THRESHOLD_RESULT}.cardinality.field`; -const THRESHOLD_CARDINALITY_VALUE = `${ALERT_THRESHOLD_RESULT}.cardinality.value`; const THRESHOLD_COUNT = `${ALERT_THRESHOLD_RESULT}.count`; +const AGENT_STATUS = i18n.translate('xpack.securitySolution.detections.alerts.agentStatus', { + defaultMessage: 'Agent status', +}); +const QUARANTINED_FILE_PATH = i18n.translate( + 'xpack.securitySolution.detections.alerts.quarantinedFilePath', + { + defaultMessage: 'Quarantined file path', + } +); +const RULE_TYPE = i18n.translate('xpack.securitySolution.detections.alerts.ruleType', { + defaultMessage: 'Rule type', +}); + /** Always show these fields */ const alwaysDisplayedFields: EventSummaryField[] = [ { id: 'host.name' }, @@ -52,7 +58,7 @@ const alwaysDisplayedFields: EventSummaryField[] = [ return { id: fieldPath, overrideField: AGENT_STATUS_FIELD_NAME, - label: i18n.AGENT_STATUS, + label: AGENT_STATUS, }; }), @@ -72,7 +78,7 @@ const alwaysDisplayedFields: EventSummaryField[] = [ { id: 'orchestrator.resource.type' }, { id: 'process.executable' }, { id: 'file.path' }, - { id: ALERT_RULE_TYPE, label: i18n.RULE_TYPE }, + { id: ALERT_RULE_TYPE, label: RULE_TYPE }, ]; /** @@ -163,7 +169,7 @@ function getFieldsByEventCode( { id: 'file.Ext.quarantine_path', overrideField: QUARANTINED_PATH_FIELD_NAME, - label: i18n.QUARANTINED_FILE_PATH, + label: QUARANTINED_FILE_PATH, }, ]; default: @@ -297,192 +303,3 @@ export function getEventCategoriesFromData(data: TimelineEventsDetailsItem[]): E return { primaryEventCategory, allEventCategories }; } - -export interface UseSummaryRowsProps { - data: TimelineEventsDetailsItem[]; - browserFields: BrowserFields; - scopeId: string; - eventId: string; - investigationFields?: string[]; - isDraggable?: boolean; - isReadOnly?: boolean; -} - -export const useSummaryRows = ({ - data, - browserFields, - scopeId, - eventId, - isDraggable = false, - isReadOnly = false, - investigationFields, -}: UseSummaryRowsProps): AlertSummaryRow[] => { - const responseActionsSupport = useAlertResponseActionsSupport(data); - - return useMemo(() => { - const eventCategories = getEventCategoriesFromData(data); - - const eventCodeField = find({ category: 'event', field: 'event.code' }, data); - - const eventCode = Array.isArray(eventCodeField?.originalValue) - ? eventCodeField?.originalValue?.[0] - : eventCodeField?.originalValue; - - const eventRuleTypeField = find({ category: 'kibana', field: ALERT_RULE_TYPE }, data); - const eventRuleType = Array.isArray(eventRuleTypeField?.originalValue) - ? eventRuleTypeField?.originalValue?.[0] - : eventRuleTypeField?.originalValue; - - const tableFields = getEventFieldsToDisplay({ - eventCategories, - eventCode, - eventRuleType, - highlightedFieldsOverride: investigationFields ?? [], - }); - - return data != null - ? tableFields.reduce((acc, field) => { - const item = data.find( - (d) => d.field === field.id || (field.legacyId && d.field === field.legacyId) - ); - if (!item || isEmpty(item.values)) { - return acc; - } - - // If we found the data by its legacy id we swap the ids to display the correct one - if (item.field === field.legacyId) { - field.id = field.legacyId; - } - - const linkValueField = - field.linkField != null && data.find((d) => d.field === field.linkField); - const description = { - ...getEnrichedFieldInfo({ - item, - linkValueField: linkValueField || undefined, - contextId: scopeId, - scopeId, - browserFields, - eventId, - field, - }), - isDraggable, - isReadOnly, - }; - - // If the field is one used by a supported Response Actions agentType, - // and the alert's host supports response actions - // but the alert field is not the one that the agentType on the alert host uses, - // then exit and return accumulator - if ( - isResponseActionsAlertAgentIdField(field.id) && - responseActionsSupport.isSupported && - responseActionsSupport.details.agentIdField !== field.id - ) { - return acc; - } - - if (field.id === THRESHOLD_TERMS_FIELD) { - const enrichedInfo = enrichThresholdTerms(item, data, description); - if (enrichedInfo) { - return [...acc, ...enrichedInfo]; - } else { - return acc; - } - } - - if (field.id === THRESHOLD_CARDINALITY_FIELD) { - const enrichedInfo = enrichThresholdCardinality(item, data, description); - if (enrichedInfo) { - return [...acc, enrichedInfo]; - } else { - return acc; - } - } - - return [ - ...acc, - { - title: field.label ?? field.id, - description, - }, - ]; - }, []) - : []; - }, [ - data, - investigationFields, - scopeId, - browserFields, - eventId, - isDraggable, - isReadOnly, - responseActionsSupport.details.agentIdField, - responseActionsSupport.isSupported, - ]); -}; - -/** - * Enriches the summary data for threshold terms. - * For any given threshold term, it generates a row with the term's name and the associated value. - */ -function enrichThresholdTerms( - { values: termsFieldArr }: TimelineEventsDetailsItem, - data: TimelineEventsDetailsItem[], - description: EnrichedFieldInfo -) { - const termsValueItem = data.find((d) => d.field === THRESHOLD_TERMS_VALUE); - const termsValueArray = termsValueItem && termsValueItem.values; - - // Make sure both `fields` and `values` are an array and that they have the same length - if ( - Array.isArray(termsFieldArr) && - termsFieldArr.length > 0 && - Array.isArray(termsValueArray) && - termsFieldArr.length === termsValueArray.length - ) { - return termsFieldArr - .map((field, index) => ({ - title: field, - description: { - ...description, - values: [termsValueArray[index]], - }, - })) - .filter( - (entry) => - !alwaysDisplayedFields - .map((alwaysThereEntry) => alwaysThereEntry.id) - .includes(entry.title) - ); - } -} - -/** - * Enriches the summary data for threshold cardinality. - * Reads out the cardinality field and the value and interpolates them into a combined string value. - */ -function enrichThresholdCardinality( - { values: cardinalityFieldArr }: TimelineEventsDetailsItem, - data: TimelineEventsDetailsItem[], - description: EnrichedFieldInfo -) { - const cardinalityValueItem = data.find((d) => d.field === THRESHOLD_CARDINALITY_VALUE); - const cardinalityValueArray = cardinalityValueItem && cardinalityValueItem.values; - - // Only return a summary row if we actually have the correct field and value - if ( - Array.isArray(cardinalityFieldArr) && - cardinalityFieldArr.length === 1 && - Array.isArray(cardinalityValueArray) && - cardinalityFieldArr.length === cardinalityValueArray.length - ) { - return { - title: ALERTS_HEADERS_THRESHOLD_CARDINALITY, - description: { - ...description, - values: [`count(${cardinalityFieldArr[0]}) >= ${cardinalityValueArray[0]}`], - }, - }; - } -} diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx index 6b3bd565f0ee..46f6449cce85 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx @@ -5,42 +5,7 @@ * 2.0. */ -import { get, getOr, isEmpty } from 'lodash/fp'; - -import { - elementOrChildrenHasFocus, - getFocusedDataColindexCell, - getTableSkipFocus, - handleSkipFocus, - stopPropagationAndPreventDefault, -} from '@kbn/timelines-plugin/public'; -import type { BrowserFields } from '../../containers/source'; -import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy/timeline'; -import type { EnrichedFieldInfo, EventSummaryField } from './types'; - -import { - AGENT_STATUS_FIELD_NAME, - QUARANTINED_PATH_FIELD_NAME, -} from '../../../timelines/components/timeline/body/renderers/constants'; - -/** - * An item rendered in the table - */ -export interface Item { - description: string; - field: JSX.Element; - fieldId: string; - type: string; - values: string[]; -} - -export interface AlertSummaryRow { - title: string; - description: EnrichedFieldInfo & { - isDraggable?: boolean; - isReadOnly?: boolean; - }; -} +import { isEmpty } from 'lodash/fp'; /** Returns example text, or an empty string if the field does not have an example */ export const getExampleText = (example: string | number | null | undefined): string => @@ -69,111 +34,3 @@ export const getIconFromType = (type: string | null | undefined) => { }; export const EVENT_FIELDS_TABLE_CLASS_NAME = 'event-fields-table'; - -/** - * Returns `true` if the Event Details "event fields" table, or it's children, - * has focus - */ -export const tableHasFocus = (containerElement: HTMLElement | null): boolean => - elementOrChildrenHasFocus( - containerElement?.querySelector(`.${EVENT_FIELDS_TABLE_CLASS_NAME}`) - ); - -/** - * This function has a side effect. It will skip focus "after" or "before" - * the Event Details table, with exceptions as noted below. - * - * If the currently-focused table cell has additional focusable children, - * i.e. draggables or always-open popover content, the browser's "natural" - * focus management will determine which element is focused next. - */ -export const onEventDetailsTabKeyPressed = ({ - containerElement, - keyboardEvent, - onSkipFocusBeforeEventsTable, - onSkipFocusAfterEventsTable, -}: { - containerElement: HTMLElement | null; - keyboardEvent: React.KeyboardEvent; - onSkipFocusBeforeEventsTable: () => void; - onSkipFocusAfterEventsTable: () => void; -}) => { - const { shiftKey } = keyboardEvent; - - const eventFieldsTableSkipFocus = getTableSkipFocus({ - containerElement, - getFocusedCell: getFocusedDataColindexCell, - shiftKey, - tableHasFocus, - tableClassName: EVENT_FIELDS_TABLE_CLASS_NAME, - }); - - if (eventFieldsTableSkipFocus !== 'SKIP_FOCUS_NOOP') { - stopPropagationAndPreventDefault(keyboardEvent); - handleSkipFocus({ - onSkipFocusBackwards: onSkipFocusBeforeEventsTable, - onSkipFocusForward: onSkipFocusAfterEventsTable, - skipFocus: eventFieldsTableSkipFocus, - }); - } -}; - -export function getEnrichedFieldInfo({ - browserFields, - contextId, - eventId, - field, - item, - linkValueField, - scopeId, -}: { - browserFields: BrowserFields; - contextId: string; - item: TimelineEventsDetailsItem; - eventId: string; - field?: EventSummaryField; - scopeId: string; - linkValueField?: TimelineEventsDetailsItem; -}): EnrichedFieldInfo { - const fieldInfo = { - contextId, - eventId, - fieldType: 'string', - linkValue: undefined, - scopeId, - }; - const linkValue = getOr(null, 'originalValue.0', linkValueField); - const category = item.category ?? ''; - const fieldName = item.field ?? ''; - - const browserField = get([category, 'fields', fieldName], browserFields); - const overrideField = field?.overrideField; - return { - ...fieldInfo, - data: { - field: overrideField ?? fieldName, - format: browserField?.format?.id ?? '', - type: browserField?.type ?? '', - isObjectArray: item.isObjectArray, - }, - values: item.values, - linkValue: linkValue ?? undefined, - fieldFromBrowserField: browserField, - }; -} - -/** - * A lookup table for fields that should not have actions - */ -export const FIELDS_WITHOUT_ACTIONS: { [field: string]: boolean } = { - [AGENT_STATUS_FIELD_NAME]: true, - [QUARANTINED_PATH_FIELD_NAME]: true, -}; - -/** - * Checks whether the given field should have hover or row actions. - * The lookup is fast, so it is not necessary to memoize the result. - */ -export function hasHoverOrRowActions(field: string): boolean { - return !FIELDS_WITHOUT_ACTIONS[field]; -} diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/insights/translations.ts b/x-pack/plugins/security_solution/public/common/components/event_details/insights/translations.ts deleted file mode 100644 index 6afd236caf3d..000000000000 --- a/x-pack/plugins/security_solution/public/common/components/event_details/insights/translations.ts +++ /dev/null @@ -1,16 +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'; - -// TODO: MOVE TO FLYOUT FOLDER - https://github.com/elastic/security-team/issues/7462 -export const SUPPRESSED_ALERTS_COUNT_TECHNICAL_PREVIEW = i18n.translate( - 'xpack.securitySolution.alertDetails.overview.insights.suppressedAlertsCountTechnicalPreview', - { - defaultMessage: 'Technical Preview', - } -); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.test.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.test.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.test.tsx index 1c364e97fbd1..c9b2312c28f5 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.test.tsx @@ -9,12 +9,12 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; import { InvestigateInTimelineButton } from './investigate_in_timeline_button'; -import { TestProviders } from '../../../mock'; +import { TestProviders } from '../../mock'; import { getDataProvider } from './use_action_cell_data_provider'; -import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/components/alerts_table/translations'; +import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../detections/components/alerts_table/translations'; -jest.mock('../../../lib/kibana'); +jest.mock('../../lib/kibana'); describe('InvestigateInTimelineButton', () => { describe('When all props are provided', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.tsx index eb43d61b2f8d..f496ecc89b90 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/investigate_in_timeline_button.tsx @@ -12,18 +12,18 @@ import type { IconType } from '@elastic/eui'; import type { Filter } from '@kbn/es-query'; import { useDispatch, useSelector } from 'react-redux'; -import { sourcererSelectors } from '../../../store'; -import { InputsModelId } from '../../../store/inputs/constants'; -import type { TimeRange } from '../../../store/inputs/model'; -import { inputsActions } from '../../../store/inputs'; -import { updateProviders, setFilters } from '../../../../timelines/store/actions'; -import { sourcererActions } from '../../../store/actions'; -import { SourcererScopeName } from '../../../../sourcerer/store/model'; -import type { DataProvider } from '../../../../../common/types'; -import { TimelineId } from '../../../../../common/types/timeline'; -import { TimelineTypeEnum } from '../../../../../common/api/timeline'; -import { useCreateTimeline } from '../../../../timelines/hooks/use_create_timeline'; -import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/components/alerts_table/translations'; +import { sourcererSelectors } from '../../store'; +import { InputsModelId } from '../../store/inputs/constants'; +import type { TimeRange } from '../../store/inputs/model'; +import { inputsActions } from '../../store/inputs'; +import { updateProviders, setFilters } from '../../../timelines/store/actions'; +import { sourcererActions } from '../../store/actions'; +import { SourcererScopeName } from '../../../sourcerer/store/model'; +import type { DataProvider } from '../../../../common/types'; +import { TimelineId } from '../../../../common/types/timeline'; +import { TimelineTypeEnum } from '../../../../common/api/timeline'; +import { useCreateTimeline } from '../../../timelines/hooks/use_create_timeline'; +import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../detections/components/alerts_table/translations'; export interface InvestigateInTimelineButtonProps { asEmptyButton: boolean; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/components/event_details/mocks.ts similarity index 99% rename from x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts rename to x-pack/plugins/security_solution/public/common/components/event_details/mocks.ts index 0f2cce38662d..ffaf78cb29b4 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/mocks.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const generateAlertDetailsDataMock = () => [ +const generateAlertDetailsDataMock = () => [ { category: 'process', field: 'process.name', values: ['-'], originalValue: '-' }, { category: 'process', field: 'process.pid', values: [0], originalValue: 0 }, { category: 'process', field: 'process.executable', values: ['-'], originalValue: '-' }, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts b/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts deleted file mode 100644 index d9bec6670766..000000000000 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/use_action_cell_data_provider.ts +++ /dev/null @@ -1,196 +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. - */ - -/* eslint-disable complexity */ - -import type { Filter } from '@kbn/es-query'; -import { escapeDataProviderId } from '@kbn/securitysolution-t-grid'; -import { isArray, isEmpty, isString } from 'lodash/fp'; -import { useMemo } from 'react'; -import type { FieldSpec } from '@kbn/data-plugin/common'; - -import { - AGENT_STATUS_FIELD_NAME, - EVENT_MODULE_FIELD_NAME, - EVENT_URL_FIELD_NAME, - GEO_FIELD_TYPE, - HOST_NAME_FIELD_NAME, - IP_FIELD_TYPE, - MESSAGE_FIELD_NAME, - REFERENCE_URL_FIELD_NAME, - RULE_REFERENCE_FIELD_NAME, - SIGNAL_RULE_NAME_FIELD_NAME, - SIGNAL_STATUS_FIELD_NAME, -} from '../../../../timelines/components/timeline/body/renderers/constants'; -import { BYTES_FORMAT } from '../../../../timelines/components/timeline/body/renderers/bytes'; -import { EVENT_DURATION_FIELD_NAME } from '../../../../timelines/components/duration'; -import { getDisplayValue } from '../../../../timelines/components/timeline/data_providers/helpers'; -import { PORT_NAMES } from '../../../../explore/network/components/port/helpers'; -import { INDICATOR_REFERENCE } from '../../../../../common/cti/constants'; -import type { DataProvider, DataProvidersAnd, QueryOperator } from '../../../../../common/types'; -import { IS_OPERATOR } from '../../../../../common/types'; - -export interface UseActionCellDataProvider { - contextId?: string; - eventId?: string; - field: string; - fieldFormat?: string; - fieldFromBrowserField?: Partial; - fieldType?: string; - isObjectArray?: boolean; - linkValue?: string | null; - values: string[] | null | undefined; -} - -export interface ActionCellValuesAndDataProvider { - values: string[]; - dataProviders: DataProvider[]; - filters: Filter[]; -} - -export const getDataProvider = ( - field: string, - id: string, - value: string | string[], - operator: QueryOperator = IS_OPERATOR, - excluded: boolean = false -): DataProvider => ({ - and: [], - enabled: true, - id: escapeDataProviderId(id), - name: field, - excluded, - kqlQuery: '', - queryMatch: { - field, - value, - operator, - displayValue: getDisplayValue(value), - }, -}); - -export const getDataProviderAnd = ( - field: string, - id: string, - value: string | string[], - operator: QueryOperator = IS_OPERATOR, - excluded: boolean = false -): DataProvidersAnd => { - const { and, ...dataProvider } = getDataProvider(field, id, value, operator, excluded); - return dataProvider; -}; - -export const useActionCellDataProvider = ({ - contextId, - eventId, - field, - fieldFormat, - fieldFromBrowserField, - fieldType, - isObjectArray, - linkValue, - values, -}: UseActionCellDataProvider): ActionCellValuesAndDataProvider | null => { - const cellData = useMemo(() => { - if (values === null || values === undefined) return null; - const arrayValues = Array.isArray(values) ? values : [values]; - - // For fields with multiple values we need add an extra filter that makes sure - // that only fields that match ALL the values are queried later on. - let filters: Filter[] = []; - if (arrayValues.length > 1) { - filters = [ - { - meta: {}, - query: { - bool: { - must: arrayValues.map((value) => ({ term: { [field]: value } })), - }, - }, - }, - ]; - } - - return arrayValues.reduce( - (memo, value, index) => { - let id: string = ''; - let valueAsString: string = isString(value) ? value : `${values}`; - const appendedUniqueId = `${contextId}-${eventId}-${field}-${index}-${value}`; - if (fieldFromBrowserField == null) { - memo.values.push(valueAsString); - return memo; - } - - if (isObjectArray || fieldType === GEO_FIELD_TYPE || [MESSAGE_FIELD_NAME].includes(field)) { - memo.values.push(valueAsString); - return memo; - } else if (fieldType === IP_FIELD_TYPE) { - id = `formatted-ip-data-provider-${contextId}-${field}-${value}-${eventId}`; - if (isString(value) && !isEmpty(value)) { - let addresses = value; - try { - addresses = JSON.parse(value); - } catch (_) { - // Default to keeping the existing string value - } - if (isArray(addresses)) { - valueAsString = addresses.join(','); - addresses.forEach((ip) => memo.dataProviders.push(getDataProvider(field, id, ip))); - } - memo.dataProviders.push(getDataProvider(field, id, addresses)); - memo.values.push(valueAsString); - return memo; - } - } else if (PORT_NAMES.some((portName) => field === portName)) { - id = `port-default-draggable-${appendedUniqueId}`; - } else if (field === EVENT_DURATION_FIELD_NAME) { - id = `duration-default-draggable-${appendedUniqueId}`; - } else if (field === HOST_NAME_FIELD_NAME) { - id = `event-details-value-default-draggable-${appendedUniqueId}`; - } else if (fieldFormat === BYTES_FORMAT) { - id = `bytes-default-draggable-${appendedUniqueId}`; - } else if (field === SIGNAL_RULE_NAME_FIELD_NAME) { - id = `event-details-value-default-draggable-${appendedUniqueId}-${linkValue}`; - } else if (field === EVENT_MODULE_FIELD_NAME) { - id = `event-details-value-default-draggable-${appendedUniqueId}-${value}`; - } else if (field === SIGNAL_STATUS_FIELD_NAME) { - id = `alert-details-value-default-draggable-${appendedUniqueId}`; - } else if (field === AGENT_STATUS_FIELD_NAME) { - const valueToUse = typeof value === 'string' ? value : ''; - id = `event-details-value-default-draggable-${appendedUniqueId}`; - valueAsString = valueToUse; - } else if ( - [ - RULE_REFERENCE_FIELD_NAME, - REFERENCE_URL_FIELD_NAME, - EVENT_URL_FIELD_NAME, - INDICATOR_REFERENCE, - ].includes(field) - ) { - id = `event-details-value-default-draggable-${appendedUniqueId}-${value}`; - } else { - id = `event-details-value-default-draggable-${appendedUniqueId}`; - } - memo.values.push(valueAsString); - memo.dataProviders.push(getDataProvider(field, id, value)); - return memo; - }, - { values: [], dataProviders: [], filters } - ); - }, [ - contextId, - eventId, - field, - fieldFormat, - fieldFromBrowserField, - fieldType, - isObjectArray, - linkValue, - values, - ]); - return cellData; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts b/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts index 2362284b3f69..f991db91582d 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts @@ -7,64 +7,6 @@ import { i18n } from '@kbn/i18n'; -export const TABLE = i18n.translate('xpack.securitySolution.eventDetails.table', { - defaultMessage: 'Table', -}); - -export const DESCRIPTION = i18n.translate('xpack.securitySolution.eventDetails.description', { - defaultMessage: 'Description', -}); - -export const AGENT_STATUS = i18n.translate('xpack.securitySolution.detections.alerts.agentStatus', { - defaultMessage: 'Agent status', -}); - -export const QUARANTINED_FILE_PATH = i18n.translate( - 'xpack.securitySolution.detections.alerts.quarantinedFilePath', - { - defaultMessage: 'Quarantined file path', - } -); - -export const RULE_TYPE = i18n.translate('xpack.securitySolution.detections.alerts.ruleType', { - defaultMessage: 'Rule type', -}); - -export const ACTIONS = i18n.translate('xpack.securitySolution.eventDetails.table.actions', { - defaultMessage: 'Actions', -}); - -export const ALERT_REASON = i18n.translate('xpack.securitySolution.eventDetails.alertReason', { - defaultMessage: 'Alert reason', -}); - -export const ENDPOINT_COMMANDS = Object.freeze({ - tried: (command: string) => - i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.tried', { - values: { command }, - defaultMessage: 'tried to execute {command} command', - }), - executed: (command: string) => - i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.executed', { - values: { command }, - defaultMessage: 'executed {command} command', - }), - pending: (command: string) => - i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.pending', { - values: { command }, - defaultMessage: 'is executing {command} command', - }), - failed: (command: string) => - i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.failed', { - values: { command }, - defaultMessage: 'failed to execute {command} command', - }), -}); - -export const SUMMARY_VIEW = i18n.translate('xpack.securitySolution.eventDetails.summaryView', { - defaultMessage: 'summary', -}); - export const ALERT_SUMMARY_CONVERSATION_ID = i18n.translate( 'xpack.securitySolution.alertSummaryView.alertSummaryViewConversationId', { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/types.ts b/x-pack/plugins/security_solution/public/common/components/event_details/types.ts index 7db13725d9eb..7aff42e2a0eb 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/types.ts @@ -17,17 +17,6 @@ export interface FieldsData { isObjectArray: boolean; } -export interface EnrichedFieldInfo { - data: FieldsData | EventFieldsData; - eventId: string; - fieldFromBrowserField?: Partial; - scopeId: string; - values: string[] | null | undefined; - linkValue?: string; -} - -export type EnrichedFieldInfoWithValues = EnrichedFieldInfo & { values: string[] }; - export interface EventSummaryField { id: string; legacyId?: string; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/use_action_cell_data_provider.ts b/x-pack/plugins/security_solution/public/common/components/event_details/use_action_cell_data_provider.ts new file mode 100644 index 000000000000..ded9ced84b3a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/event_details/use_action_cell_data_provider.ts @@ -0,0 +1,44 @@ +/* + * 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 { escapeDataProviderId } from '@kbn/securitysolution-t-grid'; + +import { getDisplayValue } from '../../../timelines/components/timeline/data_providers/helpers'; +import type { DataProvider, DataProvidersAnd, QueryOperator } from '../../../../common/types'; +import { IS_OPERATOR } from '../../../../common/types'; + +export const getDataProvider = ( + field: string, + id: string, + value: string | string[], + operator: QueryOperator = IS_OPERATOR, + excluded: boolean = false +): DataProvider => ({ + and: [], + enabled: true, + id: escapeDataProviderId(id), + name: field, + excluded, + kqlQuery: '', + queryMatch: { + field, + value, + operator, + displayValue: getDisplayValue(value), + }, +}); + +export const getDataProviderAnd = ( + field: string, + id: string, + value: string | string[], + operator: QueryOperator = IS_OPERATOR, + excluded: boolean = false +): DataProvidersAnd => { + const { and, ...dataProvider } = getDataProvider(field, id, value, operator, excluded); + return dataProvider; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index ea81a232cff5..e251370c7e4d 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -24,6 +24,7 @@ import { connect, useDispatch, useSelector } from 'react-redux'; import { ThemeContext } from 'styled-components'; import type { Filter } from '@kbn/es-query'; import type { + ColumnHeaderOptions, DeprecatedCellValueElementProps, DeprecatedRowRenderer, Direction, @@ -249,11 +250,12 @@ const StatefulEventsViewerComponent: React.FC dispatch(dataTableActions.upsertColumn({ column, id: tableId, index })), + (column: ColumnHeaderOptions, index: number) => + dispatch(dataTableActions.upsertColumn({ column, id: tableId, index })), [dispatch, tableId] ), removeColumn: useCallback( - (columnId) => dispatch(dataTableActions.removeColumn({ columnId, id: tableId })), + (columnId: string) => dispatch(dataTableActions.removeColumn({ columnId, id: tableId })), [dispatch, tableId] ), }); @@ -328,7 +330,8 @@ const StatefulEventsViewerComponent: React.FC dispatch(inputsActions.deleteOneQuery({ inputId: InputsModelId.global, id })), + ({ id }: { id: string }) => + dispatch(inputsActions.deleteOneQuery({ inputId: InputsModelId.global, id })), [dispatch] ); @@ -375,7 +378,7 @@ const StatefulEventsViewerComponent: React.FC { + (itemsChangedPerPage: number) => { dispatch( dataTableActions.updateItemsPerPage({ id: tableId, itemsPerPage: itemsChangedPerPage }) ); @@ -384,7 +387,7 @@ const StatefulEventsViewerComponent: React.FC { + (page: number) => { loadPage(page); }, [loadPage] diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/summary_view_select/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/summary_view_select/index.tsx index 88a2638976cf..40d0d4e1a7c0 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/summary_view_select/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/summary_view_select/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { EuiSelectableOption } from '@elastic/eui'; +import type { EuiSelectableOption, EuiSelectableProps } from '@elastic/eui'; import { EuiButtonEmpty, EuiPopover, EuiSelectable, EuiTitle, EuiTextColor } from '@elastic/eui'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { i18n } from '@kbn/i18n'; @@ -116,7 +116,9 @@ const SummaryViewSelectorComponent = ({ viewSelected, onViewChange }: SummaryVie [viewSelected] ); - const renderOption = useCallback((option) => { + const renderOption = useCallback< + NonNullable }>['renderOption']> + >((option) => { return ( <> diff --git a/x-pack/plugins/security_solution/public/common/components/hover_popover/hover_popover.tsx b/x-pack/plugins/security_solution/public/common/components/hover_popover/hover_popover.tsx index 827290565f28..28a72a1bb87c 100644 --- a/x-pack/plugins/security_solution/public/common/components/hover_popover/hover_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/hover_popover/hover_popover.tsx @@ -16,7 +16,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; */ const HOVER_INTENT_DELAY = 100; // ms -interface Props { +export interface HoverPopoverProps { hoverContent: React.ReactNode; anchorPosition?: PopoverAnchorPosition; } @@ -37,7 +37,7 @@ interface Props { * otherwise it will be difficult for keyboard-only and screen * reader users to navigate to and from your popover. */ -export const HoverPopover = React.memo>( +export const HoverPopover = React.memo>( ({ hoverContent, anchorPosition = 'downCenter', children }) => { const [isOpen, setIsOpen] = useState(hoverContent != null); const [showHoverContent, setShowHoverContent] = useState(false); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/index.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/index.tsx index 2e6886af03af..07a73681ec87 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/index.tsx @@ -71,7 +71,7 @@ const CardStepComponent: React.FC<{ const isDone = finishedSteps.has(stepId); const toggleStep = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); const newStatus = !isExpandedStep; diff --git a/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx index 9dd3accd15e3..5aed35ccb4b4 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/helpers.tsx @@ -82,7 +82,7 @@ export const PortContainer = styled.div` } `; -interface ReputationLinkOverflowProps { +export interface ReputationLinkOverflowProps { rowItems: ReputationLinkSetting[]; render?: (item: ReputationLinkSetting) => React.ReactNode; overflowIndexStart?: number; diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx index 4f07d53023e9..9d615d80be63 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -31,7 +31,7 @@ import { isUrlInvalid } from '../../utils/validators'; import * as i18n from './translations'; import { SecurityPageName } from '../../../app/types'; import { getTabsOnUsersDetailsUrl, getUsersDetailsUrl } from '../link_to/redirect_to_users'; -import type { ReputationLinkSetting } from './helpers'; +import type { ReputationLinkSetting, ReputationLinkOverflowProps } from './helpers'; import { LinkAnchor, GenericLinkButton, @@ -72,7 +72,7 @@ const UserDetailsLinkComponent: React.FC<{ telemetry, } = useKibana().services; const goToUsersDetails = useCallback( - (ev) => { + (ev: SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.users, @@ -122,7 +122,7 @@ const UserDetailsLinkComponent: React.FC<{ export const UserDetailsLink = React.memo(UserDetailsLinkComponent); -const HostDetailsLinkComponent: React.FC<{ +export interface HostDetailsLinkProps { children?: React.ReactNode; /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; @@ -131,7 +131,16 @@ const HostDetailsLinkComponent: React.FC<{ onClick?: (e: SyntheticEvent) => void; hostTab?: HostsTableType; title?: string; -}> = ({ children, Component, hostName, isButton, onClick: onClickParam, title, hostTab }) => { +} +const HostDetailsLinkComponent: React.FC = ({ + children, + Component, + hostName, + isButton, + onClick: onClickParam, + title, + hostTab, +}) => { const { formatUrl, search } = useFormatUrl(SecurityPageName.hosts); const { application: { navigateToApp }, @@ -141,7 +150,7 @@ const HostDetailsLinkComponent: React.FC<{ const encodedHostName = encodeURIComponent(hostName); const goToHostDetails = useCallback( - (ev) => { + (ev: SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, @@ -226,7 +235,7 @@ export const ExternalLink = React.memo<{ ExternalLink.displayName = 'ExternalLink'; -const NetworkDetailsLinkComponent: React.FC<{ +export interface NetworkDetailsLinkProps { children?: React.ReactNode; /** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */ Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon; @@ -235,7 +244,17 @@ const NetworkDetailsLinkComponent: React.FC<{ isButton?: boolean; onClick?: (e: SyntheticEvent) => void | undefined; title?: string; -}> = ({ Component, children, ip, flowTarget = FlowTarget.source, isButton, onClick, title }) => { +} + +const NetworkDetailsLinkComponent: React.FC = ({ + Component, + children, + ip, + flowTarget = FlowTarget.source, + isButton, + onClick, + title, +}) => { const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); const getLink = useCallback( @@ -310,7 +329,7 @@ const CaseDetailsLinkComponent: React.FC = ({ ); const goToCaseDetails = useCallback( - async (ev?) => { + async (ev?: SyntheticEvent) => { if (ev) ev.preventDefault(); return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, @@ -350,7 +369,7 @@ export const CreateCaseLink = React.memo<{ children: React.ReactNode }>(({ child const { formatUrl, search } = useFormatUrl(SecurityPageName.case); const { navigateToApp } = useKibana().services.application; const goToCreateCase = useCallback( - async (ev) => { + async (ev: SyntheticEvent) => { ev.preventDefault(); return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, @@ -508,7 +527,7 @@ const ReputationLinkComponent: React.FC<{ [ipReputationLinksSetting, domain, defaultNameMapping, allItemsLimit] ); - const renderCallback = useCallback( + const renderCallback: NonNullable = useCallback( (rowItem) => isReputationLink(rowItem) && ( { - const [markdownErrorMessages, setMarkdownErrorMessages] = useState([]); - const onParse = useCallback( + const [markdownErrorMessages, setMarkdownErrorMessages] = useState([]); + const onParse = useCallback>( (err, { messages }) => { setMarkdownErrorMessages(err ? [err] : messages); setIsMarkdownInvalid(err ? true : false); diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx index 8ea10b1c54f8..37d4e004edf5 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx @@ -16,15 +16,15 @@ import { import { KibanaServices } from '../../../../lib/kibana'; import type { DefaultTimeRangeSetting } from '../../../../utils/default_date_settings'; import { plugin, renderer as Renderer } from '.'; -import type { InvestigateInTimelineButtonProps } from '../../../event_details/table/investigate_in_timeline_button'; +import type { InvestigateInTimelineButtonProps } from '../../../event_details/investigate_in_timeline_button'; import { useUpsellingMessage } from '../../../../hooks/use_upselling'; jest.mock('../../../../lib/kibana'); const mockGetServices = KibanaServices.get as jest.Mock; -jest.mock('../../../event_details/table/investigate_in_timeline_button', () => { +jest.mock('../../../event_details/investigate_in_timeline_button', () => { const originalModule = jest.requireActual( - '../../../event_details/table/investigate_in_timeline_button' + '../../../event_details/investigate_in_timeline_button' ); return { ...originalModule, diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx index 791bace753ff..0496033b0ab4 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx @@ -9,7 +9,7 @@ import { pickBy, isEmpty } from 'lodash'; import type { Plugin } from 'unified'; import moment from 'moment'; import React, { useContext, useMemo, useCallback, useState } from 'react'; -import type { RemarkTokenizer } from '@elastic/eui'; +import type { RemarkTokenizer, EuiSelectProps } from '@elastic/eui'; import { EuiLoadingSpinner, EuiIcon, @@ -43,7 +43,7 @@ import { useKibana } from '../../../../lib/kibana'; import { useInsightQuery } from './use_insight_query'; import { useInsightDataProviders, type Provider } from './use_insight_data_providers'; import { BasicAlertDataContext } from '../../../../../flyout/document_details/left/components/investigation_guide_view'; -import { InvestigateInTimelineButton } from '../../../event_details/table/investigate_in_timeline_button'; +import { InvestigateInTimelineButton } from '../../../event_details/investigate_in_timeline_button'; import { getTimeRangeSettings, parseDateWithDefault, @@ -382,7 +382,7 @@ const InsightEditorComponent = ({ const onChange = useCallback((filters: Filter[]) => { setProviders(filtersToInsightProviders(filters)); }, []); - const selectOnChange = useCallback( + const selectOnChange = useCallback>( (event) => { relativeTimerangeController.field.onChange(event.target.value); }, diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/use_insight_data_providers.test.ts b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/use_insight_data_providers.test.ts index 9ab25b00eabd..4d1807b91b71 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/use_insight_data_providers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/use_insight_data_providers.test.ts @@ -11,7 +11,7 @@ import { useInsightDataProviders, type UseInsightDataProvidersResult, } from './use_insight_data_providers'; -import { mockAlertDetailsData } from '../../../event_details/__mocks__'; +import { mockAlertDetailsData } from '../../../event_details/mocks'; const mockAlertDetailsDataWithIsObject = mockAlertDetailsData.map((detail) => { return { diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx index 6cc54184db60..6a37280f9ef2 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx @@ -25,6 +25,12 @@ import { LabelField } from './label_field'; import { OsqueryNotAvailablePrompt } from './not_available_prompt'; import { useKibana } from '../../../../lib/kibana'; +interface FormData { + label: string; + query: string; + ecs_mapping: Record; +} + const OsqueryEditorComponent = ({ node, onSave, @@ -43,11 +49,7 @@ const OsqueryEditorComponent = ({ capabilities: { osquery: osqueryPermissions }, }, } = useKibana().services; - const formMethods = useForm<{ - label: string; - query: string; - ecs_mapping: Record; - }>({ + const formMethods = useForm({ defaultValues: { label: node?.configuration?.label, query: node?.configuration?.query, @@ -56,7 +58,7 @@ const OsqueryEditorComponent = ({ }); const onSubmit = useCallback( - (data) => { + (data: FormData) => { onSave( `!{osquery${JSON.stringify( pickBy( diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/select_interval.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/select_interval.tsx index 717c0d0a4840..e273487d3117 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/select_interval.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/select_interval.tsx @@ -5,6 +5,7 @@ * 2.0. */ import React, { useCallback } from 'react'; +import type { EuiSelectProps } from '@elastic/eui'; import { EuiSelect, EuiIcon, EuiToolTip } from '@elastic/eui'; import * as i18n from './translations'; @@ -31,7 +32,7 @@ export const SelectInterval: React.FC<{ interval: string; onChange: (interval: string) => void; }> = ({ interval, onChange }) => { - const onChangeCb = useCallback( + const onChangeCb = useCallback>( (e) => { onChange(e.target.value); }, diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts index e7a7571c6e51..b1064431f426 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts @@ -47,7 +47,7 @@ export const useSecurityJobs = (): UseSecurityJobsReturn => { const isMlEnabled = isMlAdmin && isLicensed; const onError = useCallback( - (error) => { + (error: unknown) => { addError(error, { title: i18n.SIEM_JOB_FETCH_FAILURE }); }, [addError] diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx index 45fb359c0e12..46fbd4c5f70e 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx @@ -7,6 +7,7 @@ import styled from 'styled-components'; import React, { useState, useCallback } from 'react'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiSwitch } from '@elastic/eui'; import { isJobLoading, @@ -36,7 +37,7 @@ export const JobSwitchComponent = ({ onJobStateChange, }: JobSwitchProps) => { const [isLoading, setIsLoading] = useState(false); - const handleChange = useCallback( + const handleChange: EuiSwitchProps['onChange'] = useCallback( async (e) => { setIsLoading(true); await onJobStateChange(job, job.latestTimestampMs || 0, e.target.checked); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx index 0f38ff32cfef..c37fed0c0281 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx @@ -29,7 +29,7 @@ const TabNavigationItemComponent = ({ const { getAppUrl, navigateTo } = useNavigation(); const handleClick = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateTo({ path: hrefWithSearch, restoreScroll: true }); track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${id}`); diff --git a/x-pack/plugins/security_solution/public/common/components/response_actions/endpoint_action_results.tsx b/x-pack/plugins/security_solution/public/common/components/response_actions/endpoint_action_results.tsx index 7444a53ee441..f0d21c00287f 100644 --- a/x-pack/plugins/security_solution/public/common/components/response_actions/endpoint_action_results.tsx +++ b/x-pack/plugins/security_solution/public/common/components/response_actions/endpoint_action_results.tsx @@ -15,7 +15,7 @@ import type { import { useUserPrivileges } from '../user_privileges'; import { useGetAutomatedActionResponseList } from '../../../management/hooks/response_actions/use_get_automated_action_list'; import { ActionsLogExpandedTray } from '../../../management/components/endpoint_response_actions_list/components/action_log_expanded_tray'; -import { ENDPOINT_COMMANDS } from '../event_details/translations'; +import { ENDPOINT_COMMANDS } from './translations'; import { ResponseActionsEmptyPrompt } from './response_actions_empty_prompt'; interface EndpointResponseActionResultsProps { diff --git a/x-pack/plugins/security_solution/public/common/components/response_actions/translations.ts b/x-pack/plugins/security_solution/public/common/components/response_actions/translations.ts index c71d344539bb..2c59cfef1bfd 100644 --- a/x-pack/plugins/security_solution/public/common/components/response_actions/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/response_actions/translations.ts @@ -13,3 +13,26 @@ export const LOAD_CONNECTORS_ERROR_MESSAGE = i18n.translate( defaultMessage: 'Error loading connectors. Please check your configuration and try again.', } ); + +export const ENDPOINT_COMMANDS = Object.freeze({ + tried: (command: string) => + i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.tried', { + values: { command }, + defaultMessage: 'tried to execute {command} command', + }), + executed: (command: string) => + i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.executed', { + values: { command }, + defaultMessage: 'executed {command} command', + }), + pending: (command: string) => + i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.pending', { + values: { command }, + defaultMessage: 'is executing {command} command', + }), + failed: (command: string) => + i18n.translate('xpack.securitySolution.eventDetails.responseActions.endpoint.failed', { + values: { command }, + defaultMessage: 'failed to execute {command} command', + }), +}); diff --git a/x-pack/plugins/security_solution/public/common/components/rule_name/index.tsx b/x-pack/plugins/security_solution/public/common/components/rule_name/index.tsx index 07592457de41..ebd0e0842dd1 100644 --- a/x-pack/plugins/security_solution/public/common/components/rule_name/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/rule_name/index.tsx @@ -32,7 +32,7 @@ const RuleNameComponents = ({ name, id, appId }: RuleNameProps) => { [getUrlForApp, id, appId] ); const goToRuleDetails = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(appId, { deepLinkId: 'rules', diff --git a/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx b/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx index af4c0aa7b0c1..792074b39cfe 100644 --- a/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx @@ -305,7 +305,7 @@ export const SearchBarComponent = memo( }, [sourcererDataView, fieldFormats]); const onTimeRangeChange = useCallback( - ({ query, dateRange }) => { + ({ dateRange }: { dateRange: TimeRange }) => { const isQuickSelection = dateRange.from.includes('now') || dateRange.to.includes('now'); updateSearch({ end: dateRange.to, @@ -313,7 +313,6 @@ export const SearchBarComponent = memo( id, isInvalid: false, isQuickSelection, - query, setTablesActivePageToZero, start: dateRange.from, updateTime: true, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.tsx index e152a5f96d61..f4838a414b1c 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.tsx @@ -12,9 +12,10 @@ import type { TimelineItem } from '@kbn/timelines-plugin/common'; import { ALERT_WORKFLOW_ASSIGNEE_IDS } from '@kbn/rule-data-utils'; import type { SetAlertAssigneesFunc } from './use_set_alert_assignees'; +import type { AssigneesApplyPanelProps } from '../../assignees/assignees_apply_panel'; import { AssigneesApplyPanel } from '../../assignees/assignees_apply_panel'; -interface BulkAlertAssigneesPanelComponentProps { +export interface BulkAlertAssigneesPanelComponentProps { alertItems: TimelineItem[]; setIsLoading: (isLoading: boolean) => void; refresh?: () => void; @@ -47,7 +48,7 @@ const BulkAlertAssigneesPanelComponent: React.FC( async (assignees) => { closePopoverMenu(); if (onSubmit) { diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx index 67ba6562abc2..8c3b48d64b63 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx @@ -18,7 +18,7 @@ import { createInitialTagsState } from './helpers'; import { createAlertTagsReducer, initialState } from './reducer'; import type { SetAlertTagsFunc } from './use_set_alert_tags'; -interface BulkAlertTagsPanelComponentProps { +export interface BulkAlertTagsPanelComponentProps { alertItems: TimelineItem[]; refetchQuery?: () => void; setIsLoading: (isLoading: boolean) => void; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.tsx index 4c25665afa5c..a91fc5ad8aed 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.tsx @@ -19,6 +19,7 @@ import { isEmpty } from 'lodash/fp'; import { useLicense } from '../../../hooks/use_license'; import { useAlertsPrivileges } from '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; import { ASSIGNEES_PANEL_WIDTH } from '../../assignees/constants'; +import type { BulkAlertAssigneesPanelComponentProps } from './alert_bulk_assignees'; import { BulkAlertAssigneesPanel } from './alert_bulk_assignees'; import * as i18n from './translations'; import { useSetAlertAssignees } from './use_set_alert_assignees'; @@ -45,7 +46,9 @@ export const useBulkAlertAssigneesItems = ({ const { hasIndexWrite } = useAlertsPrivileges(); const setAlertAssignees = useSetAlertAssignees(); - const handleOnAlertAssigneesSubmit = useCallback( + const handleOnAlertAssigneesSubmit = useCallback< + BulkAlertAssigneesPanelComponentProps['onSubmit'] + >( async (assignees, ids, onSuccess, setIsLoading) => { if (setAlertAssignees) { await setAlertAssignees(assignees, ids, onSuccess, setIsLoading); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx index c155d39e2a3a..d83d2c7dad0d 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx @@ -9,6 +9,7 @@ import { EuiFlexGroup, EuiIconTip, EuiFlexItem } from '@elastic/eui'; import type { RenderContentPanelProps } from '@kbn/triggers-actions-ui-plugin/public/types'; import React, { useCallback, useMemo } from 'react'; import { useAlertsPrivileges } from '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; +import type { BulkAlertTagsPanelComponentProps } from './alert_bulk_tags'; import { BulkAlertTagsPanel } from './alert_bulk_tags'; import * as i18n from './translations'; import { useSetAlertTags } from './use_set_alert_tags'; @@ -27,7 +28,7 @@ export interface UseBulkAlertTagsPanel { export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) => { const { hasIndexWrite } = useAlertsPrivileges(); const setAlertTags = useSetAlertTags(); - const handleOnAlertTagsSubmit = useCallback( + const handleOnAlertTagsSubmit = useCallback( async (tags, ids, onSuccess, setIsLoading) => { if (setAlertTags) { await setAlertTags(tags, ids, onSuccess, setIsLoading); diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx index debeca81783d..a72675d38140 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx @@ -19,6 +19,7 @@ import type { TypedLensByValueInput, XYState, } from '@kbn/lens-plugin/public'; +import type { LensBaseEmbeddableInput } from '@kbn/lens-plugin/public/embeddable'; import { setAbsoluteRangeDatePicker } from '../../store/inputs/actions'; import { useKibana } from '../../lib/kibana'; import { useLensAttributes } from './use_lens_attributes'; @@ -159,7 +160,7 @@ const LensEmbeddableComponent: React.FC = ({ }); const updateDateRange = useCallback( - ({ range }) => { + ({ range }: { range: Array }) => { const [min, max] = range; dispatch( setAbsoluteRangeDatePicker({ @@ -172,7 +173,7 @@ const LensEmbeddableComponent: React.FC = ({ [dispatch, inputsModelId] ); - const onFilterCallback = useCallback( + const onFilterCallback = useCallback['onFilter']>( (event) => { if (disableOnClickFilter) { event.preventDefault(); diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts index 6d285e040729..f6a90ebfd479 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts @@ -11,6 +11,7 @@ import type { FormBasedPersistedState, TypedLensByValueInput, } from '@kbn/lens-plugin/public'; +import type { IKibanaSearchResponse } from '@kbn/search-types'; import type { DataViewSpec } from '@kbn/data-views-plugin/common'; import type { Action } from '@kbn/ui-actions-plugin/public'; import type { Filter, Query } from '@kbn/es-query'; @@ -145,7 +146,7 @@ export interface RequestStatistic { } export interface Response { - json?: { rawResponse?: object }; + json?: IKibanaSearchResponse; time?: number; } diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_embeddable_inspect.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_embeddable_inspect.tsx index ca80999a8106..ee577d4a310d 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_embeddable_inspect.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_embeddable_inspect.tsx @@ -5,18 +5,19 @@ * 2.0. */ +import type { LensBaseEmbeddableInput } from '@kbn/lens-plugin/public/embeddable'; import { useCallback } from 'react'; -import type { OnEmbeddableLoaded } from './types'; +import type { OnEmbeddableLoaded, Request } from './types'; import { getRequestsAndResponses } from './utils'; export const useEmbeddableInspect = (onEmbeddableLoad?: OnEmbeddableLoaded) => { - const setInspectData = useCallback( + const setInspectData = useCallback>( (isLoading, adapters) => { if (!adapters) { return; } - const data = getRequestsAndResponses(adapters?.requests?.getRequests()); + const data = getRequestsAndResponses(adapters?.requests?.getRequests() as Request[]); onEmbeddableLoad?.({ requests: data.requests, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_redirect_to_dashboard_from_lens.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_redirect_to_dashboard_from_lens.ts index 1aebf72217c5..3aee19bf6edd 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_redirect_to_dashboard_from_lens.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_redirect_to_dashboard_from_lens.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { RedirectToProps } from '@kbn/dashboard-plugin/public/dashboard_container/types'; import { useMemo, useCallback } from 'react'; import { SecurityPageName } from '../../../../common'; import { useNavigateTo } from '../../lib/kibana'; @@ -39,11 +40,11 @@ export const useRedirectToDashboardFromLens = ({ ); const redirectTo = useCallback( - (props) => { - if (props.destination === 'listing') { + (props?: RedirectToProps) => { + if (props?.destination === 'listing') { navigateTo({ url: dashboardListingUrl }); } - if (props.destination === 'dashboard') { + if (props?.destination === 'dashboard') { navigateTo({ url: getEditOrCreateDashboardUrl(props.id) }); } }, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_save_to_library.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_save_to_library.tsx index 8940853444d1..c7a44842fc51 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_save_to_library.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_save_to_library.tsx @@ -38,6 +38,8 @@ export const useSaveToLibrary = ({ getOriginatingPath={(dashboardId) => `${SecurityPageName.dashboards}/${getEditOrCreateDashboardPath(dashboardId)}` } + // Type 'string' is not assignable to type 'RedirectToProps | undefined'. + // @ts-expect-error redirectTo={redirectTo} />, startServices diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index f305088ef3d3..a121919b412e 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -105,14 +105,17 @@ export const useFetchIndex = ( const { addError } = useAppToasts(); const indexFieldsSearch = useCallback( - (iNames) => { + (iNames: string[]) => { const asyncSearch = async () => { try { setState({ ...state, loading: true }); abortCtrl.current = new AbortController(); const dv = await data.dataViews.create({ title: iNames.join(','), allowNoIndex: true }); const dataView = dv.toSpec(); - const { browserFields } = getDataViewStateFromIndexFields(iNames, dataView.fields); + const { browserFields } = getDataViewStateFromIndexFields( + iNames.join(','), + dataView.fields + ); previousIndexesName.current = dv.getIndexPattern().split(','); diff --git a/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts b/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts index b140252e13a6..2c0988e29ed8 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts @@ -27,7 +27,7 @@ export const useNavigateByRouterEventHandler = ( ): EventHandlerCallback => { const history = useHistory(); return useCallback( - (ev) => { + (ev: React.MouseEvent) => { try { if (onClick) { onClick(ev); diff --git a/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts b/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts index a4b998d3bca9..1d284d21e914 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts @@ -41,7 +41,7 @@ export const useNavigateToAppEventHandler = ( const { path, state, onClick, deepLinkId, openInNewTab } = options || {}; return useCallback( - (ev) => { + (ev: React.MouseEvent) => { try { if (onClick) { onClick(ev); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_add_integrations_url.ts b/x-pack/plugins/security_solution/public/common/hooks/use_add_integrations_url.ts index 07a63013b068..e80c1e871d49 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_add_integrations_url.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_add_integrations_url.ts @@ -27,7 +27,7 @@ export const useAddIntegrationsUrl = () => { const href = useMemo(() => prepend(integrationsUrl), [prepend, integrationsUrl]); const onClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); navigateTo({ url: href }); }, diff --git a/x-pack/plugins/security_solution/public/common/utils/use_set_field_value_cb.ts b/x-pack/plugins/security_solution/public/common/utils/use_set_field_value_cb.ts index 8f57dd78d8a5..c067e1747b4f 100644 --- a/x-pack/plugins/security_solution/public/common/utils/use_set_field_value_cb.ts +++ b/x-pack/plugins/security_solution/public/common/utils/use_set_field_value_cb.ts @@ -18,7 +18,7 @@ export const useSetFieldValueWithCallback = ({ setFieldValue: FormHook['setFieldValue']; }) => { const isWaitingRef = useRef(false); - const valueRef = useRef(); + const valueRef = useRef(); const [callback, setCallback] = useState<() => void>(() => null); useEffect(() => { @@ -30,7 +30,7 @@ export const useSetFieldValueWithCallback = ({ }, [value, callback]); return useCallback( - (v, cb) => { + (v: unknown, cb: () => void) => { setFieldValue(field, v); setCallback(() => cb); diff --git a/x-pack/plugins/security_solution/public/dashboards/components/dashboard_renderer.tsx b/x-pack/plugins/security_solution/public/dashboards/components/dashboard_renderer.tsx index 9fc53f1a4175..83f48d76246e 100644 --- a/x-pack/plugins/security_solution/public/dashboards/components/dashboard_renderer.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/components/dashboard_renderer.tsx @@ -8,13 +8,18 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import type { DashboardContainerInput } from '@kbn/dashboard-plugin/common'; -import type { DashboardAPI, DashboardCreationOptions } from '@kbn/dashboard-plugin/public'; +import type { + DashboardAPI, + DashboardCreationOptions, + DashboardLocatorParams, +} from '@kbn/dashboard-plugin/public'; import { DashboardRenderer as DashboardContainerRenderer } from '@kbn/dashboard-plugin/public'; import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { Filter, Query } from '@kbn/es-query'; import { useDispatch } from 'react-redux'; import { BehaviorSubject } from 'rxjs'; +import type { DashboardRendererProps } from '@kbn/dashboard-plugin/public/dashboard_container/external_api/dashboard_renderer'; import { APP_UI_ID } from '../../../common'; import { DASHBOARDS_PATH, SecurityPageName } from '../../../common/constants'; import { useGetSecuritySolutionUrl } from '../../common/components/link_to'; @@ -64,7 +69,7 @@ const DashboardRendererComponent = ({ const isCreateDashboard = !savedObjectId; const getSecuritySolutionDashboardUrl = useCallback( - ({ dashboardId }) => { + ({ dashboardId }: DashboardLocatorParams) => { return getSecuritySolutionUrl({ deepLinkId: SecurityPageName.dashboards, path: dashboardId, @@ -73,7 +78,7 @@ const DashboardRendererComponent = ({ [getSecuritySolutionUrl] ); - const goToDashboard = useCallback( + const goToDashboard = useCallback['navigate']>( /** * Note: Due to the query bar being separate from the portable dashboard, the "Use filters and query from origin * dashboard" and "Use date range from origin dashboard" Link embeddable settings do not make sense in this context. diff --git a/x-pack/plugins/security_solution/public/dashboards/components/dashboard_tool_bar.tsx b/x-pack/plugins/security_solution/public/dashboards/components/dashboard_tool_bar.tsx index eb74f7c56350..3a5e3d43eae6 100644 --- a/x-pack/plugins/security_solution/public/dashboards/components/dashboard_tool_bar.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/components/dashboard_tool_bar.tsx @@ -12,6 +12,7 @@ import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { ChromeBreadcrumb } from '@kbn/core/public'; import type { DashboardCapabilities } from '@kbn/dashboard-plugin/common'; +import type { RedirectToProps } from '@kbn/dashboard-plugin/public/dashboard_container/types'; import { SecurityPageName } from '../../../common'; import { useCapabilities, useKibana, useNavigation } from '../../common/lib/kibana'; import { APP_NAME } from '../../../common/constants'; @@ -30,7 +31,7 @@ const DashboardToolBarComponent = ({ const { navigateTo, getAppUrl } = useNavigation(); const redirectTo = useCallback( - ({ destination, id }) => { + ({ destination, id }: RedirectToProps & { id?: string }) => { if (destination === 'listing') { navigateTo({ deepLinkId: SecurityPageName.dashboards }); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/ml_jobs_description/admin/ml_admin_job_description.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/ml_jobs_description/admin/ml_admin_job_description.tsx index 7f1236aef08c..af30519a3377 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/ml_jobs_description/admin/ml_admin_job_description.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/ml_jobs_description/admin/ml_admin_job_description.tsx @@ -10,6 +10,7 @@ import React, { useCallback, useMemo, memo } from 'react'; import { useEnableDataFeed } from '../../../../../common/components/ml_popover/hooks/use_enable_data_feed'; import type { SecurityJob } from '../../../../../common/components/ml_popover/types'; +import type { JobSwitchProps } from '../../../../../common/components/ml_popover/jobs_table/job_switch'; import { JobSwitch } from '../../../../../common/components/ml_popover/jobs_table/job_switch'; import { MlJobItem } from '../ml_job_item'; @@ -31,8 +32,8 @@ const MlAdminJobDescriptionComponent: FC = ({ isLoading: isLoadingEnableDataFeed, } = useEnableDataFeed(); - const handleJobStateChange = useCallback( - async (_, latestTimestampMs: number, enable: boolean) => { + const handleJobStateChange = useCallback( + async (_, latestTimestampMs, enable) => { if (enable) { await enableDatafeed(job, latestTimestampMs); } else { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_form/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_form/index.tsx index 4dbbf1f3a920..997930926f26 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_form/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_form/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { EuiSelectProps, EuiFieldNumberProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, @@ -106,7 +107,7 @@ export const ScheduleItem = ({ const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); const { value, setValue } = field; - const onChangeTimeType = useCallback( + const onChangeTimeType = useCallback>( (e) => { setTimeType(e.target.value); setValue(`${timeVal}${e.target.value}`); @@ -114,7 +115,7 @@ export const ScheduleItem = ({ [setValue, timeVal] ); - const onChangeTimeVal = useCallback( + const onChangeTimeVal = useCallback>( (e) => { const sanitizedValue = getNumberFromUserInput(e.target.value, minimumValue); setTimeVal(sanitizedValue); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/eql_query_bar/footer.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/eql_query_bar/footer.tsx index 7f7a6ab21a38..fd2bc98a048b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/eql_query_bar/footer.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/eql_query_bar/footer.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { EuiComboBoxOptionOption } from '@elastic/eui'; +import type { EuiComboBoxOptionOption, EuiFieldNumberProps } from '@elastic/eui'; import { EuiButtonIcon, EuiComboBox, @@ -78,7 +78,7 @@ export const EqlQueryBarFooter: FC = ({ onOptionsChange, }) => { const [openEqlSettings, setIsOpenEqlSettings] = useState(false); - const [localSize, setLocalSize] = useState(optionsSelected?.size ?? 100); + const [localSize, setLocalSize] = useState(optionsSelected?.size ?? 100); const debounceSize = useRef(); const openEqlSettingsHandler = useCallback(() => { @@ -124,10 +124,10 @@ export const EqlQueryBarFooter: FC = ({ }, [onOptionsChange] ); - const handleSizeField = useCallback( + const handleSizeField = useCallback>( (evt) => { if (onOptionsChange) { - setLocalSize(evt?.target?.value); + setLocalSize(evt?.target?.valueAsNumber); if (debounceSize.current?.cancel) { debounceSize.current?.cancel(); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.tsx index 1ef86c1cab1e..cc4d968d1b52 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.tsx @@ -33,6 +33,7 @@ import type { SavedQuery } from '@kbn/data-plugin/public'; import type { DataViewBase } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; import { useSetFieldValueWithCallback } from '../../../../common/utils/use_set_field_value_cb'; +import type { SetRuleQuery } from '../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'; import { useRuleFromTimeline } from '../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'; import { isMlRule } from '../../../../../common/machine_learning/helpers'; import type { EqlOptionsSelected, FieldsEqlOptions } from '../../../../../common/search_strategy'; @@ -65,7 +66,7 @@ import { useFormData, UseMultiFields, } from '../../../../shared_imports'; -import type { FormHook } from '../../../../shared_imports'; +import type { FormHook, FieldHook } from '../../../../shared_imports'; import { schema } from './schema'; import { getTermsAggregationFields } from './utils'; import { useExperimentalFeatureFieldsTransform } from './use_experimental_feature_fields_transform'; @@ -161,6 +162,14 @@ const IntendedRuleTypeEuiFormRow = styled(RuleTypeEuiFormRow)` ${({ theme }) => `padding-left: ${theme.eui.euiSizeXL};`} `; +/* eslint-disable react/no-unused-prop-types */ +interface GroupByChildrenProps { + groupByRadioSelection: FieldHook; + groupByDurationUnit: FieldHook; + groupByDurationValue: FieldHook; +} +/* eslint-enable react/no-unused-prop-types */ + // eslint-disable-next-line complexity const StepDefineRuleComponent: FC = ({ dataSourceType, @@ -225,7 +234,7 @@ const StepDefineRuleComponent: FC = ({ setFieldValue, }); - const handleSetRuleFromTimeline = useCallback( + const handleSetRuleFromTimeline = useCallback( ({ index: timelineIndex, queryBar: timelineQueryBar, eqlOptions }) => { const setQuery = () => { setFieldValue('index', timelineIndex); @@ -426,7 +435,12 @@ const StepDefineRuleComponent: FC = ({ }, []); const ThresholdInputChildren = useCallback( - ({ thresholdField, thresholdValue, thresholdCardinalityField, thresholdCardinalityValue }) => ( + ({ + thresholdField, + thresholdValue, + thresholdCardinalityField, + thresholdCardinalityValue, + }: Record) => ( = ({ ); const ThreatMatchInputChildren = useCallback( - ({ threatMapping }) => ( + ({ threatMapping }: Record) => ( = ({ const isMissingFieldsDisabled = areSuppressionFieldsDisabled || !areSuppressionFieldsSelected; const GroupByChildren = useCallback( - ({ groupByRadioSelection, groupByDurationUnit, groupByDurationValue }) => ( + ({ + groupByRadioSelection, + groupByDurationUnit, + groupByDurationValue, + }: GroupByChildrenProps) => ( = ({ ); const AlertSuppressionMissingFields = useCallback( - ({ suppressionMissingFields }) => ( + ({ suppressionMissingFields }: Record>) => ( { const { setValue } = props.field; const onChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const throttle = e.target.value; setValue(throttle); }, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index 5e6ed40d4d28..deb58fbed49a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -455,7 +455,7 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { }; const goToDetailsRule = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/search_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/search_bar.tsx index 36dac931265c..5bcfc5b0784d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/search_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/search_bar.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback, useMemo } from 'react'; +import type { EuiSearchBarProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSearchBar } from '@elastic/eui'; import * as i18n from './translations'; @@ -61,8 +62,8 @@ const ExceptionsViewerSearchBarComponent = ({ onSearch, onAddExceptionClick, }: ExceptionsViewerSearchBarProps): JSX.Element => { - const handleOnSearch = useCallback( - ({ queryText }): void => { + const handleOnSearch = useCallback>( + ({ queryText }) => { onSearch({ search: queryText }); }, [onSearch] diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/link_list_switch/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/link_list_switch/index.tsx index 486f0c7a5bf4..cb87fea8cd25 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/link_list_switch/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/link_list_switch/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ import React, { memo, useCallback, useMemo } from 'react'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiFlexItem, EuiSwitch } from '@elastic/eui'; import type { ExceptionListRuleReferencesSchema } from '../../../../../../../common/api/detection_engine/rule_exceptions'; @@ -26,7 +27,7 @@ export const LinkListSwitch = memo( () => Boolean(linkedList.find((l) => l.id === list.id)), [linkedList, list.id] ); - const onLinkOrUnlinkList = useCallback( + const onLinkOrUnlinkList = useCallback( ({ target: { checked } }) => { const newLinkedLists = !checked ? linkedList?.filter((item) => item.id !== list.id) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/link_rule_switch/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/link_rule_switch/index.tsx index 080a59a8082f..25fcf6f942c6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/link_rule_switch/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/link_rule_switch/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ import React, { memo, useCallback, useMemo } from 'react'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiFlexItem, EuiSwitch } from '@elastic/eui'; import type { RuleResponse } from '../../../../../../../common/api/detection_engine'; @@ -22,7 +23,7 @@ export const LinkRuleSwitch = memo( () => Boolean(linkedRules.find((r) => r.id === rule.id)), [linkedRules, rule.id] ); - const onLinkOrUnlinkRule = useCallback( + const onLinkOrUnlinkRule = useCallback( ({ target: { checked } }) => { const newLinkedRules = !checked ? linkedRules?.filter((item) => item.id !== rule.id) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_filters.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_filters.tsx index 913dbd5a0fbc..5640f64cd7a0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_filters.tsx @@ -31,7 +31,7 @@ const AddPrebuiltRulesTableFiltersComponent = () => { const { tags: selectedTags } = filterOptions; const handleOnSearch = useCallback( - (filterString) => { + (filterString: string) => { setFilterOptions((filters) => ({ ...filters, filter: filterString.trim(), diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_duplicate_exceptions_confirmation.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_duplicate_exceptions_confirmation.tsx index 74575c327fbc..fe01accf5e10 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_duplicate_exceptions_confirmation.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_duplicate_exceptions_confirmation.tsx @@ -27,8 +27,8 @@ const BulkActionDuplicateExceptionsConfirmationComponent = ({ ); const handleRadioChange = useCallback( - (optionId) => { - setSelectedDuplicateOption(optionId); + (optionId: string) => { + setSelectedDuplicateOption(optionId as DuplicateOptions); }, [setSelectedDuplicateOption] ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx index e7e81b8dd334..e900c20eae9a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx @@ -47,7 +47,7 @@ const RulesTableFiltersComponent = () => { } = filterOptions; const handleOnSearch = useCallback( - (filterString) => { + (filterString: string) => { startTransaction({ name: RULES_TABLE_ACTIONS.FILTER }); setFilterOptions({ filter: filterString.trim() }); }, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_filters.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_filters.tsx index fc8fecab1e07..215a810bf3aa 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_filters.tsx @@ -31,7 +31,7 @@ const UpgradePrebuiltRulesTableFiltersComponent = () => { const { tags: selectedTags } = filterOptions; const handleOnSearch = useCallback( - (filterString) => { + (filterString: string) => { setFilterOptions((filters) => ({ ...filters, filter: filterString.trim(), diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts index ecd67546e762..4e6d42e4dc60 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts @@ -28,10 +28,12 @@ export const extractSelected = < return options.filter((option) => option.checked === 'on').map((option) => option.label); }; -export const populateSelected = ( - allOptions: EuiSelectableOption[], +export const populateSelected = < + T extends CoverageOverviewRuleSource | CoverageOverviewRuleActivity +>( + allOptions: Array>, selected: string[] -): EuiSelectableOption[] => +): Array> => allOptions.map((option) => selected.includes(option.label) ? { ...option, checked: 'on' } : option ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_activity_filter.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_activity_filter.tsx index 43159822deab..ae7b6445a70c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_activity_filter.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_activity_filter.tsx @@ -51,7 +51,7 @@ const RuleActivityFilterComponent = ({ const options = populateSelected(ruleActivityFilterDefaultOptions, selected); const handleSelectableOnChange = useCallback( - (newOptions) => { + (newOptions: Array>) => { const formattedOptions = extractSelected(newOptions); onChange(formattedOptions); }, @@ -95,7 +95,7 @@ const RuleActivityFilterComponent = ({ panelPaddingSize="none" > {i18n.CoverageOverviewFilterPopoverTitle} - data-test-subj="coverageOverviewFilterList" options={options} onChange={handleSelectableOnChange} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_source_filter.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_source_filter.tsx index e55450f0a069..08bc8c334743 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_source_filter.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/rule_source_filter.tsx @@ -48,7 +48,10 @@ const RuleSourceFilterComponent = ({ const numActiveFilters = useMemo(() => selected.length, [selected]); - const options = populateSelected(ruleSourceFilterDefaultOptions, selected); + const options = populateSelected( + ruleSourceFilterDefaultOptions, + selected + ) as EuiSelectableOption[]; const handleSelectableOnChange = useCallback( (newOptions) => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action_form_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action_form_field.tsx index 7898dfef3ea9..d355187b1d0b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action_form_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action_form_field.tsx @@ -5,7 +5,10 @@ * 2.0. */ -import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import type { + FieldHook, + ValidationError, +} from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import React, { useCallback, useMemo } from 'react'; import { isEmpty, map } from 'lodash'; import { useFormContext } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; @@ -22,7 +25,7 @@ export const ResponseActionFormField = React.memo(({ field }: { field: FieldHook ); const handleError = useCallback( - (newErrors) => { + (newErrors: ValidationError) => { if (isEmpty(newErrors)) { clearErrors(); } else { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_action_add_button.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_action_add_button.tsx index a8fcccee30ef..4dc903bbd1c0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_action_add_button.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_action_add_button.tsx @@ -46,7 +46,7 @@ export const ResponseActionAddButton = ({ const isPlatinumPlus = useLicense().isPlatinumPlus(); const handleAddActionType = useCallback( - (item) => { + (item: ResponseActionType) => { setAddResponseActionButtonShown(false); addActionType(); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_wrapper.tsx index 39f036a1b332..7e2fb59cea84 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_wrapper.tsx @@ -23,7 +23,7 @@ interface ResponseActionsWrapperProps { export const ResponseActionsWrapper = React.memo( ({ items, removeItem, supportedResponseActionTypes, addItem }) => { const actionTypeIdRef = useRef(null); - const updateActionTypeId = useCallback((id) => { + const updateActionTypeId = useCallback((id: string) => { actionTypeIdRef.current = id; }, []); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx index c2f25b4b5c80..0c1c33da81e5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx @@ -8,6 +8,7 @@ import type { Action } from '@kbn/ui-actions-plugin/public'; import type { EuiComboBox, EuiTitleSize } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiToolTip } 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'; @@ -160,7 +161,7 @@ export const AlertsHistogramPanel = memo( }); const goToDetectionEngine = useCallback( - (ev) => { + (ev: SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx index bf050c2eedab..3a0dccc49247 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/components.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { EuiComboBoxOptionOption } from '@elastic/eui'; +import type { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; import { EuiPanel, EuiComboBox } from '@elastic/eui'; import styled from 'styled-components'; import type { LegacyRef } from 'react'; @@ -53,7 +53,7 @@ export const KpiPanel = styled(EuiPanel)<{ interface StackedBySelectProps { 'aria-label'?: string; 'data-test-subj'?: string; - dropDownoptions?: Array>; + dropDownoptions?: Array>; inputRef?: (inputRef: HTMLInputElement | null) => void; isDisabled?: boolean; onSelect: (selected: string) => void; @@ -84,9 +84,9 @@ export const StackByComboBox = React.forwardRef( }: StackedBySelectProps, ref ) => { - const onChange = useCallback( + const onChange = useCallback['onChange']>>( (options) => { - if (options && options.length > 0) { + if (options && options.length && options[0].value) { onSelect(options[0].value); } else { onSelect(''); @@ -117,7 +117,7 @@ export const StackByComboBox = React.forwardRef( isDisabled={isDisabled} placeholder={i18n.STACK_BY_PLACEHOLDER} prepend={prepend} - ref={ref as LegacyRef> | undefined} + ref={ref as LegacyRef> | undefined} singleSelection={singleSelection} isClearable={false} sortMatchesBy="startsWith" diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts index 75d86873c52b..a666d25b1df1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts @@ -76,7 +76,7 @@ export interface GetAggregatableFields { export function getAggregatableFields( fields: GetAggregatableFields, useLensCompatibleFields?: boolean -): EuiComboBoxOptionOption[] { +): Array> { const result = []; for (const [key, field] of Object.entries(fields)) { if (useLensCompatibleFields) { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx index fd7ca232ca8e..8b02530fec07 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx @@ -12,6 +12,7 @@ import { isNoneGroup, useGrouping } from '@kbn/grouping'; import { isEmpty, isEqual } from 'lodash/fp'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; import type { TableIdLiteral } from '@kbn/securitysolution-data-table'; +import type { GroupingArgs } from '@kbn/grouping/src'; import { groupIdSelector } from '../../../common/store/grouping/selectors'; import { getDefaultGroupingOptions } from '../../../common/utils/alerts'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; @@ -89,7 +90,7 @@ const GroupedAlertsTableComponent: React.FC = (props) [telemetry] ); - const onOptionsChange = useCallback( + const onOptionsChange = useCallback['onOptionsChange']>>( (options) => { dispatch( updateGroups({ diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx index e0e11ad0251b..044fb10a6ac1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx @@ -143,7 +143,8 @@ export const useAddBulkToTimelineAction = ({ }); const updateTimelineIsLoading = useCallback( - (payload) => dispatch(timelineActions.updateIsLoading(payload)), + (payload: Parameters[0]) => + dispatch(timelineActions.updateIsLoading(payload)), [dispatch] ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_flyout.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_flyout.tsx index 40c855341a1e..dba19fda539c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_flyout.tsx @@ -55,7 +55,7 @@ export const useExceptionFlyout = ({ }, [setAllTourStepsHidden]); const onAddExceptionConfirm = useCallback( - (didRuleChange: boolean, didCloseAlert: boolean, didBulkCloseAlert) => { + (didRuleChange: boolean, didCloseAlert: boolean, didBulkCloseAlert: boolean) => { if (refetch && (isActiveTimelines === false || didBulkCloseAlert)) { refetch(); } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx index 211bfd0db2dc..a68d773468e7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx @@ -136,7 +136,8 @@ export const useInvestigateInTimeline = ({ ); const updateTimelineIsLoading = useCallback( - (payload) => dispatch(timelineActions.updateIsLoading(payload)), + (payload: Parameters[0]) => + dispatch(timelineActions.updateIsLoading(payload)), [dispatch] ); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx index 29cec20f12d7..a8eec62f2d58 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx @@ -31,7 +31,7 @@ export interface RuleFromTimeline { onOpenTimeline: (timeline: TimelineModel) => void; } -type SetRuleQuery = ({ +export type SetRuleQuery = ({ index, queryBar, eqlOptions, diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_actions_column.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_actions_column.tsx index 4f2c995b163d..59e3cf9f07f9 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_actions_column.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_actions_column.tsx @@ -8,7 +8,10 @@ import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import React, { useCallback, useContext, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import type { AlertsTableConfigurationRegistry } from '@kbn/triggers-actions-ui-plugin/public/types'; +import type { + AlertsTableConfigurationRegistry, + RenderCustomActionsRowArgs, +} from '@kbn/triggers-actions-ui-plugin/public/types'; import { TableId } from '@kbn/securitysolution-data-table'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { StatefulEventContext } from '../../../common/components/events_viewer/stateful_event_context'; @@ -61,7 +64,7 @@ export const getUseActionColumnHook = clearSelection, ecsAlert: alert, nonEcsData, - }) => { + }: RenderCustomActionsRowArgs) => { const timelineItem: TimelineItem = { _id: (alert as Ecs)._id, _index: (alert as Ecs)._index, diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_trigger_actions_browser_fields_options.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_trigger_actions_browser_fields_options.tsx index e2876e962fd2..a627131ff05c 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_trigger_actions_browser_fields_options.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_trigger_actions_browser_fields_options.tsx @@ -6,6 +6,7 @@ */ import { useCallback, useMemo } from 'react'; import type { AlertsTableConfigurationRegistry } from '@kbn/triggers-actions-ui-plugin/public/types'; +import type { EuiDataGridColumn } from '@elastic/eui'; import { useFieldBrowserOptions } from '../../../timelines/components/fields_browser'; import type { SourcererScopeName } from '../../../sourcerer/store/model'; @@ -13,7 +14,7 @@ export const getUseTriggersActionsFieldBrowserOptions = (scopeId: SourcererScope const useTriggersActionsFieldBrowserOptions: AlertsTableConfigurationRegistry['useFieldBrowserOptions'] = ({ onToggleColumn }) => { const upsertColumn = useCallback( - (column) => { + (column: EuiDataGridColumn) => { onToggleColumn(column.id); }, [onToggleColumn] diff --git a/x-pack/plugins/security_solution/public/detections/mitre/get_mitre_threat_component.ts b/x-pack/plugins/security_solution/public/detections/mitre/get_mitre_threat_component.ts deleted file mode 100644 index 0848cbcca15c..000000000000 --- a/x-pack/plugins/security_solution/public/detections/mitre/get_mitre_threat_component.ts +++ /dev/null @@ -1,24 +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 type { Threats } from '@kbn/securitysolution-io-ts-alerting-types'; -import type { SearchHit } from '../../../common/search_strategy'; -import { buildThreatDescription } from '../../detection_engine/rule_creation_ui/components/description_step/helpers'; - -// TODO: MOVE TO FLYOUT FOLDER - https://github.com/elastic/security-team/issues/7462 -export const getMitreComponentParts = (searchHit?: SearchHit) => { - const ruleParameters = searchHit?.fields - ? searchHit?.fields['kibana.alert.rule.parameters'] - : null; - const threat = ruleParameters ? (ruleParameters[0]?.threat as Threats) : null; - return threat && threat.length > 0 - ? buildThreatDescription({ - label: threat[0].framework, - threat, - }) - : null; -}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx index d7e16697ce25..18efc5fcbad7 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx @@ -155,16 +155,6 @@ jest.mock('../../../common/lib/kibana', () => { }; }); -jest.mock('../../../timelines/components/side_panel/hooks/use_detail_panel', () => { - return { - useDetailPanel: () => ({ - openEventDetailsPanel: jest.fn(), - handleOnDetailsPanelClosed: () => {}, - DetailsPanel: () =>
, - shouldShowDetailsPanel: false, - }), - }; -}); const dataViewId = 'security-solution-default'; const stateWithBuildingBlockAlertsEnabled: State = { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 31116f7c5ecd..7784fbb5760c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -223,7 +223,7 @@ const DetectionEnginePageComponent: React.FC = () ); const goToRules = useCallback( - (ev) => { + (ev: React.MouseEvent) => { ev.preventDefault(); navigateToUrl(formatUrl(getRulesUrl())); }, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/components/edit_rule_settings_button_link.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/components/edit_rule_settings_button_link.tsx index 6ef7ebb0cae4..f1572b326a90 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/components/edit_rule_settings_button_link.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/components/edit_rule_settings_button_link.tsx @@ -29,7 +29,7 @@ export function EditRuleSettingButtonLink({ application: { navigateToApp }, } = useKibana().services; const goToEditRule = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/asset_criticality_file_uploader.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/asset_criticality_file_uploader.tsx index ddffe01955b2..0acd1f831ca7 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/asset_criticality_file_uploader.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/asset_criticality_file_uploader.tsx @@ -61,7 +61,7 @@ export const AssetCriticalityFileUploader: React.FC = () => { }, [telemetry] ); - const onValidationError = useCallback((message) => { + const onValidationError = useCallback((message: string) => { dispatch({ type: 'fileError', payload: { message } }); }, []); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx index 5dca054f013c..a451c5030212 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx @@ -9,7 +9,12 @@ import React, { useMemo, useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { Columns, Criteria, ItemsPerRow } from '../../../explore/components/paginated_table'; +import type { + Columns, + Criteria, + ItemsPerRow, + SiemTables, +} from '../../../explore/components/paginated_table'; import { PaginatedTable } from '../../../explore/components/paginated_table'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import { hostsActions, hostsModel, hostsSelectors } from '../../../explore/hosts/store'; @@ -81,7 +86,7 @@ const HostRiskScoreTableComponent: React.FC = ({ const { activePage, limit, sort } = useDeepEqualSelector((state: State) => getHostRiskScoreSelector(state, hostsModel.HostsType.page) ); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( hostsActions.updateTableLimit({ @@ -93,7 +98,7 @@ const HostRiskScoreTableComponent: React.FC = ({ [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( hostsActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx index 21ea627d3f65..b0d988eaeac1 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx @@ -95,7 +95,7 @@ const FlyoutRiskSummaryComponent = ({ ); const onToggle = useCallback( - (isOpen) => { + (isOpen: boolean) => { const entity = isUserRiskData(riskData) ? 'user' : 'host'; telemetry.reportToggleRiskSummaryClicked({ diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx index 9ecb9d9cd6cd..df99f39091a9 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo, useState } from 'react'; -import type { FilterChecked } from '@elastic/eui'; +import type { FilterChecked, EuiSelectableProps } from '@elastic/eui'; import { EuiFilterButton, EuiFilterGroup, @@ -67,8 +67,10 @@ export const SeverityFilterGroup: React.FC<{ })); }, [severityCount, selectedSeverities]); - const updateSeverityFilter = useCallback( - (newSelection: SeverityItems[], _, changedSeverity: SeverityItems) => { + const updateSeverityFilter = useCallback< + NonNullable['onChange']> + >( + (newSelection, _, changedSeverity) => { if (changedSeverity.checked === 'on') { telemetry.reportEntityRiskFiltered({ entity: riskEntity, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx index 6a99e64d04b2..0e2c64f84d61 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx @@ -9,7 +9,12 @@ import React, { useMemo, useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { Columns, Criteria, ItemsPerRow } from '../../../explore/components/paginated_table'; +import type { + Columns, + Criteria, + ItemsPerRow, + SiemTables, +} from '../../../explore/components/paginated_table'; import { PaginatedTable } from '../../../explore/components/paginated_table'; import { getUserRiskScoreColumns } from './columns'; @@ -82,7 +87,7 @@ const UserRiskScoreTableComponent: React.FC = ({ const { activePage, limit, sort } = useDeepEqualSelector((state: State) => getUserRiskScoreSelector(state) ); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => { dispatch( usersActions.updateTableLimit({ @@ -95,7 +100,7 @@ const UserRiskScoreTableComponent: React.FC = ({ [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => { dispatch( usersActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/exceptions/components/create_shared_exception_list/index.tsx b/x-pack/plugins/security_solution/public/exceptions/components/create_shared_exception_list/index.tsx index 9c465b202b8c..bf345daa1aea 100644 --- a/x-pack/plugins/security_solution/public/exceptions/components/create_shared_exception_list/index.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/components/create_shared_exception_list/index.tsx @@ -23,7 +23,7 @@ import { EuiFlexItem, useGeneratedHtmlId, } from '@elastic/eui'; -import type { HttpSetup } from '@kbn/core-http-browser'; +import type { HttpSetup, IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; import type { ErrorToastOptions, Toast, ToastInput } from '@kbn/core-notifications-browser'; import { i18n as translate } from '@kbn/i18n'; import type { ListDetails } from '@kbn/securitysolution-exception-list-components'; @@ -109,22 +109,22 @@ export const CreateSharedListFlyout = memo( http, ]); - const handleCreateSuccess = useCallback( - (response) => { - addSuccess({ - text: getSuccessText(newListDetails.name), - title: SUCCESS_TITLE, - }); - handleRefresh(); + const handleCreateSuccess = useCallback(() => { + addSuccess({ + text: getSuccessText(newListDetails.name), + title: SUCCESS_TITLE, + }); + handleRefresh(); - handleCloseFlyout(); - }, - [addSuccess, handleCloseFlyout, handleRefresh, newListDetails] - ); + handleCloseFlyout(); + }, [addSuccess, handleCloseFlyout, handleRefresh, newListDetails]); const handleCreateError = useCallback( - (error) => { - if (!error.message.includes('AbortError') && !error?.body?.message.includes('AbortError')) { + (error: IHttpFetchError | undefined) => { + if ( + !error?.message?.includes('AbortError') && + !error?.body?.message.includes('AbortError') + ) { addError(error, { title: translate.translate( 'xpack.securitySolution.exceptions.createSharedExceptionListErrorTitle', @@ -141,9 +141,11 @@ export const CreateSharedListFlyout = memo( useEffect(() => { if (!createSharedExceptionListState.loading) { if (createSharedExceptionListState?.result) { - handleCreateSuccess(createSharedExceptionListState.result); + handleCreateSuccess(); } else if (createSharedExceptionListState?.error) { - handleCreateError(createSharedExceptionListState?.error); + handleCreateError( + createSharedExceptionListState?.error as IHttpFetchError + ); } } }, [ diff --git a/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts b/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts index 99f328837953..afee35da444c 100644 --- a/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts +++ b/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts @@ -102,10 +102,15 @@ export const useListDetailsView = (exceptionListId: string) => { [toasts] ); - const initializeListRules = useCallback(async (result) => { - const listRules = await getListRules(result.list_id); - setLinkedRules(listRules); - }, []); + const initializeListRules = useCallback( + async (result: Awaited>) => { + if (result) { + const listRules = await getListRules(result.list_id); + setLinkedRules(listRules); + } + }, + [] + ); const initializeList = useCallback(async () => { try { @@ -329,7 +334,7 @@ export const useListDetailsView = (exceptionListId: string) => { return linkedRules.filter((rule) => !newLinkedRules.includes(rule)); }, [linkedRules, newLinkedRules]); - const onRuleSelectionChange = useCallback((value) => { + const onRuleSelectionChange = useCallback((value: UIRule[]) => { setNewLinkedRules(value); setDisableManageButton(false); }, []); diff --git a/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts b/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts index 9c466859334f..bacd0377982a 100644 --- a/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts +++ b/x-pack/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts @@ -7,7 +7,10 @@ import { useCallback, useState } from 'react'; import type { Pagination } from '@elastic/eui'; import { ViewerStatus } from '@kbn/securitysolution-exception-list-components'; -import type { RuleReferences } from '@kbn/securitysolution-exception-list-components'; +import type { + RuleReferences, + GetExceptionItemProps, +} from '@kbn/securitysolution-exception-list-components'; import type { ExceptionListItemSchema, ExceptionListSchema, @@ -19,6 +22,7 @@ import { getExceptionItemsReferences, prepareFetchExceptionItemsParams, } from '../../api'; +import type { DeleteExceptionItem } from '../../api/types'; export interface UseListExceptionItemsProps { list: ExceptionListSchema; @@ -73,19 +77,26 @@ export const useListExceptionItems = ({ } }, [handleErrorStatus, list, setExceptionListReferences]); - const updateViewer = useCallback((paginationResult, dataLength, viewStatus) => { - setPagination(paginationResult); - setLastUpdated(Date.now()); - setTimeout(() => { - if (viewStatus === ViewerStatus.EMPTY_SEARCH) - return setViewerStatus(!dataLength ? viewStatus : ''); + const updateViewer = useCallback( + ( + paginationResult: Awaited>['pagination'], + dataLength: number, + viewStatus?: ViewerStatus + ) => { + setPagination(paginationResult); + setLastUpdated(Date.now()); + setTimeout(() => { + if (viewStatus === ViewerStatus.EMPTY_SEARCH) + return setViewerStatus(!dataLength ? viewStatus : ''); - setViewerStatus(!dataLength ? ViewerStatus.EMPTY : ''); - }, 200); - }, []); + setViewerStatus(!dataLength ? ViewerStatus.EMPTY : ''); + }, 200); + }, + [] + ); const fetchItems = useCallback( - async (options?, viewStatus?) => { + async (options?: GetExceptionItemProps | null, viewStatus?: ViewerStatus) => { try { setViewerStatus(ViewerStatus.LOADING); const { data, pagination: paginationResult } = await fetchListExceptionItems({ @@ -104,7 +115,15 @@ export const useListExceptionItems = ({ ); const onDeleteException = useCallback( - async ({ id, name, namespaceType }) => { + async ({ + id, + name, + namespaceType, + }: { + id: DeleteExceptionItem['id']; + name: string; + namespaceType: DeleteExceptionItem['namespaceType']; + }) => { try { setViewerStatus(ViewerStatus.LOADING); await deleteException({ id, http, namespaceType }); @@ -123,7 +142,7 @@ export const useListExceptionItems = ({ if (typeof onEditListExceptionItem === 'function') onEditListExceptionItem(exception); }; const onPaginationChange = useCallback( - async (options) => { + async (options?: GetExceptionItemProps | null) => { fetchItems(options); }, [fetchItems] diff --git a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.tsx b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.tsx index 732e4f242aa4..4f8aa2f96e87 100644 --- a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_host_table.tsx @@ -9,6 +9,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { getOr } from 'lodash/fp'; import { useDispatch } from 'react-redux'; +import type { SiemTables } from '../paginated_table'; import { PaginatedTable } from '../paginated_table'; import * as i18n from './translations'; @@ -70,7 +71,7 @@ const AuthenticationsHostTableComponent: React.FC = ( ? getHostDetailsAuthenticationColumns() : getHostsPageAuthenticationColumns(); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( hostsActions.updateTableLimit({ @@ -82,7 +83,7 @@ const AuthenticationsHostTableComponent: React.FC = ( [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( hostsActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.tsx b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.tsx index f6c5fc86e761..28855562cf10 100644 --- a/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/authentication/authentications_user_table.tsx @@ -10,6 +10,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { getOr } from 'lodash/fp'; import { useDispatch } from 'react-redux'; import { AuthStackByField } from '../../../../common/search_strategy/security_solution/users/authentications'; +import type { SiemTables } from '../paginated_table'; import { PaginatedTable } from '../paginated_table'; import * as i18n from './translations'; @@ -67,7 +68,7 @@ const AuthenticationsUserTableComponent: React.FC [userName] ); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( usersActions.updateTableLimit({ @@ -79,7 +80,7 @@ const AuthenticationsUserTableComponent: React.FC [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( usersActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx b/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx index c7825d56aedd..3aa025b30eb1 100644 --- a/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx @@ -96,7 +96,7 @@ declare type BasicTableColumns = | UsersColumns | UsersTableColumns; -declare type SiemTables = BasicTableProps; +export declare type SiemTables = BasicTableProps; // Using telescoping templates to remove 'any' that was polluting downstream column type checks export interface BasicTableProps { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.tsx b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.tsx index ef9a368dac37..20299d564d58 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/index.tsx @@ -16,6 +16,7 @@ import type { Columns, Criteria, ItemsPerRow, + SiemTables, SortingBasicTable, } from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; @@ -96,7 +97,7 @@ const HostsTableComponent: React.FC = ({ getHostsSelector(state, type) ); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( hostsActions.updateTableLimit({ @@ -108,7 +109,7 @@ const HostsTableComponent: React.FC = ({ [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( hostsActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx index f60866be1e3e..6e5b69f40826 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx @@ -20,6 +20,7 @@ import type { Filter } from '@kbn/es-query'; import { buildEsQuery } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; import { dataTableSelectors, tableDefaults, TableId } from '@kbn/securitysolution-data-table'; +import type { NarrowDateRange } from '../../../../common/components/ml/types'; import { useCalculateEntityRiskScore } from '../../../../entity_analytics/api/hooks/use_calculate_entity_risk_score'; import { useAssetCriticalityData, @@ -113,7 +114,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta const isEnterprisePlus = useLicense().isEnterprise(); - const narrowDateRange = useCallback( + const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); dispatch( diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.tsx index be0558b00f67..3af67736d683 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_dns_table/index.tsx @@ -16,7 +16,7 @@ import type { NetworkDnsEdges, NetworkDnsFields, } from '../../../../../common/search_strategy'; -import type { Criteria, ItemsPerRow } from '../../../components/paginated_table'; +import type { Criteria, ItemsPerRow, SiemTables } from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; @@ -66,7 +66,7 @@ const NetworkDnsTableComponent: React.FC = ({ const getNetworkDnsSelector = useMemo(() => networkSelectors.dnsSelector(), []); const { activePage, isPtrIncluded, limit, sort } = useDeepEqualSelector(getNetworkDnsSelector); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ @@ -78,7 +78,7 @@ const NetworkDnsTableComponent: React.FC = ({ [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.tsx index 4d6cd8773d06..642fb1a13604 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_http_table/index.tsx @@ -12,7 +12,7 @@ import { networkActions, networkModel, networkSelectors } from '../../store'; import type { NetworkHttpEdges } from '../../../../../common/search_strategy'; import { NetworkHttpFields } from '../../../../../common/search_strategy'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { Criteria, ItemsPerRow } from '../../../components/paginated_table'; +import type { Criteria, ItemsPerRow, SiemTables } from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { getNetworkHttpColumns } from './columns'; @@ -64,7 +64,7 @@ const NetworkHttpTableComponent: React.FC = ({ ? networkModel.NetworkTableType.http : networkModel.NetworkDetailsTableType.http; - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ @@ -76,7 +76,7 @@ const NetworkHttpTableComponent: React.FC = ({ [dispatch, type, tableType] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.tsx index d149e1bb474e..3f34d79775f6 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_top_countries_table/index.tsx @@ -20,7 +20,7 @@ import { } from '../../../../../common/search_strategy'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { Criteria, ItemsPerRow } from '../../../components/paginated_table'; +import type { Criteria, ItemsPerRow, SiemTables } from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { getCountriesColumnsCurated } from './columns'; @@ -100,7 +100,7 @@ const NetworkTopCountriesTableComponent: React.FC ? `node.network.${sort.field}` : `node.${flowTargeted}.${sort.field}`; - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ @@ -112,7 +112,7 @@ const NetworkTopCountriesTableComponent: React.FC [dispatch, type, tableType] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.tsx index f620d5fc17df..4359520ea8f2 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/index.tsx @@ -17,7 +17,7 @@ import { NetworkTopTablesFields, } from '../../../../../common/search_strategy'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { Criteria, ItemsPerRow } from '../../../components/paginated_table'; +import type { Criteria, ItemsPerRow, SiemTables } from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { networkActions, networkModel, networkSelectors } from '../../store'; import { getNFlowColumnsCurated } from './columns'; @@ -125,7 +125,7 @@ const NetworkTopNFlowTableComponent: React.FC = ({ [flowTargeted, sort] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ @@ -137,7 +137,7 @@ const NetworkTopNFlowTableComponent: React.FC = ({ [dispatch, type, tableType] ); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.tsx index b981dba31c2b..be7318daf283 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/tls_table/index.tsx @@ -13,7 +13,12 @@ import { networkActions, networkModel, networkSelectors } from '../../store'; import type { Direction, NetworkTlsEdges, SortField } from '../../../../../common/search_strategy'; import { NetworkTlsFields } from '../../../../../common/search_strategy'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { Criteria, ItemsPerRow, SortingBasicTable } from '../../../components/paginated_table'; +import type { + Criteria, + ItemsPerRow, + SiemTables, + SortingBasicTable, +} from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { getTlsColumns } from './columns'; import * as i18n from './translations'; @@ -64,7 +69,7 @@ const TlsTableComponent: React.FC = ({ ? networkModel.NetworkTableType.tls : networkModel.NetworkDetailsTableType.tls; - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ @@ -76,7 +81,7 @@ const TlsTableComponent: React.FC = ({ [dispatch, type, tableType] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.tsx b/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.tsx index 909f4fa77d94..c88d90dc2756 100644 --- a/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/components/users_table/index.tsx @@ -19,7 +19,12 @@ import type { SortField, } from '../../../../../common/search_strategy'; import { NetworkUsersFields } from '../../../../../common/search_strategy'; -import type { Criteria, ItemsPerRow, SortingBasicTable } from '../../../components/paginated_table'; +import type { + Criteria, + ItemsPerRow, + SiemTables, + SortingBasicTable, +} from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { getUsersColumns } from './columns'; @@ -70,7 +75,7 @@ const UsersTableComponent: React.FC = ({ const getUsersSelector = useMemo(() => networkSelectors.usersSelector(), []); const { activePage, sort, limit } = useDeepEqualSelector(getUsersSelector); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => dispatch( networkActions.updateNetworkTable({ @@ -82,7 +87,7 @@ const UsersTableComponent: React.FC = ({ [dispatch, type] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => dispatch( networkActions.updateNetworkTable({ diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx index c2f034038271..adcf8a21ba47 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx @@ -28,6 +28,7 @@ import { networkToCriteria } from '../../../../common/components/ml/criteria/net import { scoreIntervalToDateTime } from '../../../../common/components/ml/score/score_interval_to_datetime'; import { manageQuery } from '../../../../common/components/page/manage_query'; import { FlowTargetSelectConnected } from '../../components/flow_target_select_connected'; +import type { IpOverviewProps } from '../../components/details'; import { IpOverview } from '../../components/details'; import { SiemSearchBar } from '../../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; @@ -82,7 +83,7 @@ const NetworkDetailsComponent: React.FC = () => { const globalFilters = useDeepEqualSelector(getGlobalFiltersQuerySelector); const type = networkModel.NetworkType.details; - const narrowDateRange = useCallback( + const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); dispatch( diff --git a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx index d05c9551a251..92303187f231 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx @@ -19,7 +19,12 @@ import { getOrEmptyTagFromValue, } from '../../../../common/components/empty_value'; -import type { Columns, Criteria, ItemsPerRow } from '../../../components/paginated_table'; +import type { + Columns, + Criteria, + ItemsPerRow, + SiemTables, +} from '../../../components/paginated_table'; import { PaginatedTable } from '../../../components/paginated_table'; import { getRowItemsWithActions } from '../../../../common/components/tables/helpers'; @@ -183,7 +188,7 @@ const UsersTableComponent: React.FC = ({ const isPlatinumOrTrialLicense = useMlCapabilities().isPlatinumOrTrialLicense; const { navigateTo } = useNavigateTo(); - const updateLimitPagination = useCallback( + const updateLimitPagination = useCallback( (newLimit) => { dispatch( usersActions.updateTableLimit({ @@ -196,7 +201,7 @@ const UsersTableComponent: React.FC = ({ [type, dispatch] ); - const updateActivePage = useCallback( + const updateActivePage = useCallback( (newPage) => { dispatch( usersActions.updateTableActivePage({ diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx index 0ff279762161..a53eaf43269b 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx @@ -64,6 +64,7 @@ import { LastEventTime } from '../../../../common/components/last_event_time'; import { LastEventIndexKey, RiskScoreEntity } from '../../../../../common/search_strategy'; import { AnomalyTableProvider } from '../../../../common/components/ml/anomaly/anomaly_table_provider'; +import type { UserSummaryProps } from '../../../../overview/components/user_overview'; import { UserOverview, USER_OVERVIEW_RISK_SCORE_QUERY_ID, @@ -159,7 +160,7 @@ const UsersDetailsComponent: React.FC = ({ useQueryInspector({ setQuery, deleteQuery, refetch, inspect, loading, queryId: QUERY_ID }); - const narrowDateRange = useCallback( + const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); dispatch( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx index 70b238825d66..ea16fcfa80e9 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx @@ -20,9 +20,9 @@ import { CellTooltipWrapper } from '../../shared/components/cell_tooltip_wrapper import type { DataProvider } from '../../../../../common/types'; import { SeverityBadge } from '../../../../common/components/severity_badge'; import { usePaginatedAlerts } from '../hooks/use_paginated_alerts'; -import { InvestigateInTimelineButton } from '../../../../common/components/event_details/table/investigate_in_timeline_button'; +import { InvestigateInTimelineButton } from '../../../../common/components/event_details/investigate_in_timeline_button'; import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/components/alerts_table/translations'; -import { getDataProvider } from '../../../../common/components/event_details/table/use_action_cell_data_provider'; +import { getDataProvider } from '../../../../common/components/event_details/use_action_cell_data_provider'; import { AlertPreviewButton } from '../../../shared/components/alert_preview_button'; export const TIMESTAMP_DATE_FORMAT = 'MMM D, YYYY @ HH:mm:ss.SSS'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/prevalence_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/prevalence_details.tsx index e3134591d6c9..5aae6c4b3926 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/prevalence_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/prevalence_details.tsx @@ -26,7 +26,7 @@ import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { useLicense } from '../../../../common/hooks/use_license'; -import { InvestigateInTimelineButton } from '../../../../common/components/event_details/table/investigate_in_timeline_button'; +import { InvestigateInTimelineButton } from '../../../../common/components/event_details/investigate_in_timeline_button'; import type { PrevalenceData } from '../../shared/hooks/use_prevalence'; import { usePrevalence } from '../../shared/hooks/use_prevalence'; import { @@ -47,7 +47,7 @@ import { useDocumentDetailsContext } from '../../shared/context'; import { getDataProvider, getDataProviderAnd, -} from '../../../../common/components/event_details/table/use_action_cell_data_provider'; +} from '../../../../common/components/event_details/use_action_cell_data_provider'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { IS_OPERATOR } from '../../../../../common/types'; import { useKibana } from '../../../../common/lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx index efd1628f9d70..b817be7a308b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx @@ -11,15 +11,22 @@ import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { ALERT_RULE_TYPE } from '@kbn/rule-data-utils'; import { EuiBetaBadge, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; import { ExpandablePanel } from '@kbn/security-solution-common'; import { CORRELATIONS_DETAILS_SUPPRESSED_ALERTS_SECTION_TEST_ID, SUPPRESSED_ALERTS_SECTION_TECHNICAL_PREVIEW_TEST_ID, } from './test_ids'; -import { SUPPRESSED_ALERTS_COUNT_TECHNICAL_PREVIEW } from '../../../../common/components/event_details/insights/translations'; import { InvestigateInTimelineAction } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_timeline_action'; import { isSuppressionRuleInGA } from '../../../../../common/detection_engine/utils'; +const SUPPRESSED_ALERTS_COUNT_TECHNICAL_PREVIEW = i18n.translate( + 'xpack.securitySolution.flyout.left.insights.suppressedAlertsCountTechnicalPreview', + { + defaultMessage: 'Technical Preview', + } +); + export interface SuppressedAlertsProps { /** * An object with top level fields from the ECS object diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/assignees.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/assignees.tsx index 5e9905107c87..fc9a09d4e37d 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/assignees.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/assignees.tsx @@ -23,6 +23,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { useSetAlertAssignees } from '../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { ASSIGNEES_PANEL_WIDTH } from '../../../../common/components/assignees/constants'; +import type { AssigneesApplyPanelProps } from '../../../../common/components/assignees/assignees_apply_panel'; import { AssigneesApplyPanel } from '../../../../common/components/assignees/assignees_apply_panel'; import { useUpsellingMessage } from '../../../../common/hooks/use_upselling'; import { useLicense } from '../../../../common/hooks/use_license'; @@ -98,7 +99,7 @@ export const Assignees: FC = memo( setIsPopoverOpen((value) => !value); }, []); - const handleApplyAssignees = useCallback( + const handleApplyAssignees = useCallback( async (assignees) => { setIsPopoverOpen(false); if (setAlertAssignees) { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.tsx index 2c7a45dc1734..7aabc3eefb96 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.tsx @@ -8,9 +8,27 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; import type { FC } from 'react'; import React, { useMemo } from 'react'; -import { MITRE_ATTACK_DETAILS_TEST_ID, MITRE_ATTACK_TITLE_TEST_ID } from './test_ids'; -import { getMitreComponentParts } from '../../../../detections/mitre/get_mitre_threat_component'; +import type { Threats } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { SearchHit } from '../../../../../common/search_strategy'; +import { buildThreatDescription } from '../../../../detection_engine/rule_creation_ui/components/description_step/helpers'; import { useDocumentDetailsContext } from '../../shared/context'; +import { MITRE_ATTACK_DETAILS_TEST_ID, MITRE_ATTACK_TITLE_TEST_ID } from './test_ids'; + +/** + * Retrieves mitre attack information from the alert information + */ +const getMitreComponentParts = (searchHit?: SearchHit) => { + const ruleParameters = searchHit?.fields + ? searchHit?.fields['kibana.alert.rule.parameters'] + : null; + const threat = ruleParameters ? (ruleParameters[0]?.threat as Threats) : null; + return threat && threat.length > 0 + ? buildThreatDescription({ + label: threat[0].framework, + threat, + }) + : null; +}; export const MitreAttack: FC = () => { const { searchHit } = useDocumentDetailsContext(); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status.tsx index 2737a5a608b5..c75e1426da10 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status.tsx @@ -9,17 +9,13 @@ import type { FC } from 'react'; import React, { useMemo } from 'react'; import { find } from 'lodash/fp'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; -import type { - EnrichedFieldInfo, - EnrichedFieldInfoWithValues, -} from '../../../../common/components/event_details/types'; import { SIGNAL_STATUS_FIELD_NAME } from '../../../../timelines/components/timeline/body/renderers/constants'; -import { StatusPopoverButton } from '../../../../common/components/event_details/overview/status_popover_button'; +import { StatusPopoverButton } from './status_popover_button'; import { useDocumentDetailsContext } from '../../shared/context'; -import { getEnrichedFieldInfo } from '../../../../common/components/event_details/helpers'; +import type { EnrichedFieldInfo, EnrichedFieldInfoWithValues } from '../utils/enriched_field_info'; +import { getEnrichedFieldInfo } from '../utils/enriched_field_info'; import { CellActions } from './cell_actions'; import { STATUS_TITLE_TEST_ID } from './test_ids'; @@ -34,7 +30,6 @@ function hasData(fieldInfo?: EnrichedFieldInfo): fieldInfo is EnrichedFieldInfoW * Document details status displayed in flyout right section header */ export const DocumentStatus: FC = () => { - const { closeFlyout } = useExpandableFlyoutApi(); const { eventId, browserFields, dataFormattedForFieldBrowser, scopeId, isPreview } = useDocumentDetailsContext(); @@ -77,7 +72,6 @@ export const DocumentStatus: FC = () => { contextId={scopeId} enrichedFieldInfo={statusData} scopeId={scopeId} - handleOnEventClosed={closeFlyout} /> )} diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx rename to x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx index e6cb909bfaf0..e9161ba909ec 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx @@ -9,8 +9,9 @@ import React from 'react'; import { render } from '@testing-library/react'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { StatusPopoverButton } from './status_popover_button'; -import { TestProviders } from '../../../mock'; +import { TestProviders } from '../../../../common/mock'; import { useAlertsPrivileges } from '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; + const props = { eventId: 'testid', contextId: 'alerts-page', diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.tsx similarity index 75% rename from x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx rename to x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.tsx index f02b37672545..b5ff44ede0dd 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.tsx @@ -6,8 +6,10 @@ */ import { EuiContextMenu, EuiPopover, EuiPopoverTitle } from '@elastic/eui'; -import React, { useCallback, useMemo, useState } from 'react'; - +import React, { memo, useCallback, useMemo, useState } from 'react'; +import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; +import { getFieldFormat } from '../utils/get_field_format'; +import type { EnrichedFieldInfoWithValues } from '../utils/enriched_field_info'; import { useAlertsActions } from '../../../../detections/components/alerts_table/timeline_actions/use_alerts_actions'; import type { Status } from '../../../../../common/api/detection_engine'; import { @@ -15,30 +17,44 @@ import { CLICK_TO_CHANGE_ALERT_STATUS, } from '../../../../detections/components/alerts_table/translations'; import { FormattedFieldValue } from '../../../../timelines/components/timeline/body/renderers/formatted_field'; -import type { EnrichedFieldInfoWithValues } from '../types'; -import type { inputsModel } from '../../../store'; -import { inputsSelectors } from '../../../store'; -import { useDeepEqualSelector } from '../../../hooks/use_selector'; -import { getFieldFormat } from '../get_field_format'; +import type { inputsModel } from '../../../../common/store'; +import { inputsSelectors } from '../../../../common/store'; +import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; interface StatusPopoverButtonProps { + /** + * Id of the document + */ eventId: string; + /** + * Value used to create a unique identifier in children components + */ contextId: string; + /** + * Information used to + */ enrichedFieldInfo: EnrichedFieldInfoWithValues; + /** + * Maintain backwards compatibility // TODO remove when possible + */ scopeId: string; - handleOnEventClosed: () => void; } -// TODO: MOVE TO FLYOUT FOLDER - https://github.com/elastic/security-team/issues/7462 -export const StatusPopoverButton = React.memo( - ({ eventId, contextId, enrichedFieldInfo, scopeId, handleOnEventClosed }) => { +/** + * Renders a button and its popover to display the status of an alert and allows the user to change it. + * It is used in the header of the document details flyout. + */ +export const StatusPopoverButton = memo( + ({ eventId, contextId, enrichedFieldInfo, scopeId }: StatusPopoverButtonProps) => { + const { closeFlyout } = useExpandableFlyoutApi(); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); const togglePopover = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); const closePopover = useCallback(() => setIsPopoverOpen(false), []); const closeAfterAction = useCallback(() => { closePopover(); - handleOnEventClosed(); - }, [closePopover, handleOnEventClosed]); + closeFlyout(); + }, [closeFlyout, closePopover]); const getGlobalQuerySelector = useMemo(() => inputsSelectors.globalQuery(), []); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/suppressed_alerts.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/suppressed_alerts.tsx index e8ef71bbe594..a8cd147a4ac1 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/suppressed_alerts.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/suppressed_alerts.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiBetaBadge } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import { i18n } from '@kbn/i18n'; import { isSuppressionRuleInGA } from '../../../../../common/detection_engine/utils'; import { @@ -16,7 +17,13 @@ import { CORRELATIONS_SUPPRESSED_ALERTS_TECHNICAL_PREVIEW_TEST_ID, } from './test_ids'; import { InsightsSummaryRow } from './insights_summary_row'; -import { SUPPRESSED_ALERTS_COUNT_TECHNICAL_PREVIEW } from '../../../../common/components/event_details/insights/translations'; + +const SUPPRESSED_ALERTS_COUNT_TECHNICAL_PREVIEW = i18n.translate( + 'xpack.securitySolution.flyout.right.overview.insights.suppressedAlertsCountTechnicalPreview', + { + defaultMessage: 'Technical Preview', + } +); export interface SuppressedAlertsProps { /** diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/table_field_value_cell.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/table_field_value_cell.tsx index 8212ddc70c42..86950fa31837 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/table_field_value_cell.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/table_field_value_cell.tsx @@ -8,7 +8,7 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import type { FieldSpec } from '@kbn/data-plugin/common'; -import { getFieldFormat } from '../../../../common/components/event_details/get_field_format'; +import { getFieldFormat } from '../utils/get_field_format'; import type { EventFieldsData } from '../../../../common/components/event_details/types'; import { OverflowField } from '../../../../common/components/tables/helpers'; import { FormattedFieldValue } from '../../../../timelines/components/timeline/body/renderers/formatted_field'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/take_action_dropdown.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/take_action_dropdown.test.tsx index 6a902ef2b5ce..6189f1b353ec 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/take_action_dropdown.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/take_action_dropdown.test.tsx @@ -11,7 +11,7 @@ import { waitFor } from '@testing-library/react'; import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; import type { TakeActionDropdownProps } from './take_action_dropdown'; import { TakeActionDropdown } from './take_action_dropdown'; -import { generateAlertDetailsDataMock } from '../../../../common/components/event_details/__mocks__'; +import { mockAlertDetailsData } from '../../../../common/components/event_details/mocks'; import { getDetectionAlertMock } from '../../../../common/mock/mock_detection_alerts'; import { TimelineId } from '../../../../../common/types/timeline'; import { TestProviders } from '../../../../common/mock'; @@ -77,7 +77,7 @@ describe('take action dropdown', () => { beforeEach(() => { defaultProps = { - dataFormattedForFieldBrowser: generateAlertDetailsDataMock() as TimelineEventsDetailsItem[], + dataFormattedForFieldBrowser: mockAlertDetailsData as TimelineEventsDetailsItem[], dataAsNestedObject: getDetectionAlertMock(), handleOnEventClosed: jest.fn(), isHostIsolationPanelOpen: false, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_assistant.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_assistant.ts index 2196674964cf..da65a684b026 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_assistant.ts +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/hooks/use_assistant.ts @@ -8,6 +8,7 @@ import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; import { useAssistantOverlay } from '@kbn/elastic-assistant'; import { useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability'; import { getRawData } from '../../../../assistant/helpers'; import { @@ -17,7 +18,6 @@ import { EVENT_SUMMARY_CONTEXT_DESCRIPTION, EVENT_SUMMARY_CONVERSATION_ID, EVENT_SUMMARY_VIEW_CONTEXT_TOOLTIP, - SUMMARY_VIEW, } from '../../../../common/components/event_details/translations'; import { PROMPT_CONTEXT_ALERT_CATEGORY, @@ -25,6 +25,10 @@ import { PROMPT_CONTEXTS, } from '../../../../assistant/content/prompt_contexts'; +const SUMMARY_VIEW = i18n.translate('xpack.securitySolution.eventDetails.summaryView', { + defaultMessage: 'summary', +}); + const useAssistantNoop = () => ({ promptContextId: undefined }); export interface UseAssistantParams { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/utils/enriched_field_info.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/utils/enriched_field_info.ts new file mode 100644 index 000000000000..110cd30556e9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/utils/enriched_field_info.ts @@ -0,0 +1,70 @@ +/* + * 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 type { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; +import { get, getOr } from 'lodash/fp'; +import type { FieldSpec } from '@kbn/data-views-plugin/common'; +import type { + EventFieldsData, + EventSummaryField, + FieldsData, +} from '../../../../common/components/event_details/types'; + +export interface EnrichedFieldInfo { + data: FieldsData | EventFieldsData; + eventId: string; + fieldFromBrowserField?: Partial; + scopeId: string; + values: string[] | null | undefined; + linkValue?: string; +} + +export type EnrichedFieldInfoWithValues = EnrichedFieldInfo & { values: string[] }; + +export function getEnrichedFieldInfo({ + browserFields, + contextId, + eventId, + field, + item, + linkValueField, + scopeId, +}: { + browserFields: BrowserFields; + contextId: string; + item: TimelineEventsDetailsItem; + eventId: string; + field?: EventSummaryField; + scopeId: string; + linkValueField?: TimelineEventsDetailsItem; +}): EnrichedFieldInfo { + const fieldInfo = { + contextId, + eventId, + fieldType: 'string', + linkValue: undefined, + scopeId, + }; + const linkValue = getOr(null, 'originalValue.0', linkValueField); + const category = item.category ?? ''; + const fieldName = item.field ?? ''; + + const browserField = get([category, 'fields', fieldName], browserFields); + const overrideField = field?.overrideField; + return { + ...fieldInfo, + data: { + field: overrideField ?? fieldName, + format: browserField?.format?.id ?? '', + type: browserField?.type ?? '', + isObjectArray: item.isObjectArray, + }, + values: item.values, + linkValue: linkValue ?? undefined, + fieldFromBrowserField: browserField, + }; +} diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/get_field_format.ts b/x-pack/plugins/security_solution/public/flyout/document_details/right/utils/get_field_format.ts similarity index 100% rename from x-pack/plugins/security_solution/public/common/components/event_details/get_field_format.ts rename to x-pack/plugins/security_solution/public/flyout/document_details/right/utils/get_field_format.ts diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/anomalies_field.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/anomalies_field.tsx index ea5e7b17202f..b050e2a55ed5 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/anomalies_field.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/anomalies_field.tsx @@ -7,6 +7,7 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; +import type { NarrowDateRange } from '../../../../common/components/ml/types'; import type { EntityAnomalies } from './observed_entity/types'; import { AnomalyScores } from '../../../../common/components/ml/score/anomaly_scores'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; @@ -18,7 +19,7 @@ export const AnomaliesField = ({ anomalies }: { anomalies: EntityAnomalies }) => const { to, from } = useGlobalTime(); const dispatch = useDispatch(); - const narrowDateRange = useCallback( + const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); dispatch( diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_set_url_params.ts b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_set_url_params.ts index f6199f1c6c17..cf3cce3dc9f0 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_set_url_params.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_set_url_params.ts @@ -10,17 +10,19 @@ import { useCallback } from 'react'; import { pickBy } from 'lodash'; import { useUrlParams } from '../../../hooks/use_url_params'; -// FIXME:PT Refactor into a more generic hooks for managing url params -export const useSetUrlParams = (): (( +type UseSetUrlParams = ( /** Any param whose value is `undefined` will be removed from the URl when in append mode */ params: Record, replace?: boolean -) => void) => { +) => void; + +// FIXME:PT Refactor into a more generic hooks for managing url params +export const useSetUrlParams = (): UseSetUrlParams => { const location = useLocation(); const history = useHistory(); const { toUrlParams, urlParams: currentUrlParams } = useUrlParams(); - return useCallback( + return useCallback( (params, replace = false) => { history.push({ ...location, diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_input/components/command_input_history.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_input/components/command_input_history.tsx index 4e192a80d5b8..6879043eb1fc 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_input/components/command_input_history.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_input/components/command_input_history.tsx @@ -122,9 +122,12 @@ export const CommandInputHistory = memo(() => { [dispatch] ); - const handleRenderOption = useCallback((option) => { - return ; - }, []); + const handleRenderOption = useCallback>( + (option) => { + return ; + }, + [] + ); // When first loaded, clear out the current text entered, and when this component // unloads, if no option from the history was selected, then set the prior text diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_list.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_list.tsx index e6323fccb847..d7644b60a7f7 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_list.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_list.tsx @@ -125,7 +125,7 @@ export const CommandList = memo(({ commands, display = 'defaul }, []); const updateInputText = useCallback( - (text) => () => { + (text: string) => () => { dispatch({ type: 'updateInputTextEnteredState', payload: () => { @@ -218,7 +218,7 @@ export const CommandList = memo(({ commands, display = 'defaul ); const getTableColumns = useCallback( - (commandsByGroup) => { + (commandsByGroup: CommandDefinition[]) => { const groupLabel = commandsByGroup[0]?.helpGroupLabel ?? otherCommandsGroupLabel; const groupTestIdSuffix = convertToTestId(groupLabel); @@ -294,7 +294,7 @@ export const CommandList = memo(({ commands, display = 'defaul ); const getFilteredCommands = useCallback( - (commandsByGroup): CommandDefinition[] => + (commandsByGroup: CommandDefinition[]): CommandDefinition[] => commandsByGroup.filter( (current: CommandDefinition) => current.name !== 'help' && current.name !== 'clear' ), diff --git a/x-pack/plugins/security_solution/public/management/components/effected_policy_select/effected_policy_select.tsx b/x-pack/plugins/security_solution/public/management/components/effected_policy_select/effected_policy_select.tsx index 079ea01492dc..fbfc76c77ac7 100644 --- a/x-pack/plugins/security_solution/public/management/components/effected_policy_select/effected_policy_select.tsx +++ b/x-pack/plugins/security_solution/public/management/components/effected_policy_select/effected_policy_select.tsx @@ -190,7 +190,7 @@ export const EffectedPolicySelect = memo( ); const handleGlobalButtonChange = useCallback( - (selectedId) => { + (selectedId: string) => { onChange({ isGlobal: selectedId === 'globalPolicy', selected, diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx index a91c87223e44..fb2caac78945 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx @@ -55,7 +55,7 @@ export const useDateRangePicker = (isFlyout: boolean) => { }); const updateActionListDateRanges = useCallback( - ({ start, end }) => { + ({ start, end }: DurationRange) => { setDateRangePickerState((prevState) => ({ ...prevState, startDate: start, @@ -66,7 +66,7 @@ export const useDateRangePicker = (isFlyout: boolean) => { ); const updateActionListRecentlyUsedDateRanges = useCallback( - (recentlyUsedDateRanges) => { + (recentlyUsedDateRanges: DateRangePickerValues['recentlyUsedDateRanges']) => { setDateRangePickerState((prevState) => ({ ...prevState, recentlyUsedDateRanges, diff --git a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx index dbcdb011d28f..51ff76158f3b 100644 --- a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx +++ b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx @@ -6,6 +6,7 @@ */ import React, { memo, useCallback, useState } from 'react'; +import type { EuiFieldSearchProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiFieldSearch, EuiButton } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { PolicySelectionItem } from '../policies_selector'; @@ -67,7 +68,7 @@ export const SearchExceptions = memo( [onSearch, query, includedPolicies] ); - const handleOnSearchQuery = useCallback( + const handleOnSearchQuery = useCallback>( (value) => { onSearch(value, includedPolicies, false); }, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index 3c0d08821f6e..2ed2b20ab78a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -7,7 +7,7 @@ import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; -import type { CriteriaWithPagination } from '@elastic/eui'; +import type { CriteriaWithPagination, EuiSuperDatePickerProps } from '@elastic/eui'; import { EuiBasicTable, type EuiBasicTableColumn, @@ -452,7 +452,7 @@ export const EndpointList = () => { }); }, [dispatch]); - const onRefreshChange = useCallback( + const onRefreshChange = useCallback>( (evt) => { dispatch({ type: 'userUpdatedEndpointListRefreshOptions', @@ -573,13 +573,15 @@ export const EndpointList = () => { ); } else if (!policyItemsLoading && hasPolicyData) { - const selectionOptions: EuiSelectableProps['options'] = policyItems.map((item) => { - return { - key: item.policy_id, - label: item.name, - checked: selectedPolicyId === item.policy_id ? 'on' : undefined, - }; - }); + const selectionOptions: EuiSelectableProps['options'] = policyItems + .filter((item) => item.policy_id) + .map((item) => { + return { + key: item.policy_id as string, + label: item.name, + checked: selectedPolicyId === item.policy_id ? 'on' : undefined, + }; + }); return ( ( searchableFields ); - const handleOnSearch = useCallback((query) => { + const handleOnSearch = useCallback((query: string) => { setSelectedArtifactIds([]); setCurrentFilter(query); }, []); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx index 75927ece7dfd..15c347438f5a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx @@ -28,6 +28,7 @@ import { usePolicyDetailsArtifactsNavigateCallback } from '../../policy_hooks'; import type { ExceptionsListApiClient } from '../../../../../services/exceptions_list/exceptions_list_api_client'; import { useListArtifact } from '../../../../../hooks/artifacts'; import { PolicyArtifactsEmptyUnassigned, PolicyArtifactsEmptyUnexisting } from '../empty'; +import type { PolicyArtifactsListProps } from '../list'; import { PolicyArtifactsList } from '../list'; import { PolicyArtifactsFlyout } from '../flyout'; import type { PolicyArtifactsPageLabels } from '../translations'; @@ -106,7 +107,9 @@ export const PolicyArtifactsLayout = React.memo( setExceptionItemToDelete(undefined); }, [setExceptionItemToDelete]); - const handleOnDeleteActionCallback = useCallback( + const handleOnDeleteActionCallback = useCallback< + PolicyArtifactsListProps['onDeleteActionCallback'] + >( (item) => { setExceptionItemToDelete(item); }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/index.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/index.ts index 260b580de749..68361a01d0d1 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/index.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/index.ts @@ -6,4 +6,5 @@ */ export { PolicyArtifactsList } from './policy_artifacts_list'; +export type { PolicyArtifactsListProps } from './policy_artifacts_list'; export { POLICY_ARTIFACT_LIST_LABELS } from './translations'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx index 082012295b02..696e29f77064 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx @@ -12,6 +12,7 @@ import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-t import type { ArtifactEntryCardDecoratorProps } from '../../../../../components/artifact_entry_card'; import { useAppUrl } from '../../../../../../common/lib/kibana'; import { APP_UI_ID } from '../../../../../../../common/constants'; +import type { SearchExceptionsProps } from '../../../../../components/search_exceptions'; import { SearchExceptions } from '../../../../../components/search_exceptions'; import { useEndpointPoliciesToArtifactPolicies } from '../../../../../components/artifact_entry_card/hooks/use_endpoint_policies_to_artifact_policies'; import { useUrlParams } from '../../../../../hooks/use_url_params'; @@ -30,7 +31,7 @@ import { useListArtifact } from '../../../../../hooks/artifacts'; import type { POLICY_ARTIFACT_LIST_LABELS } from './translations'; import type { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; -interface PolicyArtifactsListProps { +export interface PolicyArtifactsListProps { policy: ImmutableObject; apiClient: ExceptionsListApiClient; searchableFields: string[]; @@ -91,7 +92,7 @@ export const PolicyArtifactsList = React.memo( [artifacts?.total, pageSizeOptions, urlPagination.page, urlPagination.pageSize] ); - const handleOnSearch = useCallback( + const handleOnSearch = useCallback( (filter) => { navigateCallback({ filter }); }, @@ -123,7 +124,7 @@ export const PolicyArtifactsList = React.memo( }, [artifacts?.data.length, labels]); const artifactCardPolicies = useEndpointPoliciesToArtifactPolicies(policiesRequest.data?.items); - const provideCardProps = useCallback( + const provideCardProps = useCallback>( (artifact) => { const viewUrlPath = getArtifactPath({ filter: (artifact as ExceptionListItemSchema).item_id, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx index 063c3b830b7a..272012698711 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx @@ -7,6 +7,7 @@ import React, { memo, useCallback, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { EuiFieldTextProps } from '@elastic/eui'; import { EuiCallOut, EuiFieldText, @@ -120,7 +121,7 @@ export const AdvancedSection = memo( setShowAdvancedPolicy((prevState) => !prevState); }, []); - const handleAdvancedSettingUpdate = useCallback( + const handleAdvancedSettingUpdate = useCallback>( (event) => { const updatedPolicy = cloneDeep(policy); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx index ecb73adfa334..052ceffc6575 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx @@ -7,6 +7,7 @@ import React, { memo, useCallback } from 'react'; import { OperatingSystem } from '@kbn/securitysolution-utils'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiSwitch } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { cloneDeep } from 'lodash'; @@ -50,7 +51,7 @@ export const AttackSurfaceReductionCard = memo( const isChecked = policy.windows.attack_surface_reduction.credential_hardening.enabled; const isEditMode = mode === 'edit'; - const handleSwitchChange = useCallback( + const handleSwitchChange = useCallback( (event) => { const updatedPolicy = cloneDeep(policy); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx index f1eda1ac0915..634c24a1c1f5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx @@ -7,6 +7,7 @@ import React, { memo, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiSpacer, EuiSwitch, EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui'; import { OperatingSystem } from '@kbn/securitysolution-utils'; import { cloneDeep } from 'lodash'; @@ -223,7 +224,7 @@ const SubfeatureSwitch = memo( const isEditMode = mode === 'edit'; const isDisabled = policy.windows.malware.mode === 'off' || !isEditMode; - const handleBlocklistSwitchChange = useCallback( + const handleBlocklistSwitchChange = useCallback( (event) => { const value = event.target.checked; const newPayload = cloneDeep(policy); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/components/reputation_service.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/components/reputation_service.tsx index 2de776069f5e..7ff4ad6b3681 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/components/reputation_service.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/components/reputation_service.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback } from 'react'; +import type { EuiCheckboxProps } from '@elastic/eui'; import { EuiCheckbox, EuiFlexGroup, @@ -48,7 +49,7 @@ export const ReputationService = React.memo( const checkboxChecked = policy.windows.behavior_protection.reputation_service && protectionTurnedOn; - const handleChange = useCallback( + const handleChange = useCallback( (event) => { const newPayload = cloneDeep(policy); newPayload.windows.behavior_protection.reputation_service = event.target.checked; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/event_collection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/event_collection_card.tsx index c74496c7512b..a1fee2d77b01 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/event_collection_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/event_collection_card.tsx @@ -20,7 +20,7 @@ import { EuiText, } from '@elastic/eui'; import { cloneDeep, get, set } from 'lodash'; -import type { EuiCheckboxProps } from '@elastic/eui/src/components/form/checkbox/checkbox'; +import type { EuiCheckboxProps } from '@elastic/eui'; import { getEmptyValue } from '../../../../../../common/components/empty_value'; import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; import type { PolicyFormComponentCommonProps } from '../types'; @@ -253,7 +253,7 @@ const EventCheckbox = memo( ({ policy, onChange, label, keyPath, disabled, 'data-test-subj': dataTestSubj }) => { const isChecked: boolean = get(policy, keyPath); - const checkboxOnChangeHandler = useCallback( + const checkboxOnChangeHandler = useCallback>( (ev) => { const updatedPolicy = cloneDeep(policy); set(updatedPolicy, keyPath, ev.target.checked); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx index 2c05b267bb32..9181e643f393 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx @@ -9,6 +9,7 @@ import React, { useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { cloneDeep } from 'lodash'; +import type { EuiTextAreaProps, EuiCheckboxProps } from '@elastic/eui'; import { EuiSpacer, EuiFlexItem, @@ -76,7 +77,7 @@ export const NotifyUserOption = React.memo( const userNotificationSelected = policy.windows.popup[protection].enabled; const userNotificationMessage = policy.windows.popup[protection].message; - const handleUserNotificationCheckbox = useCallback( + const handleUserNotificationCheckbox = useCallback( (event) => { const newPayload = cloneDeep(policy); @@ -96,7 +97,7 @@ export const NotifyUserOption = React.memo( [policy, onChange, osList, protection] ); - const handleCustomUserNotification = useCallback( + const handleCustomUserNotification = useCallback>( (event) => { const newPayload = cloneDeep(policy); for (const os of osList) { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx index d4561be6e531..f1dfcac00921 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback } from 'react'; +import type { EuiSwitchProps } from '@elastic/eui'; import { EuiSwitch } from '@elastic/eui'; import { cloneDeep } from 'lodash'; import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; @@ -51,7 +52,7 @@ export const ProtectionSettingCardSwitch = React.memo( const isPlatinumPlus = useLicense().isPlatinumPlus(); const isEditMode = mode === 'edit'; - const handleSwitchChange = useCallback( + const handleSwitchChange = useCallback( (event) => { const newPayload = cloneDeep(policy); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx index 21e183834ea7..3ce26c70d318 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx @@ -9,8 +9,9 @@ import type { ChangeEventHandler } from 'react'; import React, { memo, useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; -import type { EuiSuperSelectOption } from '@elastic/eui'; +import type { EuiSuperSelectOption, EuiSuperSelectProps } from '@elastic/eui'; import { EuiButtonIcon, EuiFieldText, EuiFormRow, EuiSuperSelect, EuiText } from '@elastic/eui'; +import type { TrustedAppEntryTypes } from '@kbn/securitysolution-utils'; import { ConditionEntryField, OperatingSystem } from '@kbn/securitysolution-utils'; import type { TrustedAppConditionEntry } from '../../../../../../../common/endpoint/types'; import { OperatorFieldIds } from '../../../../../../../common/endpoint/types'; @@ -73,11 +74,13 @@ const InputItem = styled.div<{ gridArea: string }>` vertical-align: baseline; `; -const operatorOptions = (Object.keys(OperatorFieldIds) as OperatorFieldIds[]).map((value) => ({ - dropdownDisplay: OPERATOR_TITLES[value], - inputDisplay: OPERATOR_TITLES[value], - value: value === 'matches' ? 'wildcard' : 'match', -})); +const operatorOptions = (Object.keys(OperatorFieldIds) as OperatorFieldIds[]).map( + (value): EuiSuperSelectOption => ({ + dropdownDisplay: OPERATOR_TITLES[value], + inputDisplay: OPERATOR_TITLES[value], + value: value === 'matches' ? 'wildcard' : 'match', + }) +); export const ConditionEntryInput = memo( ({ @@ -101,7 +104,7 @@ export const ConditionEntryInput = memo( } }, [entry, isVisited, onVisited]); - const fieldOptions = useMemo>>(() => { + const fieldOptions = useMemo>>(() => { const getDropdownDisplay = (field: ConditionEntryField) => ( <> {CONDITION_FIELD_TITLE[field]} @@ -148,7 +151,9 @@ export const ConditionEntryInput = memo( [entry, onChange] ); - const handleFieldUpdate = useCallback( + const handleFieldUpdate = useCallback< + NonNullable['onChange']> + >( (newField) => { onChange({ ...entry, field: newField }, entry); @@ -159,10 +164,9 @@ export const ConditionEntryInput = memo( [handleVisited, entry, onChange] ); - const handleOperatorUpdate = useCallback( - (newOperator) => onChange({ ...entry, type: newOperator }, entry), - [entry, onChange] - ); + const handleOperatorUpdate = useCallback< + NonNullable['onChange']> + >((newOperator) => onChange({ ...entry, type: newOperator }, entry), [entry, onChange]); const handleRemoveClick = useCallback(() => onRemove(entry), [entry, onRemove]); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx index ce168c5c0646..893956af34f7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx @@ -7,7 +7,7 @@ import type { ChangeEventHandler } from 'react'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; -import type { EuiSuperSelectOption } from '@elastic/eui'; +import type { EuiFieldTextProps, EuiSuperSelectOption } from '@elastic/eui'; import { EuiFieldText, EuiForm, @@ -332,7 +332,7 @@ export const TrustedAppsForm = memo( [item, processChanged] ); - const handleOnNameBlur = useCallback( + const handleOnNameBlur = useCallback>( ({ target: { name } }) => { processChanged(item); setVisited((prevVisited) => ({ ...prevVisited, [name]: true })); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx index 89782fa56707..e702454d45ec 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx @@ -103,7 +103,7 @@ const CasesByStatusComponent: React.FC = () => { const caseUrl = getAppUrl({ deepLinkId: SecurityPageName.case, path: appendSearch(search) }); const goToCases = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateTo({ url: caseUrl }); }, diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx index ee44b775766c..2544c8697a9d 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx @@ -13,7 +13,7 @@ import { sourcererActions } from '../../../../sourcerer/store'; import { getDataProvider, getDataProviderAnd, -} from '../../../../common/components/event_details/table/use_action_cell_data_provider'; +} from '../../../../common/components/event_details/use_action_cell_data_provider'; import type { DataProvider, QueryOperator } from '../../../../../common/types/timeline'; import { TimelineId } from '../../../../../common/types/timeline'; import { TimelineTypeEnum } from '../../../../../common/api/timeline'; diff --git a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx index 4cad19444c5e..37051c2b5c82 100644 --- a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx @@ -105,7 +105,7 @@ const EventsByDatasetComponent: React.FC = ({ const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); const goToHostEvents = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx index c7616c3c6d29..f9d4319ca251 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx @@ -72,7 +72,7 @@ const OverviewNetworkComponent: React.FC = ({ }); const goToNetwork = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, diff --git a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx index 8e6ccb158bfa..a167791a7b06 100644 --- a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx @@ -54,7 +54,7 @@ const StatefulRecentTimelinesComponent: React.FC = ({ filterBy }) => { ); const goToTimelines = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.timelines, diff --git a/x-pack/plugins/security_solution/public/resolver/view/controls/date_picker.tsx b/x-pack/plugins/security_solution/public/resolver/view/controls/date_picker.tsx index aa0c0f603195..62d86cb37aed 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/controls/date_picker.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/controls/date_picker.tsx @@ -8,7 +8,7 @@ import React, { useCallback, memo } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiPopoverTitle, EuiSuperDatePicker } from '@elastic/eui'; -import type { ShortDate } from '@elastic/eui'; +import type { ShortDate, EuiSuperDatePickerProps } from '@elastic/eui'; import { formatDate } from '../../../common/components/super_date_picker'; import { StyledEuiButtonIcon } from './styles'; import { useColors } from '../use_colors'; @@ -61,7 +61,7 @@ export const DateSelectionButton = memo( return selectors.currentAppliedTimeRange(state.analyzer[id]); }); - const onTimeChange = useCallback( + const onTimeChange = useCallback( ({ start, end, isInvalid }) => { if (!isInvalid) { const isQuickSelection = start.includes('now') || end.includes('now'); diff --git a/x-pack/plugins/security_solution/public/resolver/view/controls/index.tsx b/x-pack/plugins/security_solution/public/resolver/view/controls/index.tsx index 6829f9ece1fe..a12ae2d90a7d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/controls/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/controls/index.tsx @@ -29,6 +29,8 @@ import { StyledGraphControls, StyledGraphControlsColumn, StyledEuiRange } from ' import { NodeLegend } from './legend'; import { SchemaInformation } from './schema'; +type PopoverType = null | 'schemaInfo' | 'nodeLegend' | 'sourcererSelection' | 'datePicker'; + export const GraphControls = React.memo( ({ id, @@ -51,13 +53,11 @@ export const GraphControls = React.memo( const isDatePickerAndSourcererDisabled = useIsExperimentalFeatureEnabled( 'analyzerDatePickersAndSourcererDisabled' ); - const [activePopover, setPopover] = useState< - null | 'schemaInfo' | 'nodeLegend' | 'sourcererSelection' | 'datePicker' - >(null); + const [activePopover, setPopover] = useState(null); const colorMap = useColors(); const setActivePopover = useCallback( - (value) => { + (value: PopoverType) => { if (value === activePopover) { setPopover(null); } else { diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index 0465f16d55b7..3846e1d7b19d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -317,7 +317,7 @@ const UnstyledProcessEventDot = React.memo( }, [dispatch, nodeID, timestamp, id]); const handleClick = useCallback( - (clickEvent) => { + (clickEvent: React.MouseEvent) => { if (animationTarget.current?.beginElement) { animationTarget.current.beginElement(); } diff --git a/x-pack/plugins/security_solution/public/resolver/view/use_link_props.ts b/x-pack/plugins/security_solution/public/resolver/view/use_link_props.ts index f61d768a3414..494ed521c73e 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/use_link_props.ts +++ b/x-pack/plugins/security_solution/public/resolver/view/use_link_props.ts @@ -13,8 +13,6 @@ import * as selectors from '../store/selectors'; import type { PanelViewAndParameters } from '../types'; import type { State } from '../../common/store/types'; -type EventHandlerCallback = MouseEventHandler; - /** * Get an `onClick` function and an `href` string. Use these as props for `` elements. * `onClick` will use navigate to the `panelViewAndParameters` using `history.push`. @@ -26,7 +24,7 @@ export function useLinkProps( panelViewAndParameters: PanelViewAndParameters ): { href: string; - onClick: EventHandlerCallback; + onClick: MouseEventHandler; } { const search = useSelector((state: State) => selectors.relativeHref(state.analyzer[id])(panelViewAndParameters) diff --git a/x-pack/plugins/security_solution/public/resolver/view/use_navigate_or_replace.ts b/x-pack/plugins/security_solution/public/resolver/view/use_navigate_or_replace.ts index 447bedb67352..ede554b305d3 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/use_navigate_or_replace.ts +++ b/x-pack/plugins/security_solution/public/resolver/view/use_navigate_or_replace.ts @@ -10,15 +10,13 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import type { LocationDescriptorObject } from 'history'; -type EventHandlerCallback = MouseEventHandler; - export function useNavigateOrReplace( to: LocationDescriptorObject, /** Additional onClick callback */ - additionalOnClick?: EventHandlerCallback -): { href: string; onClick: EventHandlerCallback } { + additionalOnClick?: MouseEventHandler +): { href: string; onClick: MouseEventHandler } { const history = useHistory(); - const onClick = useCallback( + const onClick = useCallback( (event) => { try { if (additionalOnClick) { diff --git a/x-pack/plugins/security_solution/public/sourcerer/components/index.tsx b/x-pack/plugins/security_solution/public/sourcerer/components/index.tsx index 0f946bd8c247..8b45d9666979 100644 --- a/x-pack/plugins/security_solution/public/sourcerer/components/index.tsx +++ b/x-pack/plugins/security_solution/public/sourcerer/components/index.tsx @@ -255,7 +255,7 @@ export const Sourcerer = React.memo(({ scope: scopeId } ); const onChangeDataView = useCallback( - (newSelectedOption) => { + (newSelectedOption: string) => { setDataViewId(newSelectedOption); setIndexPatternsByDataView(newSelectedOption); }, diff --git a/x-pack/plugins/security_solution/public/sourcerer/components/use_pick_index_patterns.tsx b/x-pack/plugins/security_solution/public/sourcerer/components/use_pick_index_patterns.tsx index 397732ed4ec9..8798a84409d1 100644 --- a/x-pack/plugins/security_solution/public/sourcerer/components/use_pick_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/sourcerer/components/use_pick_index_patterns.tsx @@ -179,11 +179,11 @@ export const usePickIndexPatterns = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [isOnlyDetectionAlerts, selectedDataViewId, missingPatterns, scopeId, selectedPatterns]); - const onChangeCombo = useCallback((newSelectedOptions) => { + const onChangeCombo = useCallback((newSelectedOptions) => { setSelectedOptions(newSelectedOptions); }, []); - const renderOption = useCallback( + const renderOption = useCallback( ({ value }) => {value}, [] ); diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts b/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts index 64e616d0a1ea..85ced6d6e153 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts +++ b/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts @@ -50,7 +50,8 @@ export const useInvestigateInTimeline = ({ const { startTransaction } = useStartTransaction(); const updateTimelineIsLoading = useCallback( - (payload) => dispatch(timelineActions.updateIsLoading(payload)), + (payload: Parameters[0]) => + dispatch(timelineActions.updateIsLoading(payload)), [dispatch] ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/modal/actions/save_timeline_modal.tsx b/x-pack/plugins/security_solution/public/timelines/components/modal/actions/save_timeline_modal.tsx index 67409a91c854..7ce0be75def6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/modal/actions/save_timeline_modal.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/modal/actions/save_timeline_modal.tsx @@ -88,7 +88,7 @@ export const SaveTimelineModal = React.memo( }); const handleSubmit = useCallback( - (titleAndDescription, isValid) => { + (titleAndDescription: { title: string; description: string }, isValid: boolean) => { if (isValid) { dispatch( timelineActions.updateTitleAndDescription({ diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx index 3ca9f88422a2..04493dfd9a4b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/export_timeline.tsx @@ -23,7 +23,7 @@ const ExportTimeline: React.FC<{ const { addSuccess } = useAppToasts(); const onExportSuccess = useCallback( - (exportCount) => { + (exportCount: number) => { if (onComplete != null) { onComplete(); } diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts index 1fb75887d6a7..1a47c22d0fb6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts @@ -240,7 +240,7 @@ export interface TimelineTab { href: string; id: TimelineType; name: string; - onClick: (ev: { preventDefault: () => void }) => void; + onClick: (ev: React.SyntheticEvent) => void; } export interface TemplateTimelineFilter { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_status.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_status.tsx index 9e39bbf8ece3..f51334d03293 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_status.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_status.tsx @@ -79,7 +79,7 @@ export const useTimelineStatus = ({ ); const onFilterClicked = useCallback( - (tabId) => { + (tabId: TemplateTimelineType) => { if (selectedTab === tabId) { setSelectedTab(null); } else { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_types.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_types.tsx index 8002798291cc..e08eccaf093e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_types.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/use_timeline_types.tsx @@ -158,7 +158,7 @@ export const useTimelineTypes = ({ data-test-subj={`open-timeline-modal-body-${TimelineTabsStyle.filter}-${tab.id}`} isSelected={tab.id === timelineType} key={`timeline-${TimelineTabsStyle.filter}-${tab.id}`} - onClick={(ev: { preventDefault: () => void }) => { + onClick={(ev: React.SyntheticEvent) => { tab.onClick(ev); onFilterClicked(tab.id, TimelineTabsStyle.filter); }} diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx index 776d1279ae71..4bef910848fc 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/index.tsx @@ -24,6 +24,7 @@ import styled from 'styled-components'; import type { State } from '../../../common/store'; import { RowRendererValues } from '../../../../common/api/timeline'; +import type { RowRendererId } from '../../../../common/api/timeline'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import { setExcludedRowRendererIds as dispatchSetExcludedRowRendererIds } from '../../store/actions'; import { timelineSelectors } from '../../store'; @@ -79,7 +80,7 @@ const StatefulRowRenderersBrowserComponent: React.FC + (payload: RowRendererId[]) => dispatch( dispatchSetExcludedRowRendererIds({ id: timelineId, diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx index 45f709013952..4656bfb0da59 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/row_renderers_browser.tsx @@ -96,7 +96,7 @@ const RowRenderersBrowserComponent = ({ ); const nameColumnRenderCallback = useCallback( - (value, item) => ( + (value: string, item: RowRendererOption) => ( {value} @@ -105,7 +105,7 @@ const RowRenderersBrowserComponent = ({ ); const idColumnRenderCallback = useCallback( - (_, item) => ( + (_: unknown, item: RowRendererOption) => ( { - connectorId?: string; - subAction: string; - subActionParams?: P; - disabled?: boolean; -} - -export const useSubAction = ({ - connectorId, - subAction, - subActionParams, - disabled = false, - ...rest -}: UseSubActionParams) => { - const { http } = useKibana().services; - - return useQuery({ - queryKey: ['useSubAction', connectorId, subAction, subActionParams], - queryFn: ({ signal }) => - executeAction({ - id: connectorId as string, - params: { - subAction, - subActionParams, - }, - http, - signal, - }), - enabled: !disabled && !!connectorId && !!subAction, - ...rest, - }); -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx deleted file mode 100644 index 6a2c788a59c2..000000000000 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx +++ /dev/null @@ -1,37 +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 { executeAction } from '@kbn/triggers-actions-ui-plugin/public'; -import { useMutation } from '@tanstack/react-query'; -import { useKibana } from '../../../../../common/lib/kibana/kibana_react'; - -export interface UseSubActionParams

{ - connectorId: string; - subAction: string; - subActionParams?: P; -} - -export const useSubActionMutation = ({ - connectorId, - subAction, - subActionParams, -}: UseSubActionParams

) => { - const { http } = useKibana().services; - - return useMutation({ - mutationKey: ['executeSubAction', connectorId, subAction, subActionParams], - mutationFn: () => - executeAction({ - id: connectorId, - params: { - subAction, - subActionParams, - }, - http, - }), - }); -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/helpers.tsx deleted file mode 100644 index fc1941b6824c..000000000000 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/helpers.tsx +++ /dev/null @@ -1,25 +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 { DEFAULT_ALERTS_INDEX, DEFAULT_PREVIEW_INDEX } from '../../../../../common/constants'; - -/* -The referenced alert _index in the flyout uses the `.internal.` such as -`.internal.alerts-security.alerts-spaceId` in the alert page flyout and -.internal.preview.alerts-security.alerts-spaceId` in the rule creation preview flyout -but we always want to use their respective aliase indices rather than accessing their backing .internal. indices. -*/ -export const getAlertIndexAlias = ( - index: string, - spaceId: string = 'default' -): string | undefined => { - if (index.startsWith(`.internal${DEFAULT_ALERTS_INDEX}`)) { - return `${DEFAULT_ALERTS_INDEX}-${spaceId}`; - } else if (index.startsWith(`.internal${DEFAULT_PREVIEW_INDEX}`)) { - return `${DEFAULT_PREVIEW_INDEX}-${spaceId}`; - } -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx deleted file mode 100644 index 06bce7781e0b..000000000000 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.test.tsx +++ /dev/null @@ -1,79 +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 { renderHook, act } from '@testing-library/react-hooks'; -import React from 'react'; -import type { UseDetailPanelConfig } from './use_detail_panel'; -import { useDetailPanel } from './use_detail_panel'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import { SourcererScopeName } from '../../../../sourcerer/store/model'; -import { TimelineId } from '../../../../../common/types/timeline'; -import { ExpandableFlyoutProvider } from '@kbn/expandable-flyout'; -import { TestProviders } from '../../../../common/mock'; -import { createTelemetryServiceMock } from '../../../../common/lib/telemetry/telemetry_service.mock'; - -const mockedTelemetry = createTelemetryServiceMock(); -jest.mock('../../../../common/lib/kibana', () => { - const original = jest.requireActual('../../../../common/lib/kibana'); - return { - ...original, - useKibana: () => ({ - ...original.useKibana(), - services: { - ...original.useKibana().services, - telemetry: mockedTelemetry, - }, - }), - }; -}); -jest.mock('../../../../common/hooks/use_selector'); -jest.mock('../../../store'); - -jest.mock('../../../../sourcerer/containers', () => { - const mockSourcererReturn = { - browserFields: {}, - loading: true, - indexPattern: {}, - selectedPatterns: [], - missingPatterns: [], - }; - return { - useSourcererDataView: jest.fn().mockReturnValue(mockSourcererReturn), - }; -}); - -describe('useDetailPanel', () => { - const defaultProps: UseDetailPanelConfig = { - sourcererScope: SourcererScopeName.detections, - scopeId: TimelineId.test, - }; - const mockGetExpandedDetail = jest.fn().mockImplementation(() => ({})); - beforeEach(() => { - (useDeepEqualSelector as jest.Mock).mockImplementation((cb) => { - return mockGetExpandedDetail(); - }); - }); - afterEach(() => { - (useDeepEqualSelector as jest.Mock).mockClear(); - }); - - const wrapper = ({ children }: { children: React.ReactChild }) => ( - - {children} - - ); - const renderUseDetailPanel = (props = defaultProps) => - renderHook(() => useDetailPanel(props), { wrapper }); - - test('should return open fns (event, host, network, user), handleOnDetailsPanelClosed fn, shouldShowDetailsPanel, and the DetailsPanel component', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderUseDetailPanel(); - await waitForNextUpdate(); - - expect(result.current.openEventDetailsPanel).toBeDefined(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx deleted file mode 100644 index fde0d04b8610..000000000000 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/hooks/use_detail_panel.tsx +++ /dev/null @@ -1,57 +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 { useMemo, useCallback } from 'react'; -import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { useKibana } from '../../../../common/lib/kibana'; -import { useSourcererDataView } from '../../../../sourcerer/containers'; -import type { SourcererScopeName } from '../../../../sourcerer/store/model'; -import { DocumentDetailsRightPanelKey } from '../../../../flyout/document_details/shared/constants/panel_keys'; - -export interface UseDetailPanelConfig { - sourcererScope: SourcererScopeName; - scopeId: string; -} -export interface UseDetailPanelReturn { - openEventDetailsPanel: (eventId?: string, onClose?: () => void) => void; -} - -export const useDetailPanel = ({ - sourcererScope, - scopeId, -}: UseDetailPanelConfig): UseDetailPanelReturn => { - const { telemetry } = useKibana().services; - const { selectedPatterns } = useSourcererDataView(sourcererScope); - - const { openFlyout } = useExpandableFlyoutApi(); - - const eventDetailsIndex = useMemo(() => selectedPatterns.join(','), [selectedPatterns]); - - const openEventDetailsPanel = useCallback( - (eventId?: string, onClose?: () => void) => { - openFlyout({ - right: { - id: DocumentDetailsRightPanelKey, - params: { - id: eventId, - indexName: eventDetailsIndex, - scopeId, - }, - }, - }); - telemetry.reportDetailsFlyoutOpened({ - location: scopeId, - panel: 'right', - }); - }, - [openFlyout, eventDetailsIndex, scopeId, telemetry] - ); - - return { - openEventDetailsPanel, - }; -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx index 635f1a91a795..2048cefb9bf0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx @@ -8,6 +8,7 @@ import type { EuiContextMenuPanelDescriptor } from '@elastic/eui'; import { EuiContextMenu, EuiIcon, EuiPopover } from '@elastic/eui'; import React, { useCallback, useMemo, useRef, useState } from 'react'; +import type { DraggableChildrenFn } from '@hello-pangea/dnd'; import { Draggable } from '@hello-pangea/dnd'; import type { ResizeCallback } from 're-resizable'; import { Resizable } from 're-resizable'; @@ -215,7 +216,7 @@ const ColumnHeaderComponent: React.FC = ({ [header, onFilterChange, sort, timelineId] ); - const DraggableContent = useCallback( + const DraggableContent = useCallback( (dragProvided) => ( = ({ ); }, [dispatch, header, sort, timelineId]); - const onColumnRemoved = useCallback( + const onColumnRemoved = useCallback( (columnId) => dispatch(timelineActions.removeColumn({ id: timelineId, columnId })), [dispatch, timelineId] ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx index d2b9a0aa7c66..f343b9af8ed9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; -import type { DraggableChildrenFn } from '@hello-pangea/dnd'; +import type { DraggableChildrenFn, DroppableProps } from '@hello-pangea/dnd'; import { Droppable } from '@hello-pangea/dnd'; import { useDispatch } from 'react-redux'; @@ -162,7 +162,7 @@ export const ColumnHeadersComponent = ({ [columnHeaders, timelineId, draggingIndex, sort, tabType] ); - const DroppableContent = useCallback( + const DroppableContent = useCallback( (dropProvided, snapshot) => ( <> = ({ const { navigateToApp, getUrlForApp } = useKibana().services.application; const goToRuleDetails = useCallback( - (ev) => { + (ev: React.SyntheticEvent) => { ev.preventDefault(); navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.tsx index 55950f9a9aac..fdb1f818f754 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_signature.tsx @@ -9,6 +9,7 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import type { DraggableWrapperProps } from '../../../../../../common/components/drag_and_drop/draggable_wrapper'; import { DragEffects, DraggableWrapper, @@ -80,7 +81,7 @@ export const DraggableSignatureId = React.memo<{ [id, signatureId] ); - const render = useCallback( + const render: DraggableWrapperProps['render'] = useCallback( (dataProvider, _, snapshot) => snapshot.isDragging ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx index 48ce6255725d..1f070d52a8de 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx @@ -49,7 +49,7 @@ const UserNameComponent: React.FC = ({ const { openRightPanel } = useExpandableFlyoutApi(); const openUserDetailsSidePanel = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); if (onClick) { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx index 6e4b87936203..493d6d054a99 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx @@ -11,6 +11,7 @@ import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; +import type { DraggableWrapperProps } from '../../../../../../common/components/drag_and_drop/draggable_wrapper'; import { DragEffects, DraggableWrapper, @@ -89,7 +90,7 @@ export const DraggableZeekElement = React.memo<{ [field, id, value] ); - const render = useCallback( + const render: DraggableWrapperProps['render'] = useCallback( (dataProvider, _, snapshot) => snapshot.isDragging ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx index d09444edd6c9..09aef63266d2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx @@ -27,6 +27,7 @@ import { StatefulEditDataProvider } from '../../edit_data_provider'; import { addContentToTimeline, getDisplayValue } from './helpers'; import { timelineSelectors } from '../../../store'; import { ADD_FIELD_LABEL, ADD_TEMPLATE_FIELD_LABEL } from './translations'; +import type { OnDataProviderEdited } from '../events'; interface AddDataProviderPopoverProps { browserFields: BrowserFields; @@ -58,7 +59,7 @@ const AddDataProviderPopoverComponent: React.FC = ( [setIsAddFilterPopoverOpen] ); - const handleDataProviderEdited = useCallback( + const handleDataProviderEdited = useCallback( ({ andProviderId, excluded, field, id, operator, providerId, value, type }) => { addContentToTimeline({ dataProviders, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx index 11c13f16275f..debb46a1f992 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx @@ -5,10 +5,11 @@ * 2.0. */ +import type { DroppableProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiFormHelpText, EuiSpacer } from '@elastic/eui'; import { rgba } from 'polished'; import React, { useCallback, useMemo, useRef, useState } from 'react'; -import type { DraggingStyle, NotDraggingStyle } from '@hello-pangea/dnd'; +import type { DraggableChildrenFn, DraggingStyle, NotDraggingStyle } from '@hello-pangea/dnd'; import { Draggable, Droppable } from '@hello-pangea/dnd'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; @@ -34,6 +35,7 @@ import { EMPTY_GROUP, flattenIntoAndGroups } from './helpers'; import { ProviderItemBadge } from './provider_item_badge'; import * as i18n from './translations'; +import type { OnDataProviderEdited } from '../events'; export const EMPTY_PROVIDERS_GROUP_CLASS_NAME = 'empty-providers-group'; @@ -222,7 +224,7 @@ export const DataProvidersGroupItem = React.memo( dispatch(timelineActions.updateDataProviderType(payload)); }, [dataProvider.id, dataProvider.type, dispatch, group, index, timelineId]); - const handleDataProviderEdited = useCallback( + const handleDataProviderEdited = useCallback( ({ andProviderId, excluded, field, operator, providerId, value }) => dispatch( timelineActions.dataProviderEdited({ @@ -267,7 +269,7 @@ export const DataProvidersGroupItem = React.memo( dataProvider.queryMatch.displayValue ?? dataProvider.queryMatch.value ); - const DraggableContent = useCallback( + const DraggableContent = useCallback( (provided, snapshot) => (

( [browserFields, group, groupIndex, timelineId] ); - const DroppableContent = useCallback( + const DroppableContent = useCallback( (droppableProvided) => ( setIsPopoverOpen(false), [setIsPopoverOpen]); const onChangeItemsPerPage = useCallback( - (itemsChangedPerPage) => + (itemsChangedPerPage: number) => dispatch(timelineActions.updateItemsPerPage({ id, itemsPerPage: itemsChangedPerPage })), [dispatch, id] ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx index 659073b3fc83..3ac5ba0cb5ac 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx @@ -121,7 +121,7 @@ export const QueryBarTimeline = memo( const savedQueryServices = useSavedQueryServices(); const applyKqlFilterQuery = useCallback( - (expression: string, kind) => + (expression: string, kind: KueryFilterQueryKind) => dispatch( timelineActions.applyKqlFilterQuery({ id: timelineId, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx index 33bbfe53bda6..246e46cfab04 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx @@ -10,6 +10,7 @@ import { EuiInputPopover, EuiFieldText, htmlIdGenerator, keys } from '@elastic/e import React, { memo, useCallback, useMemo, useState } from 'react'; import type { OpenTimelineResult } from '../../open_timeline/types'; +import type { SelectableTimelineProps } from '../selectable_timeline'; import { SelectableTimeline } from '../selectable_timeline'; import * as i18n from '../translations'; import { type TimelineType, TimelineTypeEnum } from '../../../../../common/api/timeline'; @@ -52,8 +53,8 @@ const SearchTimelineSuperSelectComponent: React.FC { - setIsPopoverOpen(true); + const handlePopover = useCallback(() => { + setIsPopoverOpen((isOpen) => !isOpen); }, []); const handleKeyboardOpen: EuiFieldTextProps['onKeyDown'] = useCallback((event) => { @@ -68,7 +69,7 @@ const SearchTimelineSuperSelectComponent: React.FC ( ( ({ timelines, onlyFavorites, searchTimelineValue }) => [ ...(!onlyFavorites && searchTimelineValue === '' ? getBasicSelectableOptions(timelineId == null ? '-1' : timelineId) diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx index 71c5b273d9dc..b1672e1a7f6f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx @@ -25,7 +25,7 @@ import { type TimelineType, SortFieldTimelineEnum } from '../../../../../common/ import { useGetAllTimeline } from '../../../containers/all'; import { isUntitled } from '../../open_timeline/helpers'; import * as i18nTimeline from '../../open_timeline/translations'; -import type { OpenTimelineResult } from '../../open_timeline/types'; +import type { FavoriteTimelineResult, OpenTimelineResult } from '../../open_timeline/types'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import * as i18n from '../translations'; import { Direction } from '../../../../../common/search_strategy'; @@ -50,8 +50,16 @@ const TIMELINE_ITEM_HEIGHT = 50; * @param {EuiSelectableOption[]} options * @returns {EuiSelectableOption[]} modified options */ -const replaceTitleInOptions = (options: EuiSelectableOption[]): EuiSelectableOption[] => - options.map(({ title, ...props }) => ({ ...props, title: undefined, timelineTitle: title })); +const replaceTitleInOptions = ( + options: EuiSelectableOption[] +): Array< + EuiSelectableOption<{ timelineTitle: string; description?: string; graphEveId?: string }> +> => + options.map(({ title, ...props }) => ({ + ...props, + title: undefined, + timelineTitle: title ?? '', + })); export interface GetSelectableOptions { timelines: OpenTimelineResult[]; @@ -97,7 +105,7 @@ const SelectableTimelineComponent: React.FC = ({ const debouncedSetSearchTimelineValue = useMemo(() => debounce(500, setSearchTimelineValue), []); const onSearchTimeline = useCallback( - (val) => { + (val: string) => { debouncedSetSearchTimelineValue(val); }, [debouncedSetSearchTimelineValue] @@ -130,7 +138,16 @@ const SelectableTimelineComponent: React.FC = ({ [heightTrigger, pageSize] ); - const renderTimelineOption = useCallback((option, searchValue) => { + const renderTimelineOption = useCallback< + NonNullable< + EuiSelectableProps<{ + timelineTitle: string; + description?: string; + graphEventId?: string; + favorite?: FavoriteTimelineResult[]; + }>['renderOption'] + > + >((option, searchValue) => { const title: string = isUntitled({ ...option, title: option.timelineTitle }) ? i18nTimeline.UNTITLED_TIMELINE : option.timelineTitle; @@ -176,17 +193,25 @@ const SelectableTimelineComponent: React.FC = ({ ); }, []); - const handleTimelineChange = useCallback( + const handleTimelineChange = useCallback< + NonNullable< + EuiSelectableProps<{ + timelineTitle: string; + description?: string; + graphEventId?: string; + }>['onChange'] + > + >( (options) => { - const selectedTimeline = options.filter( - (option: { checked: string }) => option.checked === 'on' - ); + const selectedTimeline = options.filter((option) => option.checked === 'on'); if (selectedTimeline != null && selectedTimeline.length > 0) { onTimelineChange( isEmpty(selectedTimeline[0].timelineTitle) ? i18nTimeline.UNTITLED_TIMELINE : selectedTimeline[0].timelineTitle, - selectedTimeline[0].id === '-1' ? null : selectedTimeline[0].id, + selectedTimeline[0].id === '-1' + ? null + : (selectedTimeline[0].id as unknown as string | null), selectedTimeline[0].graphEventId ?? '' ); } @@ -195,7 +220,7 @@ const SelectableTimelineComponent: React.FC = ({ [onClosePopover, onTimelineChange] ); - const EuiSelectableContent = useCallback( + const EuiSelectableContent = useCallback>( (list, search) => ( <> {search} @@ -260,7 +285,12 @@ const SelectableTimelineComponent: React.FC = ({ }, [fetchAllTimeline, onlyFavorites, pageSize, searchTimelineValue, timelineType]); return ( - data-test-subj="selectable-input" height={POPOVER_HEIGHT} isLoading={loading && timelines == null} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/index.tsx index eceb9c8dbd28..42fffc776371 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/index.tsx @@ -29,7 +29,7 @@ interface Props { const SessionTabContent: React.FC = ({ timelineId }) => { const [height, setHeight] = useState(0); - const measuredRef = useCallback((node) => { + const measuredRef = useCallback((node: HTMLDivElement | HTMLSpanElement | null) => { if (node !== null) { setHeight(node.getBoundingClientRect().height); } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx index 736b23cf0232..9c4b135b5e77 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.test.tsx @@ -68,18 +68,6 @@ jest.mock('../../../../../common/lib/kibana', () => { }), }; }); -const mockOpenDetailFn = jest.fn(); - -jest.mock('../../../side_panel/hooks/use_detail_panel', () => { - return { - useDetailPanel: () => ({ - openEventDetailsPanel: mockOpenDetailFn, - handleOnDetailsPanelClosed: () => {}, - DetailsPanel: () =>
, - shouldShowDetailsPanel: false, - }), - }; -}); describe('useSessionView with active timeline and a session id and graph event id', () => { let setTimelineFullScreen: jest.Mock; @@ -155,12 +143,7 @@ describe('useSessionView with active timeline and a session id and graph event i }, { wrapper: Wrapper } ); - expect(kibana.services.sessionView.getSessionView).toHaveBeenCalledWith({ - height: 1000, - sessionEntityId: 'test', - loadAlertDetails: mockOpenDetailFn, - canReadPolicyManagement: false, - }); + expect(kibana.services.sessionView.getSessionView).toHaveBeenCalled(); }); describe('useSessionView with non active timeline and graph event id set', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.tsx index 49af740647ce..e2aa8c42511d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/session/use_session_view.tsx @@ -11,6 +11,9 @@ import styled from 'styled-components'; import { useDispatch } from 'react-redux'; import { dataTableSelectors, tableDefaults } from '@kbn/securitysolution-data-table'; import type { TableId } from '@kbn/securitysolution-data-table'; +import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; +import { DocumentDetailsRightPanelKey } from '../../../../../flyout/document_details/shared/constants/panel_keys'; +import { useSourcererDataView } from '../../../../../sourcerer/containers'; import { getScopedActions, isActiveTimeline, @@ -20,7 +23,6 @@ import { import { useKibana } from '../../../../../common/lib/kibana'; import * as i18n from './translations'; import { TimelineTabs } from '../../../../../../common/types/timeline'; -import { useDetailPanel } from '../../../side_panel/hooks/use_detail_panel'; import { SourcererScopeName } from '../../../../../sourcerer/store/model'; import { isFullScreen } from '../../body/column_headers'; import { SCROLLING_DISABLED_CLASS_NAME } from '../../../../../../common/constants'; @@ -242,7 +244,7 @@ export const useSessionViewNavigation = ({ scopeId }: { scopeId: string }) => { }; export const useSessionView = ({ scopeId, height }: { scopeId: string; height?: number }) => { - const { sessionView } = useKibana().services; + const { sessionView, telemetry } = useKibana().services; const getScope = useMemo(() => { if (isTimelineScope(scopeId)) { return timelineSelectors.getTimelineByIdSelector(); @@ -280,10 +282,30 @@ export const useSessionView = ({ scopeId, height }: { scopeId: string; height?: return SourcererScopeName.default; } }, [scopeId]); - const { openEventDetailsPanel } = useDetailPanel({ - sourcererScope, - scopeId, - }); + + const { selectedPatterns } = useSourcererDataView(sourcererScope); + const eventDetailsIndex = useMemo(() => selectedPatterns.join(','), [selectedPatterns]); + + const { openFlyout } = useExpandableFlyoutApi(); + const openAlertDetailsFlyout = useCallback( + (eventId?: string, onClose?: () => void) => { + openFlyout({ + right: { + id: DocumentDetailsRightPanelKey, + params: { + id: eventId, + indexName: eventDetailsIndex, + scopeId, + }, + }, + }); + telemetry.reportDetailsFlyoutOpened({ + location: scopeId, + panel: 'right', + }); + }, + [openFlyout, eventDetailsIndex, scopeId, telemetry] + ); const sessionViewComponent = useMemo(() => { const sessionViewSearchBarHeight = 118; @@ -291,7 +313,7 @@ export const useSessionView = ({ scopeId, height }: { scopeId: string; height?: return sessionViewConfig !== null ? sessionView.getSessionView({ ...sessionViewConfig, - loadAlertDetails: openEventDetailsPanel, + loadAlertDetails: openAlertDetailsFlyout, isFullScreen: fullScreen, height: heightMinusSearchBar, canReadPolicyManagement, @@ -301,13 +323,13 @@ export const useSessionView = ({ scopeId, height }: { scopeId: string; height?: height, sessionViewConfig, sessionView, - openEventDetailsPanel, + openAlertDetailsFlyout, fullScreen, canReadPolicyManagement, ]); return { - openEventDetailsPanel, + openEventDetailsPanel: openAlertDetailsFlyout, SessionView: sessionViewComponent, }; }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx index 42b23945ac7b..0b629788b769 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx @@ -208,7 +208,9 @@ export const TimelineDataTableComponent: React.FC = memo( [onColumnResize] ); - const onChangeItemsPerPage = useCallback( + const onChangeItemsPerPage = useCallback< + NonNullable + >( (itemsChangedPerPage) => { dispatch( timelineActions.updateItemsPerPage({ id: timelineId, itemsPerPage: itemsChangedPerPage }) diff --git a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx index c7b5252e0897..e0783522f5dd 100644 --- a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx @@ -63,7 +63,15 @@ export const useCreateTimeline = ({ const { resetDiscoverAppState } = useDiscoverInTimelineContext(); const createTimeline = useCallback( - ({ id, show, timeRange: timeRangeParam }) => { + ({ + id, + show, + timeRange: timeRangeParam, + }: { + id: string; + show: boolean; + timeRange?: TimeRange; + }) => { const timerange = timeRangeParam ?? globalTimeRange; if (id === TimelineId.active && timelineFullScreen) { @@ -131,11 +139,11 @@ export const useCreateTimeline = ({ return useCallback( async (options?: { timeRange?: TimeRange }) => { await resetDiscoverAppState(); - createTimeline({ id: timelineId, show: true, timelineType, timeRange: options?.timeRange }); + createTimeline({ id: timelineId, show: true, timeRange: options?.timeRange }); if (typeof onClick === 'function') { onClick(); } }, - [createTimeline, timelineId, timelineType, onClick, resetDiscoverAppState] + [createTimeline, timelineId, onClick, resetDiscoverAppState] ); }; diff --git a/x-pack/plugins/security_solution/public/timelines/store/actions.ts b/x-pack/plugins/security_solution/public/timelines/store/actions.ts index fbf061529c49..e65b7273b5de 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/actions.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/actions.ts @@ -30,6 +30,7 @@ import type { } from '../../../common/types/timeline'; import type { DataProviderType, RowRendererId } from '../../../common/api/timeline'; import type { ResolveTimelineConfig } from '../components/open_timeline/types'; +import type { PrimitiveOrArrayOfPrimitives } from '../../common/lib/kuery'; const actionCreator = actionCreatorFactory('x-pack/security_solution/local/timeline'); @@ -115,7 +116,7 @@ export const dataProviderEdited = actionCreator<{ id: string; operator: QueryOperator; providerId: string; - value: string | number | Array; + value: PrimitiveOrArrayOfPrimitives; }>('DATA_PROVIDER_EDITED'); export const updateDataProviderType = actionCreator<{ diff --git a/x-pack/plugins/security_solution/public/timelines/store/helpers.ts b/x-pack/plugins/security_solution/public/timelines/store/helpers.ts index 0342c28f28aa..b87646544974 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/helpers.ts @@ -44,6 +44,7 @@ import { import { activeTimeline } from '../containers/active_timeline_context'; import type { ResolveTimelineConfig } from '../components/open_timeline/types'; import { getDisplayValue } from '../components/timeline/data_providers/helpers'; +import type { PrimitiveOrArrayOfPrimitives } from '../../common/lib/kuery'; interface AddTimelineNoteParams { id: string; @@ -841,7 +842,7 @@ const updateProviderProperties = ({ operator: QueryOperator; providerId: string; timeline: TimelineModel; - value: string | number | Array; + value: PrimitiveOrArrayOfPrimitives; }) => timeline.dataProviders.map((provider) => provider.id === providerId @@ -875,7 +876,7 @@ const updateAndProviderProperties = ({ operator: QueryOperator; providerId: string; timeline: TimelineModel; - value: string | number | Array; + value: PrimitiveOrArrayOfPrimitives; }) => timeline.dataProviders.map((provider) => provider.id === providerId @@ -909,7 +910,7 @@ interface UpdateTimelineProviderEditPropertiesParams { operator: QueryOperator; providerId: string; timelineById: TimelineById; - value: string | number | Array; + value: PrimitiveOrArrayOfPrimitives; } export const updateTimelineProviderProperties = ({ diff --git a/x-pack/plugins/security_solution/public/value_list/components/inline_edit_list_item_value.tsx b/x-pack/plugins/security_solution/public/value_list/components/inline_edit_list_item_value.tsx index d8777a8d83d0..7fe449e6cbbf 100644 --- a/x-pack/plugins/security_solution/public/value_list/components/inline_edit_list_item_value.tsx +++ b/x-pack/plugins/security_solution/public/value_list/components/inline_edit_list_item_value.tsx @@ -33,7 +33,7 @@ export const InlineEditListItemValue = ({ listItem }: { listItem: ListItemSchema }); }, }); - const onChange = useCallback((e) => { + const onChange = useCallback>((e) => { setValue(e.target.value); }, []); const onCancel = useCallback(() => { @@ -41,7 +41,7 @@ export const InlineEditListItemValue = ({ listItem }: { listItem: ListItemSchema }, [listItem]); const onSave = useCallback( - async (newValue) => { + async (newValue: string) => { track(METRIC_TYPE.COUNT, TELEMETRY_EVENT.EDIT_VALUE_LIST_ITEM); await patchListItemMutation.mutateAsync({ id: listItem.id, diff --git a/x-pack/plugins/security_solution/public/value_list/components/value_list_modal.tsx b/x-pack/plugins/security_solution/public/value_list/components/value_list_modal.tsx index 6aa6b1b7d9b6..f2741d80bd35 100644 --- a/x-pack/plugins/security_solution/public/value_list/components/value_list_modal.tsx +++ b/x-pack/plugins/security_solution/public/value_list/components/value_list_modal.tsx @@ -6,6 +6,7 @@ */ import React, { useState, useCallback } from 'react'; import { css } from '@emotion/css'; +import type { EuiSearchBarProps } from '@elastic/eui'; import { EuiModal, EuiModalHeader, @@ -100,7 +101,7 @@ export const ValueListModal = ({ listId, onCloseModal, canWriteIndex }: ValueLis pageSizeOptions: [5, 10, 25], }; - const onQueryChange = useCallback((params) => { + const onQueryChange: NonNullable = useCallback((params) => { setFilter(params.queryText); }, []); diff --git a/x-pack/plugins/session_view/public/components/process_tree_alerts/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_alerts/index.tsx index 6cadb836d166..cf688abdece5 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_alerts/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_alerts/index.tsx @@ -80,7 +80,7 @@ export function ProcessTreeAlerts({ [onAlertSelected] ); - const handleProcessEventAlertCategorySelected = useCallback((eventCategory) => { + const handleProcessEventAlertCategorySelected = useCallback((eventCategory: any) => { setSelectedProcessEventAlertCategory(eventCategory); }, []); diff --git a/x-pack/plugins/session_view/public/components/process_tree_alerts_filter/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_alerts_filter/index.tsx index a52fcc09cc4e..6f4b2b5570b4 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_alerts_filter/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_alerts_filter/index.tsx @@ -51,7 +51,7 @@ export const ProcessTreeAlertsFilter = ({ }; const onSelectedProcessEventAlertCategory = useCallback( - (event) => { + (event: any) => { const [_, selectedAlertEvent] = event.target.textContent.split(' '); setSelectedProcessEventAlertCategory(selectedAlertEvent); onAlertEventCategorySelected(selectedAlertEvent); diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx index 3bd72837e01e..a6201ea2ed50 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx @@ -128,7 +128,7 @@ export function ProcessTreeNode({ const nodeRef = useVisible({ viewPortEl: scrollerRef.current, visibleCallback: useCallback( - (isVisible, isAbove) => { + (isVisible: any, isAbove: any) => { onChangeJumpToEventVisibility(isVisible, isAbove); }, [onChangeJumpToEventVisibility] diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts index 73f85b9da378..a1f039f9caad 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts @@ -335,7 +335,7 @@ export const useXtermPlayer = ({ }, [lines, currentLine, isPlaying, playSpeed, render, hasNextPage, fetchNextPage, setIsPlaying]); const seekToLine = useCallback( - (index) => { + (index: any) => { setCurrentLine(index); render(index, true); diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx index 9ba7958cb53b..71225b4cda93 100644 --- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx @@ -37,7 +37,7 @@ export const TTYSearchBar = ({ const [currentMatch, setCurrentMatch] = useState(null); const jumpToMatch = useCallback( - (match) => { + (match: any) => { if (match) { setIsPlaying(false); const goToLine = lines.indexOf(match.line); @@ -103,7 +103,7 @@ export const TTYSearchBar = ({ }, [searchQuery, lines, jumpToMatch, xTermSearchFn]); const onSearch = useCallback( - (query) => { + (query: any) => { setIsPlaying(false); setSearchQuery(query); setCurrentMatch(null); @@ -112,7 +112,7 @@ export const TTYSearchBar = ({ ); const onSetCurrentMatch = useCallback( - (index) => { + (index: any) => { const match = searchResults[index]; if (match && currentMatch !== match) { diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx index 3b82be30c602..f169395688de 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx @@ -237,6 +237,51 @@ describe('ManageSpacePage', () => { expect(wrapper.find(EnabledFeatures)).toHaveLength(0); }); + it('hides feature visibility controls when solution view is not "classic"', async () => { + const spacesManager = spacesManagerMock.create(); + + const wrapper = mountWithIntl( + + ); + + await waitFor(async () => { + await Promise.resolve(); + + wrapper.update(); + + // default for create space: expect visible features table to exist + expect(wrapper.find(EnabledFeatures)).toHaveLength(1); + }); + + await waitFor(() => { + // switch to observability view + updateSpace(wrapper, false, 'oblt'); + // expect visible features table to not exist + expect(wrapper.find(EnabledFeatures)).toHaveLength(0); + }); + + await waitFor(() => { + // switch to classic + updateSpace(wrapper, false, 'classic'); + // expect visible features table to exist again + expect(wrapper.find(EnabledFeatures)).toHaveLength(1); + }); + }); + it('allows a space to be updated', async () => { const spaceToUpdate = { id: 'existing-space', diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx index b34d2eec88e4..cb81ae930426 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx @@ -66,6 +66,7 @@ interface State { features: KibanaFeature[]; originalSpace?: Partial; showAlteringActiveSpaceDialog: boolean; + showVisibleFeaturesPicker: boolean; haveDisabledFeaturesChanged: boolean; hasSolutionViewChanged: boolean; isLoading: boolean; @@ -85,6 +86,7 @@ export class ManageSpacePage extends Component { this.state = { isLoading: true, showAlteringActiveSpaceDialog: false, + showVisibleFeaturesPicker: !!props.allowFeatureVisibility, saveInProgress: false, space: { color: getSpaceColor({}), @@ -203,7 +205,7 @@ export class ManageSpacePage extends Component { { )} - {this.props.allowFeatureVisibility && ( + {this.state.showVisibleFeaturesPicker && ( <> { return null; }; + private onSolutionViewChange = (space: Partial) => { + if (this.props.allowFeatureVisibility) { + let showVisibleFeaturesPicker = false; + if (space.solution === 'classic' || space.solution == null) { + showVisibleFeaturesPicker = true; + } + this.setState((state) => ({ ...state, showVisibleFeaturesPicker })); + } + this.onSpaceChange(space); + }; + public onSpaceChange = (updatedSpace: FormValues) => { this.setState({ space: updatedSpace, diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx index 2797ceaad71f..be4ebbbc1321 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx @@ -12,7 +12,7 @@ import type { Filter, Query } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFormRow, EuiSpacer, EuiTitle } from '@elastic/eui'; import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public'; -import type { SearchBarProps } from '@kbn/unified-search-plugin/public'; +import type { SearchBarProps, StatefulSearchBarProps } from '@kbn/unified-search-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import { mapAndFlattenFilters, getTime } from '@kbn/data-plugin/public'; import type { SavedQuery, ISearchSource } from '@kbn/data-plugin/public'; @@ -139,9 +139,12 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp setEsFields(convertFieldSpecToFieldOption(newDataView.fields.map((field) => field.toSpec()))); }, []); - const onUpdateFilters = useCallback((newFilters) => { - dispatch({ type: 'filter', payload: mapAndFlattenFilters(newFilters) }); - }, []); + const onUpdateFilters = useCallback>( + (newFilters) => { + dispatch({ type: 'filter', payload: mapAndFlattenFilters(newFilters) }); + }, + [] + ); const onChangeQuery = useCallback( ({ query: newQuery }: { query?: Query }) => { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/dashboard_link.tsx b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/dashboard_link.tsx index e9541c3f6759..9074f2ae2b61 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/dashboard_link.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/dashboard_link.tsx @@ -29,7 +29,7 @@ export const DashboardLink: React.FC = ({ }, } = useKibana(); const onClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); if (dashboardUrl) { navigateToUrl(dashboardUrl); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/webhook_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/webhook_params.tsx index 8e6a7c587e9c..0e2491304bd9 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/webhook_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/webhook_params.tsx @@ -73,7 +73,7 @@ const WebhookParamsFields: React.FunctionComponent { + (key: string, value: string) => { return editAction( 'subActionParams', { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.tsx index 7ae1efbe13f3..b5c029282b9c 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.tsx @@ -97,7 +97,7 @@ const JiraParamsFields: React.FunctionComponent { + (key: string, value: string) => { editSubActionProperty(key, [{ commentId: '1', comment: value }]); }, [editSubActionProperty] diff --git a/x-pack/plugins/stack_connectors/public/connector_types/jira/search_issues.tsx b/x-pack/plugins/stack_connectors/public/connector_types/jira/search_issues.tsx index f12a848de9a5..35af5e6a8a0f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/jira/search_issues.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/jira/search_issues.tsx @@ -69,9 +69,11 @@ const SearchIssuesComponent: React.FC = ({ }, []); const onChangeComboBox = useCallback( - (changedOptions) => { + (changedOptions: Array>) => { setSelectedOptions(changedOptions); - onChange(changedOptions[0].value); + if (changedOptions[0].value) { + onChange(changedOptions[0].value); + } }, [onChange] ); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_app_info.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_app_info.tsx index b0b295c9b726..5a619dd557fc 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_app_info.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_app_info.tsx @@ -30,7 +30,7 @@ export const useGetAppInfo = ({ actionTypeId, http }: UseGetAppInfoProps): UseGe const abortCtrl = useRef(new AbortController()); const fetchAppInfo = useCallback( - async (connector) => { + async (connector: ServiceNowActionConnector) => { try { if (!actionTypeId || isEmpty(actionTypeId)) { return; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/openai/dashboard_link.tsx b/x-pack/plugins/stack_connectors/public/connector_types/openai/dashboard_link.tsx index 85c1a9a1955b..86b5298172a8 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/openai/dashboard_link.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/openai/dashboard_link.tsx @@ -29,7 +29,7 @@ export const DashboardLink: React.FC = ({ }, } = useKibana(); const onClick = useCallback( - (e) => { + (e: React.SyntheticEvent) => { e.preventDefault(); if (dashboardUrl) { navigateToUrl(dashboardUrl); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/index.tsx b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/index.tsx index ff67e51cad80..5e4cb6787e39 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/index.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/index.tsx @@ -19,6 +19,7 @@ import { EuiFormRow, EuiSpacer, EuiSwitch, + EuiSwitchEvent, EuiText, } from '@elastic/eui'; import type { @@ -143,7 +144,7 @@ const CreateAlertComponent: React.FC = ({ const [showJsonEditor, setShowJsonEditor] = useState(false); const toggleShowJsonEditor = useCallback( - (event) => { + (event: EuiSwitchEvent) => { if (!event.target.checked) { // when the user switches back remove the json editor error if there was one // must mark as undefined to remove the field so it is not sent to the server side diff --git a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.tsx index 3ae86b1e7f9a..e4e288623f20 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.tsx @@ -22,6 +22,7 @@ import type { OpsgenieActionParams, OpsgenieCreateAlertSubActionParams, } from '../../../server/connector_types'; +import { EditActionCallback } from './types'; const actionOptions = [ { @@ -55,7 +56,7 @@ const OpsgenieParamFields: React.FC> = ( [editAction, index] ); - const editOptionalSubAction = useCallback( + const editOptionalSubAction: EditActionCallback = useCallback( (key, value) => { if (isEmpty(value)) { const paramsCopy = cloneDeep(subActionParams); @@ -69,7 +70,7 @@ const OpsgenieParamFields: React.FC> = ( [editAction, index, subActionParams] ); - const editSubAction = useCallback( + const editSubAction: EditActionCallback = useCallback( (key, value) => { editAction('subActionParams', { ...subActionParams, [key]: value }, index); }, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx index 7cba015493d3..a1c202c36ef8 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx @@ -109,7 +109,7 @@ const ResilientParamsFields: React.FunctionComponent { + (key: string, value: string) => { editSubActionProperty(key, [{ commentId: '1', comment: value }]); }, [editSubActionProperty] diff --git a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.tsx index 51cbd8f46fc9..67de15909ded 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.tsx @@ -167,7 +167,7 @@ const ServiceNowParamsFields: React.FunctionComponent< ); const editComment = useCallback( - (key, value) => { + (key: string, value: string) => { editSubActionProperty(key, [{ commentId: '1', comment: value }]); }, [editSubActionProperty] diff --git a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.tsx index 19cc8407632f..c6b207c70b3c 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.tsx @@ -77,7 +77,7 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< ); const editComment = useCallback( - (key, value) => { + (key: string, value: string) => { editSubActionProperty(key, [{ commentId: '1', comment: value }]); }, [editSubActionProperty] diff --git a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_params.tsx index a41b6a6b73e0..5264863d6ab4 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_params.tsx @@ -225,7 +225,7 @@ const SlackParamsFields: React.FunctionComponent< }, [editAction, index, tempChannelId, text]); const onChangeTextField = useCallback( - (evt) => { + (evt: React.ChangeEvent) => { editAction('subActionParams', { channels: undefined, channelIds: [], text }, index); setTempChannelId(evt.target.value); }, @@ -323,7 +323,7 @@ const SlackParamsFields: React.FunctionComponent< {messageType === 'text' ? ( { + editAction={(_: string, value: string) => { setTextValue(value); editAction('subActionParams', { channels, channelIds, text: value }, index); }} diff --git a/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.tsx index 1faa8c8bbabf..1f60422adbca 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.tsx @@ -78,7 +78,7 @@ const SwimlaneParamsFields: React.FunctionComponent { + (key: string, value: string) => { editSubActionProperty(key, [{ commentId: '1', comment: value }]); }, [editSubActionProperty] diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts index 9274e0583547..899586abcc9f 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts @@ -2061,6 +2061,97 @@ describe('TaskManagerRunner', () => { ); expect(onTaskEvent).toHaveBeenCalledTimes(2); }); + + test('emits TaskEvent when failing to update a recurring task', async () => { + const id = _.random(1, 20).toString(); + const runAt = minutesFromNow(_.random(5)); + const onTaskEvent = jest.fn(); + const { runner, instance, store } = await readyToRunStageSetup({ + onTaskEvent, + instance: { + id, + schedule: { interval: '1m' }, + }, + definitions: { + bar: { + title: 'Bar!', + createTaskRunner: () => ({ + async run() { + return { runAt, state: {} }; + }, + }), + }, + }, + }); + + const error = new Error('fail'); + + store.update.mockImplementation(() => { + throw error; + }); + + await expect(runner.run()).rejects.toThrowError('fail'); + + expect(onTaskEvent).toHaveBeenCalledWith( + withAnyTiming( + asTaskRunEvent( + id, + asErr({ + task: instance, + persistence: TaskPersistence.Recurring, + result: TaskRunResult.Failed, + isExpired: false, + error, + }) + ) + ) + ); + }); + + test('emits TaskEvent when failing to update a non-recurring task', async () => { + const id = _.random(1, 20).toString(); + const runAt = minutesFromNow(_.random(5)); + const onTaskEvent = jest.fn(); + const { runner, instance, store } = await readyToRunStageSetup({ + onTaskEvent, + instance: { + id, + }, + definitions: { + bar: { + title: 'Bar!', + createTaskRunner: () => ({ + async run() { + return { runAt, state: {} }; + }, + }), + }, + }, + }); + + const error = new Error('fail'); + + store.update.mockImplementation(() => { + throw error; + }); + + await expect(runner.run()).rejects.toThrowError('fail'); + + expect(onTaskEvent).toHaveBeenCalledWith( + withAnyTiming( + asTaskRunEvent( + id, + asErr({ + task: instance, + persistence: TaskPersistence.NonRecurring, + result: TaskRunResult.Failed, + isExpired: false, + error, + }) + ) + ) + ); + }); }); test('does not update saved object if task expires', async () => { diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.ts index 6eaaf2cd2881..bfcabed9f6e4 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.ts @@ -719,40 +719,54 @@ export class TaskManagerRunner implements TaskRunner { await eitherAsync( result, async ({ runAt, schedule, taskRunError }: SuccessfulRunResult) => { - const processedResult = { - task, - persistence: - schedule || task.schedule ? TaskPersistence.Recurring : TaskPersistence.NonRecurring, - result: await (runAt || schedule || task.schedule - ? this.processResultForRecurringTask(result) - : this.processResultWhenDone()), - }; - - // Alerting task runner returns SuccessfulRunResult with taskRunError - // when the alerting task fails, so we check for this condition in order - // to emit the correct task run event for metrics collection - // taskRunError contains the "source" (TaskErrorSource) data - if (!!taskRunError) { - debugLogger.debug(`Emitting task run failed event for task ${this.taskType}`); + const taskPersistence = + schedule || task.schedule ? TaskPersistence.Recurring : TaskPersistence.NonRecurring; + try { + const processedResult = { + task, + persistence: taskPersistence, + result: await (runAt || schedule || task.schedule + ? this.processResultForRecurringTask(result) + : this.processResultWhenDone()), + }; + + // Alerting task runner returns SuccessfulRunResult with taskRunError + // when the alerting task fails, so we check for this condition in order + // to emit the correct task run event for metrics collection + // taskRunError contains the "source" (TaskErrorSource) data + if (!!taskRunError) { + debugLogger.debug(`Emitting task run failed event for task ${this.taskType}`); + this.onTaskEvent( + asTaskRunEvent( + this.id, + asErr({ ...processedResult, isExpired: taskHasExpired, error: taskRunError }), + taskTiming + ) + ); + } else { + this.onTaskEvent( + asTaskRunEvent( + this.id, + asOk({ ...processedResult, isExpired: taskHasExpired }), + taskTiming + ) + ); + } + } catch (err) { this.onTaskEvent( asTaskRunEvent( this.id, asErr({ - ...processedResult, + task, + persistence: taskPersistence, + result: TaskRunResult.Failed, isExpired: taskHasExpired, - error: taskRunError, + error: err, }), taskTiming ) ); - } else { - this.onTaskEvent( - asTaskRunEvent( - this.id, - asOk({ ...processedResult, isExpired: taskHasExpired }), - taskTiming - ) - ); + throw err; } }, async ({ error }: FailedRunResult) => { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts index dd8c83fd4f24..d9285fac81c8 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts @@ -68,7 +68,7 @@ export const useIndicators = ({ const { inspectorAdapters } = useInspector(); const onChangeItemsPerPage = useCallback( - (pageSize) => + (pageSize: any) => setPagination((currentPagination) => ({ ...currentPagination, pageSize, @@ -78,7 +78,7 @@ export const useIndicators = ({ ); const onChangePage = useCallback( - (pageIndex) => setPagination((currentPagination) => ({ ...currentPagination, pageIndex })), + (pageIndex: any) => setPagination((currentPagination) => ({ ...currentPagination, pageIndex })), [] ); diff --git a/x-pack/plugins/timelines/common/utils/accessibility/helpers.ts b/x-pack/plugins/timelines/common/utils/accessibility/helpers.ts index e877edd28458..f1bedd4fc42e 100644 --- a/x-pack/plugins/timelines/common/utils/accessibility/helpers.ts +++ b/x-pack/plugins/timelines/common/utils/accessibility/helpers.ts @@ -638,13 +638,6 @@ export const onKeyDownFocusHandler = ({ } }; -/** - * An `onFocus` event handler that focuses the first child draggable - * keyboard handler - */ -export const onFocusReFocusDraggable = (event: React.FocusEvent) => - event.target.querySelector(`.${DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME}`)?.focus(); - /** Returns `true` when the element, or one of it's children has focus */ export const elementOrChildrenHasFocus = (element: HTMLElement | null | undefined): boolean => element === document.activeElement || element?.querySelector(':focus-within') != null; @@ -661,18 +654,6 @@ export type FocusableElement = | HTMLTextAreaElement | HTMLVideoElement; -/** - * This function has a side effect. It focuses the first element with a - * matching `className` in the `containerElement`. - */ -export const skipFocusInContainerTo = ({ - containerElement, - className, -}: { - containerElement: HTMLElement | null; - className: string; -}) => containerElement?.querySelector(`.${className}`)?.focus(); - /** * Returns a table cell's focusable children, which may be one of the following * a) a `HTMLButtonElement` that does NOT have the `disabled` attribute diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_range_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_range_form.tsx index 1c0cb4d35030..ec4520ef87fd 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_range_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_range_form.tsx @@ -31,7 +31,7 @@ export const FilterRangeForm: FilterAggConfigRange['aggTypeConfig']['FilterAggFo const includeTo = config?.includeTo ?? false; const updateConfig = useCallback( - (update) => { + (update: any) => { onChange({ config: { ...config, diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx index 46ecd7796161..2e52eb67ac49 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx @@ -51,7 +51,7 @@ export const FilterTermForm: FilterAggConfigTerm['aggTypeConfig']['FilterAggForm }, []); const updateConfig = useCallback( - (update) => { + (update: any) => { onChange({ config: { ...config, diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_latest_function_config.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_latest_function_config.ts index a56191f660f4..72a858231c7b 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_latest_function_config.ts +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_latest_function_config.ts @@ -161,7 +161,7 @@ export function useLatestFunctionConfig( }, [dataView, data.search.aggs, runtimeMappings]); const updateLatestFunctionConfig = useCallback( - (update) => + (update: any) => setLatestFunctionConfig({ ...config, ...update, diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 5720c13617f1..f6ce2c1f5e83 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -7010,6 +7010,14 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "Applications de confiance", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "Aide à atténuer les conflits avec d'autres logiciels, généralement d'autres applications d'antivirus ou de sécurité des points de terminaison.", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux applications de confiance.", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "Réduire les détails", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "Réduire les détails", + "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "Développer les détails", + "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "Développer les détails", + "securitySolutionPackages.flyout.shared.errorDescription": "Une erreur est survenue lors de l'affichage de {message}.", + "securitySolutionPackages.flyout.shared.errorTitle": "Impossible d'afficher {title}.", + "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "Activer/Désactiver le panneau extensible", + "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "panneau extensible", "securitySolutionPackages.markdown.insight.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les informations des guides d'investigation", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les interactions des guides d'investigation", "securitySolutionPackages.navigation.landingLinks": "Vues de sécurité", @@ -11081,8 +11089,8 @@ "xpack.apm.serviceIcons.service": "Service", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "Architecture", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, =0 {Zone de disponibilité} one {Zone de disponibilité} other {Zones de disponibilité}} ", - "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, =0 {Type de déclencheur} one {Type de déclencheur} other {Types de déclencheurs}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, =0 {Nom de fonction} one {Nom de fonction} other {Noms de fonction}} ", + "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, =0 {Type de déclencheur} one {Type de déclencheur} other {Types de déclencheurs}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, =0{Type de machine} one {Type de machine} other {Types de machines}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "ID de projet", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "Fournisseur cloud", @@ -19741,7 +19749,6 @@ "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingAgentPoliciesTitle": "Erreur lors du chargement des stratégies d'agent", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingPackageTitle": "Erreur lors du chargement des informations de pack", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingSelectedAgentPolicyTitle": "Erreur lors du chargement de la stratégie d'agent sélectionnée", - "xpack.fleet.createPackagePolicy.StepSelectPolicy.noPolicySelectedError": "Une stratégie d'agent est requise.", "xpack.fleet.createPackagePolicy.transformInstallWithCurrentUserPermissionCallout": "Ce package a {count, plural, one {une ressource de transformation qui sera créée et démarrée} other {# ressources de transformation qui seront créées et démarrées}} avec les mêmes rôles que l'utilisateur responsable de l'installation du package.", "xpack.fleet.createPackagePolicyBottomBar.addAnotherIntegration": "Ajouter une autre intégration", "xpack.fleet.createPackagePolicyBottomBar.backButton": "Retour", @@ -26955,8 +26962,8 @@ "xpack.maps.source.esSearch.descendingLabel": "décroissant", "xpack.maps.source.esSearch.extentFilterLabel": "Filtre dynamique pour les données de la zone de carte visible", "xpack.maps.source.esSearch.fieldNotFoundMsg": "Impossible de trouver \"{fieldName}\" dans le modèle d'indexation \"{indexPatternName}\".", - "xpack.maps.source.esSearch.geofieldLabel": "Champ géospatial", "xpack.maps.source.esSearch.geoFieldLabel": "Champ géospatial", + "xpack.maps.source.esSearch.geofieldLabel": "Champ géospatial", "xpack.maps.source.esSearch.geoFieldTypeLabel": "Type de champ géospatial", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "Votre vue de données pointe vers plusieurs index. Un seul index est autorisé par vue de données.", "xpack.maps.source.esSearch.indexZeroLengthEditError": "Votre vue de données ne pointe vers aucun index.", @@ -33068,13 +33075,11 @@ "xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription": "Modèle d'index utilisé par l'assistant d'IA lorsqu'il recherche des logs. Les logs sont classés par catégories et utilisés pour l'analyse des causes premières", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnector": "Connecteurs Search", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnectorIndexPatternDescription": "Modèle d'index utilisé par l’assistant d’IA lors de l'interrogation des index des connecteurs de recherche (une partie de la base de connaissances). L'index de chaque connecteur de recherche sera interrogé par défaut", - "xpack.observabilityAiAssistantManagement.settingsPage.selectYourLanguageLabel": "Sélectionnez la langue que vous souhaitez que l'assistant utilise pour générer des réponses.", "xpack.observabilityAiAssistantManagement.settingsPage.settingsLabel": "Paramètres", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantButtonLabel": "Afficher le bouton de l'Assistant d'IA et les informations contextuelles dans les applications d'Observability", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantDescriptionLabel": "Affichez/masquez le bouton de l'Assistant d'IA et les informations contextuelles dans les applications d'Observability en cochant ou en décochant la fonctionnalité Assistant d'IA dans Espaces > > Fonctionnalités.", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[version d'évaluation technique] Utilisez l'appel de fonction simulé. L’appel de fonction simulé ne nécessite pas la prise en charge de l'API pour les fonctions ou les outils, mais il peut réduire les performances. L'appel de fonction simulé est actuellement toujours activé pour les connecteurs non-OpenAI, indépendamment de ce paramètre.", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "Simuler un appel de fonction", - "xpack.observabilityAiAssistantManagement.settingsPage.userPreferencesLabel": "Langue utilisée pour les réponses", "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "Modèle d'indexation des logs", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "Modèle d'indexation de connecteur de recherche", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "Développer la ligne", @@ -35423,7 +35428,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.status": "Statut", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "Nom de règle", "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "Données de risque de {riskEntity}", - "xpack.securitySolution.alertDetails.overview.insights.suppressedAlertsCountTechnicalPreview": "Version d'évaluation technique", "xpack.securitySolution.alertDetails.summary.readLess": "Lire moins", "xpack.securitySolution.alertDetails.summary.readMore": "En savoir plus", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "Impossible de mettre à jour les alertes", @@ -36419,8 +36423,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibana ne permet qu'un maximum de {maxNumber} {maxNumber, plural, =1 {alerte} other {alertes}} par exécution de règle.", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "Nom obligatoire.", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "Ajouter un guide d'investigation sur les règles...", - "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "Ajouter le guide de configuration de règle...", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "Fournissez des instructions sur les conditions préalables à la règle, telles que les intégrations requises, les étapes de configuration et tout ce qui est nécessaire au bon fonctionnement de la règle.", + "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "Ajouter le guide de configuration de règle...", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "Guide de configuration", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "Une balise ne doit pas être vide", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "Le remplacement du préfixe d'indicateur ne peut pas être vide.", @@ -38786,15 +38790,11 @@ "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "Toutes les correspondances d'indicateur", "xpack.securitySolution.event.summary.threat_indicator.modal.close": "Fermer", "xpack.securitySolution.event.summary.threat_indicator.showMatches": "Afficher les {count} alertes de correspondance d'indicateur", - "xpack.securitySolution.eventDetails.alertReason": "Raison d'alerte", - "xpack.securitySolution.eventDetails.description": "Description", "xpack.securitySolution.eventDetails.responseActions.endpoint.executed": "a exécuté la commande {command}", "xpack.securitySolution.eventDetails.responseActions.endpoint.failed": "n'a pas pu exécuter la commande {command}", "xpack.securitySolution.eventDetails.responseActions.endpoint.pending": "exécute la commande {command}", "xpack.securitySolution.eventDetails.responseActions.endpoint.tried": "a tenté d'exécuter la commande {command}", "xpack.securitySolution.eventDetails.summaryView": "résumé", - "xpack.securitySolution.eventDetails.table": "Tableau", - "xpack.securitySolution.eventDetails.table.actions": "Actions", "xpack.securitySolution.eventFilter.flyoutForm.confirmModal.name": "filtre d'événements", "xpack.securitySolution.eventFilter.flyoutForm.creationSuccessToastTitle": "\"{name}\" a été ajouté à la liste de filtres d'événements.", "xpack.securitySolution.eventFilter.form.description.placeholder": "Description", @@ -39232,10 +39232,6 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "Voir un aperçu de l'alerte avec l'id {id}", "xpack.securitySolution.flyout.right.eventCategoryText": "Catégorie d'événement", "xpack.securitySolution.flyout.right.header.assignedTitle": "Utilisateurs affectés", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "Réduire les détails", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "Réduire les détails", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "Développer les détails", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "Développer les détails", "xpack.securitySolution.flyout.right.header.headerTitle": "Détails des documents", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "Aperçu", @@ -39322,10 +39318,6 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "à", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellDescription": "Cette fonctionnalité requiert un {subscription}", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellLinkText": "Abonnement Enterprise", - "securitySolutionPackages.flyout.shared.errorDescription": "Une erreur est survenue lors de l'affichage de {message}.", - "securitySolutionPackages.flyout.shared.errorTitle": "Impossible d'afficher {title}.", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "Activer/Désactiver le panneau extensible", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "panneau extensible", "xpack.securitySolution.flyout.tour.entities.description": "Consultez la vue {entities} étendue pour en savoir plus sur les hôtes et les utilisateurs liés à l'alerte.", "xpack.securitySolution.flyout.tour.entities.text": "Entités", "xpack.securitySolution.flyout.tour.entities.title": "De nouvelles informations sur les hôtes et les utilisateurs sont disponibles", @@ -42033,8 +42025,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "Sélectionner un SLO", "xpack.slo.sloEmbeddable.displayName": "Aperçu du SLO", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "Le SLO a été supprimé. Vous pouvez supprimer sans risque le widget du tableau de bord.", - "xpack.slo.sloGridItem.targetFlexItemLabel": "Cible {target}", "xpack.slo.sLOGridItem.targetFlexItemLabel": "Cible {target}", + "xpack.slo.sloGridItem.targetFlexItemLabel": "Cible {target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "Personnaliser le filtre", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "Facultatif", "xpack.slo.sloGroupConfiguration.customFilterText": "Personnaliser le filtre", @@ -43480,8 +43472,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webhook - Données de gestion des cas", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "Éditeur de code", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "Corps", - "xpack.stackConnectors.components.d3security.connectorTypeTitle": "Données D3", "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", + "xpack.stackConnectors.components.d3security.connectorTypeTitle": "Données D3", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "Type d'événement", "xpack.stackConnectors.components.d3security.invalidActionText": "Nom d'action non valide.", "xpack.stackConnectors.components.d3security.requiredActionText": "L'action est requise.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1b7ca43b7099..eb05abc8b41d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -7006,6 +7006,14 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "信頼できるアプリケーション", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "他のソフトウェア(通常は他のウイルス対策またはエンドポイントセキュリティアプリケーション)との競合を軽減することができます。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "信頼できるアプリケーションのアクセスには、すべてのスペースが必要です。", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "詳細を折りたたむ", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "詳細を折りたたむ", + "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "詳細を展開", + "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "詳細を展開", + "securitySolutionPackages.flyout.shared.errorDescription": "{message}の表示中にエラーが発生しました。", + "securitySolutionPackages.flyout.shared.errorTitle": "{title}を表示できません。", + "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "展開可能なパネルトグル", + "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "展開可能なパネル", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "{requiredLicense}にアップグレードして、調査ガイドのインタラクションを利用", "securitySolutionPackages.navigation.landingLinks": "セキュリティビュー", "securitySolutionPackages.sideNav.betaBadge.label": "ベータ", @@ -11071,8 +11079,8 @@ "xpack.apm.serviceIcons.service": "サービス", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "アーキテクチャー", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, other {可用性ゾーン}} ", - "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {トリガータイプ}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {関数名}} ", + "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {トリガータイプ}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, other {コンピュータータイプ} }\n ", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "プロジェクト ID", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "クラウドプロバイダー", @@ -19731,7 +19739,6 @@ "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingAgentPoliciesTitle": "エージェントポリシーの読み込みエラー", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingPackageTitle": "パッケージ情報の読み込みエラー", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingSelectedAgentPolicyTitle": "選択したエージェントポリシーの読み込みエラー", - "xpack.fleet.createPackagePolicy.StepSelectPolicy.noPolicySelectedError": "エージェントポリシーは必須です。", "xpack.fleet.createPackagePolicy.transformInstallWithCurrentUserPermissionCallout": "このパッケージには、パッケージをインストールするユーザーと同じロールで作成、開始される{count, plural, one {1個のトランスフォームアセット} other {# トランスフォームアセット}}があります。", "xpack.fleet.createPackagePolicyBottomBar.addAnotherIntegration": "別の統合を追加", "xpack.fleet.createPackagePolicyBottomBar.backButton": "戻る", @@ -26944,8 +26951,8 @@ "xpack.maps.source.esSearch.descendingLabel": "降順", "xpack.maps.source.esSearch.extentFilterLabel": "マップの表示範囲でデータを動的にフィルタリング", "xpack.maps.source.esSearch.fieldNotFoundMsg": "インデックスパターン''{indexPatternName}''に''{fieldName}''が見つかりません。", - "xpack.maps.source.esSearch.geofieldLabel": "地理空間フィールド", "xpack.maps.source.esSearch.geoFieldLabel": "地理空間フィールド", + "xpack.maps.source.esSearch.geofieldLabel": "地理空間フィールド", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空間フィールドタイプ", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "データビューは複数のインデックスを参照しています。データビューごとに1つのインデックスのみが許可されています。", "xpack.maps.source.esSearch.indexZeroLengthEditError": "データビューはどのインデックスも参照していません。", @@ -33055,13 +33062,11 @@ "xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription": "ログのクエリを実行するときにAI Assistantによって使用されるインデックスパターン。ログは分類され、根本原因分析で使用されます。", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnector": "検索コネクター", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnectorIndexPatternDescription": "検索コネクターインデックス(ナレッジベースの一部)をクエリするときに、AI Assistantによって使用されるインデックスパターン。デフォルトでは、すべての検索コネクターのインデックスに対してクエリが実行されます。", - "xpack.observabilityAiAssistantManagement.settingsPage.selectYourLanguageLabel": "応答を生成するときにアシスタントで使用する言語を選択してください。", "xpack.observabilityAiAssistantManagement.settingsPage.settingsLabel": "設定", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantButtonLabel": "オブザーバビリティアプリにAI Assistantボタンと状況に応じたインサイトを表示", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantDescriptionLabel": "オブザーバビリティアプリでAI Assistantボタンと状況に応じたインサイトのオン/オフを切り替えるには、[スペース]>[]>[機能]でAI Assistant機能のチェックをオンまたはオフにします。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[technical preview] シミュレートされた関数呼び出しを使用します。シミュレートされた関数呼び出しでは、関数またはツールのAPIサポートは必要ありませんが、パフォーマンスが低下する可能性があります。現在、シミュレートされた関数呼び出しは、この設定に関係なく、非OpenAIコネクターで常に有効です。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "関数呼び出しをシミュレート", - "xpack.observabilityAiAssistantManagement.settingsPage.userPreferencesLabel": "応答言語", "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "ログインデックスパターン", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "検索コネクターインデックスパターン", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "行を展開", @@ -35408,7 +35413,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.status": "ステータス", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "ルール名", "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "{riskEntity}リスクデータ", - "xpack.securitySolution.alertDetails.overview.insights.suppressedAlertsCountTechnicalPreview": "テクニカルプレビュー", "xpack.securitySolution.alertDetails.summary.readLess": "表示を減らす", "xpack.securitySolution.alertDetails.summary.readMore": "続きを読む", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "アラートを更新できません", @@ -36403,8 +36407,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibanaで許可される最大数は、1回の実行につき、{maxNumber} {maxNumber, plural, other {アラート}}です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名前が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "ルール調査ガイドを追加...", - "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "ルールセットアップガイドを追加...", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "必要な統合、構成ステップ、ルールが正常に動作するために必要な他のすべての項目といった、ルール前提条件に関する指示を入力します。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "ルールセットアップガイドを追加...", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "セットアップガイド", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "タグを空にすることはできません", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "インジケータープレフィックスの無効化を空にすることはできません", @@ -38768,15 +38772,11 @@ "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "すべてのインジケーター一致", "xpack.securitySolution.event.summary.threat_indicator.modal.close": "閉じる", "xpack.securitySolution.event.summary.threat_indicator.showMatches": "すべての{count}件のインジケーター一致アラートを表示", - "xpack.securitySolution.eventDetails.alertReason": "アラートの理由", - "xpack.securitySolution.eventDetails.description": "説明", "xpack.securitySolution.eventDetails.responseActions.endpoint.executed": "{command}コマンドを実行しました", "xpack.securitySolution.eventDetails.responseActions.endpoint.failed": "{command}コマンドを実行できませんでした", "xpack.securitySolution.eventDetails.responseActions.endpoint.pending": "{command}コマンドを実行しています", "xpack.securitySolution.eventDetails.responseActions.endpoint.tried": "{command}コマンドを実行しようとしました", "xpack.securitySolution.eventDetails.summaryView": "まとめ", - "xpack.securitySolution.eventDetails.table": "表", - "xpack.securitySolution.eventDetails.table.actions": "アクション", "xpack.securitySolution.eventFilter.flyoutForm.confirmModal.name": "イベントフィルター", "xpack.securitySolution.eventFilter.flyoutForm.creationSuccessToastTitle": "\"{name}\"がイベントフィルターリストに追加されました。", "xpack.securitySolution.eventFilter.form.description.placeholder": "説明", @@ -39215,10 +39215,6 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "ID {id}のアラートをプレビュー", "xpack.securitySolution.flyout.right.eventCategoryText": "イベントカテゴリ", "xpack.securitySolution.flyout.right.header.assignedTitle": "担当者", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "詳細を折りたたむ", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "詳細を折りたたむ", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "詳細を展開", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "詳細を展開", "xpack.securitySolution.flyout.right.header.headerTitle": "ドキュメント詳細", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "概要", @@ -39305,10 +39301,6 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "に", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellDescription": "この機能には{subscription}が必要です", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellLinkText": "エンタープライズサブスクリプション", - "securitySolutionPackages.flyout.shared.errorDescription": "{message}の表示中にエラーが発生しました。", - "securitySolutionPackages.flyout.shared.errorTitle": "{title}を表示できません。", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "展開可能なパネルトグル", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "展開可能なパネル", "xpack.securitySolution.flyout.tour.entities.description": "アラートに関連付けられたホストとユーザーの詳細については、展開された{entities}ビューを確認してください。", "xpack.securitySolution.flyout.tour.entities.text": "エンティティ", "xpack.securitySolution.flyout.tour.entities.title": "新しいホストとユーザーのインサイトがあります", @@ -42017,8 +42009,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "SLOを選択", "xpack.slo.sloEmbeddable.displayName": "SLO概要", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "SLOが削除されました。ウィジェットをダッシュボードから安全に削除できます。", - "xpack.slo.sloGridItem.targetFlexItemLabel": "目標{target}", "xpack.slo.sLOGridItem.targetFlexItemLabel": "目標{target}", + "xpack.slo.sloGridItem.targetFlexItemLabel": "目標{target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "カスタムフィルター", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "オプション", "xpack.slo.sloGroupConfiguration.customFilterText": "カスタムフィルター", @@ -43460,8 +43452,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webフック - ケース管理データ", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "コードエディター", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "本文", - "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3データ", "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3セキュリティ", + "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3データ", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "イベントタイプ", "xpack.stackConnectors.components.d3security.invalidActionText": "無効なアクション名です。", "xpack.stackConnectors.components.d3security.requiredActionText": "アクションが必要です。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b12d587e357b..1aa124ec8af1 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -7017,6 +7017,14 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "受信任的应用程序", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "帮助减少与其他软件(通常指其他防病毒或终端安全应用程序)的冲突。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "访问受信任的应用程序需要所有工作区。", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "折叠详情", + "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "折叠详情", + "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "展开详情", + "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "展开详情", + "securitySolutionPackages.flyout.shared.errorDescription": "显示 {message} 时出现错误。", + "securitySolutionPackages.flyout.shared.errorTitle": "无法显示 {title}。", + "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "可展开面板切换按钮", + "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "可展开面板", "securitySolutionPackages.markdown.insight.upsell": "升级到{requiredLicense}以利用调查指南中的洞见", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "升级到 {requiredLicense} 以利用调查指南交互", "securitySolutionPackages.navigation.landingLinks": "安全视图", @@ -11090,8 +11098,8 @@ "xpack.apm.serviceIcons.service": "服务", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "架构", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, other {可用性区域}} ", - "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {触发类型}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {功能名称}} ", + "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {触发类型}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, other {机器类型}} ", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "项目 ID", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "云服务提供商", @@ -19757,7 +19765,6 @@ "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingAgentPoliciesTitle": "加载代理策略时出错", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingPackageTitle": "加载软件包信息时出错", "xpack.fleet.createPackagePolicy.StepSelectPolicy.errorLoadingSelectedAgentPolicyTitle": "加载选定代理策略时出错", - "xpack.fleet.createPackagePolicy.StepSelectPolicy.noPolicySelectedError": "代理策略必填。", "xpack.fleet.createPackagePolicy.transformInstallWithCurrentUserPermissionCallout": "此软件包具有 {count, plural, one {一个转换资产} other {# 个转换资产}},它们将使用与安装软件包的用户相同的角色创建并启动。", "xpack.fleet.createPackagePolicyBottomBar.addAnotherIntegration": "添加其他集成", "xpack.fleet.createPackagePolicyBottomBar.backButton": "返回", @@ -26976,8 +26983,8 @@ "xpack.maps.source.esSearch.descendingLabel": "降序", "xpack.maps.source.esSearch.extentFilterLabel": "在可见地图区域中动态筛留数据", "xpack.maps.source.esSearch.fieldNotFoundMsg": "在索引模式“{indexPatternName}”中找不到“{fieldName}”。", - "xpack.maps.source.esSearch.geofieldLabel": "地理空间字段", "xpack.maps.source.esSearch.geoFieldLabel": "地理空间字段", + "xpack.maps.source.esSearch.geofieldLabel": "地理空间字段", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空间字段类型", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "您的数据视图指向多个索引。每个数据视图只允许一个索引。", "xpack.maps.source.esSearch.indexZeroLengthEditError": "您的数据视图未指向任何索引。", @@ -33095,13 +33102,11 @@ "xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription": "AI 助手查询日志时使用的索引模式。日志将进行归类并用于根本原因分析", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnector": "搜索连接器", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnectorIndexPatternDescription": "查询搜索连接器索引(知识库的一部分)时 AI 助手使用的索引模式。默认情况下,将查询每个搜索连接器的索引", - "xpack.observabilityAiAssistantManagement.settingsPage.selectYourLanguageLabel": "选择您希望助手在生成响应时使用的语言。", "xpack.observabilityAiAssistantManagement.settingsPage.settingsLabel": "设置", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantButtonLabel": "在 Observability 应用中显示 AI 助手按钮和上下文洞察", "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantDescriptionLabel": "通过在“工作区 > > 功能”中选中或取消选中 AI 助手功能,在 Observability 应用中打开或关闭 AI 助手按钮和上下文洞察。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[技术预览] 使用模拟函数调用。模拟函数调用不需要函数或工具的 API 支持,但可能会降低性能。无论此设置如何,当前会始终对非 OpenAI 连接器启用模拟函数调用。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "模拟函数调用", - "xpack.observabilityAiAssistantManagement.settingsPage.userPreferencesLabel": "响应语言", "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "日志索引模式", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "搜索连接器索引模式", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "展开行", @@ -35449,7 +35454,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.status": "状态", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "规则名称", "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "{riskEntity}风险数据", - "xpack.securitySolution.alertDetails.overview.insights.suppressedAlertsCountTechnicalPreview": "技术预览", "xpack.securitySolution.alertDetails.summary.readLess": "阅读更少内容", "xpack.securitySolution.alertDetails.summary.readMore": "阅读更多内容", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "无法更新告警", @@ -36445,8 +36449,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "每次规则运行时,Kibana 最多只允许 {maxNumber} 个{maxNumber, plural, other {告警}}。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名称必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "添加规则调查指南......", - "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "添加规则设置指南......", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "提供有关规则先决条件的说明,如所需集成、配置步骤,以及规则正常运行所需的任何其他内容。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "添加规则设置指南......", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "设置指南", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "标签不得为空", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "指标前缀覆盖不得为空", @@ -38812,15 +38816,11 @@ "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "所有指标匹配", "xpack.securitySolution.event.summary.threat_indicator.modal.close": "关闭", "xpack.securitySolution.event.summary.threat_indicator.showMatches": "显示所有 {count} 个指标匹配告警", - "xpack.securitySolution.eventDetails.alertReason": "告警原因", - "xpack.securitySolution.eventDetails.description": "描述", "xpack.securitySolution.eventDetails.responseActions.endpoint.executed": "已执行 {command} 命令", "xpack.securitySolution.eventDetails.responseActions.endpoint.failed": "无法执行 {command} 命令", "xpack.securitySolution.eventDetails.responseActions.endpoint.pending": "正在执行 {command} 命令", "xpack.securitySolution.eventDetails.responseActions.endpoint.tried": "已尝试执行 {command} 命令", "xpack.securitySolution.eventDetails.summaryView": "摘要", - "xpack.securitySolution.eventDetails.table": "表", - "xpack.securitySolution.eventDetails.table.actions": "操作", "xpack.securitySolution.eventFilter.flyoutForm.confirmModal.name": "事件筛选", "xpack.securitySolution.eventFilter.flyoutForm.creationSuccessToastTitle": "“{name}”已添加到事件筛选列表。", "xpack.securitySolution.eventFilter.form.description.placeholder": "描述", @@ -39259,10 +39259,6 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "预览 ID 为 {id} 的告警", "xpack.securitySolution.flyout.right.eventCategoryText": "事件类别", "xpack.securitySolution.flyout.right.header.assignedTitle": "被分配人", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "折叠详情", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "折叠详情", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "展开详情", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "展开详情", "xpack.securitySolution.flyout.right.header.headerTitle": "文档详情", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "概览", @@ -39348,10 +39344,6 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "处于", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellDescription": "此功能需要{subscription}", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.upsellLinkText": "企业级订阅", - "securitySolutionPackages.flyout.shared.errorDescription": "显示 {message} 时出现错误。", - "securitySolutionPackages.flyout.shared.errorTitle": "无法显示 {title}。", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "可展开面板切换按钮", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "可展开面板", "xpack.securitySolution.flyout.tour.entities.description": "请查阅展开的 {entities} 视图以了解与该告警有关的主机和用户的更多信息。", "xpack.securitySolution.flyout.tour.entities.text": "实体", "xpack.securitySolution.flyout.tour.entities.title": "有新主机和用户洞见可用", @@ -42061,8 +42053,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "选择 SLO", "xpack.slo.sloEmbeddable.displayName": "SLO 概览", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "SLO 已删除。您可以放心从仪表板中删除小组件。", - "xpack.slo.sloGridItem.targetFlexItemLabel": "目标 {target}", "xpack.slo.sLOGridItem.targetFlexItemLabel": "目标 {target}", + "xpack.slo.sloGridItem.targetFlexItemLabel": "目标 {target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "定制筛选", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "可选", "xpack.slo.sloGroupConfiguration.customFilterText": "定制筛选", @@ -43508,8 +43500,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webhook - 案例管理数据", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "代码编辑器", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "正文", - "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3 数据", "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", + "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3 数据", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "事件类型", "xpack.stackConnectors.components.d3security.invalidActionText": "操作名称无效。", "xpack.stackConnectors.components.d3security.requiredActionText": "“操作”必填。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_autocomplete/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_autocomplete/index.tsx index 53f0d7d500ee..da3b08fda8e1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_autocomplete/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_autocomplete/index.tsx @@ -172,7 +172,7 @@ export const TextAreaWithAutocomplete: React.FunctionComponent { + (event: React.KeyboardEvent) => { if (selectableRef.current && isListOpen) { if (!selectableHasFocus && (event.code === 'ArrowUp' || event.code === 'ArrowDown')) { event.preventDefault(); @@ -219,7 +219,7 @@ export const TextAreaWithAutocomplete: React.FunctionComponent { + (event: any) => { const box = document .querySelector('.euiSelectableMsgAutoComplete') ?.getBoundingClientRect() || { @@ -292,7 +292,7 @@ export const TextAreaWithAutocomplete: React.FunctionComponent closeList(), [closeList]); const onScroll = useCallback( - (evt) => { + (evt: any) => { // FUTURE ENGINEER -> we need to make sure to not close the autocomplete option list if (selectableRef?.current?.listId !== evt.target?.firstElementChild?.id) { closeList(true); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx index bbaf73710191..683bf2943266 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import { EuiSwitch, EuiSpacer } from '@elastic/eui'; import { AlertsFilter } from '@kbn/alerting-plugin/common'; import deepEqual from 'fast-deep-equal'; -import { AlertsSearchBar } from '../alerts_search_bar'; +import { AlertsSearchBar, AlertsSearchBarProps } from '../alerts_search_bar'; interface ActionAlertsFilterQueryProps { state?: AlertsFilter['query']; @@ -52,7 +52,7 @@ export const ActionAlertsFilterQuery: React.FC = ( [query, setQuery] ); - const onQueryChange = useCallback( + const onQueryChange: AlertsSearchBarProps['onQueryChange'] = useCallback( ({ query: newQuery }) => updateQuery({ kql: newQuery }), [updateQuery] ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index 7d34fb42409d..1a55e2990fbf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -376,7 +376,7 @@ export const ActionTypeForm = ({ throttleUnit={actionThrottleUnit} hasAlertsMappings={hasAlertsMappings} onNotifyWhenChange={useCallback( - (notifyWhen) => { + (notifyWhen: RuleNotifyWhenType) => { setActionFrequencyProperty('notifyWhen', notifyWhen, index); }, [setActionFrequencyProperty, index] diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_event_log_list_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_event_log_list_table.tsx index 9cd6305b81e7..ce977ea349cb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_event_log_list_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_event_log_list_table.tsx @@ -262,7 +262,7 @@ export const ConnectorEventLogListTable = { + (e: React.ChangeEvent) => { if (e.target.value === '') { setSearchText(''); } @@ -272,7 +272,7 @@ export const ConnectorEventLogListTable = { + (e: React.KeyboardEvent) => { if (e.key === 'Enter') { setSearchText(search); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts index bc0c14772b57..61fda55c4eb3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts @@ -32,7 +32,7 @@ export function usePagination({ onPageChange, pageIndex, pageSize }: PaginationP }); const [flyoutAlertIndex, setFlyoutAlertIndex] = useState(-1); const onChangePageSize = useCallback( - (_pageSize) => { + (_pageSize: number) => { setPagination((state) => ({ ...state, pageSize: _pageSize, @@ -44,7 +44,7 @@ export function usePagination({ onPageChange, pageIndex, pageSize }: PaginationP [updateBulkActionsState, onPageChange] ); const onChangePageIndex = useCallback( - (_pageIndex) => { + (_pageIndex: number) => { setPagination((state) => ({ ...state, pageIndex: _pageIndex })); updateBulkActionsState({ action: BulkActionsVerbs.clear }); onPageChange({ pageIndex: _pageIndex, pageSize: pagination.pageSize }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx index 4999496f669c..c8afbb76f591 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx @@ -65,7 +65,7 @@ export const ExecutionDurationChart: React.FunctionComponent = ({ numberOfExecutions ); - const onChange = useCallback( + const onChange: React.ChangeEventHandler = useCallback( ({ target }) => onChangeDuration(Number(target.value)), [onChangeDuration] ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_table/field_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_table/field_table.tsx index c5bf66477630..7647e8c62576 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_table/field_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_table/field_table.tsx @@ -5,18 +5,24 @@ * 2.0. */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { EuiInMemoryTable, Pagination, Direction, useEuiTheme } from '@elastic/eui'; +import { + EuiInMemoryTable, + Pagination, + Direction, + useEuiTheme, + CriteriaWithPagination, +} from '@elastic/eui'; import { BrowserFields } from '@kbn/rule-registry-plugin/common'; import { getFieldColumns, getFieldItemsData } from '../field_items'; import { CATEGORY_TABLE_CLASS_NAME, TABLE_HEIGHT } from '../../helpers'; -import type { FieldBrowserProps, GetFieldTableColumns } from '../../types'; +import type { BrowserFieldItem, FieldBrowserProps, GetFieldTableColumns } from '../../types'; import { FieldTableHeader } from './field_table_header'; import { styles } from './field_table.styles'; -const DEFAULT_SORTING: { field: string; direction: Direction } = { - field: '', +const DEFAULT_SORTING: { field: keyof BrowserFieldItem; direction: Direction } = { + field: 'name', direction: 'asc', -} as const; +}; export interface FieldTableProps extends Pick { /** @@ -104,16 +110,19 @@ const FieldTableComponent: React.FC = ({ [sortDirection, sortField] ); - const onTableChange = useCallback(({ page, sort = DEFAULT_SORTING }) => { - const { index, size } = page; - const { field, direction } = sort; + const onTableChange = useCallback( + ({ page, sort = DEFAULT_SORTING }: CriteriaWithPagination) => { + const { index, size } = page; + const { field, direction } = sort; - setPageIndex(index); - setPageSize(size); + setPageIndex(index); + setPageSize(size); - setSortField(field); - setSortDirection(direction); - }, []); + setSortField(field); + setSortDirection(direction); + }, + [] + ); /** * Process columns diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx index 2d33a205e6e3..34993d085425 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx @@ -171,7 +171,7 @@ export const RuleErrorLog = (props: RuleErrorLogProps) => { ); const onSearchChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { if (e.target.value === '') { setSearchText(''); } @@ -181,7 +181,7 @@ export const RuleErrorLog = (props: RuleErrorLogProps) => { ); const onKeyUp = useCallback( - (e) => { + (e: React.KeyboardEvent) => { if (e.key === 'Enter') { setSearchText(search); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list_table.tsx index 0aacada7e810..bcaba9f511c6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list_table.tsx @@ -46,7 +46,10 @@ import { RulesListDocLink } from '../../rules_list/components/rules_list_doc_lin import { LoadExecutionLogAggregationsProps } from '../../../lib/rule_api'; import { RuleEventLogListKPIWithApi as RuleEventLogListKPI } from './rule_event_log_list_kpi'; import { useMultipleSpaces } from '../../../hooks/use_multiple_spaces'; -import { useLoadRuleEventLogs } from '../../../hooks/use_load_rule_event_logs'; +import { + useLoadRuleEventLogs, + UseLoadRuleEventLogsProps, +} from '../../../hooks/use_load_rule_event_logs'; import { RulesSettingsLink } from '../../../components/rules_setting/rules_settings_link'; import { RefreshToken } from './types'; @@ -196,7 +199,7 @@ export const RuleEventLogListTable = ( // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const onError = useCallback( + const onError = useCallback>( (e) => { if (e.body.statusCode === 413) { return; @@ -309,7 +312,7 @@ export const RuleEventLogListTable = ( }, []); const onSearchChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { if (e.target.value === '') { setSearchText(''); } @@ -319,7 +322,7 @@ export const RuleEventLogListTable = ( ); const onKeyUp = useCallback( - (e) => { + (e: React.KeyboardEvent) => { if (e.key === 'Enter') { setSearchText(search); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx index 2419993f1267..0e07b73b56c4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx @@ -20,6 +20,7 @@ import { EuiTitle, EuiHorizontalRule, } from '@elastic/eui'; +import { SnoozeSchedule } from '../../../../types'; import { RuleStatusDropdown } from '../..'; import { ComponentOpts as RuleApis, @@ -60,11 +61,11 @@ export const RuleStatusPanel: React.FC = ({ const isInitialized = useRef(false); const onSnoozeRule = useCallback( - (snoozeSchedule) => snoozeRule(rule, snoozeSchedule), + (snoozeSchedule: SnoozeSchedule) => snoozeRule(rule, snoozeSchedule), [rule, snoozeRule] ); const onUnsnoozeRule = useCallback( - (scheduleIds) => unsnoozeRule(rule, scheduleIds), + (scheduleIds?: string[]) => unsnoozeRule(rule, scheduleIds), [rule, unsnoozeRule] ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx index e3d564afaeda..8657248a29df 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx @@ -78,7 +78,7 @@ const RuleAdd = < }: RuleAddProps) => { const onSaveHandler = onSave ?? reloadRules; const [metadata, setMetadata] = useState(initialMetadata); - const onChangeMetaData = useCallback((newMetadata) => setMetadata(newMetadata), []); + const onChangeMetaData = useCallback((newMetadata: any) => setMetadata(newMetadata), []); const initialRule: InitialRule = useMemo(() => { return { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx index 9c0abae3eb2a..72eab243ad0c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx @@ -137,7 +137,7 @@ export const RuleEdit = < const [config, setConfig] = useState({ isUsingSecurity: false }); const [metadata, setMetadata] = useState(initialMetadata); - const onChangeMetaData = useCallback((newMetadata) => setMetadata(newMetadata), []); + const onChangeMetaData = useCallback((newMetadata: any) => setMetadata(newMetadata), []); const { http, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/helpers/number_field.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/helpers/number_field.tsx index 2483f6fc4a43..3f4be5cde90c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/helpers/number_field.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/helpers/number_field.tsx @@ -18,9 +18,12 @@ export const NumberField: React.FC< const max = typeof props.max !== 'undefined' ? props.max : Infinity; const onChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const { value } = e.target; - const isValid = !isNaN(Number(value)) && value >= min && value <= max; + const valueAsNumber = Number(value); + + const isValid = !isNaN(valueAsNumber) && valueAsNumber >= min && valueAsNumber <= max; + if (isValid || value === '') { setDisplayValue(value); } @@ -32,7 +35,7 @@ export const NumberField: React.FC< ); const onBlur = useCallback( - (e) => { + (e: React.FocusEvent) => { if (isNaN(Number(displayValue)) || displayValue === '') { setDisplayValue(props.value); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx index 40d705e87816..3d6523a144e9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx @@ -77,11 +77,18 @@ export const BaseSnoozePanel: React.FunctionComponent = ({ const { euiTheme } = useEuiTheme(); - const onChangeValue = useCallback( - ({ target }) => setIntervalValue(target.value), + const onChangeValue: React.ChangeEventHandler = useCallback( + ({ target }) => { + const value = Number(target.value); + + if (!isNaN(value)) { + setIntervalValue(value); + } + }, [setIntervalValue] ); - const onChangeUnit = useCallback( + + const onChangeUnit: React.ChangeEventHandler = useCallback( ({ target }) => setIntervalUnit(target.value), [setIntervalUnit] ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx index 97c8065c18f2..4e17bca05e4e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx @@ -196,7 +196,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent = ({ }, [setSelectingEndDate]); const selectStartDT = useCallback( - (date, clearEndDT) => { + (date: Moment, clearEndDT: boolean) => { setStartDT(moment.max(date, minDate)); if (clearEndDT) { setEndDT(null); @@ -207,7 +207,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent = ({ [setStartDT, setSelectingEndDate, minDate] ); const selectEndDT = useCallback( - (date) => { + (date: Moment) => { setEndDT(date.add(1, 'minutes')); setSelectingEndTime(true); setSelectingEndDate(false); @@ -216,7 +216,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent = ({ ); const onSelectFromInline = useCallback( - (date) => { + (date: Moment) => { const dateAsMoment = moment(date); const newDateAfterStart = !startDT || dateAsMoment.isSameOrAfter(startDT); const isEndDateTimeChange = @@ -228,6 +228,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent = ({ const applyToEndDate = !isStartDateTimeChange && (selectingEndDate || (isEndDateTimeChange && selectingEndTime)); + if (applyToEndDate && newDateAfterStart) { selectEndDT(date); } else selectStartDT(date, !isStartDateTimeChange); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx index ddd836a4f099..6ad7d525c350 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx @@ -147,7 +147,7 @@ export const RuleStatusDropdown: React.FunctionComponent = ({ ); const onSnoozeRule = useCallback( - async (snoozeSchedule) => { + async (snoozeSchedule: SnoozeSchedule) => { try { await snoozeRule(snoozeSchedule); onRuleChanged(); @@ -159,7 +159,7 @@ export const RuleStatusDropdown: React.FunctionComponent = ({ ); const onUnsnoozeRule = useCallback( - async (scheduleIds) => { + async (scheduleIds?: string[]) => { try { await unsnoozeRule(scheduleIds); onRuleChanged(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_auto_refresh.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_auto_refresh.tsx index 42c59667e0e3..3b5dff705255 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_auto_refresh.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_auto_refresh.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect, useState, useRef } from 'react'; import moment from 'moment'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiAutoRefreshButton } from '@elastic/eui'; +import { OnRefreshChangeProps } from '@elastic/eui/src/components/date_picker/types'; interface RulesListAutoRefreshProps { lastUpdate: string; @@ -95,7 +96,7 @@ export const RulesListAutoRefresh = (props: RulesListAutoRefreshProps) => { }, [isPaused, refreshInterval]); const onRefreshChange = useCallback( - ({ isPaused: newIsPaused, refreshInterval: newRefreshInterval }) => { + ({ isPaused: newIsPaused, refreshInterval: newRefreshInterval }: OnRefreshChangeProps) => { setIsPaused(newIsPaused); setRefreshInterval(newRefreshInterval); }, diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx index 4a617ba61097..7d527c27d830 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx @@ -205,7 +205,7 @@ export const EsDeprecationsTable: React.FunctionComponent = ({ [sortConfig] ); - const handleSearch = useCallback(({ query, error }) => { + const handleSearch = useCallback(({ query, error }: any) => { if (error) { setSearchError(error); } else { diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/find_csp_benchmark_rule.ts b/x-pack/test/api_integration/apis/cloud_security_posture/find_csp_benchmark_rule.ts index 17890737c4e3..f2497d08de91 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/find_csp_benchmark_rule.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/find_csp_benchmark_rule.ts @@ -9,7 +9,7 @@ import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspBenchmarkRule, FindCspBenchmarkRuleResponse, -} from '@kbn/cloud-security-posture-plugin/common/types/rules/v3'; +} from '@kbn/cloud-security-posture-common/schema/rules/v3'; import { FtrProviderContext } from '../../ftr_provider_context'; import { createPackagePolicy } from './helper'; diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/rules/v1.ts b/x-pack/test/api_integration/apis/cloud_security_posture/rules/v1.ts index 9e6b10f41054..4959c8998a5b 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/rules/v1.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/rules/v1.ts @@ -9,7 +9,7 @@ import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspBenchmarkRule, FindCspBenchmarkRuleResponse, -} from '@kbn/cloud-security-posture-plugin/common/types/rules/v3'; +} from '@kbn/cloud-security-posture-common/schema/rules/v3'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { createPackagePolicy } from '../helper'; diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/rules/v2.ts b/x-pack/test/api_integration/apis/cloud_security_posture/rules/v2.ts index 45758f93362b..747e6d1d2bd5 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/rules/v2.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/rules/v2.ts @@ -9,7 +9,7 @@ import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspBenchmarkRule, FindCspBenchmarkRuleResponse, -} from '@kbn/cloud-security-posture-plugin/common/types/latest'; +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { createPackagePolicy } from '../helper'; diff --git a/x-pack/test/cloud_security_posture_api/routes/benchmarks.ts b/x-pack/test/cloud_security_posture_api/routes/benchmarks.ts index a8b94a9f3679..93ee947cef4a 100644 --- a/x-pack/test/cloud_security_posture_api/routes/benchmarks.ts +++ b/x-pack/test/cloud_security_posture_api/routes/benchmarks.ts @@ -15,7 +15,7 @@ import { } from '@kbn/cloud-security-posture-plugin/common/constants'; import expect from '@kbn/expect'; import Chance from 'chance'; -import { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +import { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { FtrProviderContext } from '../ftr_provider_context'; import { CspSecurityCommonProvider } from './helper/user_roles_utilites'; diff --git a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts index 5b80b5c7bc99..b46ecd1ef294 100644 --- a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts +++ b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts @@ -17,7 +17,7 @@ import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, DETECTION_RULE_RULES_API_CURRENT_VERSION, } from '@kbn/cloud-security-posture-plugin/common/constants'; -import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; // eslint-disable @kbn/imports/no_boundary_crossing import { generateBenchmarkRuleTags } from '@kbn/cloud-security-posture-plugin/common/utils/detection_rules'; import type { FtrProviderContext } from '../ftr_provider_context'; diff --git a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_get_states.ts b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_get_states.ts index 3b023ca4d352..61a22a234b6d 100644 --- a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_get_states.ts +++ b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_get_states.ts @@ -13,7 +13,7 @@ import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '@kbn/cloud-security-posture-plugin/common/constants'; -import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import type { FtrProviderContext } from '../ftr_provider_context'; import { CspSecurityCommonProvider } from './helper/user_roles_utilites'; diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings.ts b/x-pack/test/cloud_security_posture_functional/pages/findings.ts index 35f1f0b5cbff..9b5460f3141d 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/findings.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/findings.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import Chance from 'chance'; -import { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +import { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '@kbn/cloud-security-posture-plugin/common/constants'; import { ELASTIC_HTTP_VERSION_HEADER, diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts index acfd5918afe9..1f3a95b81bd6 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import Chance from 'chance'; import { asyncForEach } from '@kbn/std'; -import { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +import { CspBenchmarkRule } from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE } from '@kbn/cloud-security-posture-plugin/common/constants'; import { ELASTIC_HTTP_VERSION_HEADER, diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts index 9f9cdbbbdbb3..5beb4a066dc9 100644 --- a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts +++ b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts @@ -186,6 +186,28 @@ export default function (providerContext: FtrProviderContext) { expect(response.body.item.policy_ids).to.eql([agentPolicyId, agentPolicyId2]); }); + it('should work with no policy ids', async function () { + const response = await supertest + .post(`/api/fleet/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'filetest-no-policies', + description: '', + namespace: 'default', + policy_ids: [], + enabled: true, + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }) + .expect(200); + expect(response.body.item.policy_id).to.eql(null); + expect(response.body.item.policy_ids).to.eql([]); + }); + it('should allow to pass an empty namespace', async function () { await supertest .post(`/api/fleet/package_policies`) diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/update.ts b/x-pack/test/fleet_api_integration/apis/package_policy/update.ts index 6c456bea90d3..a8b89723a01a 100644 --- a/x-pack/test/fleet_api_integration/apis/package_policy/update.ts +++ b/x-pack/test/fleet_api_integration/apis/package_policy/update.ts @@ -320,6 +320,35 @@ export default function (providerContext: FtrProviderContext) { expect(response.body.item.policy_ids).to.eql([agentPolicyId, managedAgentPolicyId]); }); + it('should work with no policy ids', async function () { + const { body: packagePolicyResponse } = await supertest + .post(`/api/fleet/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'filetest-to-clear-policy', + description: '', + namespace: 'default', + policy_id: agentPolicyId, + policy_ids: [agentPolicyId], + enabled: true, + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }); + const response = await supertest + .put(`/api/fleet/package_policies/${packagePolicyResponse.item.id}`) + .set('kbn-xsrf', 'xxxx') + .send({ + policy_ids: [], + }) + .expect(200); + expect(response.body.item.policy_id).to.eql(null); + expect(response.body.item.policy_ids).to.eql([]); + }); + it('should trim whitespace from name on update', async function () { await supertest .put(`/api/fleet/package_policies/${packagePolicyId}`) diff --git a/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts b/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts index ff20297efdec..68b1d97d531d 100644 --- a/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts +++ b/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts @@ -77,7 +77,7 @@ export default function ApiTest({ getService, getPageObjects }: FtrProviderConte message: { role: MessageRole.System, content: - 'You are a helpful assistant for Elastic Observability. Your goal is to help the Elastic Observability users to quickly assess what is happening in their observed systems. You can help them visualise and analyze data, investigate their systems, perform root cause analysis or identify optimisation opportunities.\n\nIt\'s very important to not assume what the user is meaning. Ask them for clarification if needed.\n\nIf you are unsure about which function should be used and with what arguments, ask the user for clarification or confirmation.\n\nIn KQL ("kqlFilter")) escaping happens with double quotes, not single quotes. Some characters that need escaping are: \':()\\ /". Always put a field value in double quotes. Best: service.name:"opbeans-go". Wrong: service.name:opbeans-go. This is very important!\n\nYou can use Github-flavored Markdown in your responses. If a function returns an array, consider using a Markdown table to format the response.\n\nNote that ES|QL (the Elasticsearch Query Language which is a new piped language) is the preferred query language.\n\nYou MUST use the "query" function when the user wants to:\n- visualize data\n- run any arbitrary query\n- breakdown or filter ES|QL queries that are displayed on the current page\n- convert queries from another language to ES|QL\n- asks general questions about ES|QL\n\nDO NOT UNDER ANY CIRCUMSTANCES generate ES|QL queries or explain anything about the ES|QL query language yourself.\nDO NOT UNDER ANY CIRCUMSTANCES try to correct an ES|QL query yourself - always use the "query" function for this.\n\nDO NOT UNDER ANY CIRCUMSTANCES USE ES|QL syntax (`service.name == "foo"`) with "kqlFilter" (`service.name:"foo"`).\n\nEven if the "context" function was used before that, follow it up with the "query" function. If a query fails, do not attempt to correct it yourself. Again you should call the "query" function,\neven if it has been called before.\n\nWhen the "visualize_query" function has been called, a visualization has been displayed to the user. DO NOT UNDER ANY CIRCUMSTANCES follow up a "visualize_query" function call with your own visualization attempt.\nIf the "execute_query" function has been called, summarize these results for the user. The user does not see a visualization in this case.\n\nYou MUST use the get_dataset_info function function before calling the "query" or "changes" function.\n\nIf a function requires an index, you MUST use the results from the dataset info functions.\n\n\n\nThe user is able to change the language which they want you to reply in on the settings page of the AI Assistant for Observability, which can be found in the Stack Management app under the option AI Assistants.\nIf the user asks how to change the language, reply in the same language the user asked in.You do not have a working memory. If the user expects you to remember the previous conversations, tell them they can set up the knowledge base.\n\nYou MUST respond in the users preferred language which is: English.', + 'You are a helpful assistant for Elastic Observability. Your goal is to help the Elastic Observability users to quickly assess what is happening in their observed systems. You can help them visualise and analyze data, investigate their systems, perform root cause analysis or identify optimisation opportunities.\n\nIt\'s very important to not assume what the user is meaning. Ask them for clarification if needed.\n\nIf you are unsure about which function should be used and with what arguments, ask the user for clarification or confirmation.\n\nIn KQL ("kqlFilter")) escaping happens with double quotes, not single quotes. Some characters that need escaping are: \':()\\ /". Always put a field value in double quotes. Best: service.name:"opbeans-go". Wrong: service.name:opbeans-go. This is very important!\n\nYou can use Github-flavored Markdown in your responses. If a function returns an array, consider using a Markdown table to format the response.\n\nNote that ES|QL (the Elasticsearch Query Language which is a new piped language) is the preferred query language.\n\nYou MUST use the "query" function when the user wants to:\n- visualize data\n- run any arbitrary query\n- breakdown or filter ES|QL queries that are displayed on the current page\n- convert queries from another language to ES|QL\n- asks general questions about ES|QL\n\nDO NOT UNDER ANY CIRCUMSTANCES generate ES|QL queries or explain anything about the ES|QL query language yourself.\nDO NOT UNDER ANY CIRCUMSTANCES try to correct an ES|QL query yourself - always use the "query" function for this.\n\nDO NOT UNDER ANY CIRCUMSTANCES USE ES|QL syntax (`service.name == "foo"`) with "kqlFilter" (`service.name:"foo"`).\n\nEven if the "context" function was used before that, follow it up with the "query" function. If a query fails, do not attempt to correct it yourself. Again you should call the "query" function,\neven if it has been called before.\n\nWhen the "visualize_query" function has been called, a visualization has been displayed to the user. DO NOT UNDER ANY CIRCUMSTANCES follow up a "visualize_query" function call with your own visualization attempt.\nIf the "execute_query" function has been called, summarize these results for the user. The user does not see a visualization in this case.\n\nYou MUST use the get_dataset_info function function before calling the "query" or "changes" function.\n\nIf a function requires an index, you MUST use the results from the dataset info functions.\n\n\n\nThe user is able to change the language which they want you to reply in on the settings page of the AI Assistant for Observability, which can be found in the Stack Management app under the option AI Assistants.\nIf the user asks how to change the language, reply in the same language the user asked in.You do not have a working memory. If the user expects you to remember the previous conversations, tell them they can set up the knowledge base.', }, }, { @@ -398,10 +398,6 @@ export default function ApiTest({ getService, getPageObjects }: FtrProviderConte expect(messages.length).to.eql(9); expect(messages[0].message.role).to.eql('system'); - // Verify that system message extension that happen on the server are captured in the telemetry - expect(messages[0].message.content).to.contain( - 'You MUST respond in the users preferred language which is: English.' - ); }); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/fields_browser.ts b/x-pack/test/security_solution_cypress/cypress/tasks/fields_browser.ts index f9e83fb449b7..c05bfbc6d281 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/fields_browser.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/fields_browser.ts @@ -75,6 +75,8 @@ export const toggleCategory = (category: string) => { }; export const removesMessageField = () => { + cy.get(FIELDS_BROWSER_FILTER_INPUT).clear(); + cy.get(FIELDS_BROWSER_FILTER_INPUT).type('message'); cy.get(FIELDS_BROWSER_MESSAGE_CHECKBOX).uncheck(); }; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/rule_snoozing.ts b/x-pack/test/security_solution_cypress/cypress/tasks/rule_snoozing.ts index 33ade4482951..9c1f5d45fe07 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/rule_snoozing.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/rule_snoozing.ts @@ -119,8 +119,7 @@ function snoozeRuleInOpenPopover(duration: SnoozeDuration): void { cy.log(`Snooze a rule for ${value} ${units}`); - cy.get(SNOOZE_POPOVER_INTERVAL_VALUE_INPUT).clear(); - cy.get(SNOOZE_POPOVER_INTERVAL_VALUE_INPUT).type(value.toString()); + cy.get(SNOOZE_POPOVER_INTERVAL_VALUE_INPUT).type(`{selectAll}${value.toString()}`); cy.get(SNOOZE_POPOVER_INTERVAL_UNIT_INPUT).select(units); cy.get(SNOOZE_POPOVER_APPLY_BUTTON).click(); } diff --git a/x-pack/test/stack_functional_integration/apps/ccs/ccs_console.js b/x-pack/test/stack_functional_integration/apps/ccs/ccs_console.js index 01205ed528a1..e105ceecf6cf 100644 --- a/x-pack/test/stack_functional_integration/apps/ccs/ccs_console.js +++ b/x-pack/test/stack_functional_integration/apps/ccs/ccs_console.js @@ -31,7 +31,7 @@ export default function ({ getService, getPageObjects }) { }); it('it should be able to access remote data', async () => { await PageObjects.console.monaco.enterText( - '\nGET ftr-remote:makelogs工程-*/_search\n {\n "query": {\n "bool": {\n "must": [\n {"match": {"extension" : "jpg"} \n}\n}\n}\n}\n}' + '\nGET ftr-remote:makelogs工程-*/_search\n {\n "query": {\n "bool": {\n "must": [\n {"match": {"extension" : "jpg"} \n}\n]\n}\n}\n}' ); await PageObjects.console.clickPlay(); await retry.try(async () => { diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/find_csp_benchmark_rule.ts b/x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/find_csp_benchmark_rule.ts index b03ba641ddd1..cefe3dc598b4 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/find_csp_benchmark_rule.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/find_csp_benchmark_rule.ts @@ -9,7 +9,7 @@ import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspBenchmarkRule, FindCspBenchmarkRuleResponse, -} from '@kbn/cloud-security-posture-plugin/common/types/latest'; +} from '@kbn/cloud-security-posture-common/schema/rules/latest'; import { createPackagePolicy } from '@kbn/test-suites-xpack/api_integration/apis/cloud_security_posture/helper'; import { FtrProviderContext } from '../../../ftr_provider_context'; diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts index 9a48fd898d3c..ffac91496106 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts @@ -7,6 +7,7 @@ import path from 'path'; import expect from '@kbn/expect'; +import { byIdAscComparator } from '@kbn/core-saved-objects-import-export-server-internal/src/export/utils'; import { FtrProviderContext } from '../../../ftr_provider_context'; const fixturePaths = { @@ -55,11 +56,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { .expect(200) .then((resp) => { expect( - resp.body.saved_objects.map((obj: any) => ({ - id: obj.id, - type: obj.type, - hidden: obj.meta.hiddenType, - })) + resp.body.saved_objects + .map((obj: any) => ({ + id: obj.id, + type: obj.type, + hidden: obj.meta.hiddenType, + })) + .sort(byIdAscComparator) ).to.eql([ { id: 'obj_1', diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 7a7747a964ca..1770916bbace 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -98,5 +98,6 @@ "@kbn/test-suites-src", "@kbn/console-plugin", "@kbn/cloud-security-posture-common", + "@kbn/core-saved-objects-import-export-server-internal", ] }