From 57db4509e5bb5aaf8f4e880aeb61f475d6aacf06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20David=20Guti=C3=A9rrez?= Date: Wed, 29 Nov 2023 14:18:14 +0100 Subject: [PATCH 1/3] feat: remove application menu in IT Hygiene application - Remove application menu - Add link to Endpoint Summary - Refactor the responsive of header button using styles instead of controlled by JS - Changed the icon of Endpoint Summary application --- .../common/welcome/agents-welcome.js | 259 ++++-------------- .../components/common/welcome/welcome.scss | 94 +++++-- plugins/main/public/utils/applications.ts | 2 +- 3 files changed, 115 insertions(+), 240 deletions(-) diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 1452cc06a8..bb1e20e90b 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -21,7 +21,6 @@ import { EuiFlexGrid, EuiButtonEmpty, EuiPage, - EuiPopover, EuiLoadingChart, EuiToolTip, EuiButtonIcon, @@ -35,7 +34,6 @@ import { } from './components'; import { AgentInfo } from './agents-info'; import WzReduxProvider from '../../../redux/wz-redux-provider'; -import MenuAgent from './components/menu-agent'; import './welcome.scss'; import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker'; import KibanaVis from '../../../kibana-integrations/kibana-vis'; @@ -53,7 +51,6 @@ import { getCore, getDataPlugin, } from '../../../kibana-services'; -import { hasAgentSupportModule } from '../../../react-services/wz-agents'; import { withErrorBoundary, withGlobalBreadcrumb, @@ -62,7 +59,6 @@ import { } from '../hocs'; import { compose } from 'redux'; import { API_NAME_AGENT_STATUS } from '../../../../common/constants'; -import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; import { PromptAgentNeverConnected, PromptNoSelectedAgent, @@ -71,12 +67,8 @@ import { connect } from 'react-redux'; import { WzButton } from '../buttons'; import { Applications, - configurationAssessment, - fileIntegrityMonitoring, itHygiene, mitreAttack, - threatHunting, - vulnerabilityDetection, } from '../../../utils/applications'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; @@ -120,14 +112,9 @@ export const AgentsWelcome = compose( )( class AgentsWelcome extends Component { _isMount = false; - sidebarSizeDefault; constructor(props) { super(props); - this.offset = 275; - - this.sidebarSizeDefault = 320; - this.state = { lastScans: [], isLoading: true, @@ -135,43 +122,12 @@ export const AgentsWelcome = compose( sortDirection: 'desc', actionAgents: true, // Hide actions agents selectedRequirement: 'pci', - menuAgent: [], - maxModules: 5, widthWindow: window.innerWidth, - isLocked: false, }; } updateWidth = () => { - let menuSize; - if (this.state.isLocked) { - menuSize = window.innerWidth - this.offset - this.sidebarSizeDefault; - } else { - menuSize = window.innerWidth - this.offset; - } - let maxModules = 5; - if (menuSize > 1400) { - maxModules = 5; - } else { - if (menuSize > 1250) { - maxModules = 4; - } else { - if (menuSize > 1100) { - maxModules = 3; - } else { - if (menuSize > 900) { - maxModules = 2; - } else { - maxModules = 1; - if (menuSize < 750) { - maxModules = null; - } - } - } - } - } - - this.setState({ maxModules: maxModules, widthWindow: window.innerWidth }); + this.setState({ widthWindow: window.innerWidth }); }; /* TODO: we should to create a unique Explore agent button instead @@ -192,7 +148,6 @@ export const AgentsWelcome = compose( /* WORKAROUND: ensure the $scope.agent is synced with the agent stored in Redux (this.props.agent). See agents.js controller. */ this.props.setAgent(this.props.agent); - this.updatePinnedApplications(); this.updateWidth(); const tabVisualizations = new TabVisualizations(); tabVisualizations.removeAll(); @@ -204,10 +159,8 @@ export const AgentsWelcome = compose( const $injector = getAngularModule().$injector; this.drawerLokedSubscribtion = getChrome() .getIsNavDrawerLocked$() - .subscribe(isLocked => { - this.setState({ isLocked }, () => { - this.updateWidth(); - }); + .subscribe(() => { + this.updateWidth(); }); this.router = $injector.get('$route'); window.addEventListener('resize', this.updateWidth); //eslint-disable-line @@ -230,117 +183,34 @@ export const AgentsWelcome = compose( this.drawerLokedSubscribtion?.unsubscribe(); } - updatePinnedApplications(applications) { - let pinnedApplications; - - if (applications) { - pinnedApplications = applications; - } else { - pinnedApplications = window.localStorage.getItem( - 'wz-menu-agent-apps-pinned', - ) - ? JSON.parse(window.localStorage.getItem('wz-menu-agent-apps-pinned')) - : [ - // Default pinned applications - threatHunting.id, - fileIntegrityMonitoring.id, - configurationAssessment.id, - vulnerabilityDetection.id, - mitreAttack.id, - ]; - } - - // Ensure the pinned applications are supported - pinnedApplications = pinnedApplications.filter(pinnedApplication => - Applications.some(({ id }) => id === pinnedApplication), + renderEndpointsSummaryButton() { + const application = Applications.find( + ({ id }) => id === 'endpoints-summary', ); - - window.localStorage.setItem( - 'wz-menu-agent-apps-pinned', - JSON.stringify(pinnedApplications), - ); - this.setState({ menuAgent: pinnedApplications }); - } - - renderModules() { return ( - - {this.state.menuAgent.map((applicationId, i) => { - const moduleID = Object.keys(WAZUH_MODULES).find( - key => WAZUH_MODULES[key]?.appId === applicationId, - ).appId; - if ( - i < this.state.maxModules && - hasAgentSupportModule(this.props.agent, moduleID) - ) { - return ( - - - - - { - Applications.find(({ id }) => id === applicationId) - .title - } -   - - - - - ); - } - })} - - - this.setState({ switchModule: !this.state.switchModule }) - } - > - More... - - } - isOpen={this.state.switchModule} - closePopover={() => this.setState({ switchModule: false })} - repositionOnScroll={false} - anchorPosition='downCenter' - > -
- -
- - this.updatePinnedApplications(applications) - } - closePopover={() => { - this.setState({ switchModule: false }); - }} - switchTab={module => this.props.switchTab(module)} - > -
-
-
-
-
-
+ + + {application.title} + + ); } renderTitle() { const notNeedStatus = true; const thereAreAgentSelected = Boolean(this.props.agent?.id); + // Calculate if the header buttons should display the name or only the icon to be responsive + return ( - {(this.state.maxModules !== null && this.renderModules()) || ( - - - this.setState({ - switchModule: !this.state.switchModule, - }) - } - > - Applications - - } - isOpen={this.state.switchModule} - closePopover={() => this.setState({ switchModule: false })} - repositionOnScroll={false} - anchorPosition='downCenter' - > -
- -
- - this.updatePinnedApplications(applications) - } - closePopover={() => { - this.setState({ switchModule: false }); - }} - switchTab={module => this.props.switchTab(module)} - > -
-
-
-
-
- )} + + {this.renderEndpointsSummaryButton()} +
@@ -433,13 +265,14 @@ export const AgentsWelcome = compose( onClick={() => this.props.switchTab('syscollector', notNeedStatus) } - tooltip={ - this.state.maxModules === null - ? { position: 'bottom', content: 'Inventory data' } - : undefined - } + className='wz-it-hygiene-header-button' + tooltip={{ + position: 'bottom', + content: 'Inventory data', + className: 'wz-it-hygiene-header-button-tooltip', + }} > - {this.state.maxModules !== null ? 'Inventory data' : ''} + Inventory data @@ -447,13 +280,14 @@ export const AgentsWelcome = compose( buttonType='empty' iconType='stats' onClick={() => this.props.switchTab('stats', notNeedStatus)} - tooltip={ - this.state.maxModules === null - ? { position: 'bottom', content: 'Stats' } - : undefined - } + className='wz-it-hygiene-header-button' + tooltip={{ + position: 'bottom', + content: 'Stats', + className: 'wz-it-hygiene-header-button-tooltip', + }} > - {this.state.maxModules !== null ? 'Stats' : ''} + Stats @@ -463,13 +297,14 @@ export const AgentsWelcome = compose( onClick={() => this.props.switchTab('configuration', notNeedStatus) } - tooltip={ - this.state.maxModules === null - ? { position: 'bottom', content: 'Configuration' } - : undefined - } + className='wz-it-hygiene-header-button' + tooltip={{ + position: 'bottom', + content: 'Configuration', + className: 'wz-it-hygiene-header-button-tooltip', + }} > - {this.state.maxModules !== null ? 'Configuration' : ''} + Configuration
diff --git a/plugins/main/public/components/common/welcome/welcome.scss b/plugins/main/public/components/common/welcome/welcome.scss index e04bf5525c..dab373eee2 100644 --- a/plugins/main/public/components/common/welcome/welcome.scss +++ b/plugins/main/public/components/common/welcome/welcome.scss @@ -1,44 +1,84 @@ -.wz-welcome-page .euiCard .euiTitle, .wz-module-body .euiCard .euiTitle { - font-size: 16px; - font-weight: 400; +.wz-welcome-page .euiCard .euiTitle, +.wz-module-body .euiCard .euiTitle { + font-size: 16px; + font-weight: 400; } -.wz-welcome-page .euiCard .euiText, .wz-module-body .euiCard .euiText { - font-size: 12px; - font-family: sans-serif; +.wz-welcome-page .euiCard .euiText, +.wz-module-body .euiCard .euiText { + font-size: 12px; + font-family: sans-serif; } -.wz-module-header-agent:not(.wz-module-header-agent-main){ - background: white; - border-bottom: 1px solid #D3DAE6; +.wz-module-header-agent:not(.wz-module-header-agent-main) { + background: white; + border-bottom: 1px solid #d3dae6; } -.wz-welcome-page-agent-info.wz-welcome-page-agent-info-gray{ - border-top: 1px solid #d3dae6; - background: #fafbfd!important; - border-bottom: 1px solid #d3dae6; +.wz-welcome-page-agent-info.wz-welcome-page-agent-info-gray { + border-top: 1px solid #d3dae6; + background: #fafbfd !important; + border-bottom: 1px solid #d3dae6; } -.wz-welcome-page-agent-tabs{ - padding: 12px 16px 1px 10px; - min-height: 54px; - border-bottom: 1px solid #D3DAE6; - background-color: white; +.wz-welcome-page-agent-tabs { + padding: 12px 16px 1px 10px; + min-height: 54px; + border-bottom: 1px solid #d3dae6; + background-color: white; } -.wz-welcome-page-agent-info-actions{ - padding: 6px 0px 6px 0px; +.wz-welcome-page-agent-info-actions { + padding: 6px 0px 6px 0px; } -.wz-welcome-page-agent-info .euiStat .euiText{ - font-size: 12px; - font-family: sans-serif; +.wz-welcome-page-agent-info .euiStat .euiText { + font-size: 12px; + font-family: sans-serif; } .statWithLink:hover .euiTitle { - text-decoration: underline; + text-decoration: underline; } -span.statWithLink:hover { - text-decoration: underline; -} \ No newline at end of file +span.statWithLink:hover { + text-decoration: underline; +} + +// Header buttons of IT Hygiene application + +// Sidebar is open and locked +body.euiBody--hasFlyout:not(.euiBody-hasOverlayMask) { + @media only screen and (max-width: 1345px) { + // Hide button text depending on the window size + .wz-it-hygiene-header-button .euiButtonEmpty__text { + display: none; + } + } + + @media only screen and (min-width: 1346px) { + // Hide the tooltip of button depending on the window size + .wz-it-hygiene-header-button-tooltip { + display: none; + } + } +} + +// Sidebar is closed +body:not(.euiBody--hasFlyout) { + @media only screen and (max-width: 1025px) { + // Hide button text depending on the window size + .wz-it-hygiene-header-button .euiButtonEmpty__text { + display: none; + } + } + + @media only screen and (min-width: 1026px) { + // Hide the tooltip of button depending on the window size + .wz-it-hygiene-header-button-tooltip { + display: none; + } + } +} + +// Header buttons of IT Hygiene application diff --git a/plugins/main/public/utils/applications.ts b/plugins/main/public/utils/applications.ts index e198f0f7d9..aa675cd06b 100644 --- a/plugins/main/public/utils/applications.ts +++ b/plugins/main/public/utils/applications.ts @@ -76,7 +76,7 @@ export const endpointSumary = { description: i18n.translate('wz-app-endpoints-summary-description', { defaultMessage: 'Summary of agents and their status.', }), - euiIconType: 'usersRolesApp', + euiIconType: 'spacesApp', order: 600, showInOverviewApp: false, showInAgentMenu: false, From 9ce696d1dd76b33a63963ac2f7e26a4820ffaa09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20David=20Guti=C3=A9rrez?= Date: Wed, 29 Nov 2023 14:21:09 +0100 Subject: [PATCH 2/3] fix: remove unused files and styles --- .../welcome/components/agent-sections.ts | 134 ----------- .../common/welcome/components/menu-agent.js | 218 ------------------ .../public/components/wz-menu/wz-menu.scss | 8 - 3 files changed, 360 deletions(-) delete mode 100644 plugins/main/public/components/common/welcome/components/agent-sections.ts delete mode 100644 plugins/main/public/components/common/welcome/components/menu-agent.js diff --git a/plugins/main/public/components/common/welcome/components/agent-sections.ts b/plugins/main/public/components/common/welcome/components/agent-sections.ts deleted file mode 100644 index 3278e60914..0000000000 --- a/plugins/main/public/components/common/welcome/components/agent-sections.ts +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Wazuh app - Build all sections for MenuAgent. - * 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 { WAZUH_MODULES_ID } from '../../../../../common/constants'; - -export const getAgentSections = (menuAgent) => { - return { - securityInformation: { - id: 'securityInformation', - text: 'Security information management', - isTitle: true, - }, - auditing: { - id: 'auditing', - text: 'Auditing and Policy Monitoring', - isTitle: true, - }, - threatDetection: { - id: 'threatDetection', - text: 'Threat detection and response', - isTitle: true, - }, - regulatoryCompliance: { - id: 'regulatoryCompliance', - text: 'Regulatory Compliance', - isTitle: true, - }, - general: { - id: WAZUH_MODULES_ID.SECURITY_EVENTS, - text: 'Security events', - isPin: menuAgent.general ? menuAgent.general : false, - }, - fim: { - id: WAZUH_MODULES_ID.INTEGRITY_MONITORING, - text: 'Integrity monitoring', - isPin: menuAgent.fim ? menuAgent.fim : false, - }, - aws: { - id: WAZUH_MODULES_ID.AMAZON_WEB_SERVICES, - text: 'Amazon AWS', - isPin: menuAgent.aws ? menuAgent.aws : false, - }, - gcp: { - id: WAZUH_MODULES_ID.GOOGLE_CLOUD_PLATFORM, - text: 'Google Cloud Platform', - isPin: menuAgent.gcp ? menuAgent.gcp : false, - }, - github: { - id: WAZUH_MODULES_ID.GITHUB, - text: 'GitHub', - isPin: menuAgent.github ? menuAgent.github : false - }, - pm: { - id: WAZUH_MODULES_ID.POLICY_MONITORING, - text: 'Policy Monitoring', - isPin: menuAgent.pm ? menuAgent.pm : false, - }, - sca: { - id: WAZUH_MODULES_ID.SECURITY_CONFIGURATION_ASSESSMENT, - text: 'Security configuration assessment', - isPin: menuAgent.sca ? menuAgent.sca : false, - }, - audit: { - id: WAZUH_MODULES_ID.AUDITING, - text: 'System Auditing', - isPin: menuAgent.audit ? menuAgent.audit : false, - }, - oscap: { - id: WAZUH_MODULES_ID.OPEN_SCAP, - text: 'OpenSCAP', - isPin: menuAgent.oscap ? menuAgent.oscap : false, - }, - ciscat: { - id: WAZUH_MODULES_ID.CIS_CAT, - text: 'CIS-CAT', - isPin: menuAgent.oscap ? menuAgent.oscap : false, - }, - vuls: { - id: WAZUH_MODULES_ID.VULNERABILITIES, - text: 'Vulnerabilities', - isPin: menuAgent.vuls ? menuAgent.vuls : false, - }, - virustotal: { - id: WAZUH_MODULES_ID.VIRUSTOTAL, - text: 'VirusTotal', - isPin: menuAgent.virustotal ? menuAgent.virustotal : false, - }, - osquery: { - id: WAZUH_MODULES_ID.OSQUERY, - text: 'Osquery', - isPin: menuAgent.osquery ? menuAgent.osquery : false, - }, - docker: { - id: WAZUH_MODULES_ID.DOCKER, - text: 'Docker Listener', - isPin: menuAgent.docker ? menuAgent.docker : false, - }, - mitre: { - id: WAZUH_MODULES_ID.MITRE_ATTACK, - text: 'MITRE ATT&CK', - isPin: menuAgent.mitre ? menuAgent.mitre : false, - }, - pci: { - id: WAZUH_MODULES_ID.PCI_DSS, - text: 'PCI DSS', - isPin: menuAgent.pci ? menuAgent.pci : false, - }, - gdpr: { - id: WAZUH_MODULES_ID.GDPR, - text: 'GDPR', - isPin: menuAgent.gdpr ? menuAgent.gdpr : false, - }, - hipaa: { - id: WAZUH_MODULES_ID.HIPAA, - text: 'HIPAA', - isPin: menuAgent.hipaa ? menuAgent.hipaa : false, - }, - nist: { - id: WAZUH_MODULES_ID.NIST_800_53, - text: 'NIST 800-53', - isPin: menuAgent.nist ? menuAgent.nist : false, - }, - tsc: { id: WAZUH_MODULES_ID.TSC, text: 'TSC', isPin: menuAgent.tsc ? menuAgent.tsc : false }, - }; -}; diff --git a/plugins/main/public/components/common/welcome/components/menu-agent.js b/plugins/main/public/components/common/welcome/components/menu-agent.js deleted file mode 100644 index f11013ad54..0000000000 --- a/plugins/main/public/components/common/welcome/components/menu-agent.js +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Wazuh app - React component for registering agents. - * 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 { - EuiFlexGrid, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiSideNav, - EuiLink, -} from '@elastic/eui'; -import { connect } from 'react-redux'; -import { hasAgentSupportModule } from '../../../../react-services/wz-agents'; -import { - getAngularModule, - getCore, - getToasts, -} from '../../../../kibana-services'; -import { updateCurrentAgentData } from '../../../../redux/actions/appStateActions'; -import { Applications, Categories } from '../../../../utils/applications'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; - -class WzMenuAgent extends Component { - constructor(props) { - super(props); - this.state = { - hoverAddFilter: '', - }; - - this.appCategories = Applications.reduce((categories, app) => { - const existingCategory = categories.find( - category => category.id === app.category, - ); - if (app.showInAgentMenu) { - if (existingCategory) { - existingCategory.apps.push(app); - } else { - const category = Categories.find( - category => app.category === category.id, - ); - categories.push({ - id: category.id, - label: Categories.find(category => app.category === category.id) - .label, - icon: category.euiIconType, - apps: [app], - }); - } - } - return categories; - }, []).sort((a, b) => { - return ( - Categories.find(category => a.id === category.id).order - - Categories.find(category => b.id === category.id).order - ); - }); - } - - componentDidMount() { - const $injector = getAngularModule().$injector; - this.router = $injector.get('$route'); - } - - clickMenuItem = appId => { - this.props.closePopover(); - // do not redirect if we already are in that tab - this.props.updateCurrentAgentData(this.props.isAgent); - this.router.reload(); - }; - - addToast({ color, title, text, time = 3000 }) { - getToasts().add({ title, text, toastLifeTimeMs: time, color }); - } - - createItems = items => { - return items - .filter(item => - hasAgentSupportModule(this.props.currentAgentData, item.id), - ) - .map(item => this.createItem(item)); - }; - - createItem = (item, data = {}) => { - // NOTE: Duplicate `name` values will cause `id` collisions. - return { - ...data, - id: item.id, - name: ( - { - this.setState({ hoverAddFilter: item.id }); - }} - onMouseLeave={() => { - this.setState({ hoverAddFilter: '' }); - }} - > - (!item.isTitle ? this.clickMenuItem(item.id) : null)} - style={{ cursor: !item.isTitle ? 'pointer' : 'normal' }} - > - - - {item.title} - - - - {this.state.hoverAddFilter === item.id && - !item.isTitle && - (this.props.pinnedApplications.length < 6 || item.isPin) && - (this.props.pinnedApplications.length > 1 || !item.isPin) && ( - - { - if ( - !item.isPin && - this.props.pinnedApplications.length < 6 - ) { - this.props.updatePinnedApplications([ - ...this.props.pinnedApplications, - item.id, - ]); - } else if ( - this.props.pinnedApplications.includes(item.id) - ) { - this.props.updatePinnedApplications([ - ...this.props.pinnedApplications.filter( - id => id !== item.id, - ), - ]); - } else { - this.addToast({ - title: - 'The limit of pinned applications has been reached', - color: 'danger', - }); - } - }} - color='primary' - type={ - this.props.pinnedApplications.includes(item.id) - ? 'pinFilled' - : 'pin' - } - aria-label='Next' - style={{ cursor: 'pointer' }} - /> - - )} - - ), - isSelected: this.props.currentTab === item.id, - }; - }; - - render() { - const items = this.appCategories.map(({ apps, ...rest }) => ({ - ...rest, - items: this.createItems( - apps.map(app => ({ - id: app.id, - title: app.title, - isPin: this.props.pinnedApplications.includes(app.id), - })), - ), - })); - - return ( -
-
- - {items.map(item => ( - - , - items: item.items, - }, - ]} - style={{ padding: '4px 12px' }} - /> - - ))} - -
-
- ); - } -} - -const mapStateToProps = state => { - return { - currentAgentData: state.appStateReducers.currentAgentData, - currentTab: state.appStateReducers.currentTab, - }; -}; - -const mapDispatchToProps = dispatch => ({ - updateCurrentAgentData: agentData => - dispatch(updateCurrentAgentData(agentData)), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(WzMenuAgent); diff --git a/plugins/main/public/components/wz-menu/wz-menu.scss b/plugins/main/public/components/wz-menu/wz-menu.scss index 02afe9d394..7eed9064ed 100644 --- a/plugins/main/public/components/wz-menu/wz-menu.scss +++ b/plugins/main/public/components/wz-menu/wz-menu.scss @@ -244,11 +244,3 @@ md-toolbar .md-button { height: 16px !important; margin-right: 6px; } - -.WzManagementSideMenu { - padding: 16px; -} - -.WzManagementSideMenu span { - font-size: 14px !important; -} From 93c017d4192474d1093a2f919f3d4ff150a456fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20David=20Guti=C3=A9rrez?= Date: Wed, 29 Nov 2023 14:32:10 +0100 Subject: [PATCH 3/3] changelog: add pull request entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b96d858fd..90c0bd90b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) +- Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) ### Changed @@ -30,6 +31,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed the `disabled_roles` and `customization.logo.sidebar` settings [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Removed the ability to configure the visibility of modules and removed `extensions.*` settings [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) +- Removed the application menu in the IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) ## Wazuh v4.7.1 - OpenSearch Dashboards 2.8.0 - Revision 01