Skip to content
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

Fixed propagation event for flyout on decoders #5597

6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

All notable changes to the Wazuh app project will be documented in this file.

## Wazuh v4.7.0 - OpenSearch Dashboards 2.6.0 - Revision 01
## Wazuh v4.7.0 - OpenSearch Dashboards 2.6.0 - Revision 00
Desvelao marked this conversation as resolved.
Show resolved Hide resolved

### Added

- Support for Wazuh 4.7.0

### Fixed

- Fixed the propagation event so that the flyout data, in the decoders, does not change when the button is pressed. [#5597](https://github.com/wazuh/wazuh-kibana-app/pull/5597)

## Wazuh v4.6.0 - OpenSearch Dashboards 2.6.0 - Revision 01

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,38 @@ import {
EuiFlexGrid,
} from '@elastic/eui';

import { ResourcesHandler, ResourcesConstants } from '../../common/resources-handler';
import {
ResourcesHandler,
ResourcesConstants,
} from '../../common/resources-handler';
import { colors } from '../../common/colors';
import { TableWzAPI } from '../../../../../../components/common/tables';
import { UI_ERROR_SEVERITIES } from '../../../../../../react-services/error-orchestrator/types';
import { UI_LOGGER_LEVELS } from '../../../../../../../common/constants';
import { getErrorOrchestrator } from '../../../../../../react-services/common-services';

export default class WzDecoderInfo extends Component {
columns: object[];
resourcesHandler;

constructor(props) {
super(props);
this.onClickRow = this.onClickRow.bind(this);
this.state = {
currentInfo: {}
currentInfo: {},
};

this.resourcesHandler = new ResourcesHandler(ResourcesConstants.DECODERS);

const handleFileClick = async (value, item) => {
const handleFileClick = async (event, value, item) => {
event.stopPropagation();
try {
const result = await this.resourcesHandler.getFileContent(value);
const file = { name: value, content: result, path: item.relative_dirname };
const file = {
name: value,
content: result,
path: item.relative_dirname,
};
this.props.updateFileContent(file);
} catch (error) {
const options = {
Expand Down Expand Up @@ -77,8 +88,12 @@ export default class WzDecoderInfo extends Component {
sortable: true,
render: (value, item) => {
return (
<EuiToolTip position="top" content={`Show ${value} content`}>
<EuiLink onClick={async () => handleFileClick(value, item)}>{value}</EuiLink>
<EuiToolTip position='top' content={`Show ${value} content`}>
<EuiLink
onClick={async event => handleFileClick(event, value, item)}
>
{value}
</EuiLink>
</EuiToolTip>
);
},
Expand All @@ -97,7 +112,7 @@ export default class WzDecoderInfo extends Component {
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera

this.setState({
currentId: this.props.item
currentId: this.props.item,
});
}

Expand All @@ -119,39 +134,43 @@ export default class WzDecoderInfo extends Component {
renderInfo(position, file, path) {
return (
<EuiFlexGrid columns={4}>
<EuiFlexItem key="position">
<EuiFlexItem key='position'>
<b style={{ paddingBottom: 6 }}>Position</b>
{position}
</EuiFlexItem>
<EuiFlexItem key="file">
<EuiFlexItem key='file'>
<b style={{ paddingBottom: 6 }}>File</b>
<span>
<EuiToolTip position="top" content={`Filter by this file: ${file}`}>
<EuiToolTip position='top' content={`Filter by this file: ${file}`}>
<EuiLink
onClick={async () =>
this.setNewFiltersAndBack([{ field: 'filename', value: file }])
this.setNewFiltersAndBack([
{ field: 'filename', value: file },
])
}
>
&nbsp;{file}
</EuiLink>
</EuiToolTip>
</span>
</EuiFlexItem>
<EuiFlexItem key="path">
<EuiFlexItem key='path'>
<b style={{ paddingBottom: 6 }}>Path</b>
<span>
<EuiToolTip position="top" content={`Filter by this path: ${path}`}>
<EuiToolTip position='top' content={`Filter by this path: ${path}`}>
<EuiLink
onClick={async () =>
this.setNewFiltersAndBack([{ field: 'relative_dirname', value: path }])
this.setNewFiltersAndBack([
{ field: 'relative_dirname', value: path },
])
}
>
&nbsp;{path}
</EuiLink>
</EuiToolTip>
</span>
</EuiFlexItem>
<EuiSpacer size="s" />
<EuiSpacer size='s' />
</EuiFlexGrid>
);
}
Expand All @@ -162,17 +181,21 @@ export default class WzDecoderInfo extends Component {
*/
renderDetails(details) {
const detailsToRender = [];
const capitalize = (str) => str[0].toUpperCase() + str.slice(1);
const capitalize = str => str[0].toUpperCase() + str.slice(1);

Object.keys(details).forEach((key) => {
Object.keys(details).forEach(key => {
let content = details[key];
if (key === 'order') {
content = this.colorOrder(content);
} else if (typeof details[key] === 'object') {
content = (
<ul>
{Object.keys(details[key]).map((k) => (
<li key={k} style={{ marginBottom: '4px', wordBreak: 'break-word' }} className="subdued-color">
{Object.keys(details[key]).map(k => (
<li
key={k}
style={{ marginBottom: '4px', wordBreak: 'break-word' }}
className='subdued-color'
>
{k}:&nbsp;
{details[key][k]}
<br />
Expand All @@ -181,7 +204,7 @@ export default class WzDecoderInfo extends Component {
</ul>
);
} else {
content = <span className="subdued-color">{details[key]}</span>;
content = <span className='subdued-color'>{details[key]}</span>;
}
detailsToRender.push(
<EuiFlexItem
Expand All @@ -191,7 +214,7 @@ export default class WzDecoderInfo extends Component {
>
<b style={{ paddingBottom: 6 }}>{capitalize(key)}</b>
<div>{content}</div>
</EuiFlexItem>
</EuiFlexItem>,
);
});

Expand All @@ -208,8 +231,13 @@ export default class WzDecoderInfo extends Component {
const result = [];
for (let i = 0, len = valuesArray.length; i < len; i++) {
const coloredString = (
<span key={`decoder-info-color-order-${i}`} style={{ color: colors[i] }}>
{valuesArray[i].startsWith(' ') ? valuesArray[i] : ` ${valuesArray[i]}`}
<span
key={`decoder-info-color-order-${i}`}
style={{ color: colors[i] }}
>
{valuesArray[i].startsWith(' ')
? valuesArray[i]
: ` ${valuesArray[i]}`}
</span>
);
result.push(coloredString);
Expand All @@ -224,15 +252,18 @@ export default class WzDecoderInfo extends Component {
colorRegex(regex) {
regex = regex.toString();
const starts = (
<span key={`decoder-info-color-regex-start`} className="subdued-color">
<span key={'decoder-info-color-regex-start'} className='subdued-color'>
{regex.split('(')[0]}
</span>
);
let valuesArray = regex.match(/\(((?!<\/span>).)*?\)(?!<\/span>)/gim);
const result = [starts];
for (let i = 0, len = valuesArray.length; i < len; i++) {
const coloredString = (
<span key={`decoder-info-color-regex-${i}`} style={{ color: colors[i] }}>
<span
key={`decoder-info-color-regex-${i}`}
style={{ color: colors[i] }}
>
{valuesArray[i]}
</span>
);
Expand All @@ -241,53 +272,54 @@ export default class WzDecoderInfo extends Component {
return result;
}

/**
* Update decoder details with the selected detail row
* @param decoder
*/
/**
* Update decoder details with the selected detail row
* @param decoder
*/
onClickRow(decoder) {
return {
onClick: () => {
this.setState({ currentDecoder: decoder });
},
};
};
}

render() {
const currentDecoder =
this.state && this.state.currentDecoder ? this.state.currentDecoder : this.props.item;
const { position, details, filename, name, relative_dirname } = currentDecoder;
this.state && this.state.currentDecoder
? this.state.currentDecoder
: this.props.item;
const { position, details, filename, name, relative_dirname } =
currentDecoder;

return (
<>
<EuiFlyoutHeader hasBorder className="flyout-header">
<EuiFlyoutHeader hasBorder className='flyout-header'>
{/* Decoder description name */}
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiTitle>
<span style={{ fontSize: '22px' }}>
{name}
</span>
<span style={{ fontSize: '22px' }}>{name}</span>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutHeader>
<EuiFlyoutBody className="flyout-body">
{/* Cards */}
<EuiFlyoutBody className='flyout-body'>
{/* Cards */}
<EuiFlexGroup>
{/* General info */}
<EuiFlexItem style={{ marginBottom: 16, marginTop: 8 }}>
<EuiAccordion
id="Info"
id='Info'
buttonContent={
<EuiTitle size="s">
<EuiTitle size='s'>
<h3>Information</h3>
</EuiTitle>
}
paddingSize="none"
paddingSize='none'
initialIsOpen={true}
>
<div className="flyout-row details-row">
<div className='flyout-row details-row'>
{this.renderInfo(position, filename, relative_dirname)}
</div>
</EuiAccordion>
Expand All @@ -296,44 +328,46 @@ export default class WzDecoderInfo extends Component {
<EuiFlexGroup>
<EuiFlexItem style={{ marginTop: 8 }}>
<EuiAccordion
id="Details"
id='Details'
buttonContent={
<EuiTitle size="s">
<EuiTitle size='s'>
<h3>Details</h3>
</EuiTitle>
}
paddingSize="none"
paddingSize='none'
initialIsOpen={true}
>
<div className="flyout-row details-row">{this.renderDetails(details)}</div>
<div className='flyout-row details-row'>
{this.renderDetails(details)}
</div>
</EuiAccordion>
</EuiFlexItem>
</EuiFlexGroup>
{/* Table */}
<EuiFlexGroup>
<EuiFlexItem style={{ marginTop: 8 }}>
<EuiAccordion
id="Related"
id='Related'
buttonContent={
<EuiTitle size="s">
<EuiTitle size='s'>
<h3>Related decoders</h3>
</EuiTitle>
}
paddingSize="none"
paddingSize='none'
initialIsOpen={true}
>
<div className="flyout-row related-rules-row">
<div className='flyout-row related-rules-row'>
<EuiFlexGroup>
<EuiFlexItem>
{currentDecoder?.filename &&
{currentDecoder?.filename && (
<TableWzAPI
tableColumns={this.columns}
tableInitialSortingField={'name'}
endpoint={`/decoders?filename=${currentDecoder.filename}`}
tableProps={{ rowProps: this.onClickRow }}
tablePageSizeOptions={[10, 25]}
/>
}
)}
</EuiFlexItem>
</EuiFlexGroup>
</div>
Expand Down