-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rule flyout opening from Findings and Alerts page #219
Changes from 2 commits
be9f14e
8ad1b1f
264c4ea
dae1c8f
dbb89b2
547b8ae
250a31e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,16 +25,21 @@ import { | |
import { capitalizeFirstLetter, renderTime } from '../../../utils/helpers'; | ||
import { DEFAULT_EMPTY_DATA, ROUTES } from '../../../utils/constants'; | ||
import { Finding, Query } from '../models/interfaces'; | ||
import { RuleViewerFlyout } from '../../Rules/components/RuleViewerFlyout/RuleViewerFlyout'; | ||
import { RuleTableItem } from '../../Rules/utils/helpers'; | ||
import { RuleSource } from '../../../../server/models/interfaces'; | ||
|
||
interface FindingDetailsFlyoutProps { | ||
finding: Finding; | ||
closeFlyout: () => void; | ||
backButton?: React.ReactNode; | ||
allRules: object; | ||
allRules: { [id: string]: RuleSource }; | ||
} | ||
|
||
interface FindingDetailsFlyoutState { | ||
loading: boolean; | ||
ruleViewerFlyoutShown: boolean; | ||
ruleViewerFlyoutData: RuleTableItem | null; | ||
} | ||
|
||
export default class FindingDetailsFlyout extends Component< | ||
|
@@ -45,6 +50,8 @@ export default class FindingDetailsFlyout extends Component< | |
super(props); | ||
this.state = { | ||
loading: false, | ||
ruleViewerFlyoutShown: false, | ||
ruleViewerFlyoutData: null, | ||
}; | ||
} | ||
|
||
|
@@ -62,6 +69,28 @@ export default class FindingDetailsFlyout extends Component< | |
); | ||
}; | ||
|
||
showRuleDetails = (fullRule, ruleId: string) => { | ||
this.setState({ | ||
...this.state, | ||
ruleViewerFlyoutShown: true, | ||
ruleViewerFlyoutData: { | ||
ruleId: ruleId, | ||
title: fullRule.title, | ||
level: fullRule.level, | ||
category: fullRule.category, | ||
description: fullRule.description, | ||
source: fullRule.source, | ||
ruleInfo: { | ||
_source: fullRule, | ||
} as any, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've changed it to TS assertion is needed because we don't have all the data to construct whole object. Other properties are anyway not in use in the Rule flyout. Let me know if you have some better idea. |
||
}, | ||
}); | ||
}; | ||
|
||
hideRuleDetails = () => { | ||
this.setState({ ...this.state, ruleViewerFlyoutShown: false, ruleViewerFlyoutData: null }); | ||
}; | ||
|
||
renderRuleDetails = (rules: Query[] = []) => { | ||
const { | ||
allRules, | ||
|
@@ -94,8 +123,7 @@ export default class FindingDetailsFlyout extends Component< | |
{/*//TODO: Refactor EuiLink to filter rules table to the specific rule.*/} | ||
<EuiFormRow label={'Rule name'}> | ||
<EuiLink | ||
href={`#${ROUTES.RULES}`} | ||
target={'_blank'} | ||
onClick={() => this.showRuleDetails(fullRule, rule.id)} | ||
data-test-subj={`finding-details-flyout-${fullRule.title}-details`} | ||
> | ||
{fullRule.title || DEFAULT_EMPTY_DATA} | ||
|
@@ -208,6 +236,13 @@ export default class FindingDetailsFlyout extends Component< | |
hideCloseButton | ||
data-test-subj={'finding-details-flyout'} | ||
> | ||
{this.state.ruleViewerFlyoutShown && this.state.ruleViewerFlyoutData && ( | ||
<RuleViewerFlyout | ||
hideFlyout={this.hideRuleDetails} | ||
ruleTableItem={this.state.ruleViewerFlyoutData} | ||
/> | ||
)} | ||
|
||
<EuiFlyoutHeader hasBorder={true}> | ||
<EuiFlexGroup justifyContent="flexStart" alignItems="center"> | ||
<EuiFlexItem> | ||
|
@@ -222,6 +257,7 @@ export default class FindingDetailsFlyout extends Component< | |
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiButtonIcon | ||
aria-label="close" | ||
iconType="cross" | ||
display="empty" | ||
iconSize="m" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ import { | |
EuiFlyoutBody, | ||
EuiFlyoutHeader, | ||
EuiTitle, | ||
EuiButtonIcon, | ||
} from '@elastic/eui'; | ||
import { ROUTES } from '../../../../utils/constants'; | ||
import React, { useMemo, useState } from 'react'; | ||
|
@@ -21,9 +22,9 @@ import { RuleViewerFlyoutHeaderActions } from './RuleViewFlyoutHeaderActions'; | |
import { RuleService } from '../../../../services'; | ||
|
||
export interface RuleViewerFlyoutProps { | ||
history: RouteComponentProps['history']; | ||
history?: RouteComponentProps['history']; | ||
ruleTableItem: RuleTableItem; | ||
ruleService: RuleService; | ||
ruleService?: RuleService; | ||
hideFlyout: (refreshRules?: boolean) => void; | ||
} | ||
|
||
|
@@ -42,13 +43,19 @@ export const RuleViewerFlyout: React.FC<RuleViewerFlyoutProps> = ({ | |
setActionsPopoverOpen(false); | ||
}; | ||
const duplicateRule = () => { | ||
if (!history) { | ||
return; | ||
} | ||
history.push({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Club together into
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
pathname: ROUTES.RULES_DUPLICATE, | ||
state: { ruleItem: ruleTableItem.ruleInfo }, | ||
}); | ||
}; | ||
|
||
const editRule = () => { | ||
if (!history) { | ||
return; | ||
} | ||
history.push({ | ||
pathname: ROUTES.RULES_EDIT, | ||
state: { ruleItem: ruleTableItem.ruleInfo }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we clubbed into
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
@@ -74,6 +81,9 @@ export const RuleViewerFlyout: React.FC<RuleViewerFlyoutProps> = ({ | |
}; | ||
|
||
const onDeleteRuleConfirmed = async () => { | ||
if (!ruleService) { | ||
return; | ||
} | ||
const deleteRuleRes = await ruleService.deleteRule(ruleTableItem.ruleId); | ||
|
||
if (!deleteRuleRes.ok) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's fix this Todo? we can show an error toast saying There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check this commit, I think its a right error handling here now: |
||
|
@@ -97,17 +107,35 @@ export const RuleViewerFlyout: React.FC<RuleViewerFlyoutProps> = ({ | |
); | ||
|
||
return ( | ||
<EuiFlyout onClose={hideFlyout} data-test-subj={`rule_flyout_${ruleTableItem.title}`}> | ||
<EuiFlyout | ||
onClose={hideFlyout} | ||
hideCloseButton | ||
ownFocus={true} | ||
size={'m'} | ||
data-test-subj={`rule_flyout_${ruleTableItem.title}`} | ||
> | ||
{isDeleteModalVisible && deleteModal ? deleteModal : null} | ||
<EuiFlyoutHeader hasBorder> | ||
<EuiFlexGroup> | ||
<EuiFlyoutHeader hasBorder={true}> | ||
<EuiFlexGroup alignItems="center"> | ||
<EuiFlexItem> | ||
<EuiTitle size="m"> | ||
<h3>{ruleTableItem.title}</h3> | ||
</EuiTitle> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false} style={{ marginRight: '50px' }}> | ||
{headerActions} | ||
{ruleService && history && ( | ||
<EuiFlexItem grow={false} style={{ marginRight: '50px' }}> | ||
{headerActions} | ||
</EuiFlexItem> | ||
)} | ||
<EuiFlexItem grow={false}> | ||
<EuiButtonIcon | ||
aria-label="close" | ||
iconType="cross" | ||
display="empty" | ||
iconSize="m" | ||
onClick={() => hideFlyout()} | ||
data-test-subj={`close-finding-details-flyout`} | ||
/> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFlyoutHeader> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This boolean seems redundant since we are anyways rendering the flyout based on the data. I think just
ruleViewerFlyoutData
is enough for check. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally right. I've cleaned it up