Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 4.11.0 into 4.12.0 #7248

Merged
merged 7 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ All notable changes to the Wazuh app project will be documented in this file.
- Refined the layout of the agent details view [#7193](https://github.com/wazuh/wazuh-dashboard-plugins/issues/7193)
- Changed the width of the command column, relocate argvs column and change the width of the rest of the columns in the table processes. [#7195](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7195)

## Wazuh v4.10.1 - OpenSearch Dashboards 2.16.0 - Revision 00
## Wazuh v4.10.1 - OpenSearch Dashboards 2.16.0 - Revision 01

### Added

- Support for Wazuh 4.10.1
- Added comma separators to numbers [#7233](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7233)

### Changed

- Move the ability to manage the visibility of fields in `Events` and `Vulnerability Detection` > `Inventory` tables from `Columns` button to a new `Available fields` button enhancing the performance of the view [#7226](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7226)
- Change the color of `Export formatted` button of data grid tables to match the color of the rest of table buttons [#7226](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7226)

## Wazuh v4.10.0 - OpenSearch Dashboards 2.16.0 - Revision 08

Expand Down Expand Up @@ -87,6 +93,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Fixed error message to prevent pass no strings to the wazuh logger [#7167](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7167)
- Fixed the rendering of the `data.vunerability.reference` in the table and flyout [#7177](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7177)
- Fixed incorrect or empty Wazuh API version displayed after upgrade [#440](https://github.com/wazuh/wazuh-dashboard/issues/440)
- Fixed typo in flyout title for available updates [#7235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7235)

### Removed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { EuiListGroup } from '@elastic/eui';
import './legend.scss';
import { formatUINumber } from '../../../../react-services/format-number';

type ChartLegendProps = {
data: {
Expand All @@ -24,7 +25,7 @@ export function ChartLegend({ data }: ChartLegendProps) {
textOverflow: 'ellipsis',
overflow: 'hidden',
}}
>{`${label} (${value})`}</div>
>{`${label} (${formatUINumber(value)})`}</div>
),
icon: <EuiIcon type='dot' size='l' color={labelColor} />,
...rest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,10 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => {

return {
'aria-labelledby': props.ariaLabelledBy,
columns: orderFirstMatchedColumns(getColumns, visibleColumns),
columnsAvailable: orderFirstMatchedColumns(getColumns, visibleColumns), // This is a custom property used by the Available fields and is not part of EuiDataGrid component specification
columns: visibleColumns.map(columnId =>
getColumns.find(({ id }) => id === columnId),
),
columnVisibility: {
visibleColumns,
setVisibleColumns,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { TableDefault } from './table-default';
import { WzRequest } from '../../../react-services/wz-request';
import { ExportTableCsv } from './components/export-table-csv';
import { useStateStorage, useAppConfig } from '../hooks';
import { formatUINumber } from '../../../react-services/format-number';

/**
* Search input custom filter button
*/
Expand Down Expand Up @@ -217,7 +219,7 @@ export function TableWzAPI({
{isLoading ? (
<EuiLoadingSpinner size='s' />
) : (
<span>({totalItems})</span>
<span>({formatUINumber(totalItems)})</span>
)}
</h1>
</EuiTitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ const WazuhDataGrid = (props: tWazuhDataGridProps) => {
{!isLoading && results?.hits?.total > 0 ? (
<div className='wazuhDataGridContainer'>
<EuiDataGrid
/* TODO: this component is not used in the current plugins so this could be removed.
If this is used in future versions, we should add the functionality to manage the
visibility of columns thorugh the Available fields button.
*/
{...dataGridProps}
className={sideNavDocked ? 'dataGridDockedNav' : ''}
toolbarVisibility={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ import {
EuiFlexItem,
EuiFlexGroup,
EuiText,
EuiDataGridColumn,
EuiDataGridColumnVisibility,
} from '@elastic/eui';
import { HitsCounter } from '../../../../kibana-integrations/discover/application/components/hits_counter';
import { formatNumWithCommas } from '../../../../kibana-integrations/discover/application/helpers';
import { MAX_ENTRIES_PER_QUERY } from '../../data-grid/data-grid-service';
import { formatUIDate } from '../../../../react-services/time-service';
import { DataGridVisibleColumnsSelector } from './visible-columns-selector';

type tDiscoverDataGridAdditionalControlsProps = {
totalHits: number;
isExporting: boolean;
onClickExportResults: () => void;
maxEntriesPerQuery?: number;
dateRange: TimeRange;
columnsAvailable: EuiDataGridColumn[];
columnVisibility: EuiDataGridColumnVisibility;
};

const DiscoverDataGridAdditionalControls = (
Expand All @@ -27,8 +32,9 @@ const DiscoverDataGridAdditionalControls = (
maxEntriesPerQuery = MAX_ENTRIES_PER_QUERY,
onClickExportResults,
dateRange,
columnsAvailable,
columnVisibility,
} = props;

const onHandleExportResults = () => {
onClickExportResults && onClickExportResults();
};
Expand Down Expand Up @@ -69,13 +75,18 @@ const DiscoverDataGridAdditionalControls = (
disabled={totalHits === 0 || isExporting}
size='xs'
iconType='exportAction'
color='primary'
color='text'
isLoading={isExporting}
className='euiDataGrid__controlBtn'
onClick={onHandleExportResults}
>
Export Formatted
</EuiButtonEmpty>

<DataGridVisibleColumnsSelector
availableColumns={columnsAvailable}
columnVisibility={columnVisibility}
/>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import React, { useState, ChangeEvent } from 'react';
import { FormattedMessage } from '@osd/i18n/react';
import classNames from 'classnames';
import {
EuiPopover,
EuiPopoverTitle,
EuiButtonEmpty,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiSwitch,
EuiDataGridColumn,
EuiDataGridColumnVisibility,
EuiToolTip,
EuiIcon,
} from '@elastic/eui';

// Based on https://github.com/opensearch-project/oui/blob/1.8.1/src/components/datagrid/column_selector.tsx
// Only select visibility funcitonality
// Replace OuiI18n by FormattedMessage
export const DataGridVisibleColumnsSelector = ({
availableColumns,
columnVisibility,
}: {
availableColumns: EuiDataGridColumn[];
columnVisibility: EuiDataGridColumnVisibility;
}) => {
const [searchValue, setSearchValue] = useState('');
const [isOpen, setIsOpen] = useState(false);

const maxAvailableColumns = 500;

const { visibleColumns, setVisibleColumns } = columnVisibility;

const searchValueLowerCase = searchValue.toLowerCase();

const filteredColumns = (
searchValue
? availableColumns.filter(({ name }) =>
name.toLowerCase().includes(searchValueLowerCase),
)
: availableColumns
).slice(0, maxAvailableColumns);

const controlBtnClasses = classNames('euiDataGrid__controlBtn', {
// TODO: research if this is required
// 'euiDataGrid__controlBtn--active':
// availableColumns.length - visibleColumns.length > 0,
});

return (
<EuiPopover
data-test-subj='dataGridColumnSelectorPopover'
isOpen={isOpen}
closePopover={() => setIsOpen(false)}
anchorPosition='downLeft'
panelPaddingSize='s'
panelClassName='euiDataGridColumnSelectorPopover'
button={
<EuiButtonEmpty
iconType='listAdd'
iconSide='left'
size='xs'
color='text'
className={controlBtnClasses}
data-test-subj='dataGridColumnSelectorButton'
onClick={() => setIsOpen(!isOpen)}
>
<FormattedMessage
id='wz.discover.availableFields'
defaultMessage='{availableColumns} available fields'
values={{ availableColumns: availableColumns?.length ?? 0 }}
/>
{availableColumns.length > maxAvailableColumns && (
<EuiToolTip
position='top'
content={
<FormattedMessage
id='wz.discover.availableFields.warningTooltip'
defaultMessage='The number of columns exceeds the limit of {maxAvailableColumns}. Only the first {maxAvailableColumns} columns are displayed but you can still search on all columns.'
values={{ maxAvailableColumns }}
/>
}
>
<EuiIcon
className='wz-margin-left-4'
type='iInCircle'
aria-label='Info'
/>
</EuiToolTip>
)}
</EuiButtonEmpty>
}
>
<EuiPopoverTitle>
<EuiFieldText
fullWidth
compressed
placeholder='Search'
aria-label='Search columns'
value={searchValue}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchValue(e.currentTarget.value)
}
/>
</EuiPopoverTitle>
<div className='euiDataGrid__controlScroll'>
{filteredColumns.map(({ name, id }) => {
return (
<div key={id} className='euiDataGridColumnSelector__item'>
<EuiFlexGroup
responsive={false}
gutterSize='m'
alignItems='center'
>
<EuiFlexItem>
<EuiSwitch
name={id}
label={name}
checked={visibleColumns.includes(id)}
compressed
className='euiSwitch--mini'
onChange={event => {
const {
target: { checked },
} = event;

let nextVisibleColumns;

if (checked) {
if (!visibleColumns.includes(id)) {
nextVisibleColumns = [...visibleColumns, id];
}
} else {
if (visibleColumns.includes(id)) {
nextVisibleColumns = visibleColumns.filter(
(visibleColumnId: string) => visibleColumnId !== id,
);
}
}
if (nextVisibleColumns) {
setVisibleColumns(nextVisibleColumns);
}
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
})}
</div>
</EuiPopover>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,14 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => {
{...dataGridProps}
className={sideNavDocked ? 'dataGridDockedNav' : ''}
toolbarVisibility={{
showColumnSelector: { allowHide: false },
additionalControls: (
<>
<DiscoverDataGridAdditionalControls
totalHits={results?.hits?.total || 0}
isExporting={isExporting}
columnsAvailable={dataGridProps.columnsAvailable}
columnVisibility={dataGridProps.columnVisibility}
onClickExportResults={onClickExportResults}
maxEntriesPerQuery={MAX_ENTRIES_PER_QUERY}
dateRange={absoluteDateRange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { WzLink } from '../../../../../components/wz-link/wz-link';
import { withErrorBoundary } from '../../../../common/hocs';
import { compose } from 'redux';
import { withVulnerabilitiesStateDataSource } from '../../../../../components/overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern';
import { formatUINumber } from '../../../../../react-services/format-number';

const VulsPanelContent = ({ agent }) => {
const {
Expand Down Expand Up @@ -97,7 +98,7 @@ const VulsPanelContent = ({ agent }) => {
const value =
severityStats?.find(v => v.key.toUpperCase() === severity.toUpperCase())
?.doc_count || '0';
return value ? `${value} ${severity}` : '0';
return value ? `${formatUINumber(value)} ${severity}` : '0';
};

const renderSeverityStats = (severity, index) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '../dashboard/cluster_dashboard.scss';
import { getPlugins } from '../../../../kibana-services';
import { DiscoverNoResults } from '../../../common/no-results/no-results';
import { tFilter, tParsedIndexPattern } from '../../../common/data-source';
import { formatUINumber } from '../../../../react-services/format-number';

interface OverviewCardsProps {
goAgents: () => void;
Expand Down Expand Up @@ -155,7 +156,7 @@ export const OverviewCards = ({
onClick={goNodes}
style={{ height: 'auto' }}
>
{nodesCount}
{formatUINumber(nodesCount)}
</EuiButtonEmpty>
</EuiToolTip>
),
Expand Down Expand Up @@ -187,7 +188,7 @@ export const OverviewCards = ({
onClick={goAgents}
style={{ height: 'auto' }}
>
{agentsCount}
{formatUINumber(agentsCount)}
</EuiButtonEmpty>
</EuiToolTip>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import VulsEvaluationFilter, {
excludeUnderEvaluationFilter,
getUnderEvaluationFilterValue,
} from '../../common/components/vuls-evaluation-filter';
import { DataGridVisibleColumnsSelector } from '../../../../common/wazuh-discover/components/visible-columns-selector';

const InventoryVulsComponent = () => {
const {
Expand Down Expand Up @@ -255,6 +256,7 @@ const InventoryVulsComponent = () => {
{...dataGridProps}
className={sideNavDocked ? 'dataGridDockedNav' : ''}
toolbarVisibility={{
showColumnSelector: { allowHide: false },
additionalControls: (
<>
<HitsCounter
Expand Down Expand Up @@ -283,13 +285,18 @@ const InventoryVulsComponent = () => {
}
size='xs'
iconType='exportAction'
color='primary'
color='text'
isLoading={isExporting}
className='euiDataGrid__controlBtn'
onClick={onClickExportResults}
>
Export Formatted
</EuiButtonEmpty>

<DataGridVisibleColumnsSelector
availableColumns={dataGridProps.columnsAvailable}
columnVisibility={dataGridProps.columnVisibility}
/>
</>
),
}}
Expand Down
2 changes: 1 addition & 1 deletion plugins/main/public/components/settings/api/api-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ export const ApiTable = compose(withErrorBoundary)(
<EuiFlexItem grow={false}>
<WzButtonOpenFlyout
tooltip={{ content: 'View available updates' }}
flyoutTitle={'Availabe updates'}
flyoutTitle={'Available updates'}
flyoutBody={() => {
return <AvailableUpdatesFlyout api={api} />;
}}
Expand Down
Loading
Loading