* init commit * lots of cleanup * starting on tests... problems * Ready for review * remove sample data * remove comment and fix type * pr changes * fix type * scratchy * sourcerer in timeline * sourcerer in timeline * wip * moving to redux * working on types * fixed * more adjustments, tests fixed * FF off * pr ready * renaming * url state working, hoc not working * url state working for timeline and default scope * script to build fields for beat doc * refactor sourcerer * refactor host to useSourcerer * refactor network to useSourcerer * refactor overview to useSourcerer * refactor detections to useSourcerer * wip for timelines to remove all useSource * wip indexes timeline * do component tests * start container tests * start container tests * update selection widget of index patterns + remove last useWithSource * add indexeNames in network kpi * fix type errors * fix type * missing merge master * get existing index from config file * fixing broken tests * add saving button to avoid to many queries to be aborted * reducer timeline tests broke * need to rewind * much better * timeline saving index names + clean up url state to only manage default * more test fixing * more test changes * remove all the useWithSource + deprecated the graphql until we delete it in a new PR + delete all the beat doc * default timeline to all index when creation + filter index patterns to make sure you do not add one who we do not know * fix types * test for stateful timeline render * we should not have change that * no chnages + snapshot * fix test + bugs from review * fix uncommon processes indexNames * review III * change design for main page of the sourcerer from design * bug fixes when opening old timeline + implementation of new design * fix circular deps * remove unused attributes for event details * design cleanup * fix api integration test with the new search strategy * add reset + manage accordion state * fix bugs + types issues * cleanup * update docs * review -> remove tooltip when popover is open * cypress fixing * fix for ml_condition_links and url_state cypress tests * add cy wait for race condition in pagination tests * missing plumbing kpi host Co-authored-by: Steph Milovic <stephanie.milovic@elastic.co> Co-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>
109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License;
|
|
* you may not use this file except in compliance with the Elastic License.
|
|
*/
|
|
|
|
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
|
import React, { useCallback, useState } from 'react';
|
|
import styled from 'styled-components';
|
|
import { useParams } from 'react-router-dom';
|
|
|
|
import { TimelineId, TimelineType } from '../../../common/types/timeline';
|
|
import { HeaderPage } from '../../common/components/header_page';
|
|
import { WrapperPage } from '../../common/components/wrapper_page';
|
|
import { useKibana } from '../../common/lib/kibana';
|
|
import { SpyRoute } from '../../common/utils/route/spy_routes';
|
|
import { useApolloClient } from '../../common/utils/apollo_context';
|
|
import { OverviewEmpty } from '../../overview/components/overview_empty';
|
|
import { StatefulOpenTimeline } from '../components/open_timeline';
|
|
import { NEW_TEMPLATE_TIMELINE } from '../components/timeline/properties/translations';
|
|
import { NewTemplateTimeline } from '../components/timeline/properties/new_template_timeline';
|
|
import { NewTimeline } from '../components/timeline/properties/helpers';
|
|
import * as i18n from './translations';
|
|
import { SecurityPageName } from '../../app/types';
|
|
import { useSourcererScope } from '../../common/containers/sourcerer';
|
|
|
|
const TimelinesContainer = styled.div`
|
|
width: 100%;
|
|
`;
|
|
|
|
export const DEFAULT_SEARCH_RESULTS_PER_PAGE = 10;
|
|
|
|
export const TimelinesPageComponent: React.FC = () => {
|
|
const { tabName } = useParams<{ pageName: SecurityPageName; tabName: string }>();
|
|
const [importDataModalToggle, setImportDataModalToggle] = useState<boolean>(false);
|
|
const onImportTimelineBtnClick = useCallback(() => {
|
|
setImportDataModalToggle(true);
|
|
}, [setImportDataModalToggle]);
|
|
const { indicesExist } = useSourcererScope();
|
|
|
|
const apolloClient = useApolloClient();
|
|
const capabilitiesCanUserCRUD: boolean = !!useKibana().services.application.capabilities.siem
|
|
.crud;
|
|
|
|
return (
|
|
<>
|
|
{indicesExist ? (
|
|
<>
|
|
<WrapperPage>
|
|
<HeaderPage border hideSourcerer={true} title={i18n.PAGE_TITLE}>
|
|
<EuiFlexGroup gutterSize="s" alignItems="center">
|
|
<EuiFlexItem>
|
|
{capabilitiesCanUserCRUD && (
|
|
<EuiButton
|
|
iconType="indexOpen"
|
|
onClick={onImportTimelineBtnClick}
|
|
data-test-subj="open-import-data-modal-btn"
|
|
>
|
|
{i18n.ALL_TIMELINES_IMPORT_TIMELINE_TITLE}
|
|
</EuiButton>
|
|
)}
|
|
</EuiFlexItem>
|
|
{tabName === TimelineType.default ? (
|
|
<EuiFlexItem>
|
|
<NewTimeline
|
|
timelineId={TimelineId.active}
|
|
outline={true}
|
|
data-test-subj="create-default-btn"
|
|
/>
|
|
</EuiFlexItem>
|
|
) : (
|
|
<EuiFlexItem>
|
|
<NewTemplateTimeline
|
|
outline={true}
|
|
title={NEW_TEMPLATE_TIMELINE}
|
|
data-test-subj="create-template-btn"
|
|
/>
|
|
</EuiFlexItem>
|
|
)}
|
|
</EuiFlexGroup>
|
|
</HeaderPage>
|
|
|
|
<TimelinesContainer>
|
|
<StatefulOpenTimeline
|
|
apolloClient={apolloClient!}
|
|
defaultPageSize={DEFAULT_SEARCH_RESULTS_PER_PAGE}
|
|
isModal={false}
|
|
importDataModalToggle={importDataModalToggle && capabilitiesCanUserCRUD}
|
|
setImportDataModalToggle={setImportDataModalToggle}
|
|
title={i18n.ALL_TIMELINES_PANEL_TITLE}
|
|
data-test-subj="stateful-open-timeline"
|
|
/>
|
|
</TimelinesContainer>
|
|
</WrapperPage>
|
|
</>
|
|
) : (
|
|
<WrapperPage>
|
|
<HeaderPage hideSourcerer={true} border title={i18n.PAGE_TITLE} />
|
|
<OverviewEmpty />
|
|
</WrapperPage>
|
|
)}
|
|
|
|
<SpyRoute pageName={SecurityPageName.timelines} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const TimelinesPage = React.memo(TimelinesPageComponent);
|