Skip to content

Commit

Permalink
Refactor Asset Inventory page
Browse files Browse the repository at this point in the history
  • Loading branch information
albertoblaz committed Mar 3, 2025
1 parent 86973f5 commit c50144e
Show file tree
Hide file tree
Showing 19 changed files with 239 additions and 293 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,9 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
import illustration from '../../common/images/illustration_product_no_results_magnifying_glass.svg';
import { DOCS_URL, TEST_SUBJ_EMPTY_STATE, I18N_PREFIX } from '../constants';

const ASSET_INVENTORY_DOCS_URL = 'https://ela.st/asset-inventory';
const EMPTY_STATE_TEST_SUBJ = 'assetInventory:empty-state';

export const EmptyState = ({
onResetFilters,
docsUrl = ASSET_INVENTORY_DOCS_URL,
}: {
onResetFilters: () => void;
docsUrl?: string;
}) => {
export const EmptyState = ({ onResetFilters }: { onResetFilters: () => void }) => {
const { euiTheme } = useEuiTheme();

return (
Expand All @@ -35,11 +27,11 @@ export const EmptyState = ({
margin-top: ${euiTheme.size.xxxl}};
}
`}
data-test-subj={EMPTY_STATE_TEST_SUBJ}
data-test-subj={TEST_SUBJ_EMPTY_STATE}
icon={
<EuiImage
url={illustration}
alt={i18n.translate('xpack.securitySolution.assetInventory.emptyState.illustrationAlt', {
alt={i18n.translate(`${I18N_PREFIX}.emptyState.illustrationAlt`, {
defaultMessage: 'No results',
})}
css={css`
Expand All @@ -50,7 +42,7 @@ export const EmptyState = ({
title={
<h2>
<FormattedMessage
id="xpack.securitySolution.assetInventory.emptyState.title"
id={`${I18N_PREFIX}.emptyState.title`}
defaultMessage="No results match your search criteria"
/>
</h2>
Expand All @@ -61,7 +53,7 @@ export const EmptyState = ({
<>
<p>
<FormattedMessage
id="xpack.securitySolution.assetInventory.emptyState.description"
id={`${I18N_PREFIX}.emptyState.description`}
defaultMessage="Try modifying your search or filter set"
/>
</p>
Expand All @@ -70,13 +62,13 @@ export const EmptyState = ({
actions={[
<EuiButton color="primary" fill onClick={onResetFilters}>
<FormattedMessage
id="xpack.securitySolution.assetInventory.emptyState.resetFiltersButton"
id={`${I18N_PREFIX}.emptyState.resetFiltersButton`}
defaultMessage="Reset filters"
/>
</EuiButton>,
<EuiLink href={docsUrl} target="_blank">
<EuiLink href={DOCS_URL} target="_blank">
<FormattedMessage
id="xpack.securitySolution.assetInventory.emptyState.readDocsLink"
id={`${I18N_PREFIX}.emptyState.readDocsLink`}
defaultMessage="Read the docs"
/>
</EuiLink>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,37 @@ import type { FilterControlConfig } from '@kbn/alerts-ui-shared';
import type { Filter } from '@kbn/es-query';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { ControlGroupRenderer } from '@kbn/controls-plugin/public';
import { useDataViewContext } from '../../hooks/data_view_context';
import { useSpaceId } from '../../../common/hooks/use_space_id';
import { ASSET_INVENTORY_INDEX_PATTERN } from '../../constants';
import { useDataViewContext } from '../../hooks/data_view_context';
import type { AssetsURLQuery } from '../../hooks/use_asset_inventory_data_table';
import { ASSET_INVENTORY_INDEX_PATTERN, I18N_PREFIX } from '../../constants';
import { FilterGroupLoading } from './filters_loading';
import { ASSET_INVENTORY_RULE_TYPE_IDS } from './rule_type_ids';

const DEFAULT_ASSET_INVENTORY_FILTERS: FilterControlConfig[] = [
{
title: i18n.translate('xpack.securitySolution.assetInventory.filters.type', {
defaultMessage: 'Type',
}),
title: i18n.translate(`${I18N_PREFIX}.filters.type`, { defaultMessage: 'Type' }),
fieldName: 'entity.category',
},
{
title: i18n.translate('xpack.securitySolution.assetInventory.filters.criticality', {
defaultMessage: 'Criticality',
}),
title: i18n.translate(`${I18N_PREFIX}.filters.criticality`, { defaultMessage: 'Criticality' }),
fieldName: 'asset.criticality',
},
{
title: i18n.translate('xpack.securitySolution.assetInventory.filters.tags', {
defaultMessage: 'Tags',
}),
title: i18n.translate(`${I18N_PREFIX}.filters.tags`, { defaultMessage: 'Tags' }),
fieldName: 'asset.tags.name',
},
{
title: i18n.translate('xpack.securitySolution.assetInventory.filters.name', {
defaultMessage: 'Name',
}),
title: i18n.translate(`${I18N_PREFIX}.filters.name`, { defaultMessage: 'Name' }),
fieldName: 'asset.name',
},
];

export interface FiltersProps {
onFiltersChange: (newFilters: Filter[]) => void;
setQuery: (v: Partial<AssetsURLQuery>) => void;
}

export const Filters = ({ onFiltersChange }: FiltersProps) => {
export const Filters = ({ setQuery }: FiltersProps) => {
const { dataView, dataViewIsLoading } = useDataViewContext();
const spaceId = useSpaceId();

Expand Down Expand Up @@ -85,7 +78,9 @@ export const Filters = ({ onFiltersChange }: FiltersProps) => {
<EuiSpacer size="l" />
<FilterGroup
dataViewId={dataViewSpec?.id || null}
onFiltersChange={onFiltersChange}
onFiltersChange={(filters: Filter[]) => {
setQuery({ filters });
}}
ruleTypeIds={ASSET_INVENTORY_RULE_TYPE_IDS}
Storage={Storage}
defaultControls={DEFAULT_ASSET_INVENTORY_FILTERS}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
import React from 'react';
import { EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { I18N_PREFIX } from '../constants';

export const InventoryTitle = () => {
return (
<EuiTitle size="l" data-test-subj="inventory-title">
<h1>
<FormattedMessage
id="xpack.securitySolution.assetInventory.inventoryTitle"
defaultMessage="Inventory"
/>
<FormattedMessage id={`${I18N_PREFIX}.inventoryTitle`} defaultMessage="Inventory" />
</h1>
</EuiTitle>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,29 @@ import { EuiBadge, EuiToolTip } from '@elastic/eui';
import { RiskSeverity } from '../../../common/search_strategy';
import { RISK_SEVERITY_COLOUR } from '../../entity_analytics/common/utils';
import { getRiskLevel } from '../../../common/entity_analytics/risk_engine/risk_levels';
import { I18N_PREFIX } from '../constants';

export interface RiskBadgeProps {
risk: number;
'data-test-subj'?: string;
}

const tooltips = {
[RiskSeverity.Unknown]: i18n.translate(
'xpack.securitySolution.assetInventory.allAssets.risks.unknown',
{ defaultMessage: RiskSeverity.Unknown }
),
[RiskSeverity.Low]: i18n.translate('xpack.securitySolution.assetInventory.allAssets.risks.low', {
[RiskSeverity.Unknown]: i18n.translate(`${I18N_PREFIX}.risks.unknown`, {
defaultMessage: RiskSeverity.Unknown,
}),
[RiskSeverity.Low]: i18n.translate(`${I18N_PREFIX}.risks.low`, {
defaultMessage: RiskSeverity.Low,
}),
[RiskSeverity.Moderate]: i18n.translate(
'xpack.securitySolution.assetInventory.allAssets.risks.moderate',
{ defaultMessage: RiskSeverity.Moderate }
),
[RiskSeverity.High]: i18n.translate(
'xpack.securitySolution.assetInventory.allAssets.risks.high',
{ defaultMessage: RiskSeverity.High }
),
[RiskSeverity.Critical]: i18n.translate(
'xpack.securitySolution.assetInventory.allAssets.risks.critical',
{ defaultMessage: RiskSeverity.Critical }
),
[RiskSeverity.Moderate]: i18n.translate(`${I18N_PREFIX}.risks.moderate`, {
defaultMessage: RiskSeverity.Moderate,
}),
[RiskSeverity.High]: i18n.translate(`${I18N_PREFIX}.risks.high`, {
defaultMessage: RiskSeverity.High,
}),
[RiskSeverity.Critical]: i18n.translate(`${I18N_PREFIX}.risks.critical`, {
defaultMessage: RiskSeverity.Critical,
}),
};

export const RiskBadge = ({ risk, ...props }: RiskBadgeProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,23 @@ import type { Filter } from '@kbn/es-query';
import { useKibana } from '../../common/lib/kibana';
import { FiltersGlobal } from '../../common/components/filters_global/filters_global';
import { useDataViewContext } from '../hooks/data_view_context';
import type { AssetsBaseURLQuery } from '../hooks/use_asset_inventory_data_table';

type SearchBarQueryProps = Pick<AssetsBaseURLQuery, 'query' | 'filters'>;
import type { AssetsURLQuery } from '../hooks/use_asset_inventory_data_table';
import { I18N_PREFIX } from '../constants';

interface AssetInventorySearchBarProps {
setQuery(v: Partial<SearchBarQueryProps>): void;
setQuery(v: Partial<AssetsURLQuery>): void;
loading: boolean;
placeholder?: string;
query: SearchBarQueryProps;
query: AssetsURLQuery;
}

export const AssetInventorySearchBar = ({
loading,
query,
setQuery,
placeholder = i18n.translate(
'xpack.securitySolution.assetInventory.searchBar.searchPlaceholder',
{
defaultMessage: 'Filter your data using KQL syntax',
}
),
placeholder = i18n.translate(`${I18N_PREFIX}.searchBar.searchPlaceholder`, {
defaultMessage: 'Filter your data using KQL syntax',
}),
}: AssetInventorySearchBarProps) => {
const { euiTheme } = useEuiTheme();
const {
Expand All @@ -54,7 +50,7 @@ export const AssetInventorySearchBar = ({
isLoading={loading}
indexPatterns={[dataView]}
onQuerySubmit={setQuery}
onFiltersUpdated={(value: Filter[]) => setQuery({ filters: value })}
onFiltersUpdated={(filters: Filter[]) => setQuery({ filters })}
placeholder={placeholder}
query={{
query: query?.query?.query || '',
Expand All @@ -69,6 +65,6 @@ export const AssetInventorySearchBar = ({

const getContainerStyle = (theme: EuiThemeComputed) => css`
border-bottom: ${theme.border.thin};
background-color: ${theme.colors.body};
background-color: ${theme.colors.backgroundBaseSubdued};
padding: ${theme.size.base};
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { css } from '@emotion/react';
import { EuiBetaBadge, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { I18N_PREFIX } from '../constants';

export const TechnicalPreviewBadge = () => {
const { euiTheme } = useEuiTheme();

return (
<EuiBetaBadge
css={css`
margin-left: ${euiTheme.size.s};
`}
label={i18n.translate(`${I18N_PREFIX}.technicalPreviewLabel`, {
defaultMessage: 'Technical Preview',
})}
size="s"
color="subdued"
tooltipContent={i18n.translate(`${I18N_PREFIX}.technicalPreviewTooltip`, {
defaultMessage:
'This functionality is experimental and not supported. It may change or be removed at any time.',
})}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,15 @@ import { Chart, Settings, Axis, BarSeries, Position, ScaleType } from '@elastic/
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
import type { AggregationResult } from '../hooks/use_fetch_chart_data';
import { I18N_PREFIX } from '../constants';

const chartTitle = i18n.translate(
'xpack.securitySolution.assetInventory.topAssetsBarChart.chartTitle',
{
defaultMessage: 'Top 10 Asset Types',
}
);
const chartTitle = i18n.translate(`${I18N_PREFIX}.topAssetsBarChart.chartTitle`, {
defaultMessage: 'Top 10 Asset Types',
});

const yAxisTitle = i18n.translate(
'xpack.securitySolution.assetInventory.topAssetsBarChart.yAxisTitle',
{
defaultMessage: 'Count of Assets',
}
);
const yAxisTitle = i18n.translate(`${I18N_PREFIX}.topAssetsBarChart.yAxisTitle`, {
defaultMessage: 'Count of Assets',
});

const chartStyles = { height: '260px' };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
* 2.0.
*/

export const MAX_ASSETS_TO_LOAD = 500; // equivalent to MAX_FINDINGS_TO_LOAD in @kbn/cloud-security-posture-common
export const MAX_ASSETS_TO_LOAD = 500;
export const DEFAULT_VISIBLE_ROWS_PER_PAGE = 25;
export const ASSET_INVENTORY_INDEX_PATTERN = 'logs-cloud_asset_inventory.asset_inventory-*';

export const QUERY_KEY_GRID_DATA = 'asset_inventory_grid_data';
export const QUERY_KEY_CHART_DATA = 'asset_inventory_chart_data';

export const ASSET_INVENTORY_TABLE_ID = 'asset-inventory-table';

const LOCAL_STORAGE_PREFIX = 'assetInventory';
export const LOCAL_STORAGE_COLUMNS_KEY = `${LOCAL_STORAGE_PREFIX}:columns`;
export const LOCAL_STORAGE_COLUMNS_SETTINGS_KEY = `${LOCAL_STORAGE_COLUMNS_KEY}:settings`;
export const LOCAL_STORAGE_DATA_TABLE_PAGE_SIZE_KEY = `${LOCAL_STORAGE_PREFIX}:dataTable:pageSize`;
export const LOCAL_STORAGE_DATA_TABLE_COLUMNS_KEY = `${LOCAL_STORAGE_PREFIX}:dataTable:columns`;

export const TEST_SUBJ_DATA_GRID = 'asset-inventory-test-subj-grid-wrapper';
export const TEST_SUBJ_PAGE_TITLE = 'asset-inventory-test-subj-page-title';
export const TEST_SUBJ_EMPTY_STATE = 'asset-inventory-empty-state';

export const I18N_PREFIX = 'xpack.securitySolution.assetInventory';

export const DOCS_URL = 'https://ela.st/asset-inventory';
Loading

0 comments on commit c50144e

Please sign in to comment.