diff --git a/x-pack/plugins/data_usage/common/index.ts b/x-pack/plugins/data_usage/common/index.ts
index eb0787f53f344..8b952b13d4cc7 100644
--- a/x-pack/plugins/data_usage/common/index.ts
+++ b/x-pack/plugins/data_usage/common/index.ts
@@ -12,6 +12,8 @@ export const PLUGIN_NAME = i18n.translate('xpack.dataUsage.name', {
defaultMessage: 'Data Usage',
});
+export const DEFAULT_SELECTED_OPTIONS = 50 as const;
+
export const DATA_USAGE_API_ROUTE_PREFIX = '/api/data_usage/';
export const DATA_USAGE_METRICS_API_ROUTE = `/internal${DATA_USAGE_API_ROUTE_PREFIX}metrics`;
export const DATA_USAGE_DATA_STREAMS_API_ROUTE = `/internal${DATA_USAGE_API_ROUTE_PREFIX}data_streams`;
diff --git a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.test.tsx b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.test.tsx
index 951a8eca08802..72814a0f09c5f 100644
--- a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.test.tsx
+++ b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.test.tsx
@@ -4,9 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
import React from 'react';
-
import { render, waitFor } from '@testing-library/react';
import userEvent, { type UserEvent } from '@testing-library/user-event';
import { DataUsageMetrics } from './data_usage_metrics';
@@ -147,6 +145,13 @@ const getBaseMockedDataUsageMetrics = () => ({
refetch: jest.fn(),
});
+const generateDataStreams = (count: number) => {
+ return Array.from({ length: count }, (_, i) => ({
+ name: `.ds-${i}`,
+ storageSizeBytes: 1024 ** 2 * (22 / 7),
+ }));
+};
+
describe('DataUsageMetrics', () => {
let user: UserEvent;
const testId = 'test';
@@ -174,8 +179,9 @@ describe('DataUsageMetrics', () => {
it('should show date filter', () => {
const { getByTestId } = render();
- expect(getByTestId(`${testIdFilter}-date-range`)).toBeTruthy();
- expect(getByTestId(`${testIdFilter}-date-range`).textContent).toContain('Last 24 hours');
+ const dateFilter = getByTestId(`${testIdFilter}-date-range`);
+ expect(dateFilter).toBeTruthy();
+ expect(dateFilter.textContent).toContain('to');
expect(getByTestId(`${testIdFilter}-super-refresh-button`)).toBeTruthy();
});
@@ -196,28 +202,7 @@ describe('DataUsageMetrics', () => {
it('should show selected data streams on the filter', () => {
mockUseGetDataUsageDataStreams.mockReturnValue({
error: undefined,
- data: [
- {
- name: '.ds-1',
- storageSizeBytes: 10000,
- },
- {
- name: '.ds-2',
- storageSizeBytes: 20000,
- },
- {
- name: '.ds-3',
- storageSizeBytes: 10300,
- },
- {
- name: '.ds-4',
- storageSizeBytes: 23000,
- },
- {
- name: '.ds-5',
- storageSizeBytes: 23200,
- },
- ],
+ data: generateDataStreams(5),
isFetching: false,
});
const { getByTestId } = render();
@@ -226,46 +211,35 @@ describe('DataUsageMetrics', () => {
);
});
+ it('should show at most 50 selected data streams on the filter', async () => {
+ mockUseGetDataUsageDataStreams.mockReturnValue({
+ error: undefined,
+ data: generateDataStreams(100),
+ isFetching: false,
+ });
+ const { getByTestId } = render();
+ const toggleFilterButton = getByTestId(`${testIdFilter}-dataStreams-popoverButton`);
+
+ expect(toggleFilterButton).toHaveTextContent('Data streams50');
+ });
+
it('should allow de-selecting all but one data stream option', async () => {
mockUseGetDataUsageDataStreams.mockReturnValue({
error: undefined,
- data: [
- {
- name: '.ds-1',
- storageSizeBytes: 10000,
- },
- {
- name: '.ds-2',
- storageSizeBytes: 20000,
- },
- {
- name: '.ds-3',
- storageSizeBytes: 10300,
- },
- {
- name: '.ds-4',
- storageSizeBytes: 23000,
- },
- {
- name: '.ds-5',
- storageSizeBytes: 23200,
- },
- ],
+ data: generateDataStreams(5),
isFetching: false,
});
const { getByTestId, getAllByTestId } = render();
- expect(getByTestId(`${testIdFilter}-dataStreams-popoverButton`)).toHaveTextContent(
- 'Data streams5'
- );
- await user.click(getByTestId(`${testIdFilter}-dataStreams-popoverButton`));
+ const toggleFilterButton = getByTestId(`${testIdFilter}-dataStreams-popoverButton`);
+
+ expect(toggleFilterButton).toHaveTextContent('Data streams5');
+ await user.click(toggleFilterButton);
const allFilterOptions = getAllByTestId('dataStreams-filter-option');
for (let i = 0; i < allFilterOptions.length - 1; i++) {
await user.click(allFilterOptions[i]);
}
- expect(getByTestId(`${testIdFilter}-dataStreams-popoverButton`)).toHaveTextContent(
- 'Data streams1'
- );
+ expect(toggleFilterButton).toHaveTextContent('Data streams1');
});
it('should not call usage metrics API if no data streams', async () => {
diff --git a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx
index 59354a1746346..8bedde117785a 100644
--- a/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx
+++ b/x-pack/plugins/data_usage/public/app/components/data_usage_metrics.tsx
@@ -72,7 +72,9 @@ export const DataUsageMetrics = memo(
setUrlMetricTypesFilter(metricsFilters.metricTypes.join(','));
}
if (!dataStreamsFromUrl && dataStreams) {
- setUrlDataStreamsFilter(dataStreams.map((ds) => ds.name).join(','));
+ const hasMoreThan50 = dataStreams.length > 50;
+ const _dataStreams = hasMoreThan50 ? dataStreams.slice(0, 50) : dataStreams;
+ setUrlDataStreamsFilter(_dataStreams.map((ds) => ds.name).join(','));
}
if (!startDateFromUrl || !endDateFromUrl) {
setUrlDateRangeFilter({ startDate: metricsFilters.from, endDate: metricsFilters.to });
diff --git a/x-pack/plugins/data_usage/public/app/components/filters/date_picker.tsx b/x-pack/plugins/data_usage/public/app/components/filters/date_picker.tsx
index 044a036eea61f..62c6cc542a523 100644
--- a/x-pack/plugins/data_usage/public/app/components/filters/date_picker.tsx
+++ b/x-pack/plugins/data_usage/public/app/components/filters/date_picker.tsx
@@ -15,6 +15,7 @@ import type {
OnRefreshChangeProps,
} from '@elastic/eui/src/components/date_picker/types';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
+import moment from 'moment';
import { useTestIdGenerator } from '../../../hooks/use_test_id_generator';
export interface DateRangePickerValues {
@@ -66,7 +67,7 @@ export const UsageMetricsDateRangePicker = memo
);
diff --git a/x-pack/plugins/data_usage/public/app/hooks/use_charts_filter.tsx b/x-pack/plugins/data_usage/public/app/hooks/use_charts_filter.tsx
index 5cff100d9752e..d2c5dc554ff2d 100644
--- a/x-pack/plugins/data_usage/public/app/hooks/use_charts_filter.tsx
+++ b/x-pack/plugins/data_usage/public/app/hooks/use_charts_filter.tsx
@@ -11,6 +11,7 @@ import {
METRIC_TYPE_API_VALUES_TO_UI_OPTIONS_MAP,
METRIC_TYPE_VALUES,
} from '../../../common/rest_types';
+import { DEFAULT_SELECTED_OPTIONS } from '../../../common';
import { FILTER_NAMES } from '../translations';
import { useDataUsageMetricsUrlParams } from './use_charts_url_params';
import { formatBytes } from '../../utils/format_bytes';
@@ -77,7 +78,7 @@ export const useChartsFilter = ({
'data-test-subj': `${filterOptions.filterName}-filter-option`,
}))
: isDataStreamsFilter && !!filterOptions.options.length
- ? filterOptions.options?.map((filterOption) => ({
+ ? filterOptions.options?.map((filterOption, i) => ({
key: filterOption,
label: filterOption,
append: formatBytes(filterOptions.appendOptions?.[filterOption] ?? 0),
@@ -85,7 +86,9 @@ export const useChartsFilter = ({
? selectedDataStreamsFromUrl.includes(filterOption)
? 'on'
: undefined
- : 'on',
+ : i < DEFAULT_SELECTED_OPTIONS
+ ? 'on'
+ : undefined,
'data-test-subj': `${filterOptions.filterName}-filter-option`,
}))
: []
diff --git a/x-pack/plugins/data_usage/public/app/hooks/use_charts_url_params.test.tsx b/x-pack/plugins/data_usage/public/app/hooks/use_charts_url_params.test.tsx
index 93a4b434931a3..2b009f05f3bb1 100644
--- a/x-pack/plugins/data_usage/public/app/hooks/use_charts_url_params.test.tsx
+++ b/x-pack/plugins/data_usage/public/app/hooks/use_charts_url_params.test.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import moment from 'moment';
import { METRIC_TYPE_VALUES, MetricTypes } from '../../../common/rest_types';
import { getDataUsageMetricsFiltersFromUrlParams } from './use_charts_url_params';
@@ -56,12 +57,12 @@ describe('#getDataUsageMetricsFiltersFromUrlParams', () => {
it('should use given relative startDate and endDate values URL params', () => {
expect(
getDataUsageMetricsFiltersFromUrlParams({
- startDate: 'now-24h/h',
- endDate: 'now',
+ startDate: moment().subtract(24, 'hours').toISOString(),
+ endDate: moment().toISOString(),
})
).toEqual({
- endDate: 'now',
- startDate: 'now-24h/h',
+ endDate: moment().toISOString(),
+ startDate: moment().subtract(24, 'hours').toISOString(),
});
});
diff --git a/x-pack/plugins/data_usage/public/app/hooks/use_date_picker.tsx b/x-pack/plugins/data_usage/public/app/hooks/use_date_picker.tsx
index cc4bfd2376da1..1b4b7e38e3554 100644
--- a/x-pack/plugins/data_usage/public/app/hooks/use_date_picker.tsx
+++ b/x-pack/plugins/data_usage/public/app/hooks/use_date_picker.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import moment from 'moment';
import { useCallback, useState } from 'react';
import type {
DurationRange,
@@ -18,8 +19,8 @@ export const DEFAULT_DATE_RANGE_OPTIONS = Object.freeze({
enabled: false,
duration: 10000,
},
- startDate: 'now-24h/h',
- endDate: 'now',
+ startDate: moment().subtract(24, 'hours').startOf('day').toISOString(),
+ endDate: moment().toISOString(),
recentlyUsedDateRanges: [],
});
diff --git a/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts b/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts
index acb41e45f4eb6..d43c3fff139fb 100644
--- a/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts
+++ b/x-pack/plugins/data_usage/public/hooks/use_get_data_streams.ts
@@ -8,7 +8,7 @@
import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core-http-browser';
-import { DATA_USAGE_DATA_STREAMS_API_ROUTE } from '../../common';
+import { DATA_USAGE_DATA_STREAMS_API_ROUTE, DEFAULT_SELECTED_OPTIONS } from '../../common';
import { useKibanaContextForPlugin } from '../utils/use_kibana';
type GetDataUsageDataStreamsResponse = Array<{
@@ -17,11 +17,6 @@ type GetDataUsageDataStreamsResponse = Array<{
selected: boolean;
}>;
-const PAGING_PARAMS = Object.freeze({
- default: 50,
- all: 10000,
-});
-
export const useGetDataUsageDataStreams = ({
selectedDataStreams,
options = {
@@ -51,14 +46,14 @@ export const useGetDataUsageDataStreams = ({
selected: GetDataUsageDataStreamsResponse;
rest: GetDataUsageDataStreamsResponse;
}>(
- (acc, ds) => {
+ (acc, ds, i) => {
const item = {
name: ds.name,
storageSizeBytes: ds.storageSizeBytes,
selected: ds.selected,
};
- if (selectedDataStreams?.includes(ds.name)) {
+ if (selectedDataStreams?.includes(ds.name) && i < DEFAULT_SELECTED_OPTIONS) {
acc.selected.push({ ...item, selected: true });
} else {
acc.rest.push({ ...item, selected: false });
@@ -69,20 +64,10 @@ export const useGetDataUsageDataStreams = ({
{ selected: [], rest: [] }
);
- let selectedDataStreamsCount = 0;
- if (selectedDataStreams) {
- selectedDataStreamsCount = selectedDataStreams.length;
- }
-
return [
...augmentedDataStreamsBasedOnSelectedItems.selected,
...augmentedDataStreamsBasedOnSelectedItems.rest,
- ].slice(
- 0,
- selectedDataStreamsCount >= PAGING_PARAMS.default
- ? selectedDataStreamsCount + 10
- : PAGING_PARAMS.default
- );
+ ];
},
});
};
diff --git a/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.test.tsx b/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.test.tsx
index efc3d2a9f4640..677bd4bdfcef1 100644
--- a/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.test.tsx
+++ b/x-pack/plugins/data_usage/public/hooks/use_get_usage_metrics.test.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import moment from 'moment';
import React, { ReactNode } from 'react';
import { QueryClient, QueryClientProvider, useQuery as _useQuery } from '@tanstack/react-query';
import { renderHook } from '@testing-library/react-hooks';
@@ -41,8 +42,8 @@ jest.mock('../utils/use_kibana', () => {
});
const defaultUsageMetricsRequestBody = {
- from: 'now-15m',
- to: 'now',
+ from: moment().subtract(15, 'minutes').toISOString(),
+ to: moment().toISOString(),
metricTypes: ['ingest_rate'],
dataStreams: ['ds-1'],
};
diff --git a/x-pack/plugins/data_usage/server/routes/internal/usage_metrics.test.ts b/x-pack/plugins/data_usage/server/routes/internal/usage_metrics.test.ts
index 2c236e58a5af1..d6337bbcc8dcd 100644
--- a/x-pack/plugins/data_usage/server/routes/internal/usage_metrics.test.ts
+++ b/x-pack/plugins/data_usage/server/routes/internal/usage_metrics.test.ts
@@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
+import moment from 'moment';
import type { MockedKeys } from '@kbn/utility-types-jest';
import type { CoreSetup } from '@kbn/core/server';
import { registerUsageMetricsRoute } from './usage_metrics';
@@ -56,8 +56,8 @@ describe('registerUsageMetricsRoute', () => {
const mockRequest = httpServerMock.createKibanaRequest({
body: {
- from: 'now-15m',
- to: 'now',
+ from: moment().subtract(15, 'minutes').toISOString(),
+ to: moment().toISOString(),
metricTypes: ['ingest_rate'],
dataStreams: [],
},
@@ -123,8 +123,8 @@ describe('registerUsageMetricsRoute', () => {
const mockRequest = httpServerMock.createKibanaRequest({
body: {
- from: 'now-15m',
- to: 'now',
+ from: moment().subtract(15, 'minutes').toISOString(),
+ to: moment().toISOString(),
metricTypes: ['ingest_rate', 'storage_retained'],
dataStreams: ['.ds-1', '.ds-2'],
},
@@ -191,8 +191,8 @@ describe('registerUsageMetricsRoute', () => {
const mockRequest = httpServerMock.createKibanaRequest({
body: {
- from: 'now-15m',
- to: 'now',
+ from: moment().subtract(15, 'minutes').toISOString(),
+ to: moment().toISOString(),
metricTypes: ['ingest_rate'],
dataStreams: ['.ds-1', '.ds-2'],
},