diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx
index 6bc3a4904e031..fa0684e5593bf 100644
--- a/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx
@@ -51,6 +51,14 @@ const HoverActionsContainer = styled(EuiPanel)`
HoverActionsContainer.displayName = 'HoverActionsContainer';
+const FullWidthFlexGroup = styled(EuiFlexGroup)`
+ width: 100%;
+`;
+
+const FullWidthFlexItem = styled(EuiFlexItem)`
+ width: 100%;
+`;
+
export const getColumns = ({
browserFields,
columnHeaders,
@@ -159,10 +167,15 @@ export const getColumns = ({
sortable: true,
truncateText: false,
render: (values: ToStringArray | null | undefined, data: EventFieldsData) => (
-
+
{values != null &&
values.map((value, i) => (
-
)}
-
+
))}
-
+
),
},
{
diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx
index 8d2488b269d76..4b03e7e0d32c4 100644
--- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx
@@ -8,6 +8,7 @@ import React, { useCallback, memo } from 'react';
import {
EuiSelectableOption,
EuiModalBody,
+ EuiModalHeader,
EuiMarkdownEditorUiPlugin,
EuiCodeBlock,
} from '@elastic/eui';
@@ -47,24 +48,32 @@ const TimelineEditorComponent: React.FC = ({ onClosePopover
[]
);
+ const handleTimelineChange = useCallback(
+ (timelineTitle, timelineId, graphEventId) => {
+ const url = formatUrl(getTimelineUrl(timelineId ?? '', graphEventId), {
+ absolute: true,
+ skipSearch: true,
+ });
+ onInsert(`[${timelineTitle}](${url})`, {
+ block: false,
+ });
+ },
+ [formatUrl, onInsert]
+ );
+
return (
-
- {
- const url = formatUrl(getTimelineUrl(timelineId ?? '', graphEventId), {
- absolute: true,
- skipSearch: true,
- });
- onInsert(`[${timelineTitle}](${url})`, {
- block: false,
- });
- }}
- onClosePopover={onClosePopover}
- timelineType={TimelineType.default}
- />
-
+ <>
+
+
+
+
+ >
);
};
diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
index 5f567508a4011..e71cf054c87b4 100644
--- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
@@ -58,7 +58,7 @@ const HeaderChildrenFlexItem = styled(EuiFlexItem)`
const HistogramPanel = styled(Panel)<{ height?: number }>`
display: flex;
flex-direction: column;
- ${({ height }) => (height != null ? `height: ${height}px;` : '')}
+ ${({ height }) => (height != null ? `min-height: ${height}px;` : '')}
`;
export const MatrixHistogramComponent: React.FC = ({
diff --git a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/header.tsx b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/header.tsx
index 8ab099ab78ee9..6fd24ebca7c82 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/header.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/header.tsx
@@ -156,6 +156,7 @@ export const Header = React.memo(
onChange={onSearchInputChange}
placeholder={i18n.FILTER_PLACEHOLDER}
value={searchInput}
+ fullWidth
/>
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
index 519372d0ac797..6e31b822e73c2 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
@@ -3,11 +3,14 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
+
+import { EuiSelectableProps } from '@elastic/eui';
import React from 'react';
import { shallow, ShallowWrapper, mount } from 'enzyme';
+
import { TimelineType } from '../../../../../common/types/timeline';
import { SortFieldTimeline, Direction } from '../../../../graphql/types';
-import { SelectableTimeline, ORIGINAL_PAGE_SIZE, SearchProps } from './';
+import { SelectableTimeline, ORIGINAL_PAGE_SIZE } from './';
const mockFetchAllTimeline = jest.fn();
jest.mock('../../../containers/all', () => {
@@ -40,10 +43,10 @@ describe('SelectableTimeline', () => {
});
test('render placeholder', () => {
- const searchProps: SearchProps = wrapper
+ const searchProps: EuiSelectableProps['searchProps'] = wrapper
.find('[data-test-subj="selectable-input"]')
.prop('searchProps');
- expect(searchProps.placeholder).toEqual('e.g. Timeline name or description');
+ expect(searchProps!.placeholder).toEqual('e.g. Timeline name or description');
});
});
@@ -58,10 +61,10 @@ describe('SelectableTimeline', () => {
});
test('render placeholder', () => {
- const searchProps: SearchProps = wrapper
+ const searchProps: EuiSelectableProps['searchProps'] = wrapper
.find('[data-test-subj="selectable-input"]')
.prop('searchProps');
- expect(searchProps.placeholder).toEqual('e.g. Timeline template name or description');
+ expect(searchProps!.placeholder).toEqual('e.g. Timeline template name or description');
});
});
});
@@ -89,7 +92,7 @@ describe('SelectableTimeline', () => {
jest.clearAllMocks();
});
- test('shoule be called with correct args', () => {
+ test('should be called with correct args', () => {
expect(mockFetchAllTimeline).toBeCalledWith(args);
});
});
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 a80576c7237f4..7dbc4a17f4b3b 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
@@ -12,8 +12,7 @@ import {
EuiIcon,
EuiTextColor,
EuiSelectableOption,
- EuiPortal,
- EuiFilterGroup,
+ EuiSelectableProps,
EuiFilterButton,
} from '@elastic/eui';
import { isEmpty, debounce } from 'lodash/fp';
@@ -41,30 +40,9 @@ const MyEuiFlexItem = styled(EuiFlexItem)`
white-space: nowrap;
`;
-const MyEuiFlexGroup = styled(EuiFlexGroup)`
- padding 0px 4px;
-`;
-
-const EuiSelectableContainer = styled.div<{ isLoading: boolean }>`
- .euiSelectable {
- .euiFormControlLayout__childrenWrapper {
- display: flex;
- }
- ${({ isLoading }) => `${
- isLoading
- ? `
- .euiFormControlLayoutIcons {
- display: none;
- }
- .euiFormControlLayoutIcons.euiFormControlLayoutIcons--right {
- display: block;
- left: 12px;
- top: 12px;
- }`
- : ''
- }
- `}
- }
+const StyledEuiFilterButton = styled(EuiFilterButton)`
+ border-top: 0;
+ border-bottom: 0;
`;
export const ORIGINAL_PAGE_SIZE = 50;
@@ -95,15 +73,6 @@ export interface SelectableTimelineProps {
timelineType: TimelineTypeLiteral;
}
-export interface SearchProps {
- 'data-test-subj'?: string;
- isLoading: boolean;
- placeholder: string;
- onSearch: (arg: string) => void;
- incremental: boolean;
- inputRef: (arg: HTMLInputElement | null) => void;
-}
-
const SelectableTimelineComponent: React.FC = ({
hideUntitled = false,
getSelectableOptions,
@@ -115,7 +84,6 @@ const SelectableTimelineComponent: React.FC = ({
const [heightTrigger, setHeightTrigger] = useState(0);
const [searchTimelineValue, setSearchTimelineValue] = useState('');
const [onlyFavorites, setOnlyFavorites] = useState(false);
- const [searchRef, setSearchRef] = useState(null);
const { fetchAllTimeline, timelines, loading, totalCount: timelineCount } = useGetAllTimeline();
const selectableListOuterRef = useRef(null);
const selectableListInnerRef = useRef(null);
@@ -156,8 +124,8 @@ const SelectableTimelineComponent: React.FC = ({
[heightTrigger, pageSize]
);
- const renderTimelineOption = useCallback((option, searchValue) => {
- return (
+ const renderTimelineOption = useCallback(
+ (option, searchValue) => (
= ({
/>
- );
- }, []);
+ ),
+ []
+ );
const handleTimelineChange = useCallback(
(options) => {
@@ -215,39 +184,53 @@ const SelectableTimelineComponent: React.FC = ({
[onClosePopover, onTimelineChange]
);
- const favoritePortal = useMemo(
- () =>
- searchRef != null ? (
-
-
-
-
-
- {i18nTimeline.ONLY_FAVORITES}
-
-
-
-
-
- ) : null,
- [searchRef, onlyFavorites, handleOnToggleOnlyFavorites]
+ const EuiSelectableContent = useCallback(
+ (list, search) => (
+ <>
+ {search}
+ {list}
+ >
+ ),
+ []
);
- const searchProps: SearchProps = {
- 'data-test-subj': 'timeline-super-select-search-box',
- isLoading: loading,
- placeholder: useMemo(() => i18n.SEARCH_BOX_TIMELINE_PLACEHOLDER(timelineType), [timelineType]),
- onSearch: onSearchTimeline,
- incremental: true,
- inputRef: (node: HTMLInputElement | null) => {
- setSearchRef(node);
- },
- };
+ const searchProps: EuiSelectableProps['searchProps'] = useMemo(
+ () => ({
+ 'data-test-subj': 'timeline-super-select-search-box',
+ placeholder: i18n.SEARCH_BOX_TIMELINE_PLACEHOLDER(timelineType),
+ onSearch: onSearchTimeline,
+ incremental: true,
+ append: (
+
+ {i18nTimeline.ONLY_FAVORITES}
+
+ ),
+ }),
+ [handleOnToggleOnlyFavorites, onSearchTimeline, onlyFavorites, timelineType]
+ );
+
+ const listProps: EuiSelectableProps['listProps'] = useMemo(
+ () => ({
+ rowHeight: TIMELINE_ITEM_HEIGHT,
+ showIcons: false,
+ windowProps: {
+ onScroll: ({ scrollOffset }) =>
+ handleOnScroll(
+ timelines.filter((t) => !hideUntitled || t.title !== '').length,
+ timelineCount,
+ scrollOffset
+ ),
+ outerRef: selectableListOuterRef,
+ innerRef: selectableListInnerRef,
+ },
+ }),
+ [handleOnScroll, hideUntitled, timelineCount, timelines]
+ );
useEffect(() => {
fetchAllTimeline({
@@ -267,46 +250,25 @@ const SelectableTimelineComponent: React.FC = ({
}, [fetchAllTimeline, onlyFavorites, pageSize, searchTimelineValue, timelineType]);
return (
-
-
- handleOnScroll(
- timelines.filter((t) => !hideUntitled || t.title !== '').length,
- timelineCount,
- scrollOffset
- ),
- outerRef: selectableListOuterRef,
- innerRef: selectableListInnerRef,
- },
- }}
- renderOption={renderTimelineOption}
- onChange={handleTimelineChange}
- searchable
- searchProps={searchProps}
- singleSelection={true}
- options={getSelectableOptions({
- timelines,
- onlyFavorites,
- searchTimelineValue,
- timelineType,
- })}
- >
- {(list, search) => (
- <>
- {search}
- {favoritePortal}
- {list}
- >
- )}
-
-
+
+ {EuiSelectableContent}
+
);
};
diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/__mocks__/index.ts
index b1f9b04daa1c1..574be4b45fe26 100644
--- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/__mocks__/index.ts
+++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/__mocks__/index.ts
@@ -322,7 +322,7 @@ export const formattedSearchStrategyResponse = {
endgameSecurity: 0,
filebeatSystemModule: 1793,
winlogbeatSecurity: 42,
- winlogbeatMWSysmonOperational: null,
+ winlogbeatMWSysmonOperational: 1781,
},
};
diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/index.ts
index 61c228a5fd164..4a9d4c7af103c 100644
--- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/index.ts
+++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/overview/index.ts
@@ -58,7 +58,7 @@ export const hostOverview: SecuritySolutionFactory = {
winlogbeatMWSysmonOperational: getOr(
null,
'winlog_module.mwsysmon_operational_event_count.doc_count',
- response
+ aggregations
),
},
};
diff --git a/x-pack/test/api_integration/apis/security_solution/overview_host.ts b/x-pack/test/api_integration/apis/security_solution/overview_host.ts
index f3de9a6481b8f..6077332b3a652 100644
--- a/x-pack/test/api_integration/apis/security_solution/overview_host.ts
+++ b/x-pack/test/api_integration/apis/security_solution/overview_host.ts
@@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) {
endgameSecurity: 4,
filebeatSystemModule: 0,
winlogbeatSecurity: 0,
- winlogbeatMWSysmonOperational: null,
+ winlogbeatMWSysmonOperational: 0,
};
it('Make sure that we get OverviewHost data', async () => {