Skip to content

Commit

Permalink
Merge branch 'main' into move-restructure-exception-api-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
WafaaNasr authored Oct 16, 2023
2 parents ec56eb3 + 0a002ed commit 5c86ff3
Show file tree
Hide file tree
Showing 21 changed files with 235 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ export type TestSubjects =
| 'filter-option-h'
| 'infiniteRetentionPeriod.input'
| 'saveButton'
| 'dataRetentionDetail'
| 'createIndexSaveButton';
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ export const createDataStreamPayload = (dataStream: Partial<DataStream>): DataSt
},
hidden: false,
lifecycle: {
enabled: true,
data_retention: '7d',
},
...dataStream,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,55 @@ describe('Data Streams tab', () => {
});

describe('update data retention', () => {
test('Should show disabled or infinite retention period accordingly in table and flyout', async () => {
const { setLoadDataStreamsResponse, setLoadDataStreamResponse } = httpRequestsMockHelpers;

const ds1 = createDataStreamPayload({
name: 'dataStream1',
lifecycle: {
enabled: false,
},
});
const ds2 = createDataStreamPayload({
name: 'dataStream2',
lifecycle: {
enabled: true,
},
});

setLoadDataStreamsResponse([ds1, ds2]);
setLoadDataStreamResponse(ds1.name, ds1);

testBed = await setup(httpSetup, {
history: createMemoryHistory(),
url: urlServiceMock,
});
await act(async () => {
testBed.actions.goToDataStreamsList();
});
testBed.component.update();

const { actions, find, table } = testBed;
const { tableCellsValues } = table.getMetaData('dataStreamTable');

expect(tableCellsValues).toEqual([
['', 'dataStream1', 'green', '1', 'Disabled', 'Delete'],
['', 'dataStream2', 'green', '1', '', 'Delete'],
]);

await actions.clickNameAt(0);
expect(find('dataRetentionDetail').text()).toBe('Disabled');

await act(async () => {
testBed.find('closeDetailsButton').simulate('click');
});
testBed.component.update();

setLoadDataStreamResponse(ds2.name, ds2);
await actions.clickNameAt(1);
expect(find('dataRetentionDetail').text()).toBe('Keep data indefinitely');
});

test('can set data retention period', async () => {
const {
actions: { clickNameAt, clickEditDataRetentionButton },
Expand Down
4 changes: 3 additions & 1 deletion x-pack/plugins/index_management/common/types/data_streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export interface DataStream {
_meta?: Metadata;
privileges: Privileges;
hidden: boolean;
lifecycle?: IndicesDataLifecycleWithRollover;
lifecycle?: IndicesDataLifecycleWithRollover & {
enabled?: boolean;
};
}

export interface DataStreamIndex {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 { getLifecycleValue } from './data_streams';

describe('Data stream helpers', () => {
describe('getLifecycleValue', () => {
it('Knows when it should be marked as disabled', () => {
expect(
getLifecycleValue({
enabled: false,
})
).toBe('Disabled');

expect(getLifecycleValue()).toBe('Disabled');
});

it('knows when it should be marked as infinite', () => {
expect(
getLifecycleValue({
enabled: true,
})
).toBe('Keep data indefinitely');
});

it('knows when it has a defined data retention period', () => {
expect(
getLifecycleValue({
enabled: true,
data_retention: '2d',
})
).toBe('2d');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
* 2.0.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiIcon, EuiToolTip } from '@elastic/eui';

import { DataStream } from '../../../common';

export const isFleetManaged = (dataStream: DataStream): boolean => {
Expand Down Expand Up @@ -38,3 +42,37 @@ export const isSelectedDataStreamHidden = (
?.hidden
);
};

export const getLifecycleValue = (
lifecycle?: DataStream['lifecycle'],
inifniteAsIcon?: boolean
) => {
if (!lifecycle?.enabled) {
return i18n.translate('xpack.idxMgmt.dataStreamList.dataRetentionDisabled', {
defaultMessage: 'Disabled',
});
} else if (!lifecycle?.data_retention) {
const infiniteDataRetention = i18n.translate(
'xpack.idxMgmt.dataStreamList.dataRetentionInfinite',
{
defaultMessage: 'Keep data indefinitely',
}
);

if (inifniteAsIcon) {
return (
<EuiToolTip
data-test-subj="infiniteRetention"
position="top"
content={infiniteDataRetention}
>
<EuiIcon type="infinity" />
</EuiToolTip>
);
}

return infiniteDataRetention;
}

return lifecycle?.data_retention;
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
} from '@elastic/eui';

import { DiscoverLink } from '../../../../lib/discover_link';
import { getLifecycleValue } from '../../../../lib/data_streams';
import { SectionLoading, reactRouterNavigate } from '../../../../../shared_imports';
import { SectionError, Error, DataHealth } from '../../../../components';
import { useLoadDataStream } from '../../../../services/api';
Expand Down Expand Up @@ -147,19 +148,6 @@ export const DataStreamDetailPanel: React.FunctionComponent<Props> = ({
const getManagementDetails = () => {
const managementDetails = [];

if (lifecycle?.data_retention) {
managementDetails.push({
name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.dataRetentionTitle', {
defaultMessage: 'Data retention',
}),
toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.dataRetentionToolTip', {
defaultMessage: 'The amount of time to retain the data in the data stream.',
}),
content: lifecycle.data_retention,
dataTestSubj: 'dataRetentionDetail',
});
}

if (ilmPolicyName) {
managementDetails.push({
name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.ilmPolicyTitle', {
Expand Down Expand Up @@ -278,6 +266,16 @@ export const DataStreamDetailPanel: React.FunctionComponent<Props> = ({
),
dataTestSubj: 'indexTemplateDetail',
},
{
name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.dataRetentionTitle', {
defaultMessage: 'Data retention',
}),
toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.dataRetentionToolTip', {
defaultMessage: 'The amount of time to retain the data in the data stream.',
}),
content: getLifecycleValue(lifecycle),
dataTestSubj: 'dataRetentionDetail',
},
];

const managementDetails = getManagementDetails();
Expand Down Expand Up @@ -376,7 +374,7 @@ export const DataStreamDetailPanel: React.FunctionComponent<Props> = ({
}
}}
dataStreamName={dataStreamName}
dataRetention={dataStream?.lifecycle?.data_retention as string}
lifecycle={dataStream?.lifecycle}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { ScopedHistory } from '@kbn/core/public';

import { DataStream } from '../../../../../../common/types';
import { getLifecycleValue } from '../../../../lib/data_streams';
import { UseRequestResponse, reactRouterNavigate } from '../../../../../shared_imports';
import { getDataStreamDetailsLink, getIndexListUri } from '../../../../services/routing';
import { DataHealth } from '../../../../components';
Expand All @@ -34,6 +35,8 @@ interface Props {
filters?: string;
}

const INFINITE_AS_ICON = true;

export const DataStreamTable: React.FunctionComponent<Props> = ({
dataStreams,
reload,
Expand Down Expand Up @@ -144,7 +147,7 @@ export const DataStreamTable: React.FunctionComponent<Props> = ({
),
truncateText: true,
sortable: true,
render: (lifecycle: DataStream['lifecycle']) => lifecycle?.data_retention,
render: (lifecycle: DataStream['lifecycle']) => getLifecycleValue(lifecycle, INFINITE_AS_ICON),
});

columns.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ import {
} from '../../../../../shared_imports';

import { documentationService } from '../../../../services/documentation';
import { splitSizeAndUnits } from '../../../../../../common';
import { splitSizeAndUnits, DataStream } from '../../../../../../common';
import { useAppContext } from '../../../../app_context';
import { UnitField } from './unit_field';
import { updateDataRetention } from '../../../../services/api';

interface Props {
dataRetention: string;
lifecycle: DataStream['lifecycle'];
dataStreamName: string;
onClose: (data?: { hasUpdatedDataRetention: boolean }) => void;
}
Expand Down Expand Up @@ -83,33 +83,6 @@ export const timeUnits = [
}
),
},
{
value: 'ms',
text: i18n.translate(
'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnits.millisecondsLabel',
{
defaultMessage: 'milliseconds',
}
),
},
{
value: 'micros',
text: i18n.translate(
'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnits.microsecondsLabel',
{
defaultMessage: 'microseconds',
}
),
},
{
value: 'nanos',
text: i18n.translate(
'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnits.nanosecondsLabel',
{
defaultMessage: 'nanoseconds',
}
),
},
];

const configurationFormSchema: FormSchema = {
Expand All @@ -124,7 +97,12 @@ const configurationFormSchema: FormSchema = {
formatters: [fieldFormatters.toInt],
validations: [
{
validator: ({ value }) => {
validator: ({ value, formData }) => {
// If infiniteRetentionPeriod is set, we dont need to validate the data retention field
if (formData.infiniteRetentionPeriod) {
return undefined;
}

if (!value) {
return {
message: i18n.translate(
Expand Down Expand Up @@ -171,11 +149,11 @@ const configurationFormSchema: FormSchema = {
};

export const EditDataRetentionModal: React.FunctionComponent<Props> = ({
dataRetention,
lifecycle,
dataStreamName,
onClose,
}) => {
const { size, unit } = splitSizeAndUnits(dataRetention);
const { size, unit } = splitSizeAndUnits(lifecycle?.data_retention as string);
const {
services: { notificationService },
} = useAppContext();
Expand All @@ -184,7 +162,10 @@ export const EditDataRetentionModal: React.FunctionComponent<Props> = ({
defaultValue: {
dataRetention: size,
timeUnit: unit || 'd',
infiniteRetentionPeriod: !dataRetention,
// When data retention is not set and lifecycle is enabled, is the only scenario in
// which data retention will be infinite. If lifecycle isnt set or is not enabled, we
// dont have inifinite data retention.
infiniteRetentionPeriod: lifecycle?.enabled && !lifecycle?.data_retention,
},
schema: configurationFormSchema,
id: 'editDataRetentionForm',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ export function getSuggestions({
return {
previewIcon: IconChartTagcloud,
title: TAGCLOUD_LABEL,
hide: true, // hide suggestions while in tech preview
score: 0.1,
score: bucket.operation.dataType === 'string' ? 0.4 : 0.2,
state: {
layerId: table.layerId,
tagAccessor: bucket.columnId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export const getTagcloudVisualization = ({
groupLabel: i18n.translate('xpack.lens.pie.groupLabel', {
defaultMessage: 'Proportion',
}),
showExperimentalBadge: true,
},
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export interface CustomEquationEditorProps {
dataView: DataViewBase;
}

const NEW_METRIC = { name: 'A', aggType: Aggregators.AVERAGE as CustomMetricAggTypes };
const NEW_METRIC = {
name: 'A',
aggType: Aggregators.COUNT as CustomMetricAggTypes,
};
const MAX_VARIABLES = 26;
const CHAR_CODE_FOR_A = 65;
const CHAR_CODE_FOR_Z = CHAR_CODE_FOR_A + MAX_VARIABLES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface MetricRowWithAggProps extends MetricRowBaseProps {

export function MetricRowWithAgg({
name,
aggType = Aggregators.AVERAGE,
aggType = Aggregators.COUNT,
field,
onDelete,
dataView,
Expand Down Expand Up @@ -128,7 +128,7 @@ export function MetricRowWithAgg({
description={aggregationTypes[aggType].text}
value={aggType === Aggregators.COUNT ? filter : field}
isActive={aggTypePopoverOpen}
display={'columns'}
display="columns"
onClick={() => {
setAggTypePopoverOpen(true);
}}
Expand Down
Loading

0 comments on commit 5c86ff3

Please sign in to comment.