Skip to content

Commit

Permalink
Feature add new dev tools (#3055)
Browse files Browse the repository at this point in the history
* First commit added testlog view and menu with navigation to dev console and testlogs.

* Added reducers for tools.

* Added PUT request logtest and pretty json.

* Clear initial value.

* Apply prettier.

* Fixed pined menu selected. Change some files js to ts.
Added updateSelectedToolsSection redux.

* Removed debuggers

* Fix error on render elements

* Fix render items

* Fixed error on tabs

* Updated CHANGELOG

* Added flyout from ruleset edit and fixed styles.

* Added OverlayMask and event to close.

* Changed title of Logtest

* Fixed styles, PR comments.
  • Loading branch information
gabiwassan committed Apr 5, 2021
1 parent 06f75e9 commit 6e57023
Show file tree
Hide file tree
Showing 22 changed files with 622 additions and 358 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

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

## Wazuh v4.2.0 - Kibana 7.10.0 , 7.10.2 - Revision 4201

### Added

- Added Tools on wazuh menu with Dev Console and Logtest [#1434](https://github.com/wazuh/wazuh-kibana-app/pull/1434)

## Wazuh v4.1.4 - Kibana 7.10.0 , 7.10.2 - Revision 4105

Expand Down
2 changes: 1 addition & 1 deletion common/api-info/endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -10732,4 +10732,4 @@
}
]
}
]
]
2 changes: 2 additions & 0 deletions public/components/eui-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { NodeList } from './management/cluster/node-list';
import { HealthCheck } from './health-check/health-check';
import { WzEmptyPromptNoPermissions } from './common/permissions/prompt';
import { getAngularModule } from '../kibana-services';
import { Logtest } from '../directives/wz-logtest/components/logtest';

const app = getAngularModule();

Expand All @@ -57,3 +58,4 @@ app
.value('NodeList', NodeList)
.value('HealthCheck', HealthCheck)
.value('WzEmptyPromptNoPermissions', WzEmptyPromptNoPermissions)
.value('Logtest', Logtest)
88 changes: 88 additions & 0 deletions public/components/wz-menu/wz-menu-tools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Wazuh app - React component for Settings submenu.
* Copyright (C) 2015-2021 Wazuh, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Find more information about this on the LICENSE file.
*/
import React, { Component } from 'react';
import { EuiFlexItem, EuiFlexGroup, EuiSideNav, EuiIcon } from '@elastic/eui';
import { WzRequest } from '../../react-services/wz-request';
import { connect } from 'react-redux';
import { AppNavigate } from '../../react-services/app-navigate';

class WzMenuTools extends Component {
constructor(props) {
super(props);
this.state = {
// TODO: Fix the selected section
selectedItemName: null
};
this.wzReq = WzRequest;
}

UNSAFE_componentWillReceiveProps(nextProps) {
// You don't have to do this check first, but it can help prevent an unneeded render
if (nextProps.section !== this.state.selectedItemName) {
this.setState({ selectedItemName: nextProps.section });
}
}

avaibleRenderSettings() {
return [
this.createItem({ id: 'devTools', text: 'API Console' }),
this.createItem({ id: 'logtest', text: 'Ruleset Test' }),
]
}

clickMenuItem = async (ev, section) => {
this.props.closePopover();
AppNavigate.navigateToModule(ev, 'wazuh-dev', { tab: section });
};

createItem = (item, data = {}) => {
// NOTE: Duplicate `name` values will cause `id` collisions.
return {
...data,
id: item.id,
name: item.text,
isSelected: window.location.href.includes('/wazuh-dev') && this.props.state.selected_tools_section === item.id,
onClick: () => { },
onMouseDown: (ev) => this.clickMenuItem(ev, item.id)
};
};

render() {
const renderSettings = this.avaibleRenderSettings()
const sideNavAdmin = [
{
name: 'Tools',
id: 0,
icon: <EuiIcon type="devToolsApp" color="primary" />,
items: renderSettings
}
];

return (
<div className="WzManagementSideMenu" style={{ width: 200 }}>
<EuiFlexGroup responsive={false}>
<EuiFlexItem grow={false}>
<EuiSideNav items={sideNavAdmin} style={{ padding: '4px 12px' }} />
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
}
}

const mapStateToProps = state => {
return {
state: state.toolsReducers
};
};

export default connect(mapStateToProps, null)(WzMenuTools);
65 changes: 54 additions & 11 deletions public/components/wz-menu/wz-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import store from '../../redux/store';
import Management from './wz-menu-management';
import MenuSettings from './wz-menu-settings';
import MenuSecurity from './wz-menu-security';
import MenuTools from './wz-menu-tools';
import Overview from './wz-menu-overview';
import { getAngularModule, getHttp, getToasts } from '../../kibana-services';
import { GenericRequest } from '../../react-services/generic-request';
Expand Down Expand Up @@ -245,7 +246,7 @@ class WzMenu extends Component {
this.isLoading = false;
}

changePattern = event => {
changePattern = (event) => {
try {
if (!AppState.getPatternSelector()) return;
PatternHandler.changePattern(event.target.value);
Expand Down Expand Up @@ -381,6 +382,21 @@ class WzMenu extends Component {
this.setState({ currentMenuTab: item });
}

toolsPopoverToggle() {
if (!this.state.isToolsPopoverOpen) {
this.setState(() => {
return {
isToolsPopoverOpen: true,
currentMenuTab: 'wazuh-dev',
isOverviewPopoverOpen: false,
isManagementPopoverOpen: false,
isSecurityPopoverOpen: false,
isSettingsPopoverOpen: false,
};
});
}
}

settingsPopoverToggle() {
if (!this.state.isSettingsPopoverOpen) {
this.setState(() => {
Expand All @@ -390,6 +406,7 @@ class WzMenu extends Component {
isOverviewPopoverOpen: false,
isManagementPopoverOpen: false,
isSecurityPopoverOpen: false,
isToolsPopoverOpen: false,
};
});
}
Expand All @@ -404,6 +421,7 @@ class WzMenu extends Component {
isOverviewPopoverOpen: false,
isManagementPopoverOpen: false,
isSettingsPopoverOpen: false,
isToolsPopoverOpen: false,
};
});
}
Expand All @@ -418,6 +436,7 @@ class WzMenu extends Component {
isOverviewPopoverOpen: false,
isSettingsPopoverOpen: false,
isSecurityPopoverOpen: false,
isToolsPopoverOpen: false,
};
});
}
Expand All @@ -432,11 +451,17 @@ class WzMenu extends Component {
isManagementPopoverOpen: false,
isSettingsPopoverOpen: false,
isSecurityPopoverOpen: false,
isToolsPopoverOpen: false,
};
});
}
}

onClickToolsButton() {
this.setMenuItem('wazuh-dev');
this.toolsPopoverToggle();
}

onClickSettingsButton() {
this.setMenuItem('settings');
this.settingsPopoverToggle();
Expand Down Expand Up @@ -464,14 +489,22 @@ class WzMenu extends Component {
}

closeAllPopover() {
this.setState({ isOverviewPopoverOpen: false, isManagementPopoverOpen: false, isSettingsPopoverOpen: false, })
this.setState({
isOverviewPopoverOpen: false,
isManagementPopoverOpen: false,
isSettingsPopoverOpen: false,
isToolsPopoverOpen: false,
});
}

isAnyPopoverOpen() {
return this.state.isOverviewPopoverOpen ||
return (
this.state.isOverviewPopoverOpen ||
this.state.isManagementPopoverOpen ||
this.state.isSettingsPopoverOpen ||
this.state.isSecurityPopoverOpen;
this.state.isSecurityPopoverOpen ||
this.state.isToolsPopoverOpen
);
}

switchMenuOpened = () => {
Expand All @@ -480,6 +513,8 @@ class WzMenu extends Component {
this.managementPopoverToggle();
} else if (this.state.currentMenuTab === 'overview') {
this.overviewPopoverToggle();
} else if (this.state.currentMenuTab === 'wazuh-dev') {
this.toolsPopoverToggle();
} else if (this.state.currentMenuTab === 'settings') {
this.settingsPopoverToggle();
} else if (this.state.currentMenuTab === 'security') {
Expand Down Expand Up @@ -628,19 +663,20 @@ class WzMenu extends Component {
<EuiButtonEmpty
className={
'wz-menu-button ' +
(this.state.currentMenuTab === "wazuh-dev" && !this.isAnyPopoverOpen()
(this.state.currentMenuTab === "wazuh-dev" && !this.isAnyPopoverOpen() || (this.state.isToolsPopoverOpen)
? 'wz-menu-active'
: '')}
color="text"
href="#/wazuh-dev"
onClick={() => {
this.setMenuItem('wazuh-dev');
this.setState({ menuOpened: false });
}}
onClick={this.onClickToolsButton.bind(this)}
>
<EuiIcon type="console" color="primary" size="m" />
<span className="wz-menu-button-title ">Dev Tools</span>
<span className="wz-menu-button-title ">Tools</span>
<span className="flex"></span>
{this.state.isToolsPopoverOpen && (
<EuiIcon color="subdued" type="arrowRight" />
)}
</EuiButtonEmpty>

<EuiSpacer size='xl'></EuiSpacer>
<EuiButtonEmpty
className={
Expand Down Expand Up @@ -716,6 +752,13 @@ class WzMenu extends Component {
></MenuSecurity>
)}

{ this.state.isToolsPopoverOpen && (
<MenuTools
currentMenuTab={this.state.currentMenuTab}
closePopover={() => this.setState({ menuOpened: false })}
></MenuTools>
)}

{/*this.state.hover === 'overview' */this.state.isOverviewPopoverOpen && currentAgent.id && (
<EuiFlexGroup className="wz-menu-agent-info">
{/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { DynamicHeight } from '../../utils/dynamic-height';
import { AppState } from '../../react-services/app-state';
import { GenericRequest } from '../../react-services/generic-request';
import store from '../../redux/store';
import { updateGlobalBreadcrumb } from '../../redux/actions/globalBreadcrumbActions';
import { WzRequest } from '../../react-services/wz-request';
import { ErrorHandler } from '../../react-services/error-handler';
import { getUiSettings } from '../../kibana-services';
Expand Down Expand Up @@ -57,8 +56,6 @@ export class DevToolsController {
) {
AppState.setWzMenu();
}
const breadcrumb = [{ text: '' }, { text: 'Dev Tools' }];
store.dispatch(updateGlobalBreadcrumb(breadcrumb));
$(this.$document[0]).keydown(e => {
if (!this.multipleKeyPressed.includes(e.which)) {
this.multipleKeyPressed.push(e.which);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ import './management';
import './agent';
import './settings';
import './security';
import './dev-tools';
import './tools';
import './misc';
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class WzManagementMain extends Component {
(section === 'statistics' && <WzStatistics />) ||
(section === 'logs' && <WzLogs />) ||
(section === 'configuration' && <WzConfiguration {...this.props.configurationProps} />) ||
(ruleset.includes(section) && <WzRuleset clusterStatus={this.props.clusterStatus} />)}
(ruleset.includes(section) && <WzRuleset logtestProps={this.props.logtestProps} clusterStatus={this.props.clusterStatus} />)}
</Fragment>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,29 @@ export default class WzRuleset extends Component {
componentWillUnmount() {
this._isMount = false;
// When the component is going to be unmounted the ruleset state is reset
const {
ruleInfo,
decoderInfo,
listInfo,
fileContent,
addingRulesetFile
} = this.state;
if (!window.location.href.includes('rules?tab=rules') &&
(!ruleInfo && !decoderInfo && !listInfo && !fileContent,
!addingRulesetFile)
const { ruleInfo, decoderInfo, listInfo, fileContent, addingRulesetFile } = this.state;
if (
!window.location.href.includes('rules?tab=rules') &&
(!ruleInfo && !decoderInfo && !listInfo && !fileContent, !addingRulesetFile)
) {
this.store.dispatch({ type: 'RESET' });
}
}

render() {
const {
ruleInfo,
decoderInfo,
listInfo,
fileContent,
addingRulesetFile
} = this.state;
const { ruleInfo, decoderInfo, listInfo, fileContent, addingRulesetFile } = this.state;

return (
<WzReduxProvider>
{(ruleInfo && <WzRuleInfo />) ||
(decoderInfo && <WzDecoderInfo />) ||
(listInfo && <WzListEditor clusterStatus={this.props.clusterStatus} />) ||
((fileContent || addingRulesetFile) && <WzRulesetEditor clusterStatus={this.props.clusterStatus}/>) || (
<WzRulesetOverview clusterStatus={this.props.clusterStatus} />
)}
((fileContent || addingRulesetFile) && (
<WzRulesetEditor
logtestProps={this.props.logtestProps}
clusterStatus={this.props.clusterStatus}
/>
)) || <WzRulesetOverview clusterStatus={this.props.clusterStatus} />}
</WzReduxProvider>
);
}
Expand Down
Loading

0 comments on commit 6e57023

Please sign in to comment.