diff --git a/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx b/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx index a5fe3e09eb..278a6224b8 100644 --- a/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx +++ b/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx @@ -9,31 +9,24 @@ * * Find more information about this on the LICENSE file. */ -import React, { Fragment, Component } from 'react'; +import React, { Component } from 'react'; import { - EuiButtonIcon, - EuiCard, - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, - EuiIcon, EuiPage, EuiPageBody, EuiSpacer, - EuiTabbedContent, EuiText, EuiTitle, - EuiToolTip } from '@elastic/eui'; -import WzModuleGuide from './module-guide'; import WzSampleData from './sample-data'; import modeGuides from './guides'; -import { WAZUH_MODULES } from '../../../common/wazuh-modules'; -import { updateGlobalBreadcrumb } from '../../redux/actions/globalBreadcrumbActions'; -import store from '../../redux/store'; +import { compose } from 'redux'; + +import { withGlobalBreadcrumb } from '../common/hocs'; const guides = Object.keys(modeGuides).map(key => modeGuides[key]).sort((a,b) => { if (a.name < b.name) { return -1 } @@ -50,7 +43,7 @@ interface IStateWzAddModulesData { selectedGuideCategory: any }; -export default class WzAddModulesData extends Component{ +class WzAddModulesData extends Component{ tabs: any constructor(props){ super(props); @@ -96,17 +89,7 @@ export default class WzAddModulesData extends Component { this.setState({ guide }); } @@ -117,7 +100,7 @@ export default class WzAddModulesData extends Component guide.category === category) : guides; } render(){ - // const { guide, selectedGuideCategory } = this.state; // DON'T DELETE. IT'S FOR MODULE GUIDES. + // const { guide, selectedGuideCategory } = this.state; // DON'T DELETE. IT'S FOR MODULE GUIDES. return ( @@ -177,4 +160,14 @@ export default class WzAddModulesData extends Component ) } -} \ No newline at end of file +} + + +export default compose( + withGlobalBreadcrumb(props => { + return [ + { text: '' }, + { text: 'Server data' } + ]; + }), +)(WzAddModulesData); diff --git a/plugins/main/public/components/agents/stats/agent-stats.tsx b/plugins/main/public/components/agents/stats/agent-stats.tsx index f58b63992c..635257e98d 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.tsx @@ -18,21 +18,33 @@ import { EuiPage, EuiPageBody, EuiSpacer, - EuiText + EuiText, } from '@elastic/eui'; -import { withGlobalBreadcrumb, withReduxProvider, withGuard, withUserAuthorizationPrompt, withErrorBoundary } from '../../common/hocs'; +import { + withGlobalBreadcrumb, + withReduxProvider, + withGuard, + withUserAuthorizationPrompt, + withErrorBoundary, +} from '../../common/hocs'; import { compose } from 'redux'; import { WzRequest, formatUIDate } from '../../../react-services'; import { AgentStatTable } from './table'; -import { PromptNoActiveAgentWithoutSelect, PromptAgentFeatureVersion } from '../prompts'; +import { + PromptNoActiveAgentWithoutSelect, + PromptAgentFeatureVersion, +} from '../prompts'; import { UIErrorLog, UI_ERROR_SEVERITIES, UILogLevel, UIErrorSeverity, } from '../../../react-services/error-orchestrator/types'; -import { API_NAME_AGENT_STATUS, UI_LOGGER_LEVELS } from '../../../../common/constants'; +import { + API_NAME_AGENT_STATUS, + UI_LOGGER_LEVELS, +} from '../../../../common/constants'; import { getErrorOrchestrator } from '../../../react-services/common-services'; const tableColumns = [ @@ -50,83 +62,111 @@ const tableColumns = [ field: 'bytes', name: 'Bytes', sortable: true, - } -]; - -const statsAgents: {title: string, field: string, render?: (value) => any}[] = [ - { - title: 'Status', - field: 'status', - }, - { - title: 'Buffer', - field: 'buffer_enabled', - render: (value) => value ? 'enabled' : 'disabled' - }, - { - title: 'Message buffer', - field: 'msg_buffer' - }, - { - title: 'Messages count', - field: 'msg_count' - }, - { - title: 'Messages sent', - field: 'msg_sent' - }, - { - title: 'Last ack', - field: 'last_ack', - render: formatUIDate }, - { - title: 'Last keep alive', - field: 'last_keepalive', - render: formatUIDate - } ]; +const statsAgents: { title: string; field: string; render?: (value) => any }[] = + [ + { + title: 'Status', + field: 'status', + }, + { + title: 'Buffer', + field: 'buffer_enabled', + render: value => (value ? 'enabled' : 'disabled'), + }, + { + title: 'Message buffer', + field: 'msg_buffer', + }, + { + title: 'Messages count', + field: 'msg_count', + }, + { + title: 'Messages sent', + field: 'msg_sent', + }, + { + title: 'Last ack', + field: 'last_ack', + render: formatUIDate, + }, + { + title: 'Last keep alive', + field: 'last_keepalive', + render: formatUIDate, + }, + ]; + export const MainAgentStats = compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb(({agent}) => [ + withGlobalBreadcrumb(({ agent }) => [ { - text: '' + text: '', }, { - text: 'Agents', - href: "#/agents-preview" + text: 'IT Hygiene', }, { agent }, { - text: 'Stats' + text: 'Stats', }, ]), - withUserAuthorizationPrompt(({agent}) => [[ - {action: 'agent:read', resource: `agent:id:${agent.id}`}, - ...(agent.group || []).map(group => ({ action: 'agent:read', resource: `agent:group:${group}` })) - ]]), - withGuard(({agent}) => agent.status !== API_NAME_AGENT_STATUS.ACTIVE, PromptNoActiveAgentWithoutSelect), - withGuard(({agent}) => { - const [major, minor, patch] = agent.version.replace('Wazuh v','').split('.').map(value => parseInt(value)); - return !(major >= 4 && minor >= 2 && patch >= 0) - }, () => ) + withUserAuthorizationPrompt(({ agent }) => [ + [ + { action: 'agent:read', resource: `agent:id:${agent.id}` }, + ...(agent.group || []).map(group => ({ + action: 'agent:read', + resource: `agent:group:${group}`, + })), + ], + ]), + withGuard( + ({ agent }) => agent.status !== API_NAME_AGENT_STATUS.ACTIVE, + PromptNoActiveAgentWithoutSelect, + ), + withGuard( + ({ agent }) => { + const [major, minor, patch] = agent.version + .replace('Wazuh v', '') + .split('.') + .map(value => parseInt(value)); + return !(major >= 4 && minor >= 2 && patch >= 0); + }, + () => ( + + ), + ), )(AgentStats); -function AgentStats({agent}){ +function AgentStats({ agent }) { const [loading, setLoading] = useState(); const [dataStatLogcollector, setDataStatLogcollector] = useState({}); const [dataStatAgent, setDataStatAgent] = useState(); useEffect(() => { - (async function(){ + (async function () { setLoading(true); - try{ - const responseDataStatLogcollector = await WzRequest.apiReq('GET', `/agents/${agent.id}/stats/logcollector`, {}); - const responseDataStatAgent = await WzRequest.apiReq('GET', `/agents/${agent.id}/stats/agent`, {}); - setDataStatLogcollector(responseDataStatLogcollector?.data?.data?.affected_items?.[0] || {}); - setDataStatAgent(responseDataStatAgent?.data?.data?.affected_items?.[0] || undefined); - } catch(error) { + try { + const responseDataStatLogcollector = await WzRequest.apiReq( + 'GET', + `/agents/${agent.id}/stats/logcollector`, + {}, + ); + const responseDataStatAgent = await WzRequest.apiReq( + 'GET', + `/agents/${agent.id}/stats/agent`, + {}, + ); + setDataStatLogcollector( + responseDataStatLogcollector?.data?.data?.affected_items?.[0] || {}, + ); + setDataStatAgent( + responseDataStatAgent?.data?.data?.affected_items?.[0] || undefined, + ); + } catch (error) { const options: UIErrorLog = { context: `${AgentStats.name}.useEffect`, level: UI_LOGGER_LEVELS.ERROR as UILogLevel, @@ -141,18 +181,31 @@ function AgentStats({agent}){ } finally { setLoading(false); } - })() + })(); }, []); return ( - + {statsAgents.map(stat => ( - {stat.title}: {loading ? : {dataStatAgent !== undefined ? (stat.render ? stat.render(dataStatAgent[stat.field]) : dataStatAgent?.[stat.field]) : '-'}} + + {stat.title}:{' '} + {loading ? ( + + ) : ( + + {dataStatAgent !== undefined + ? stat.render + ? stat.render(dataStatAgent[stat.field]) + : dataStatAgent?.[stat.field] + : '-'} + + )} + ))} @@ -186,5 +239,5 @@ function AgentStats({agent}){ - ) + ); } diff --git a/plugins/main/public/components/agents/syscollector/main.tsx b/plugins/main/public/components/agents/syscollector/main.tsx index d3ec5e566e..6868613e59 100644 --- a/plugins/main/public/components/agents/syscollector/main.tsx +++ b/plugins/main/public/components/agents/syscollector/main.tsx @@ -11,7 +11,29 @@ */ import React from 'react'; -import { withErrorBoundary } from '../../common/hocs'; +import { + withErrorBoundary, + withGlobalBreadcrumb, + withReduxProvider, +} from '../../common/hocs'; import { SyscollectorInventory } from './inventory'; +import { compose } from 'redux'; -export const MainSyscollector = withErrorBoundary(SyscollectorInventory); +export const MainSyscollector = compose( + withReduxProvider, + withErrorBoundary, + withGlobalBreadcrumb(({ agent }) => { + return [ + { + text: '', + }, + { + text: 'IT Hygiene', + }, + { agent }, + { + text: 'Inventory Data', + }, + ]; + }), +)(SyscollectorInventory); diff --git a/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.scss b/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.scss deleted file mode 100644 index 21a4177b19..0000000000 --- a/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.scss +++ /dev/null @@ -1,38 +0,0 @@ -.euiBreadcrumbs--truncate .wz-global-breadcrumb .euiBreadcrumb:not(.euiBreadcrumb--collapsed) span.euiToolTipAnchor { - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: text-bottom; -} - -.wz-global-breadcrumb { - font-size: 14px; - padding: 0px; -} - -.wz-global-breadcrumb-btn { - max-width: unset !important; -} - -@media screen and (-webkit-min-device-pixel-ratio: 0) { - - _::-webkit-full-page-media, - _:future, - :root, - .wz-global-breadcrumb { - line-height: 1.5; - } -} - -@-moz-document url-prefix() { - .wz-global-breadcrumb #breadcrumbNoTitle { - height: auto !important; - } -} - -// styles for opensearch >2.x - -.osdHeaderBreadcrumbs , -.osdHeaderBreadcrumbs--dark { - filter: none; -} diff --git a/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.tsx b/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.tsx index 60574fa8ed..db9e9fb4a5 100644 --- a/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.tsx +++ b/plugins/main/public/components/common/globalBreadcrumb/globalBreadcrumb.tsx @@ -1,9 +1,8 @@ import React, { Component } from 'react'; import { EuiBreadcrumbs } from '@elastic/eui'; import { connect } from 'react-redux'; -import './globalBreadcrumb.scss'; -import { AppNavigate } from '../../../react-services/app-navigate'; import { getAngularModule } from '../../../kibana-services'; +import { navigateAppURL } from '../../../react-services/navigate-app'; class WzGlobalBreadcrumb extends Component { props: { state: { breadcrumb: [{ agent; text }] } }; @@ -18,16 +17,15 @@ class WzGlobalBreadcrumb extends Component { } crumbs = () => { - const breadcrumbs = this.props.state.breadcrumb.map((breadcrumb) => + const breadcrumbs = this.props.state.breadcrumb.map(breadcrumb => breadcrumb.agent ? { className: 'euiLink euiLink--subdued osdBreadcrumbs', - onClick: (ev) => { + onClick: ev => { ev.stopPropagation(); - AppNavigate.navigateToModule(ev, 'agents', { - tab: 'welcome', - agent: breadcrumb.agent.id, - }); + navigateAppURL( + `/app/it-hygiene#/agents?tab=welcome&agent=${breadcrumb.agent.id}`, + ); this.router.reload(); }, truncate: true, @@ -36,7 +34,7 @@ class WzGlobalBreadcrumb extends Component { : { ...breadcrumb, className: 'osdBreadcrumbs', - } + }, ); // remove frist breadcrumb if it's empty @@ -52,12 +50,11 @@ class WzGlobalBreadcrumb extends Component {
{!!this.props.state.breadcrumb.length && ( )}
@@ -65,7 +62,7 @@ class WzGlobalBreadcrumb extends Component { } } -const mapStateToProps = (state) => { +const mapStateToProps = state => { return { state: state.globalBreadcrumbReducers, }; diff --git a/plugins/main/public/components/common/modules/agents-current-section-wrapper.tsx b/plugins/main/public/components/common/modules/agents-current-section-wrapper.tsx deleted file mode 100644 index df5eb8ce61..0000000000 --- a/plugins/main/public/components/common/modules/agents-current-section-wrapper.tsx +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Wazuh app - React component for building the Overview welcome screen. - * - * Copyright (C) 2015-2022 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 WzCurrentAgentsSection from './agents-current-section'; -import { compose } from 'redux'; -import { withErrorBoundary, withReduxProvider } from '../hocs'; - -export const WzCurrentAgentsSectionWrapper = compose (withErrorBoundary, withReduxProvider) (WzCurrentAgentsSection); diff --git a/plugins/main/public/components/common/modules/agents-current-section.tsx b/plugins/main/public/components/common/modules/agents-current-section.tsx deleted file mode 100644 index 12a519d6cf..0000000000 --- a/plugins/main/public/components/common/modules/agents-current-section.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Wazuh app - React component for building the Overview welcome screen. - * - * Copyright (C) 2015-2022 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 { - EuiTitle -} from '@elastic/eui'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; -import { updateCurrentTab } from '../../../redux/actions/appStateActions'; -import store from '../../../redux/store'; -import { connect } from 'react-redux'; -import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; -import { getAngularModule } from '../../../kibana-services'; - -// TODO: check if this component is deprecated, if so remove it. -// This component is wrapped by WzCurrentAgentsSectionWrapper -class WzCurrentAgentsSection extends Component { - constructor(props) { - super(props); - this.state = { - }; - } - - setGlobalBreadcrumb() { - if (WAZUH_MODULES[this.props.currentTab]) { - const breadcrumb = [ - { text: '' }, - { - text: 'Agents', - href: "#/agents-preview" - }, - { - text: `${this.props.agent.name} (${this.props.agent.id})`, - onClick: () => { - window.location.href = `#/agents?agent=${this.props.agent.id}`; - this.router.reload(); - }, - className: 'wz-global-breadcrumb-btn euiBreadcrumb--truncate', - truncate: false, - }, - { text: WAZUH_MODULES[this.props.currentTab].title }, - ]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - } - } - - async componentDidMount() { - this.setGlobalBreadcrumb(); - store.dispatch(updateCurrentTab(this.props.currentTab)); - const $injector = getAngularModule().$injector; - this.router = $injector.get('$route'); - } - - - async componentDidUpdate() { - if (this.props.state.currentTab !== this.props.currentTab) { - const forceUpdate = this.props.tabView === 'discover'; - if (this.props.state.currentTab) this.props.switchTab(this.props.state.currentTab, forceUpdate); - } - this.setGlobalBreadcrumb(); - } - - componentWillUnmount() { - store.dispatch(updateCurrentTab("")); - } - - render() { - return ( - - {this.props.currentTab && WAZUH_MODULES[this.props.currentTab] && WAZUH_MODULES[this.props.currentTab].title && ( - -

- {WAZUH_MODULES[this.props.currentTab].title} -

-
)} -
- ); - } -} - - - -const mapStateToProps = state => { - return { - state: state.appStateReducers, - }; -}; - -export default connect(mapStateToProps, null)(WzCurrentAgentsSection); \ No newline at end of file diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index 7cab6c416f..ea74feb706 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -11,21 +11,14 @@ */ import React, { Component, Fragment } from 'react'; -import ReactDOM from 'react-dom'; import { EuiFlexGroup, EuiFlexItem, EuiCallOut, - EuiHorizontalRule, - EuiSpacer, EuiTitle, - EuiIcon, - EuiPopover, EuiButtonEmpty, - EuiButton, } from '@elastic/eui'; import '../../common/modules/module.scss'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; import store from '../../../redux/store'; import { FilterHandler } from '../../../utils/filter-handler'; import { AppState } from '../../../react-services/app-state'; @@ -33,19 +26,21 @@ import { ReportingService } from '../../../react-services/reporting'; import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; import { AgentInfo } from '../../common/welcome/agents-info'; import { getAngularModule } from '../../../kibana-services'; +import { compose } from 'redux'; +import { withGlobalBreadcrumb } from '../hocs'; export class MainModuleAgent extends Component { props!: { - [key: string]: any + [key: string]: any; }; state: { - selectView: Boolean, - loadingReport: Boolean, - switchModule: Boolean, - showAgentInfo: Boolean + selectView: Boolean; + loadingReport: Boolean; + switchModule: Boolean; + showAgentInfo: Boolean; }; reportingService: ReportingService; - filterHandler: FilterHandler + filterHandler: FilterHandler; constructor(props) { super(props); @@ -55,57 +50,22 @@ export class MainModuleAgent extends Component { selectView: false, loadingReport: false, switchModule: false, - showAgentInfo: false + showAgentInfo: false, }; } - UNSAFE_componentWillReceiveProps(nextProps) { - if (nextProps.section !== this.props.section) { - this.setGlobalBreadcrumb(); - } - } - - setGlobalBreadcrumb() { - let breadcrumb; - if (this.props.section === 'welcome') { - breadcrumb = [ - { text: '' }, - { text: 'Agents', href: '#/agents-preview' }, - { text: this.props.agent.id } - ]; - } else { - breadcrumb = [ - { - text: '', - }, - { - text: 'Agents', - href: "#/agents-preview" - }, - { agent: this.props.agent }, - { - text: WAZUH_MODULES[this.props.section].title, - className: 'wz-global-breadcrumb-popover' - }, - ]; - } - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - $('#breadcrumbNoTitle').attr("title",""); - } - async componentDidMount() { const $injector = getAngularModule().$injector; this.router = $injector.get('$route'); - this.setGlobalBreadcrumb(); } showAgentInfo() { const elem = document.getElementsByClassName('wz-module-body-main')[0]; if (elem) { if (!this.state.showAgentInfo) { - elem.classList.add("wz-module-body-main-double"); + elem.classList.add('wz-module-body-main-double'); } else { - elem.classList.remove("wz-module-body-main-double"); + elem.classList.remove('wz-module-body-main-double'); } } this.setState({ showAgentInfo: !this.state.showAgentInfo }); @@ -114,31 +74,33 @@ export class MainModuleAgent extends Component { async startReport() { this.setState({ loadingReport: true }); const syscollectorFilters: any[] = []; - const agent = (this.props.agent || store.getState().appStateReducers.currentAgentData || {}).id || false; + const agent = + ( + this.props.agent || + store.getState().appStateReducers.currentAgentData || + {} + ).id || false; if (this.props.section === 'syscollector' && agent) { - syscollectorFilters.push( - this.filterHandler.managerQuery(agent, true) - ); - syscollectorFilters.push( - this.filterHandler.agentQuery(agent) - ); + syscollectorFilters.push(this.filterHandler.managerQuery(agent, true)); + syscollectorFilters.push(this.filterHandler.agentQuery(agent)); } await this.reportingService.startVis2Png( this.props.section, agent, - syscollectorFilters.length ? syscollectorFilters : null + syscollectorFilters.length ? syscollectorFilters : null, ); this.setState({ loadingReport: false }); } renderReportButton() { return ( - (this.props.section === 'syscollector' && + this.props.section === 'syscollector' && ( this.startReport()}> + onClick={async () => this.startReport()} + > Generate report @@ -149,81 +111,26 @@ export class MainModuleAgent extends Component { renderTitle() { return ( - + - +

{ window.location.href = `#/agents?agent=${this.props.agent.id}`; this.router.reload(); - }}> - {/* */} -  {this.props.agent.name}    + }} + > + +  {this.props.agent.name}   

- {/* - {this.props.agent.status} - */}
- {/* - this.showAgentInfo()} /> - */} - - {/* {this.props.section && ( - - this.setState({ switchModule: !this.state.switchModule })} style={{ cursor: 'pointer' }} - iconType="apps"> - Navigation  - - } - isOpen={this.state.switchModule} - closePopover={() => this.setState({ switchModule: false })} - repositionOnScroll={true} - anchorPosition="downLeft"> -
- -
- this.setState({ switchModule: false })}> -
-
- - - - - { - this.props.cardsProps.switchTab('syscollector'); - this.setState({ switchModule: false }); - }} - iconType="inspect"> - Inventory data - - - - { - this.props.cardsProps.switchTab('configuration'); - this.setState({ switchModule: false }); - }} - iconType="gear" > - Configuration - - - -
-
-
- )} */} -
{this.renderReportButton()}
@@ -232,59 +139,123 @@ export class MainModuleAgent extends Component { ); } - render() { const { agent, section, selectView } = this.props; const title = this.renderTitle(); - const ModuleTabView = (this.props.tabs || []).find(tab => tab.id === selectView); + const ModuleTabView = (this.props.tabs || []).find( + tab => tab.id === selectView, + ); return ( -
+
-
- {title} -
+
{title}
- {(agent && agent.os) && + {agent && agent.os && (
-
- {this.state.showAgentInfo && -
- -
+
+ > + {this.state.showAgentInfo && ( +
+ +
+ )} + {this.props.tabs && this.props.tabs.length && ( +
{this.props.renderTabs()} - + - {ModuleTabView && ModuleTabView.buttons && ModuleTabView.buttons.map((ModuleViewButton, index) => - typeof ModuleViewButton !== 'string' ? : null)} + {ModuleTabView && + ModuleTabView.buttons && + ModuleTabView.buttons.map( + (ModuleViewButton, index) => + typeof ModuleViewButton !== 'string' ? ( + + + + ) : null, + )}
- } + )}
{!['syscollector', 'configuration'].includes(section) && - ModuleTabView && ModuleTabView.component && - } + ModuleTabView && + ModuleTabView.component && ( + + )} - } - {(!agent || !agent.os) && + )} + {(!agent || !agent.os) && ( - - } + title='This agent has never connected' + color='warning' + iconType='alert' + > + )}
); } } + + +export default compose( + withGlobalBreadcrumb(({agent, section}) => { + if (section === 'welcome') { + return [ + { text: '' }, + { text: 'IT Hygiene' }, + { text: agent.id }, + ]; + } else { + return [ + { + text: '', + }, + { + text: 'IT Hygiene', + }, + { agent: agent }, + { + text: WAZUH_MODULES[section].title, + }, + ]; + } + }), +)(MainModuleAgent); diff --git a/plugins/main/public/components/common/modules/main-overview.tsx b/plugins/main/public/components/common/modules/main-overview.tsx index bc936b168f..b4ec0e48a3 100644 --- a/plugins/main/public/components/common/modules/main-overview.tsx +++ b/plugins/main/public/components/common/modules/main-overview.tsx @@ -10,127 +10,103 @@ * Find more information about this on the LICENSE file. */ -import React, { Component, Fragment } from 'react'; -import ReactDOM from 'react-dom'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiButtonIcon, - EuiTitle, - EuiToolTip, - EuiPopover, - EuiBadge, - EuiIcon, - EuiText, - EuiPopoverTitle, -} from '@elastic/eui'; +import React, { Component } from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import '../../common/modules/module.scss'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; - -import store from '../../../redux/store'; import { ReportingService } from '../../../react-services/reporting'; import { AppNavigate } from '../../../react-services/app-navigate'; -import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; - import { connect } from 'react-redux'; import { getDataPlugin } from '../../../kibana-services'; -const mapStateToProps = (state) => ({ +const mapStateToProps = state => ({ agent: state.appStateReducers.currentAgentData, }); -export const MainModuleOverview = connect(mapStateToProps)(class MainModuleOverview extends Component { - constructor(props) { - super(props); - this.reportingService = new ReportingService(); - this.state = { - selectView: false, - loadingReport: false, - isDescPopoverOpen: false, - }; - } - - setGlobalBreadcrumb() { - const currentAgent = store.getState().appStateReducers.currentAgentData; - if (WAZUH_MODULES[this.props.section]) { - let breadcrumb:any[] = [ - { - text: '', - }, - { - text: 'Modules', - href: '#/overview' - }, - ]; - if (currentAgent.id) { - breadcrumb.push({ - agent: currentAgent - }) - } - breadcrumb.push({ - text: ( - - - <> - {WAZUH_MODULES[this.props.section].title} - - - - - - - ), - truncate: false, - },) - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); +export const MainModuleOverview = connect(mapStateToProps)( + class MainModuleOverview extends Component { + constructor(props) { + super(props); + this.reportingService = new ReportingService(); + this.state = { + selectView: false, + loadingReport: false, + isDescPopoverOpen: false, + }; } - } - componentDidUpdate() { - this.setGlobalBreadcrumb(); - } - - async componentDidMount() { - const { module } = this.props; - const tabView = AppNavigate.getUrlParameter('tabView') || 'panels'; - const tab = AppNavigate.getUrlParameter('tab'); - const tabExceptions = ['sca', 'vuls']; - if (tabView && tabView !== this.props.selectView) { - if (tabView === 'panels' && tabExceptions.includes(tab)) { - // SCA & Vulnerabilities initial tab is inventory - this.props.onSelectedTabChanged(module.init); - } else { - this.props.onSelectedTabChanged(tabView); + async componentDidMount() { + const { module } = this.props; + const tabView = AppNavigate.getUrlParameter('tabView') || 'panels'; + const tab = AppNavigate.getUrlParameter('tab'); + const tabExceptions = ['sca', 'vuls']; + if (tabView && tabView !== this.props.selectView) { + if (tabView === 'panels' && tabExceptions.includes(tab)) { + // SCA & Vulnerabilities initial tab is inventory + this.props.onSelectedTabChanged(module.init); + } else { + this.props.onSelectedTabChanged(tabView); + } } - } - this.setGlobalBreadcrumb(); - const { filterManager } = getDataPlugin().query; - this.filterManager = filterManager; - } + const { filterManager } = getDataPlugin().query; + this.filterManager = filterManager; + } - render() { - const { section, selectView } = this.props; - const ModuleTabView = (this.props.tabs ||[]).find(tab => tab.id === selectView); - return ( -
-
- {this.props.tabs && this.props.tabs.length && ( -
- - {this.props.renderTabs()} - - - {ModuleTabView && ModuleTabView.buttons && ModuleTabView.buttons.map((ModuleViewButton, index) => - typeof ModuleViewButton !== 'string' ? : null)} - - - -
+ render() { + const { section, selectView } = this.props; + const ModuleTabView = (this.props.tabs || []).find( + tab => tab.id === selectView, + ); + return ( +
+
+ {this.props.tabs && this.props.tabs.length && ( +
+ + {this.props.renderTabs()} + + + {ModuleTabView && + ModuleTabView.buttons && + ModuleTabView.buttons.map((ModuleViewButton, index) => + typeof ModuleViewButton !== 'string' ? ( + + + + ) : null, + )} + + + +
+ )} +
+ {ModuleTabView && ModuleTabView.component && ( + )}
- {ModuleTabView && ModuleTabView.component && } -
- ); - } -}) + ); + } + }, +); diff --git a/plugins/main/public/components/common/modules/overview-current-section.tsx b/plugins/main/public/components/common/modules/overview-current-section.tsx index 4e8413f4bb..a7fb92d54b 100644 --- a/plugins/main/public/components/common/modules/overview-current-section.tsx +++ b/plugins/main/public/components/common/modules/overview-current-section.tsx @@ -20,29 +20,24 @@ import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; class WzCurrentOverviewSection extends Component { constructor(props) { super(props); - this.state = { - }; + this.state = {}; } setGlobalBreadcrumb() { const currentAgent = store.getState().appStateReducers.currentAgentData; - if(WAZUH_MODULES[this.props.currentTab]){ - const breadcrumb = currentAgent.id ? [ - { text: '' }, - { text: 'Modules', href: '#/overview' }, - { agent: currentAgent }, - { text: WAZUH_MODULES[this.props.currentTab].title}, - ] : - [ - { text: '' }, - { text: 'Modules', href: '#/overview' }, - - - { text: WAZUH_MODULES[this.props.currentTab].title}, - ]; + if (WAZUH_MODULES[this.props.currentTab]) { + const breadcrumb = currentAgent.id + ? [ + { text: '' }, + { + text: WAZUH_MODULES[this.props.currentTab].title, + }, + { agent: currentAgent }, + ] + : [{ text: '' }, { text: WAZUH_MODULES[this.props.currentTab].title }]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - $('#breadcrumbNoTitle').attr("title",""); + $('#breadcrumbNoTitle').attr('title', ''); } } @@ -51,39 +46,37 @@ class WzCurrentOverviewSection extends Component { store.dispatch(updateCurrentTab(this.props.currentTab)); } - async componentDidUpdate() { - if(this.props.state.currentTab !== this.props.currentTab){ + if (this.props.state.currentTab !== this.props.currentTab) { const forceUpdate = this.props.tabView === 'discover'; - if(this.props.state.currentTab) this.props.switchTab(this.props.state.currentTab,forceUpdate); + if (this.props.state.currentTab) + this.props.switchTab(this.props.state.currentTab, forceUpdate); } this.setGlobalBreadcrumb(); } - - componentWillUnmount(){ - store.dispatch(updateCurrentTab("")); + + componentWillUnmount() { + store.dispatch(updateCurrentTab('')); } render() { return ( - {/*this.props.currentTab && WAZUH_MODULES[this.props.currentTab] && WAZUH_MODULES[this.props.currentTab].title && ( + {/*this.props.currentTab && WAZUH_MODULES[this.props.currentTab] && WAZUH_MODULES[this.props.currentTab].title && (

{WAZUH_MODULES[this.props.currentTab].title}

)*/} -
+ ); } } - - const mapStateToProps = state => { return { state: state.appStateReducers, }; }; -export default connect(mapStateToProps, null)(WzCurrentOverviewSection); \ No newline at end of file +export default connect(mapStateToProps, null)(WzCurrentOverviewSection); diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 4d40211286..8e3b8ebd73 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -38,7 +38,6 @@ import { } from './components'; import { AgentInfo } from './agents-info'; import store from '../../../redux/store'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; import WzReduxProvider from '../../../redux/wz-redux-provider'; import MenuAgent from './components/menu-agent'; import './welcome.scss'; @@ -51,7 +50,7 @@ import { TabVisualizations } from '../../../factories/tab-visualizations'; import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; import { getAngularModule } from '../../../kibana-services'; import { hasAgentSupportModule } from '../../../react-services/wz-agents'; -import { withErrorBoundary, withReduxProvider } from '../hocs'; +import { withErrorBoundary, withGlobalBreadcrumb, withReduxProvider } from '../hocs'; import { compose } from 'redux'; import { API_NAME_AGENT_STATUS } from '../../../../common/constants'; import { webDocumentationLink } from '../../../../common/services/web_documentation'; @@ -59,6 +58,18 @@ import { webDocumentationLink } from '../../../../common/services/web_documentat export const AgentsWelcome = compose( withReduxProvider, withErrorBoundary, + withGlobalBreadcrumb(({ agent }) => { + return [ + { text: '' }, + { + text: 'IT Hygiene', + }, + { + text: `${agent.name}`, + truncate: true, + }, + ]; + }), )( class AgentsWelcome extends Component { _isMount = false; @@ -104,28 +115,11 @@ export const AgentsWelcome = compose( this.setState({ maxModules: maxModules, widthWindow: window.innerWidth }); }; - setGlobalBreadcrumb() { - const breadcrumb = [ - { text: '' }, - { - text: 'Agents', - href: '#/agents-preview', - }, - { - text: `${this.props.agent.name}`, - className: 'wz-global-breadcrumb-btn euiBreadcrumb--truncate', - truncate: false, - }, - ]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - } - async componentDidMount() { this._isMount = true; store.dispatch(updateCurrentAgentData(this.props.agent)); this.updateMenuAgents(); this.updateWidth(); - this.setGlobalBreadcrumb(); const tabVisualizations = new TabVisualizations(); tabVisualizations.removeAll(); tabVisualizations.setTab('welcome'); diff --git a/plugins/main/public/components/common/welcome/overview-welcome.js b/plugins/main/public/components/common/welcome/overview-welcome.js index 355aa72fd8..578ec047e9 100644 --- a/plugins/main/public/components/common/welcome/overview-welcome.js +++ b/plugins/main/public/components/common/welcome/overview-welcome.js @@ -16,162 +16,197 @@ import { StringsTools } from '../../../utils/strings-tools'; import { EuiCard, EuiIcon, - EuiPanel, EuiFlexItem, EuiFlexGroup, EuiSpacer, EuiFlexGrid, EuiCallOut, EuiPage, - EuiButton, - EuiButtonEmpty + EuiButtonEmpty, } from '@elastic/eui'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; import { updateCurrentTab } from '../../../redux/actions/appStateActions'; import store from '../../../redux/store'; import './welcome.scss'; import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; -import { withErrorBoundary } from '../hocs'; -import { LogoDocker, LogoGitHub, LogoGoogleCloud, LogoOffice365 } from '../logos'; - -export const OverviewWelcome = withErrorBoundary(class OverviewWelcome extends Component { - constructor(props) { - super(props); - this.strtools = new StringsTools(); - - this.state = { - extensions: this.props.extensions - }; - } - setGlobalBreadcrumb() { - const breadcrumb = [{ text: '' }, { text: 'Modules' }]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - } +import { + withErrorBoundary, + withGlobalBreadcrumb, + withReduxProvider, +} from '../hocs'; +import { + LogoDocker, + LogoGitHub, + LogoGoogleCloud, + LogoOffice365, +} from '../logos'; +import { compose } from 'redux'; - componentDidMount() { - this.setGlobalBreadcrumb(); - } +export const OverviewWelcome = compose( + withReduxProvider, + withErrorBoundary, + withGlobalBreadcrumb(props => { + return [ + { text: '' }, + { text: 'Overview' } + ]; + }) +)( + class OverviewWelcome extends Component { + constructor(props) { + super(props); + this.strtools = new StringsTools(); - buildTabCard(tab, icon) { - return ( - - } - className="homSynopsis__card" - title={WAZUH_MODULES[tab].title} - onClick={() => store.dispatch(updateCurrentTab(tab))} - data-test-subj={`overviewWelcome${this.strtools.capitalize(tab)}`} - description={WAZUH_MODULES[tab].description} - /> - - ); - } + this.state = { + extensions: this.props.extensions, + }; + } - addAgent() { - return ( - <> - - - No agents were added to this manager. Add agent} color="warning" iconType="alert"> - - - - - - ); - } + buildTabCard(tab, icon) { + return ( + + } + className='homSynopsis__card' + title={WAZUH_MODULES[tab].title} + onClick={() => store.dispatch(updateCurrentTab(tab))} + data-test-subj={`overviewWelcome${this.strtools.capitalize(tab)}`} + description={WAZUH_MODULES[tab].description} + /> + + ); + } - render() { - return ( - - + addAgent() { + return ( + <> - {this.props.agentsCountTotal == 0 && this.addAgent()} - - - - - - {this.buildTabCard('general', 'dashboardApp')} - {this.buildTabCard('fim', 'filebeatApp')} - {this.props.extensions.aws && - this.buildTabCard('aws', 'logoAWSMono')} - {this.props.extensions.office && - this.buildTabCard('office', LogoOffice365)} - {this.props.extensions.gcp && - this.buildTabCard('gcp', LogoGoogleCloud)} - {this.props.extensions.github && - this.buildTabCard('github', LogoGitHub)} - - - - - - - - {this.buildTabCard('pm', 'advancedSettingsApp')} - {this.props.extensions.audit && - this.buildTabCard('audit', 'monitoringApp')} - {this.props.extensions.oscap && - this.buildTabCard('oscap', 'codeApp')} - {this.props.extensions.ciscat && - this.buildTabCard('ciscat', 'auditbeatApp')} - {this.buildTabCard('sca', 'securityAnalyticsApp')} - - - - + + No agents were added to this manager.{' '} + + Add agent + + + } + color='warning' + iconType='alert' + > + + + + + ); + } - - - - - - - {this.buildTabCard('vuls', 'securityApp')} - {this.props.extensions.virustotal && - this.buildTabCard('virustotal', 'savedObjectsApp')} - {this.props.extensions.osquery && - this.buildTabCard('osquery', 'searchProfilerApp')} - {this.props.extensions.docker && - this.buildTabCard('docker', LogoDocker)} - {this.buildTabCard('mitre', 'spacesApp')} - {/* TODO- Change "spacesApp" icon*/} - - - + render() { + return ( + + + + + {this.props.agentsCountTotal == 0 && this.addAgent()} + + + + + + {this.buildTabCard('general', 'dashboardApp')} + {this.buildTabCard('fim', 'filebeatApp')} + {this.props.extensions.aws && + this.buildTabCard('aws', 'logoAWSMono')} + {this.props.extensions.office && + this.buildTabCard('office', LogoOffice365)} + {this.props.extensions.gcp && + this.buildTabCard('gcp', LogoGoogleCloud)} + {this.props.extensions.github && + this.buildTabCard('github', LogoGitHub)} + + + + + + + + {this.buildTabCard('pm', 'advancedSettingsApp')} + {this.props.extensions.audit && + this.buildTabCard('audit', 'monitoringApp')} + {this.props.extensions.oscap && + this.buildTabCard('oscap', 'codeApp')} + {this.props.extensions.ciscat && + this.buildTabCard('ciscat', 'auditbeatApp')} + {this.buildTabCard('sca', 'securityAnalyticsApp')} + + + + - - - - {!this.props.extensions.pci && - !this.props.extensions.gdpr && - !this.props.extensions.hipaa && - !this.props.extensions.tsc && - !this.props.extensions.nist && ( - - - - Click the icon to show - regulatory compliance extensions. -

- } - color="success" - iconType="help" - /> -
-
- )} - {(this.props.extensions.pci || - this.props.extensions.gdpr || - this.props.extensions.hipaa || - this.props.extensions.tsc || - this.props.extensions.nist) && ( + + + + + + + {this.buildTabCard('vuls', 'securityApp')} + {this.props.extensions.virustotal && + this.buildTabCard('virustotal', 'savedObjectsApp')} + {this.props.extensions.osquery && + this.buildTabCard('osquery', 'searchProfilerApp')} + {this.props.extensions.docker && + this.buildTabCard('docker', LogoDocker)} + {this.buildTabCard('mitre', 'spacesApp')} + {/* TODO- Change "spacesApp" icon*/} + + + + + + + + {!this.props.extensions.pci && + !this.props.extensions.gdpr && + !this.props.extensions.hipaa && + !this.props.extensions.tsc && + !this.props.extensions.nist && ( + + + + Click the icon to + show regulatory compliance extensions. +

+ } + color='success' + iconType='help' + /> +
+
+ )} + {(this.props.extensions.pci || + this.props.extensions.gdpr || + this.props.extensions.hipaa || + this.props.extensions.tsc || + this.props.extensions.nist) && ( {this.props.extensions.pci && this.buildTabCard('pci', 'visTagCloud')} @@ -185,13 +220,14 @@ export const OverviewWelcome = withErrorBoundary(class OverviewWelcome extends C this.buildTabCard('hipaa', 'emsApp')} )} -
-
-
-
-
-
-
- ); - } -}) \ No newline at end of file + + +
+ + +
+
+ ); + } + }, +); diff --git a/plugins/main/public/components/security/main.tsx b/plugins/main/public/components/security/main.tsx index fff3f9d4f8..294917ba8c 100644 --- a/plugins/main/public/components/security/main.tsx +++ b/plugins/main/public/components/security/main.tsx @@ -57,7 +57,7 @@ const tabs = [ export const WzSecurity = compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb([{ text: '' }, { text: 'Security' }]), + withGlobalBreadcrumb([{ text: '' }, { text: 'RBAC' }]), )(() => { const dispatch = useDispatch(); diff --git a/plugins/main/public/components/wz-menu/wz-menu.js b/plugins/main/public/components/wz-menu/wz-menu.js index 621f833ab9..16bcb7e731 100644 --- a/plugins/main/public/components/wz-menu/wz-menu.js +++ b/plugins/main/public/components/wz-menu/wz-menu.js @@ -15,1027 +15,632 @@ import { EuiFlexGroup, EuiFlexItem, EuiPopover, - EuiIcon, EuiButtonEmpty, EuiCallOut, EuiToolTip, EuiLoadingSpinner, EuiFormRow, EuiSelect, - EuiSpacer } from '@elastic/eui'; import { AppState } from '../../react-services/app-state'; import { PatternHandler } from '../../react-services/pattern-handler'; import { WazuhConfig } from '../../react-services/wazuh-config'; import { connect } from 'react-redux'; import WzReduxProvider from '../../redux/wz-redux-provider'; -import { updateCurrentAgentData, showExploreAgentModalGlobal } from '../../redux/actions/appStateActions'; +import { updateCurrentAgentData } from '../../redux/actions/appStateActions'; 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, getDataPlugin, } from '../../kibana-services'; import { GenericRequest } from '../../react-services/generic-request'; import { ApiCheck } from '../../react-services/wz-api-check'; import { WzGlobalBreadcrumbWrapper } from '../common/globalBreadcrumb/globalBreadcrumbWrapper'; -import { AppNavigate } from '../../react-services/app-navigate'; -import WzTextWithTooltipIfTruncated from '../../components/common/wz-text-with-tooltip-if-truncated'; import { withWindowSize } from '../../components/common/hocs/withWindowSize'; import { UI_LOGGER_LEVELS } from '../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../react-services/error-orchestrator/types'; -import { getErrorOrchestrator } from '../../react-services/common-services' -import { getThemeAssetURL, getAssetURL } from '../../utils/assets'; -import { AgentStatus } from '../agents/agent-status'; - +import { getErrorOrchestrator } from '../../react-services/common-services'; const sections = { - 'overview': 'overview', - 'manager': 'manager', + overview: 'overview', + manager: 'manager', 'agents-preview': 'agents-preview', - 'agents': 'agents-preview', - 'settings': 'settings', + agents: 'agents-preview', + settings: 'settings', 'wazuh-dev': 'wazuh-dev', 'health-check': 'health-check', - 'security': 'security' + security: 'security', }; -export const WzMenu = withWindowSize(class WzMenu extends Component { - constructor(props) { - super(props); - this.state = { - showMenu: false, - menuOpened: false, - currentMenuTab: '', - currentAPI: '', - APIlist: [], - showSelector: false, - theresPattern: false, - currentPattern: '', - patternList: [], - currentSelectedPattern: '', - isManagementPopoverOpen: false, - isOverviewPopoverOpen: false - }; - this.store = store; - this.genericReq = GenericRequest; - this.wazuhConfig = new WazuhConfig(); - this.indexPatterns = getDataPlugin().indexPatterns; - this.isLoading = false; - } +export const WzMenu = withWindowSize( + class WzMenu extends Component { + constructor(props) { + super(props); + this.state = { + showMenu: false, + menuOpened: false, + currentMenuTab: '', + currentAPI: '', + APIlist: [], + showSelector: false, + theresPattern: false, + currentPattern: '', + patternList: [], + currentSelectedPattern: '', + isManagementPopoverOpen: false, + isOverviewPopoverOpen: false, + }; + this.store = store; + this.genericReq = GenericRequest; + this.wazuhConfig = new WazuhConfig(); + this.indexPatterns = getDataPlugin().indexPatterns; + this.isLoading = false; + } - async componentDidMount() { - const $injector = getAngularModule().$injector; - this.router = $injector.get('$route'); - try { - const result = await this.genericReq.request('GET', '/hosts/apis', {}); - const APIlist = (result || {}).data || []; - if (APIlist.length) { - const { id: apiId } = JSON.parse(AppState.getCurrentAPI()); - const filteredApi = APIlist.filter(api => api.id === apiId); - const selectedApi = filteredApi[0]; - if (selectedApi) { - const apiData = await ApiCheck.checkStored(selectedApi.id); - //update cluster info - const cluster_info = (((apiData || {}).data || {}).data || {}) - .cluster_info; - if (cluster_info) { - AppState.setClusterInfo(cluster_info); + async componentDidMount() { + const $injector = getAngularModule().$injector; + this.router = $injector.get('$route'); + try { + const result = await this.genericReq.request('GET', '/hosts/apis', {}); + const APIlist = result?.data || []; + if (APIlist.length) { + const { id: apiId } = JSON.parse(AppState.getCurrentAPI()); + const filteredApi = APIlist.filter(api => api.id === apiId); + const selectedApi = filteredApi[0]; + if (selectedApi) { + const apiData = await ApiCheck.checkStored(selectedApi.id); + //update cluster info + const cluster_info = apiData?.data?.data?.cluster_info; + if (cluster_info) { + AppState.setClusterInfo(cluster_info); + } } } + } catch (error) { + const options = { + context: `${WzMenu.name}.componentDidMount`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.CRITICAL, + store: true, + display: true, + error: { + error: error, + message: error.message || error, + title: error.name || error, + }, + }; + getErrorOrchestrator().handleError(options); } - } catch (error) { - const options = { - context: `${WzMenu.name}.componentDidMount`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.CRITICAL, - store: true, - display: true, - error: { - error: error, - message: error.message || error, - title: error.name || error, - }, - }; - getErrorOrchestrator().handleError(options); } - } - showToast = (color, title, text, time) => { - getToasts().add({ - color: color, - title: title, - text: text, - toastLifeTimeMs: time - }); - }; - - getCurrentTab() { - const currentWindowLocation = window.location.hash; - let currentTab = ''; - Object.keys(sections).some((section) => { - if (currentWindowLocation.match(`#/${section}`)) { - currentTab = sections[section]; - return true; - } - }); - return currentTab; - } + showToast = (color, title, text, time) => { + getToasts().add({ + color: color, + title: title, + text: text, + toastLifeTimeMs: time, + }); + }; - loadApiList = async () => { - const result = await this.genericReq.request('GET', '/hosts/apis', {}); - const APIlist = (result || {}).data || []; - if (APIlist.length) this.setState({ APIlist }); - }; + getCurrentTab() { + const currentWindowLocation = window.location.hash; + let currentTab = ''; + Object.keys(sections).some(section => { + if (currentWindowLocation.match(`#/${section}`)) { + currentTab = sections[section]; + return true; + } + }); + return currentTab; + } - loadIndexPatternsList = async () => { - try { - let list = await PatternHandler.getPatternList('api'); - if (!list) return; - this.props?.appConfig?.data?.['ip.ignore']?.length && (list = list.filter(indexPattern => !this.props?.appConfig?.data?.['ip.ignore'].includes(indexPattern.title))); + loadApiList = async () => { + const result = await this.genericReq.request('GET', '/hosts/apis', {}); + const APIlist = (result || {}).data || []; + if (APIlist.length) this.setState({ APIlist }); + }; - // Abort if we have disabled the pattern selector - if (!AppState.getPatternSelector()) return; + loadIndexPatternsList = async () => { + try { + let list = await PatternHandler.getPatternList('api'); + if (!list) return; + this.props?.appConfig?.data?.['ip.ignore']?.length && + (list = list.filter( + indexPattern => + !this.props?.appConfig?.data?.['ip.ignore'].includes( + indexPattern.title, + ), + )); + + // Abort if we have disabled the pattern selector + if (!AppState.getPatternSelector()) return; + + let filtered = false; + // If there is no current pattern, fetch it + if (!AppState.getCurrentPattern()) { + AppState.setCurrentPattern(list[0].id); + } else { + // Check if the current pattern cookie is valid + filtered = list.find(item => + item.id.includes(AppState.getCurrentPattern()), + ); + if (!filtered) AppState.setCurrentPattern(list[0].id); + } - let filtered = false; - // If there is no current pattern, fetch it - if (!AppState.getCurrentPattern()) { - AppState.setCurrentPattern(list[0].id); - } else { - // Check if the current pattern cookie is valid - filtered = list.find(item => - item.id.includes(AppState.getCurrentPattern()) - ); - if (!filtered) AppState.setCurrentPattern(list[0].id); + const data = filtered + ? filtered + : await this.indexPatterns.get(AppState.getCurrentPattern()); + this.setState({ theresPattern: true, currentPattern: data.title }); + + // Getting the list of index patterns + if (list) { + this.setState({ + patternList: list, + currentSelectedPattern: AppState.getCurrentPattern(), + }); + } + } catch (error) { + throw error; } + }; - const data = filtered - ? filtered - : await this.indexPatterns.get(AppState.getCurrentPattern()); - this.setState({ theresPattern: true, currentPattern: data.title }); - - // Getting the list of index patterns - if (list) { - this.setState({ - patternList: list, - currentSelectedPattern: AppState.getCurrentPattern() - }); + async componentDidUpdate(prevProps) { + if (this.state.APIlist && !this.state.APIlist.length) { + this.loadApiList(); } - } catch (error) { - throw error; - } - } - - - async componentDidUpdate(prevProps) { - - if (this.state.APIlist && !this.state.APIlist.length) { - this.loadApiList(); - } - const { id: apiId } = JSON.parse(AppState.getCurrentAPI()); - const { currentAPI } = this.state; - const currentTab = this.getCurrentTab(); + const { id: apiId } = JSON.parse(AppState.getCurrentAPI()); + const { currentAPI } = this.state; + const currentTab = this.getCurrentTab(); - if (currentTab !== this.state.currentMenuTab) { - this.setState({ currentMenuTab: currentTab }); - } + if (currentTab !== this.state.currentMenuTab) { + this.setState({ currentMenuTab: currentTab }); + } - if(this.props.windowSize){ - this.showSelectorsInPopover = this.props.windowSize.width < 1100; - } + if (this.props.windowSize) { + this.showSelectorsInPopover = this.props.windowSize.width < 1100; + } - if ( - prevProps.state.showMenu !== this.props.state.showMenu || - (this.props.state.showMenu === true && this.state.showMenu === false) - ) { - this.load(); - } - if ((!currentAPI && apiId) || apiId !== currentAPI) { - this.setState({ currentAPI: apiId }); - } else { if ( - currentAPI && - this.props.state.currentAPI && - currentAPI !== this.props.state.currentAPI + prevProps.state.showMenu !== this.props.state.showMenu || + (this.props.state.showMenu === true && this.state.showMenu === false) ) { - this.setState({ currentAPI: this.props.state.currentAPI }); + this.load(); } - } - if(!_.isEqual(prevProps?.appConfig?.data?.['ip.ignore'], this.props?.appConfig?.data?.['ip.ignore'])){ - this.loadIndexPatternsList(); - } - } - - async load() { - try { - this.setState({ - showMenu: true, - isOverviewPopoverOpen: false, - isManagementPopoverOpen: false, - isSelectorsPopoverOpen: false - }); - - const currentTab = this.getCurrentTab(); - if (currentTab !== this.state.currentMenuTab) { - this.setState({ currentMenuTab: currentTab, hover: currentTab }); - } - let list = await PatternHandler.getPatternList('api'); - if (!list || (list && !list.length)) return; - this.props?.appConfig?.data?.['ip.ignore']?.length && (list = list.filter(indexPattern => !this.props?.appConfig?.data?.['ip.ignore'].includes(indexPattern.title))); - - // Abort if we have disabled the pattern selector - if (!AppState.getPatternSelector()) return; - - let filtered = false; - // If there is no current pattern, fetch it - if (!AppState.getCurrentPattern()) { - AppState.setCurrentPattern(list[0].id); + if ((!currentAPI && apiId) || apiId !== currentAPI) { + this.setState({ currentAPI: apiId }); } else { - // Check if the current pattern cookie is valid - filtered = list.filter(item => - item.id.includes(AppState.getCurrentPattern()) - ); - if (!filtered.length) AppState.setCurrentPattern(list[0].id); + if ( + currentAPI && + this.props.state.currentAPI && + currentAPI !== this.props.state.currentAPI + ) { + this.setState({ currentAPI: this.props.state.currentAPI }); + } } + if ( + !_.isEqual( + prevProps?.appConfig?.data?.['ip.ignore'], + this.props?.appConfig?.data?.['ip.ignore'], + ) + ) { + this.loadIndexPatternsList(); + } + } - const data = filtered - ? filtered - : await this.indexPatterns.get(AppState.getCurrentPattern()); - this.setState({ theresPattern: true, currentPattern: data.title }); - - // Getting the list of index patterns - if (list) { + async load() { + try { this.setState({ - patternList: list, - currentSelectedPattern: AppState.getCurrentPattern() + showMenu: true, + isOverviewPopoverOpen: false, + isManagementPopoverOpen: false, + isSelectorsPopoverOpen: false, }); + + const currentTab = this.getCurrentTab(); + if (currentTab !== this.state.currentMenuTab) { + this.setState({ currentMenuTab: currentTab, hover: currentTab }); + } + let list = await PatternHandler.getPatternList('api'); + if (!list || (list && !list.length)) return; + this.props?.appConfig?.data?.['ip.ignore']?.length && + (list = list.filter( + indexPattern => + !this.props?.appConfig?.data?.['ip.ignore'].includes( + indexPattern.title, + ), + )); + + // Abort if we have disabled the pattern selector + if (!AppState.getPatternSelector()) return; + + let filtered = false; + // If there is no current pattern, fetch it + if (!AppState.getCurrentPattern()) { + AppState.setCurrentPattern(list[0].id); + } else { + // Check if the current pattern cookie is valid + filtered = list.filter(item => + item.id.includes(AppState.getCurrentPattern()), + ); + if (!filtered.length) AppState.setCurrentPattern(list[0].id); + } + + const data = filtered + ? filtered + : await this.indexPatterns.get(AppState.getCurrentPattern()); + this.setState({ theresPattern: true, currentPattern: data.title }); + + // Getting the list of index patterns + if (list) { + this.setState({ + patternList: list, + currentSelectedPattern: AppState.getCurrentPattern(), + }); + } + } catch (error) { + const options = { + context: `${WzMenu.name}.load`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.BUSINESS, + store: true, + display: true, + error: { + error: error, + message: error.message || error, + title: error.name || error, + }, + }; + getErrorOrchestrator().handleError(options); } - } catch (error) { - const options = { - context: `${WzMenu.name}.load`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: true, - display: true, - error: { - error: error, - message: error.message || error, - title: error.name || error, - }, - }; - getErrorOrchestrator().handleError(options); + this.isLoading = false; } - this.isLoading = false; - } - changePattern = async (event) => { - try { - const newPattern = event.target; - if (!AppState.getPatternSelector()) return; - await PatternHandler.changePattern(newPattern.value); - this.setState({ currentSelectedPattern: newPattern.value }); - if (this.state.currentMenuTab !== 'wazuh-dev') { - this.router.reload(); - } + changePattern = async event => { + try { + const newPattern = event.target; + if (!AppState.getPatternSelector()) return; + await PatternHandler.changePattern(newPattern.value); + this.setState({ currentSelectedPattern: newPattern.value }); + if (this.state.currentMenuTab !== 'wazuh-dev') { + this.router.reload(); + } - if (newPattern?.id === 'selectIndexPatternBar') { - this.updatePatternAndApi(); + if (newPattern?.id === 'selectIndexPatternBar') { + this.updatePatternAndApi(); + } + } catch (error) { + const options = { + context: `${WzMenu.name}.changePattern`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.BUSINESS, + store: false, + display: true, + error: { + error: error, + message: error.message || error, + title: `Error changing the Index Pattern`, + }, + }; + getErrorOrchestrator().handleError(options); } - } catch (error) { - const options = { - context: `${WzMenu.name}.changePattern`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: false, - display: true, - error: { - error: error, - message: error.message || error, - title: `Error changing the Index Pattern`, - }, - }; - getErrorOrchestrator().handleError(options); - } - }; + }; - updatePatternAndApi = () => { - this.setState({ menuOpened: false, hover: this.state.currentMenuTab }, async () => { - await this.loadApiList(); - await this.loadIndexPatternsList(); - }); - } + updatePatternAndApi = () => { + this.setState( + { menuOpened: false, hover: this.state.currentMenuTab }, + async () => { + await this.loadApiList(); + await this.loadIndexPatternsList(); + }, + ); + }; - /** - * @param {String} id - * @param {Object} clusterInfo - * Updates the wazuh registry of an specific api id - */ - updateClusterInfoInRegistry = async (id, clusterInfo) => { - try { - const url = `/hosts/update-hostname/${id}`; - await this.genericReq.request('PUT', url, { - cluster_info: clusterInfo - }); - } catch (error) { - return Promise.reject(error); - } - }; + /** + * @param {String} id + * @param {Object} clusterInfo + * Updates the wazuh registry of an specific api id + */ + updateClusterInfoInRegistry = async (id, clusterInfo) => { + try { + const url = `/hosts/update-hostname/${id}`; + await this.genericReq.request('PUT', url, { + cluster_info: clusterInfo, + }); + } catch (error) { + return Promise.reject(error); + } + }; - changeAPI = async event => { - try { - const apiId = event.target[event.target.selectedIndex]; - const apiEntry = this.state.APIlist.filter(item => { - return item.id === apiId.value; - }); - const response = await ApiCheck.checkApi(apiEntry[0]); - const clusterInfo = response.data || {}; - const apiData = this.state.APIlist.filter(item => { - return item.id === apiId.value; - }); + changeAPI = async event => { + try { + const apiId = event.target[event.target.selectedIndex]; + const apiEntry = this.state.APIlist.filter(item => { + return item.id === apiId.value; + }); + const response = await ApiCheck.checkApi(apiEntry[0]); + const clusterInfo = response.data || {}; + const apiData = this.state.APIlist.filter(item => { + return item.id === apiId.value; + }); - this.updateClusterInfoInRegistry(apiId.value, clusterInfo); - apiData[0].cluster_info = clusterInfo; + this.updateClusterInfoInRegistry(apiId.value, clusterInfo); + apiData[0].cluster_info = clusterInfo; - AppState.setClusterInfo(apiData[0].cluster_info); - AppState.setCurrentAPI( - JSON.stringify({ name: apiData[0].manager, id: apiId.value }) - ); + AppState.setClusterInfo(apiData[0].cluster_info); + AppState.setCurrentAPI( + JSON.stringify({ name: apiData[0].manager, id: apiId.value }), + ); - if (this.state.currentMenuTab !== 'wazuh-dev') { - this.router.reload(); + if (this.state.currentMenuTab !== 'wazuh-dev') { + this.router.reload(); + } + } catch (error) { + const options = { + context: `${WzMenu.name}.changePattern`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.BUSINESS, + error: { + error: error, + message: error.message || error, + title: `Error changing the selected API`, + }, + }; + getErrorOrchestrator().handleError(options); } - } catch (error) { - const options = { - context: `${WzMenu.name}.changePattern`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - error: { - error: error, - message: error.message || error, - title: `Error changing the selected API`, - }, - }; - getErrorOrchestrator().handleError(options); - } - }; + }; - buildPatternSelector() { - return ( - - { - return { value: item.id, text: item.title } - }) - } - value={this.state.currentSelectedPattern} - onChange={this.changePattern} - aria-label="Index pattern selector" - /> - - ); - } + buildPatternSelector() { + return ( + + { + return { value: item.id, text: item.title }; + })} + value={this.state.currentSelectedPattern} + onChange={this.changePattern} + aria-label='Index pattern selector' + /> + + ); + } - buildApiSelector() { - return ( - - { - return { value: item.id, text: item.id } - }) - } - value={this.state.currentAPI} - onChange={this.changeAPI} - aria-label="API selector" - /> - - ); - } + buildApiSelector() { + return ( + + { + return { value: item.id, text: item.id }; + })} + value={this.state.currentAPI} + onChange={this.changeAPI} + aria-label='API selector' + /> + + ); + } - buildWazuhNotReadyYet() { - const container = document.getElementsByClassName('wazuhNotReadyYet'); - return ReactDOM.createPortal( - - - -

-
- {typeof this.props.state.wazuhNotReadyYet === "string" && this.props.state.wazuhNotReadyYet.includes('Restarting') && ( - -

- {' '} -    {' '} -

+ buildWazuhNotReadyYet() { + const container = document.getElementsByClassName('wazuhNotReadyYet'); + return ReactDOM.createPortal( + + + +

- )} - {this.props.state.wazuhNotReadyYet === - 'Wazuh could not be recovered.' && ( + {typeof this.props.state.wazuhNotReadyYet === 'string' && + this.props.state.wazuhNotReadyYet.includes('Restarting') && ( + +

+ {' '} +    {' '} +

+
+ )} + {this.props.state.wazuhNotReadyYet === + 'Wazuh could not be recovered.' && ( location.reload()} - className="WzNotReadyButton" + className='WzNotReadyButton' > Reload )} -
-
, - container[0] - ); - } - - setMenuItem(item) { - 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, - isSelectorsPopoverOpen: false - }; - }); - } - } - - settingsPopoverToggle() { - if (!this.state.isSettingsPopoverOpen) { - this.setState(() => { - return { - isSettingsPopoverOpen: true, - currentMenuTab: 'settings', - isOverviewPopoverOpen: false, - isManagementPopoverOpen: false, - isSecurityPopoverOpen: false, - isToolsPopoverOpen: false, - isSelectorsPopoverOpen: false - }; - }); +
+
, + container[0], + ); } - } - securityPopoverToggle() { - if (!this.state.isSecurityPopoverOpen) { - this.setState(() => { - return { - isSecurityPopoverOpen: true, - currentMenuTab: 'security', - isOverviewPopoverOpen: false, - isManagementPopoverOpen: false, - isSettingsPopoverOpen: false, - isToolsPopoverOpen: false, - isSelectorsPopoverOpen: false - }; + removeSelectedAgent() { + store.dispatch(updateCurrentAgentData({})); + if (window.location.href.includes('/agents?')) { + window.location.href = '#/agents-preview'; + this.router.reload(); + return; + } + const { filterManager } = getDataPlugin().query; + const currentAppliedFilters = filterManager.getFilters(); + const agentFilters = currentAppliedFilters.filter(x => { + return x.meta.key === 'agent.id'; }); - } - } - - managementPopoverToggle() { - if (!this.state.isManagementPopoverOpen) { - this.setState(() => { - return { - isManagementPopoverOpen: true, - currentMenuTab: 'manager', - isOverviewPopoverOpen: false, - isSettingsPopoverOpen: false, - isSecurityPopoverOpen: false, - isToolsPopoverOpen: false, - isSelectorsPopoverOpen: false - }; + agentFilters.map(x => { + filterManager.removeFilter(x); }); } - } - overviewPopoverToggle() { - if (!this.state.isOverviewPopoverOpen) { - this.setState(state => { - return { - isOverviewPopoverOpen: true, - currentMenuTab: 'overview', - isManagementPopoverOpen: false, - isSettingsPopoverOpen: false, - isSecurityPopoverOpen: false, - isToolsPopoverOpen: false, - isSelectorsPopoverOpen: false - }; - }); + thereAreSelectors() { + return ( + (AppState.getAPISelector() && + this.state.currentAPI && + this.state.APIlist && + this.state.APIlist.length > 1) || + !this.state.currentAPI || + (AppState.getPatternSelector() && + this.state.theresPattern && + this.state.patternList && + this.state.patternList.length > 1) + ); } - } - onClickToolsButton() { - this.setMenuItem('wazuh-dev'); - this.toolsPopoverToggle(); - } - - onClickSettingsButton() { - this.setMenuItem('settings'); - this.settingsPopoverToggle(); - } - - onClickSecurityButton() { - this.setMenuItem('security'); - this.securityPopoverToggle(); - } - - onClickManagementButton() { - this.setMenuItem('manager'); - this.managementPopoverToggle(); - } - - onClickOverviewButton() { - this.setMenuItem('overview'); - this.overviewPopoverToggle(); - } - - onClickAgentButton() { - this.setState({ menuOpened: false }); - window.location.href = '#/agents-preview'; - - } - - closeAllPopover() { - this.setState({ - isOverviewPopoverOpen: false, - isManagementPopoverOpen: false, - isSettingsPopoverOpen: false, - isToolsPopoverOpen: false, - isSelectorsPopoverOpen: false - }); - } - - isAnyPopoverOpen() { - return ( - this.state.isOverviewPopoverOpen || - this.state.isManagementPopoverOpen || - this.state.isSettingsPopoverOpen || - this.state.isSecurityPopoverOpen || - this.state.isToolsPopoverOpen || - this.state.isSelectorsPopoverOpen - ); - } + getApiSelectorComponent() { + let style = { minWidth: 100, textOverflow: 'ellipsis' }; + if (this.showSelectorsInPopover) { + style = { width: '100%', minWidth: 200 }; + } - switchMenuOpened = () => { - const pluginPlatformMenuBlockedOrOpened = document.body.classList.contains('euiBody--collapsibleNavIsDocked') || document.body.classList.contains('euiBody--collapsibleNavIsOpen'); - if (!this.state.menuOpened && this.state.currentMenuTab === 'manager') { - 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') { - this.securityPopoverToggle(); - } else { - this.closeAllPopover() + return ( + <> + +

API

+
+ +
+ { + return { value: item.id, text: item.id }; + })} + value={this.state.currentAPI} + onChange={this.changeAPI} + aria-label='API selector' + /> +
+
+ + ); } - this.setState({ menuOpened: !this.state.menuOpened, pluginPlatformMenuBlockedOrOpened, hover: this.state.currentMenuTab }, async () => { - await this.loadApiList(); - await this.loadIndexPatternsList(); - }); - }; - - removeSelectedAgent() { - store.dispatch(updateCurrentAgentData({})); - if (window.location.href.includes("/agents?")) { - window.location.href = "#/agents-preview"; - this.router.reload(); - return; - } - const { filterManager } = getDataPlugin().query; - const currentAppliedFilters = filterManager.getFilters(); - const agentFilters = currentAppliedFilters.filter(x => { - return x.meta.key === 'agent.id'; - }); - agentFilters.map(x => { - filterManager.removeFilter(x); - }); - } + getIndexPatternSelectorComponent() { + let style = { maxWidth: 200, maxHeight: 50 }; + if (this.showSelectorsInPopover) { + style = { width: '100%', maxHeight: 50, minWidth: 200 }; + } - thereAreSelectors() { - return ((AppState.getAPISelector() && this.state.currentAPI && this.state.APIlist && this.state.APIlist.length > 1) - || (!this.state.currentAPI) - || (AppState.getPatternSelector() && this.state.theresPattern && this.state.patternList && this.state.patternList.length > 1)) - } + return ( + <> + +

Index pattern

+
- getApiSelectorComponent() { - let style = { minWidth: 100, textOverflow: 'ellipsis' }; - if (this.showSelectorsInPopover){ - style = { width: '100%', minWidth: 200 }; + +
+ { + return { value: item.id, text: item.title }; + })} + value={this.state.currentSelectedPattern} + onChange={this.changePattern} + aria-label='Index pattern selector' + /> +
+
+ + ); } - return ( - <> - -

API

-
- -
- { - return { value: item.id, text: item.id } - }) - } - value={this.state.currentAPI} - onChange={this.changeAPI} - aria-label="API selector" - /> -
-
- - ) - } - - getIndexPatternSelectorComponent(){ - - let style = { maxWidth: 200, maxHeight: 50 }; - if (this.showSelectorsInPopover){ - style = { width: '100%', maxHeight: 50, minWidth: 200 }; + switchSelectorsPopOver() { + this.setState({ + isSelectorsPopoverOpen: !this.state.isSelectorsPopoverOpen, + }); } - return( - <> - -

Index pattern

-
- - -
- { - return { value: item.id, text: item.title } - }) - } - value={this.state.currentSelectedPattern} - onChange={this.changePattern} - aria-label="Index pattern selector" - /> -
-
- - - ) - } - - switchSelectorsPopOver(){ - this.setState({ isSelectorsPopoverOpen: !this.state.isSelectorsPopoverOpen }) - } - - render() { - const currentAgent = store.getState().appStateReducers.currentAgentData; - const thereAreSelectors = this.thereAreSelectors(); - - const menu = ( -
-
-
- { this.setState({ hover: "overview" }) }} - className={ - 'wz-menu-button ' + - (this.state.currentMenuTab === "overview" && !this.isAnyPopoverOpen() || (this.state.isOverviewPopoverOpen) - ? 'wz-menu-active' - : '') - } - color="text" - onClick={this.onClickOverviewButton.bind(this)} - > - - Modules - - - {/*this.state.hover === 'overview' */this.state.isOverviewPopoverOpen && ( - - )} - - - { this.setState({ hover: "manager" }) }} - className={ - 'wz-menu-button ' + - (this.state.currentMenuTab === "manager" && !this.isAnyPopoverOpen() || (this.state.isManagementPopoverOpen) - ? 'wz-menu-active' - : '') - } - color="text" - onClick={this.onClickManagementButton.bind(this)} - > - - Management - - {/*this.state.hover === 'manager' */ this.state.isManagementPopoverOpen && ( - - )} - - - { - this.setMenuItem('agents-preview'); - this.setState({ menuOpened: false }); - }} - > - - Agents - - - - - Tools - - {this.state.isToolsPopoverOpen && ( - - )} - - - - - - Security - - {this.state.isSecurityPopoverOpen && ( - - )} - - - - Settings - - {this.state.isSettingsPopoverOpen && ( - - )} - -
-
- -
- {/*this.state.hover === 'manager'*/ this.state.isManagementPopoverOpen && ( - this.setState({ menuOpened: false })} - > - )} - - {/*this.state.hover === 'settings'*/ this.state.isSettingsPopoverOpen && ( - this.setState({ menuOpened: false })} - > - )} - - {/*this.state.hover === 'security'*/ this.state.isSecurityPopoverOpen && ( - this.setState({ menuOpened: false })} - > - )} - - {this.state.isToolsPopoverOpen && ( - this.setState({ menuOpened: false })} - > - )} + render() { + const openSelectorsButton = ( + + this.switchSelectorsPopOver()} + size='s' + aria-label='Open selectors' + > + + ); - {/*this.state.hover === 'overview' */this.state.isOverviewPopoverOpen && currentAgent.id && ( - - - - - {currentAgent.name} - - - - - - { AppNavigate.navigateToModule(ev, 'agents', { "tab": "welcome", "agent": currentAgent.id }); this.router.reload(); this.setState({ menuOpened: false }) }}> - - - - - - - { store.dispatch(showExploreAgentModalGlobal({})); this.setState({ menuOpened: false }) }}> - - - - - - - { this.setState({ menuOpened: false }); this.removeSelectedAgent(); }}> - - - + const container = document.getElementsByClassName('euiBreadcrumbs'); + return ReactDOM.createPortal( + + {this.state.showMenu && ( + + + - - )} - - {this.state.isOverviewPopoverOpen && ( - this.setState({ menuOpened: false })} - > - )} -
-
- ); - - - const logotypeURL = getHttp().basePath.prepend(this.wazuhConfig.getConfig()['customization.enabled'] && this.wazuhConfig.getConfig()['customization.logo.app'] ? getAssetURL(this.wazuhConfig.getConfig()['customization.logo.app']) : getThemeAssetURL('logo.svg')); - const mainButton = ( - - ); - - - const openSelectorsButton = ( - - this.switchSelectorsPopOver()} - size="s" - aria-label="Open selectors"> - - ) - - - const container = document.getElementsByClassName('euiBreadcrumbs'); - const expandedHeader = document.getElementById('globalHeaderBars') - const wzExpandedHeader = expandedHeader.children.length === 1 - ? 'wz-expanded-header-min' - : 'wz-expanded-header-max' - return ReactDOM.createPortal( - - {this.state.showMenu && ( - - - - this.setState({ menuOpened: false })} - anchorPosition="downLeft" - panelPaddingSize='none' - hasArrow={false} - > - {menu} - - - - - - - - - <> - - - { !this.showSelectorsInPopover && this.state.patternList.length > 1 && - this.getIndexPatternSelectorComponent() - } + + <> + - { !this.showSelectorsInPopover && this.state.APIlist.length > 1 && - this.getApiSelectorComponent() - } + {!this.showSelectorsInPopover && + this.state.patternList.length > 1 && + this.getIndexPatternSelectorComponent()} - { this.showSelectorsInPopover && - (this.state.patternList.length > 1 || this.state.APIlist.length > 1) && - <> + {!this.showSelectorsInPopover && + this.state.APIlist.length > 1 && + this.getApiSelectorComponent()} - - 1 || + this.state.APIlist.length > 1) && ( + <> + + this.switchSelectorsPopOver()}> - { this.state.patternList.length > 1 && - - {this.getIndexPatternSelectorComponent()} - - } - { this.state.APIlist.length > 1 && - - {this.getApiSelectorComponent()} - - } - - - - - - } - {this.props.state.wazuhNotReadyYet && this.buildWazuhNotReadyYet()} - - - )} - - , container[0]); - } -}); + closePopover={() => this.switchSelectorsPopOver()} + > + {this.state.patternList.length > 1 && ( + + {this.getIndexPatternSelectorComponent()} + + )} + {this.state.APIlist.length > 1 && ( + + {this.getApiSelectorComponent()} + + )} + + + + )} + {this.props.state.wazuhNotReadyYet && + this.buildWazuhNotReadyYet()} + + )} + , + container[0], + ); + } + }, +); const mapStateToProps = state => { return { state: state.appStateReducers, - appConfig: state.appConfig + appConfig: state.appConfig, }; }; -export default connect( - mapStateToProps, - null -)(WzMenu); +export default connect(mapStateToProps, null)(WzMenu); diff --git a/plugins/main/public/controllers/agent/agents.js b/plugins/main/public/controllers/agent/agents.js index 4f0e7114a9..4c2f46c676 100644 --- a/plugins/main/public/controllers/agent/agents.js +++ b/plugins/main/public/controllers/agent/agents.js @@ -22,8 +22,6 @@ import { getToasts, getDataPlugin } from '../../kibana-services'; import { ShareAgent } from '../../factories/share-agent'; import { TabVisualizations } from '../../factories/tab-visualizations'; import { formatUIDate } from '../../react-services/time-service'; -import store from '../../redux/store'; -import { updateGlobalBreadcrumb } from '../../redux/actions/globalBreadcrumbActions'; import { hasAgentSupportModule } from '../../react-services/wz-agents'; import { UI_LOGGER_LEVELS } from '../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../react-services/error-orchestrator/types'; @@ -50,7 +48,7 @@ export class AgentsController { commonData, reportingService, visFactoryService, - csvReq + csvReq, ) { this.$scope = $scope; this.$location = $location; @@ -75,12 +73,7 @@ export class AgentsController { this.$scope.integrations = {}; this.$scope.selectedItem = 0; this.targetLocation = null; - this.ignoredTabs = [ - 'syscollector', - 'welcome', - 'configuration', - 'stats' - ]; + this.ignoredTabs = ['syscollector', 'welcome', 'configuration', 'stats']; this.$scope.expandArray = [ false, @@ -133,7 +126,8 @@ export class AgentsController { this.$scope.tab = this.commonData.checkTabLocation(); } this.tabHistory = []; - if (!this.ignoredTabs.includes(this.$scope.tab)) this.tabHistory.push(this.$scope.tab); + if (!this.ignoredTabs.includes(this.$scope.tab)) + this.tabHistory.push(this.$scope.tab); // Tab names this.$scope.tabNames = TabNames; @@ -145,15 +139,19 @@ export class AgentsController { * @param {Object} item * @param {Array} array */ - this.$scope.inArray = (item, array) => item && Array.isArray(array) && array.includes(item); + this.$scope.inArray = (item, array) => + item && Array.isArray(array) && array.includes(item); - this.$scope.switchSubtab = async (subtab, force = false, onlyAgent = false) => - this.switchSubtab(subtab, force, onlyAgent); + this.$scope.switchSubtab = async ( + subtab, + force = false, + onlyAgent = false, + ) => this.switchSubtab(subtab, force, onlyAgent); this.changeAgent = false; this.$scope.switchTab = (tab, force = false) => this.switchTab(tab, force); - this.$scope.getAgent = async (newAgentId) => this.getAgent(newAgentId); + this.$scope.getAgent = async newAgentId => this.getAgent(newAgentId); this.$scope.goGroups = (agent, group) => this.goGroups(agent, group); this.$scope.search = (term, specificPath) => @@ -174,7 +172,8 @@ export class AgentsController { specificFilter, }); - this.$scope.shouldShowComponent = (component) => this.shouldShowComponent(component); + this.$scope.shouldShowComponent = component => + this.shouldShowComponent(component); this.$scope.$on('$destroy', () => { this.visFactoryService.clearAll(); @@ -187,11 +186,14 @@ export class AgentsController { this.$location.path('/manager/groups'); }; - this.$scope.exportConfiguration = (enabledComponents) => { - this.reportingService.startConfigReport(this.$scope.agent, 'agentConfig', enabledComponents); + this.$scope.exportConfiguration = enabledComponents => { + this.reportingService.startConfigReport( + this.$scope.agent, + 'agentConfig', + enabledComponents, + ); }; - //Load try { this.$scope.getAgent(); @@ -213,10 +215,16 @@ export class AgentsController { // Config on demand this.$scope.getXML = () => this.configurationHandler.getXML(this.$scope); this.$scope.getJSON = () => this.configurationHandler.getJSON(this.$scope); - this.$scope.isString = (item) => typeof item === 'string'; - this.$scope.hasSize = (obj) => obj && typeof obj === 'object' && Object.keys(obj).length; - this.$scope.offsetTimestamp = (text, time) => this.offsetTimestamp(text, time); - this.$scope.switchConfigTab = (configurationTab, sections, navigate = true) => { + this.$scope.isString = item => typeof item === 'string'; + this.$scope.hasSize = obj => + obj && typeof obj === 'object' && Object.keys(obj).length; + this.$scope.offsetTimestamp = (text, time) => + this.offsetTimestamp(text, time); + this.$scope.switchConfigTab = ( + configurationTab, + sections, + navigate = true, + ) => { this.$scope.navigate = navigate; try { this.$scope.configSubTab = JSON.stringify({ @@ -224,7 +232,10 @@ export class AgentsController { sections: sections, }); if (!this.$location.search().configSubTab) { - AppState.setSessionStorageItem('configSubTab', this.$scope.configSubTab); + AppState.setSessionStorageItem( + 'configSubTab', + this.$scope.configSubTab, + ); this.$location.search('configSubTab', true); } } catch (error) { @@ -245,7 +256,7 @@ export class AgentsController { configurationTab, sections, this.$scope, - this.$scope.agent.id + this.$scope.agent.id, ); }; @@ -255,12 +266,19 @@ export class AgentsController { if (!this.$location.search().configWodle) { this.$location.search('configWodle', this.$scope.configWodle); } - this.configurationHandler.switchWodle(wodleName, this.$scope, this.$scope.agent.id); + this.configurationHandler.switchWodle( + wodleName, + this.$scope, + this.$scope.agent.id, + ); }; this.$scope.switchConfigurationTab = (configurationTab, navigate) => { this.$scope.navigate = navigate; - this.configurationHandler.switchConfigurationTab(configurationTab, this.$scope); + this.configurationHandler.switchConfigurationTab( + configurationTab, + this.$scope, + ); if (!this.$scope.navigate) { const configSubTab = this.$location.search().configSubTab; if (configSubTab) { @@ -270,7 +288,7 @@ export class AgentsController { this.$scope.switchConfigTab( configSubTabObj.configurationTab, configSubTabObj.sections, - false + false, ); } catch (error) { throw new Error(error); @@ -287,24 +305,27 @@ export class AgentsController { this.$location.search('configWodle', null); } }; - this.$scope.switchConfigurationSubTab = (configurationSubTab) => { - this.configurationHandler.switchConfigurationSubTab(configurationSubTab, this.$scope); + this.$scope.switchConfigurationSubTab = configurationSubTab => { + this.configurationHandler.switchConfigurationSubTab( + configurationSubTab, + this.$scope, + ); if (configurationSubTab === 'pm-sca') { this.$scope.currentConfig.sca = this.configurationHandler.parseWodle( this.$scope.currentConfig, - 'sca' + 'sca', ); } }; - this.$scope.updateSelectedItem = (i) => (this.$scope.selectedItem = i); - this.$scope.getIntegration = (list) => + this.$scope.updateSelectedItem = i => (this.$scope.selectedItem = i); + this.$scope.getIntegration = list => this.configurationHandler.getIntegration(list, this.$scope); this.$scope.$on('$routeChangeStart', () => { return AppState.removeSessionStorageItem('configSubTab'); }); - this.$scope.expand = (i) => this.expand(i); + this.$scope.expand = i => this.expand(i); this.setTabs(); } @@ -327,7 +348,7 @@ export class AgentsController { this.filterHandler, this.$scope.tab, subtab, - this.$scope.agent.id + this.$scope.agent.id, ); this.changeAgent = false; @@ -363,25 +384,6 @@ export class AgentsController { } else if (this.ignoredTabs.includes(this.$scope.tab)) { timefilter.setRefreshInterval(this.commonData.getRefreshInterval()); } - if (tab === 'syscollector') { - // TODO: Migrate syscollector to React - let breadcrumb = [ - { - text: '', - }, - { - text: 'Agents', - href: '#/agents-preview', - }, - { agent: this.$scope.agent }, - { - text: 'Inventory Data', - className: 'wz-global-breadcrumb-popover', - }, - ]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - $('#breadcrumbNoTitle').attr('title', ''); - } // Update agent status if (!force && this.$scope.agent) { @@ -403,7 +405,6 @@ export class AgentsController { } try { - if (tab === 'configuration') { this.$scope.switchConfigurationTab('welcome'); } else { @@ -411,7 +412,8 @@ export class AgentsController { } if (!this.ignoredTabs.includes(tab)) this.tabHistory.push(tab); - if (this.tabHistory.length > 2) this.tabHistory = this.tabHistory.slice(-2); + if (this.tabHistory.length > 2) + this.tabHistory = this.tabHistory.slice(-2); if (this.$scope.tab === tab && !force) { this.$scope.$applyAsync(); @@ -422,7 +424,9 @@ export class AgentsController { const sameTab = this.$scope.tab === tab; this.$location.search('tab', tab); const preserveDiscover = - this.tabHistory.length === 2 && this.tabHistory[0] === this.tabHistory[1] && !force; + this.tabHistory.length === 2 && + this.tabHistory[0] === this.tabHistory[1] && + !force; this.$scope.tab = tab; const targetSubTab = @@ -431,7 +435,13 @@ export class AgentsController { : 'panels'; if (!this.ignoredTabs.includes(this.$scope.tab)) { - this.$scope.switchSubtab(targetSubTab, true, onlyAgent, sameTab, preserveDiscover); + this.$scope.switchSubtab( + targetSubTab, + true, + onlyAgent, + sameTab, + preserveDiscover, + ); } this.shareAgent.deleteTargetLocation(); @@ -453,9 +463,9 @@ export class AgentsController { } this.$scope.configurationTabsProps = {}; - this.$scope.buildProps = (tabs) => { + this.$scope.buildProps = tabs => { const cleanTabs = []; - tabs.forEach((x) => { + tabs.forEach(x => { if ( this.$scope.configurationTab === 'integrity-monitoring' && x.id === 'fim-whodata' && @@ -470,10 +480,13 @@ export class AgentsController { }); }); this.$scope.configurationTabsProps = { - clickAction: (tab) => { + clickAction: tab => { this.$scope.switchConfigurationSubTab(tab); }, - selectedTab: this.$scope.configurationSubTab || (tabs && tabs.length) ? tabs[0].id : '', + selectedTab: + this.$scope.configurationSubTab || (tabs && tabs.length) + ? tabs[0].id + : '', tabs: cleanTabs, }; }; @@ -500,18 +513,21 @@ export class AgentsController { setTabs() { this.$scope.agentsTabsProps = false; if (this.$scope.agent) { - this.currentPanel = this.commonData.getCurrentPanel(this.$scope.tab, true); + this.currentPanel = this.commonData.getCurrentPanel( + this.$scope.tab, + true, + ); if (!this.currentPanel) return; const tabs = this.commonData.getTabsFromCurrentPanel( this.currentPanel, this.$scope.extensions, - this.$scope.tabNames + this.$scope.tabNames, ); const cleanTabs = []; - tabs.forEach((x) => { + tabs.forEach(x => { if (!hasAgentSupportModule(this.$scope.agent, x.id)) return; cleanTabs.push({ @@ -521,12 +537,14 @@ export class AgentsController { }); this.$scope.agentsTabsProps = { - clickAction: (tab) => { + clickAction: tab => { this.switchTab(tab, true); }, selectedTab: this.$scope.tab || - (this.currentPanel && this.currentPanel.length ? this.currentPanel[0] : ''), + (this.currentPanel && this.currentPanel.length + ? this.currentPanel[0] + : ''), tabs: cleanTabs, }; this.$scope.$applyAsync(); @@ -566,7 +584,10 @@ export class AgentsController { */ async loadSyscollector(id) { try { - const syscollectorData = await this.genericReq.request('GET', `/api/syscollector/${id}`); + const syscollectorData = await this.genericReq.request( + 'GET', + `/api/syscollector/${id}`, + ); this.$scope.syscollector = syscollectorData?.data || {}; return; } catch (error) { @@ -600,9 +621,12 @@ export class AgentsController { if (!this.$scope.agent) return; if (agentInfo && this.$scope.agent.os) { - this.$scope.agentOS = this.$scope.agent.os.name + ' ' + this.$scope.agent.os.version; + this.$scope.agentOS = + this.$scope.agent.os.name + ' ' + this.$scope.agent.os.version; const isLinux = this.$scope.agent.os.uname.includes('Linux'); - this.$scope.agent.agentPlatform = isLinux ? 'linux' : this.$scope.agent.os.platform; + this.$scope.agent.agentPlatform = isLinux + ? 'linux' + : this.$scope.agent.os.platform; } else { this.$scope.agentOS = '-'; this.$scope.agent.agentPlatform = false; @@ -611,7 +635,7 @@ export class AgentsController { await this.$scope.switchTab(this.$scope.tab, true); this.loadWelcomeCardsProps(); - this.$scope.getWelcomeCardsProps = (resultState) => { + this.$scope.getWelcomeCardsProps = resultState => { return { ...this.$scope.welcomeCardsProps, resultState }; }; this.$scope.load = false; @@ -623,7 +647,11 @@ export class AgentsController { this.$scope.emptyAgent = 'Wazuh API timeout.'; } } - if (error && typeof error === 'string' && error.includes('Agent does not exist')) { + if ( + error && + typeof error === 'string' && + error.includes('Agent does not exist') + ) { this.$location.search('agent', null); this.$location.path('/agents-preview'); } @@ -705,8 +733,6 @@ export class AgentsController { this.$location.path('/manager'); } - - falseAllExpand() { this.$scope.expandArray = [ false, diff --git a/plugins/main/public/controllers/agent/components/agents-preview.js b/plugins/main/public/controllers/agent/components/agents-preview.js index 31ed799603..6702447292 100644 --- a/plugins/main/public/controllers/agent/components/agents-preview.js +++ b/plugins/main/public/controllers/agent/components/agents-preview.js @@ -57,7 +57,7 @@ import { export const AgentsPreview = compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb([{ text: '' }, { text: 'Agents' }]), + withGlobalBreadcrumb([{ text: '' }, { text: 'Endpoints summary' }]), withUserAuthorizationPrompt([ [ { action: 'agent:read', resource: 'agent:id:*' }, diff --git a/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx b/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx index 374cc479ab..10e75dd501 100644 --- a/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx @@ -57,7 +57,6 @@ export default compose( withGlobalBreadcrumb(props => { return [ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: SECTION_CDBLIST_NAME} ]; }), diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js index 47a769eade..a8e938b1ef 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js @@ -16,25 +16,20 @@ import { withGlobalBreadcrumb, withReduxProvider, } from '../../../../../components/common/hocs'; -import { compose } from 'redux' +import { compose } from 'redux'; export default compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb((props) => { + withGlobalBreadcrumb(props => { let breadcrumb = false; if (props.agent.id === '000') { - breadcrumb = [ - { text: '' }, - { text: 'Management', href: '#/manager' }, - { text: 'Configuration' }, - ]; + breadcrumb = [{ text: '' }, { text: 'Settings' }]; } else { breadcrumb = [ { text: '' }, { - text: 'Agents', - href: '#/agents-preview', + text: 'IT Hygiene', }, { agent: props.agent }, { text: 'Configuration' }, @@ -42,5 +37,5 @@ export default compose( } $('#breadcrumbNoTitle').attr('title', ''); return breadcrumb; - }) + }), )(WzConfigurationSwitch); diff --git a/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx b/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx index 9001328e1d..31762d2e69 100644 --- a/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx @@ -59,7 +59,6 @@ export default compose( withGlobalBreadcrumb(props => { return [ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: SECTION_DECODERS_NAME} ]; }), diff --git a/plugins/main/public/controllers/management/components/management/groups/__snapshots__/groups-main.test.tsx.snap b/plugins/main/public/controllers/management/components/management/groups/__snapshots__/groups-main.test.tsx.snap index 74554618bf..2923c94f31 100644 --- a/plugins/main/public/controllers/management/components/management/groups/__snapshots__/groups-main.test.tsx.snap +++ b/plugins/main/public/controllers/management/components/management/groups/__snapshots__/groups-main.test.tsx.snap @@ -25,7 +25,7 @@ exports[`Group main component renders correctly to match the snapshot 1`] = ` } } > - { updateGroupDetail: (groupDetail) => dispatch(updateGroupDetail(groupDetail)), }; }; -export default connect(mapStateToProps, mapDispatchToProps)(WzGroups); +export default compose( + connect(mapStateToProps, mapDispatchToProps), + withGlobalBreadcrumb(props => { + return [ + { text: '' }, + { text: 'Groups' } + ]; + }) +)(WzGroups); diff --git a/plugins/main/public/controllers/management/components/management/mg-logs/logs.js b/plugins/main/public/controllers/management/components/management/mg-logs/logs.js index a13d833d7b..1c43201a1c 100644 --- a/plugins/main/public/controllers/management/components/management/mg-logs/logs.js +++ b/plugins/main/public/controllers/management/components/management/mg-logs/logs.js @@ -43,7 +43,7 @@ import { getErrorOrchestrator } from '../../../../../react-services/common-servi import { WzFieldSearchDelay } from '../../../../../components/common/search'; export default compose( - withGlobalBreadcrumb([{ text: '' }, { text: 'Management', href: '#/manager' }, { text: 'Logs' }]), + withGlobalBreadcrumb([{ text: '' }, { text: 'Logs' }]), withUserAuthorizationPrompt([ { action: 'cluster:status', resource: '*:*:*' }, { action: 'cluster:read', resource: 'node:id:*' }, diff --git a/plugins/main/public/controllers/management/components/management/reporting/__snapshots__/reporting-main.test.tsx.snap b/plugins/main/public/controllers/management/components/management/reporting/__snapshots__/reporting-main.test.tsx.snap index b7a65fb1b1..5941b82a4a 100644 --- a/plugins/main/public/controllers/management/components/management/reporting/__snapshots__/reporting-main.test.tsx.snap +++ b/plugins/main/public/controllers/management/components/management/reporting/__snapshots__/reporting-main.test.tsx.snap @@ -2,6 +2,6 @@ exports[`Reporting component renders correctly to match the snapshot 1`] = ` - + `; diff --git a/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js b/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js index 2a55a2e667..1b69de3f0b 100644 --- a/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js +++ b/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js @@ -14,8 +14,8 @@ import React, { Component } from 'react'; import WzReduxProvider from '../../../../../redux/wz-redux-provider'; //Wazuh groups overview import WzReportingOverview from './reporting-overview'; -import { updateGlobalBreadcrumb } from '../../../../../redux/actions/globalBreadcrumbActions'; -import store from '../../../../../redux/store'; +import { compose } from 'redux'; +import { withGlobalBreadcrumb, withReduxProvider } from '../../../../../components/common/hocs'; class WzReporting extends Component { constructor(props) { @@ -23,19 +23,6 @@ class WzReporting extends Component { this.state = {}; } - setGlobalBreadcrumb() { - const breadcrumb = [ - { text: '' }, - { text: 'Management', href: '#/manager' }, - { text: 'Reporting' } - ]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - } - - componentDidMount() { - this.setGlobalBreadcrumb(); - } - render() { return ( @@ -45,4 +32,11 @@ class WzReporting extends Component { } } -export default WzReporting; +export default compose( + withReduxProvider, + withGlobalBreadcrumb( props => { + return [ + { text: '' }, + { text: 'Reporting' } + ]; +}))(WzReporting); diff --git a/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx b/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx index 377728711b..11c1dd9698 100644 --- a/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx @@ -56,7 +56,6 @@ export default compose( withGlobalBreadcrumb(props => { return [ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: SECTION_RULES_NAME} ]; }), diff --git a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js index 0b204e0008..3742b4265e 100644 --- a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js +++ b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js @@ -251,7 +251,6 @@ export class WzStatisticsOverview extends Component { export default compose( withGlobalBreadcrumb([ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: 'Statistics' } ]), withGuard(props => { @@ -283,7 +282,7 @@ export default compose( } setLoading(false); }; - + fetchData(); }, []); if(loading){ diff --git a/plugins/main/public/controllers/management/components/management/status/status-overview.js b/plugins/main/public/controllers/management/components/management/status/status-overview.js index b47a931aef..e05d12d374 100644 --- a/plugins/main/public/controllers/management/components/management/status/status-overview.js +++ b/plugins/main/public/controllers/management/components/management/status/status-overview.js @@ -247,7 +247,6 @@ const mapDispatchToProps = (dispatch) => { export default compose( withGlobalBreadcrumb([ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: 'Status' }, ]), withUserAuthorizationPrompt([ diff --git a/plugins/main/public/controllers/management/monitoring.js b/plugins/main/public/controllers/management/monitoring.js index d2cbe5b7d4..79cb2593ff 100644 --- a/plugins/main/public/controllers/management/monitoring.js +++ b/plugins/main/public/controllers/management/monitoring.js @@ -319,7 +319,6 @@ export function ClusterController( const breadcrumb = [ { text: '' }, - { text: 'Management', href: '#/manager' }, { text: 'Cluster' } ]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); diff --git a/plugins/main/public/controllers/overview/index.js b/plugins/main/public/controllers/overview/index.js index 5650327927..c0af0d133b 100644 --- a/plugins/main/public/controllers/overview/index.js +++ b/plugins/main/public/controllers/overview/index.js @@ -12,8 +12,7 @@ import { OverviewController } from './overview'; import { OverviewWelcome } from '../../components/common/welcome/overview-welcome'; import { WzCurrentOverviewSectionWrapper } from '../../components/common/modules/overview-current-section-wrapper'; -import { WzCurrentAgentsSectionWrapper } from '../../components/common/modules/agents-current-section-wrapper'; -import { Mitre } from '../../components/overview' +import { Mitre } from '../../components/overview'; import { Stats } from './components/stats'; import { SelectAgent } from './components/select-agent'; import { RequirementCard } from './components/requirement-card'; @@ -23,7 +22,6 @@ const app = getAngularModule(); OverviewWelcome.displayName = 'OverviewWelcome'; WzCurrentOverviewSectionWrapper.displayName = 'WzCurrentOverviewSectionWrapper'; -WzCurrentAgentsSectionWrapper.displayName = 'WzCurrentAgentsSectionWrapper'; Stats.displayName = 'StatsOverview'; Mitre.displayName = 'Mitre'; SelectAgent.displayName = 'SelectAgent'; @@ -33,7 +31,6 @@ app .controller('overviewController', OverviewController) .value('OverviewWelcome', OverviewWelcome) .value('WzCurrentOverviewSectionWrapper', WzCurrentOverviewSectionWrapper) - .value('WzCurrentAgentsSectionWrapper', WzCurrentAgentsSectionWrapper) .value('StatsOverview', Stats) .value('Mitre', Mitre) .value('SelectAgent', SelectAgent) diff --git a/plugins/main/public/controllers/settings/settings.js b/plugins/main/public/controllers/settings/settings.js index f30a9fb442..7487872dd7 100644 --- a/plugins/main/public/controllers/settings/settings.js +++ b/plugins/main/public/controllers/settings/settings.js @@ -61,6 +61,15 @@ export class SettingsController { this.indexPatterns = []; this.apiEntries = []; this.$scope.googleGroupsSVG = getHttp().basePath.prepend(getAssetURL('images/icons/google_groups.svg')); + this.tabs = [ + { id: 'api', name: 'Server API' }, + { id: 'modules', name: 'Modules' }, + { id: 'sample_data', name: 'Server data' }, + { id: 'configuration', name: 'Configuration' }, + { id: 'logs', name: 'Logs' }, + { id: 'miscellaneous', name: 'Miscellaneous' }, + { id: 'about', name: 'About' }, + ]; } /** @@ -68,14 +77,24 @@ export class SettingsController { */ async $onInit() { try { - const breadcrumb = [{ text: '' }, { text: 'Settings' }]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - const location = this.$location.search(); - if (location && location.tab) { + if (location?.tab) { this.tab = location.tab; + const tabActive = this.tabs.find(tab => tab.id === this.tab); if(this.tab==='about') store.dispatch(updateSelectedSettingsSection('about')); + const breadcrumb = [ + { text: '' }, + { text: tabActive?.name || 'Server API' } + ]; + store.dispatch(updateGlobalBreadcrumb(breadcrumb)); + } else { + const breadcrumb = [ + { text: '' }, + { text: 'Server API' }, + ]; + store.dispatch(updateGlobalBreadcrumb(breadcrumb)); } + // Set component props this.setComponentProps(); // Loading data @@ -138,16 +157,6 @@ export class SettingsController { this.updateClusterInfoInRegistry(id, clusterInfo), copyToClipBoard: msg => this.copyToClipBoard(msg) }; - - let tabs = [ - { id: 'api', name: 'API' }, - { id: 'modules', name: 'Modules' }, - { id: 'sample_data', name: 'Sample data' }, - { id: 'configuration', name: 'Configuration' }, - { id: 'logs', name: 'Logs' }, - { id: 'miscellaneous', name: 'Miscellaneous'}, - { id: 'about', name: 'About' } - ]; this.settingsTabsProps = { clickAction: tab => { this.switchTab(tab, true); @@ -156,7 +165,7 @@ export class SettingsController { } }, selectedTab: this.tab || 'api', - tabs, + tabs: this.tabs, wazuhConfig: this.wazuhConfig }; diff --git a/plugins/main/public/react-services/generic-request.test.ts b/plugins/main/public/react-services/generic-request.test.ts index 07149833fc..badf182bca 100644 --- a/plugins/main/public/react-services/generic-request.test.ts +++ b/plugins/main/public/react-services/generic-request.test.ts @@ -28,6 +28,7 @@ jest.mock('../kibana-services', () => ({ }, }, }), + getWzCurrentAppID: jest.fn().mockReturnValue('wz-endpoints-summary'), getCookies: jest.fn(), })); @@ -71,7 +72,7 @@ describe('Generic Request', () => { await GenericRequest.request(null, '/api/request'); } catch (error) { expect(error).toBeInstanceOf(Error); - if(error instanceof Error) + if(error instanceof Error) expect(error.message).toBe('Missing parameters'); } }); diff --git a/plugins/main/public/styles/theme/dark/index.dark.scss b/plugins/main/public/styles/theme/dark/index.dark.scss index c7277ec5fb..386d7d30b0 100644 --- a/plugins/main/public/styles/theme/dark/index.dark.scss +++ b/plugins/main/public/styles/theme/dark/index.dark.scss @@ -27,10 +27,6 @@ html { color: white; } */ -.wz-global-breadcrumb .euiToolTipAnchor { - color: #98a2b3 !important; -} - .app-wrapper-panel { background-color: #1a1b20; }