From 1a6dfb5b1a4238ba13dec1d10ff8db5247e7c136 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 11:51:31 +0000 Subject: [PATCH 01/30] [Index Management] Add bulk edit data retention --- .../data_stream_actions_menu.tsx | 66 +++++++++++++++++++ .../data_stream_actions_menu/index.ts | 8 +++ .../data_stream_table/data_stream_table.tsx | 49 ++++++++++---- 3 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/data_stream_actions_menu.tsx create mode 100644 x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/index.ts diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/data_stream_actions_menu.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/data_stream_actions_menu.tsx new file mode 100644 index 0000000000000..2464f7ac03e3c --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/data_stream_actions_menu.tsx @@ -0,0 +1,66 @@ +/* + * 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 { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui'; +import React, { useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiContextMenuPanelItemDescriptor } from '@elastic/eui/src/components/context_menu/context_menu'; +import { i18n } from '@kbn/i18n'; + +interface Props { + dataStreamActions: EuiContextMenuPanelItemDescriptor[]; + selectedDataStreamsCount: number; +} + +export const DataStreamActionsMenu = ({ dataStreamActions, selectedDataStreamsCount }: Props) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const popoverButton = ( + setIsPopoverOpen(!isPopoverOpen)} + iconType="arrowDown" + iconSide="right" + fill={true} + > + + + ); + + return ( + setIsPopoverOpen(false)} + panelPaddingSize="none" + anchorPosition="rightUp" + repositionOnScroll={true} + > + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/index.ts b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/index.ts new file mode 100644 index 0000000000000..0eb726d3eb79f --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_actions_menu/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export { DataStreamActionsMenu } from './data_stream_actions_menu'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index 59daae719bf47..3fcb6e049b319 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -24,6 +24,7 @@ import { import { ScopedHistory } from '@kbn/core/public'; import { useEuiTablePersist } from '@kbn/shared-ux-table-persist'; +import { EuiContextMenuPanelItemDescriptor } from '@elastic/eui/src/components/context_menu/context_menu'; import { MAX_DATA_RETENTION } from '../../../../../../common/constants'; import { useAppContext } from '../../../../app_context'; import { DataStream } from '../../../../../../common/types'; @@ -39,6 +40,8 @@ import { isDataStreamFullyManagedByILM } from '../../../../lib/data_streams'; import { indexModeLabels } from '../../../../lib/index_mode_labels'; import { FilterListButton, Filters } from '../../components'; import { type DataStreamFilterName } from '../data_stream_list'; +import { DataStreamActionsMenu } from '../data_stream_actions_menu'; +import { EditDataRetentionModal } from '../edit_data_retention_modal'; interface TableDataStream extends DataStream { isDataStreamFullyManagedByILM: boolean; @@ -70,6 +73,9 @@ export const DataStreamTable: React.FunctionComponent = ({ }) => { const [selection, setSelection] = useState([]); const [dataStreamsToDelete, setDataStreamsToDelete] = useState([]); + const [dataStreamsToEditDataRetention, setDataStreamsToEditDataRetention] = useState< + DataStream[] + >([]); const { config } = useAppContext(); const data = useMemo(() => { @@ -284,25 +290,34 @@ export const DataStreamTable: React.FunctionComponent = ({ onSelectionChange: setSelection, }; + const dataStreamActions: EuiContextMenuPanelItemDescriptor[] = [ + { + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.bulkEditDataRetentionButtonLabel', { + defaultMessage: 'Edit data retention', + }), + icon: 'pencil', + onClick: () => setDataStreamsToEditDataRetention(selection), + }, + { + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel', { + defaultMessage: 'Delete data streams', + }), + icon: 'trash', + onClick: () => setDataStreamsToDelete(selection.map(({ name }: DataStream) => name)), + }, + ]; + const searchConfig = { query: filters, box: { incremental: true, }, toolsLeft: - selection.length > 0 && - selection.every((dataStream: DataStream) => dataStream.privileges.delete_index) ? ( - setDataStreamsToDelete(selection.map(({ name }: DataStream) => name))} - color="danger" - > - - + selection.length > 0 ? ( + ) : undefined, toolsRight: [ @@ -365,6 +380,14 @@ export const DataStreamTable: React.FunctionComponent = ({ return ( <> + {dataStreamsToEditDataRetention && dataStreamsToEditDataRetention.length > 0 ? ( + setDataStreamsToEditDataRetention([])} + dataStream={dataStreamsToEditDataRetention[0]} + ilmPolicyLink="" + ilmPolicyName="Test" + /> + ) : null} {dataStreamsToDelete && dataStreamsToDelete.length > 0 ? ( { From 4026250abee1254bc1bea77b2476c804fd54a589 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 13:54:29 +0000 Subject: [PATCH 02/30] Refactor edit data retention modal --- .../data_stream_table/data_stream_table.tsx | 12 +- .../edit_data_retention_modal.tsx | 204 +++--------------- .../mixed_indices_callout.tsx | 74 +++++++ .../edit_data_retention_modal/schema.ts | 104 +++++++++ .../public/application/services/api.ts | 10 +- .../api/data_streams/register_put_route.ts | 15 +- 6 files changed, 223 insertions(+), 196 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx create mode 100644 x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/schema.ts diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index 3fcb6e049b319..bb2e72d371a85 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -382,10 +382,14 @@ export const DataStreamTable: React.FunctionComponent = ({ <> {dataStreamsToEditDataRetention && dataStreamsToEditDataRetention.length > 0 ? ( setDataStreamsToEditDataRetention([])} - dataStream={dataStreamsToEditDataRetention[0]} - ilmPolicyLink="" - ilmPolicyName="Test" + onClose={(res) => { + if (res && res.hasUpdatedDataRetention) { + reload(); + } else { + setDataStreamsToEditDataRetention([]); + } + }} + dataStreams={dataStreamsToEditDataRetention} /> ) : null} {dataStreamsToDelete && dataStreamsToDelete.length > 0 ? ( diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index b8f2593131663..f89dc65e68f88 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -17,29 +17,21 @@ import { EuiSpacer, EuiLink, EuiText, - EuiCallOut, } from '@elastic/eui'; import { has } from 'lodash'; -import { ScopedHistory } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { isBiggerThanGlobalMaxRetention } from './validations'; +import { editDataRetentionFormSchema } from './schema'; import { useForm, useFormData, useFormIsModified, Form, - fieldFormatters, - FormSchema, - FIELD_TYPES, UseField, ToggleField, NumericField, - fieldValidators, } from '../../../../../shared_imports'; -import { reactRouterNavigate } from '../../../../../shared_imports'; -import { getIndexListUri } from '../../../../services/routing'; import { documentationService } from '../../../../services/documentation'; import { splitSizeAndUnits, DataStream } from '../../../../../../common'; import { timeUnits } from '../../../../constants/time_units'; @@ -47,179 +39,31 @@ import { deserializeGlobalMaxRetention, isDSLWithILMIndices } from '../../../../ import { useAppContext } from '../../../../app_context'; import { UnitField } from '../../../../components/shared'; import { updateDataRetention } from '../../../../services/api'; +import { MixedIndicesCallout } from './mixed_indices_callout'; interface Props { - dataStream: DataStream; + dataStreams: DataStream[]; ilmPolicyName?: string; - ilmPolicyLink: string; + ilmPolicyLink?: string; onClose: (data?: { hasUpdatedDataRetention: boolean }) => void; } -const configurationFormSchema: FormSchema = { - dataRetention: { - type: FIELD_TYPES.TEXT, - label: i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField', - { - defaultMessage: 'Data retention period', - } - ), - formatters: [fieldFormatters.toInt], - validations: [ - { - validator: fieldValidators.isInteger({ - message: i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldIntegerError', - { - defaultMessage: 'Only integers are allowed.', - } - ), - }), - }, - { - validator: ({ value, formData, customData }) => { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!formData.infiniteRetentionPeriod) { - // If project level data retention is enabled, we need to enforce the global max retention - const { globalMaxRetention, enableProjectLevelRetentionChecks } = - customData.value as any; - if (enableProjectLevelRetentionChecks) { - return isBiggerThanGlobalMaxRetention(value, formData.timeUnit, globalMaxRetention); - } - } - }, - }, - { - validator: (args) => { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!args.formData.infiniteRetentionPeriod) { - return fieldValidators.emptyField( - i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError', - { - defaultMessage: 'A data retention value is required.', - } - ) - )(args); - } - }, - }, - { - validator: (args) => { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!args.formData.infiniteRetentionPeriod) { - return fieldValidators.numberGreaterThanField({ - than: 0, - allowEquality: false, - message: i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError', - { - defaultMessage: `A positive value is required.`, - } - ), - })(args); - } - }, - }, - ], - }, - timeUnit: { - type: FIELD_TYPES.TEXT, - label: i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField', - { - defaultMessage: 'Time unit', - } - ), - }, - infiniteRetentionPeriod: { - type: FIELD_TYPES.TOGGLE, - defaultValue: false, - }, - dataRetentionEnabled: { - type: FIELD_TYPES.TOGGLE, - defaultValue: false, - label: i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField', - { - defaultMessage: 'Enable data retention', - } - ), - }, -}; - -interface MixedIndicesCalloutProps { - history: ScopedHistory; - ilmPolicyLink: string; - ilmPolicyName?: string; - dataStreamName: string; -} - -const MixedIndicesCallout = ({ - ilmPolicyLink, - ilmPolicyName, - dataStreamName, - history, -}: MixedIndicesCalloutProps) => { - const { core } = useAppContext(); - - return ( - -

- core.application.navigateToUrl(ilmPolicyLink)} - > - {ilmPolicyName} - - ), - viewAllIndicesLink: ( - - - - ), - }} - /> -

-
- ); -}; - export const EditDataRetentionModal: React.FunctionComponent = ({ - dataStream, + dataStreams, ilmPolicyName, ilmPolicyLink, onClose, }) => { - const lifecycle = dataStream?.lifecycle; - const dataStreamName = dataStream?.name as string; + const lifecycle = dataStreams[0]?.lifecycle; const { history } = useAppContext(); - const dslWithIlmIndices = isDSLWithILMIndices(dataStream); - const { size, unit } = splitSizeAndUnits(lifecycle?.data_retention as string); + const isSingleDataStream = dataStreams.length === 1; + const dataStreamNames = dataStreams.map(({ name }: DataStream) => name as string); const globalMaxRetention = deserializeGlobalMaxRetention(lifecycle?.globalMaxRetention); + const { size, unit } = isSingleDataStream + ? splitSizeAndUnits(lifecycle?.data_retention as string) + : { size: undefined, unit: undefined }; + const { services: { notificationService }, config: { enableTogglingDataRetention, enableProjectLevelRetentionChecks }, @@ -229,13 +73,14 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ defaultValue: { dataRetention: size, timeUnit: unit || 'd', - dataRetentionEnabled: lifecycle?.enabled, + dataRetentionEnabled: isSingleDataStream ? lifecycle?.enabled : true, // 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, + infiniteRetentionPeriod: + isSingleDataStream && lifecycle?.enabled && !lifecycle?.data_retention, }, - schema: configurationFormSchema, + schema: editDataRetentionFormSchema, id: 'editDataRetentionForm', }); const [formData] = useFormData({ form }); @@ -247,8 +92,10 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ // Whenever the timeUnit field changes, we need to re-validate // the dataRetention field useEffect(() => { - form.validateFields(['dataRetention']); - }, [formData.timeUnit, form]); + if (formData.dataRetention) { + form.validateFields(['dataRetention']); + } + }, [formData.timeUnit, form, formData.dataRetention]); const onSubmitForm = async () => { const { isValid, data } = await form.submit(); @@ -267,7 +114,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ data.dataRetentionEnabled = true; } - return updateDataRetention(dataStreamName, data).then(({ data: responseData, error }) => { + return updateDataRetention(dataStreamNames, data).then(({ data: responseData, error }) => { if (responseData) { // If the response came back with a warning from ES, rely on that for the // toast message. @@ -315,19 +162,20 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {dslWithIlmIndices && ( + {isSingleDataStream && isDSLWithILMIndices(dataStreams[0]) && ( <> @@ -375,7 +223,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ } componentProps={{ - fullWidth: false, + fullWidth: !isSingleDataStream, euiFieldProps: { disabled: formData.infiniteRetentionPeriod || diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx new file mode 100644 index 0000000000000..b3ffe0f52bee4 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx @@ -0,0 +1,74 @@ +/* + * 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 { EuiCallOut, EuiLink } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public'; +import React from 'react'; +import { ScopedHistory } from '@kbn/core-application-browser'; +import { getIndexListUri } from '../../../../..'; +import { useAppContext } from '../../../../app_context'; + +interface MixedIndicesCalloutProps { + history: ScopedHistory; + ilmPolicyLink?: string; + ilmPolicyName?: string; + dataStreamName: string; +} + +export const MixedIndicesCallout = ({ + ilmPolicyLink, + ilmPolicyName, + dataStreamName, + history, +}: MixedIndicesCalloutProps) => { + const { core } = useAppContext(); + + return ( + +

+ core.application.navigateToUrl(ilmPolicyLink)} + > + {ilmPolicyName} + + ), + viewAllIndicesLink: ( + + + + ), + }} + /> +

+
+ ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/schema.ts b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/schema.ts new file mode 100644 index 0000000000000..104174b27c27d --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/schema.ts @@ -0,0 +1,104 @@ +/* + * 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 { FIELD_TYPES, FormSchema } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { i18n } from '@kbn/i18n'; +import { fieldFormatters, fieldValidators } from '@kbn/es-ui-shared-plugin/static/forms/helpers'; +import { isBiggerThanGlobalMaxRetention } from './validations'; + +export const editDataRetentionFormSchema: FormSchema = { + dataRetention: { + type: FIELD_TYPES.TEXT, + label: i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField', + { + defaultMessage: 'Data retention period', + } + ), + formatters: [fieldFormatters.toInt], + validations: [ + { + validator: fieldValidators.isInteger({ + message: i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldIntegerError', + { + defaultMessage: 'Only integers are allowed.', + } + ), + }), + }, + { + validator: ({ value, formData, customData }) => { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false + if (!formData.infiniteRetentionPeriod) { + // If project level data retention is enabled, we need to enforce the global max retention + const { globalMaxRetention, enableProjectLevelRetentionChecks } = + customData.value as any; + if (enableProjectLevelRetentionChecks) { + return isBiggerThanGlobalMaxRetention(value, formData.timeUnit, globalMaxRetention); + } + } + }, + }, + { + validator: (args) => { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false + if (!args.formData.infiniteRetentionPeriod) { + return fieldValidators.emptyField( + i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError', + { + defaultMessage: 'A data retention value is required.', + } + ) + )(args); + } + }, + }, + { + validator: (args) => { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false + if (!args.formData.infiniteRetentionPeriod) { + return fieldValidators.numberGreaterThanField({ + than: 0, + allowEquality: false, + message: i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError', + { + defaultMessage: `A positive value is required.`, + } + ), + })(args); + } + }, + }, + ], + }, + timeUnit: { + type: FIELD_TYPES.TEXT, + label: i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField', + { + defaultMessage: 'Time unit', + } + ), + }, + infiniteRetentionPeriod: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + }, + dataRetentionEnabled: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + label: i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField', + { + defaultMessage: 'Enable data retention', + } + ), + }, +}; diff --git a/x-pack/plugins/index_management/public/application/services/api.ts b/x-pack/plugins/index_management/public/application/services/api.ts index 5e4f88ebb6b18..f2600220612e7 100644 --- a/x-pack/plugins/index_management/public/application/services/api.ts +++ b/x-pack/plugins/index_management/public/application/services/api.ts @@ -88,7 +88,7 @@ export async function deleteDataStreams(dataStreams: string[]) { } export async function updateDataRetention( - name: string, + dataStreams: string[], data: { dataRetention: string; timeUnit: string; @@ -99,15 +99,15 @@ export async function updateDataRetention( let body; if (!data.dataRetentionEnabled) { - body = { enabled: false }; + body = { enabled: false, dataStreams }; } else { body = data.infiniteRetentionPeriod - ? {} - : { dataRetention: `${data.dataRetention}${data.timeUnit}` }; + ? { dataStreams } + : { dataRetention: `${data.dataRetention}${data.timeUnit}`, dataStreams }; } return sendRequest({ - path: `${API_BASE_PATH}/data_streams/${encodeURIComponent(name)}/data_retention`, + path: `${API_BASE_PATH}/data_streams/data_retention`, method: 'put', body, }); diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_put_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_put_route.ts index 1f4930a9ec426..97ea662daaa14 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_put_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_put_route.ts @@ -20,29 +20,26 @@ export const getEsWarningText = (warning: string): string | null => { }; export function registerPutDataRetention({ router, lib: { handleEsError } }: RouteDependencies) { - const paramsSchema = schema.object({ - name: schema.string(), - }); const bodySchema = schema.object({ + dataStreams: schema.arrayOf(schema.string()), dataRetention: schema.maybe(schema.string()), enabled: schema.maybe(schema.boolean()), }); router.put( { - path: addBasePath('/data_streams/{name}/data_retention'), - validate: { params: paramsSchema, body: bodySchema }, + path: addBasePath('/data_streams/data_retention'), + validate: { body: bodySchema }, }, async (context, request, response) => { - const { name } = request.params as TypeOf; - const { dataRetention, enabled } = request.body as TypeOf; + const { dataStreams, dataRetention, enabled } = request.body as TypeOf; const { client } = (await context.core).elasticsearch; try { // Only when enabled is explicitly set to false, we delete the data retention policy. if (enabled === false) { - await client.asCurrentUser.indices.deleteDataLifecycle({ name }); + await client.asCurrentUser.indices.deleteDataLifecycle({ name: dataStreams }); } else { // Otherwise, we create or update the data retention policy. // @@ -51,7 +48,7 @@ export function registerPutDataRetention({ router, lib: { handleEsError } }: Rou // global data retention limit set. const { headers } = await client.asCurrentUser.indices.putDataLifecycle( { - name, + name: dataStreams, data_retention: dataRetention, }, { meta: true } From 15d935340b78377a421a78257b04f86eeceddb69 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 14:11:34 +0000 Subject: [PATCH 03/30] Refactor toast messages --- .../edit_data_retention_modal.tsx | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index f89dc65e68f88..38c25196bed91 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -123,27 +123,44 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ return onClose({ hasUpdatedDataRetention: true }); } - const successMessage = i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification', - { - defaultMessage: - 'Data retention {disabledDataRetention, plural, one { disabled } other { updated } }', - values: { disabledDataRetention: !data.dataRetentionEnabled ? 1 : 0 }, - } - ); + const successMessage = isSingleDataStream + ? i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification', + { + defaultMessage: + 'Data retention {disabledDataRetention, plural, one { disabled } other { updated } }', + values: { disabledDataRetention: !data.dataRetentionEnabled ? 1 : 0 }, + } + ) + : i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successBulkDataRetentionNotification', + { + defaultMessage: + 'Data retention has been updated for {dataStreamCount, plural, one {one data stream} other {{dataStreamCount} data streams}}.', + values: { dataStreamCount: dataStreams.length }, + } + ); notificationService.showSuccessToast(successMessage); return onClose({ hasUpdatedDataRetention: true }); } if (error) { - const errorMessage = i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification', - { - defaultMessage: "Error updating data retention: ''{error}''", - values: { error: error.message }, - } - ); + const errorMessage = isSingleDataStream + ? i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification', + { + defaultMessage: "Error updating data retention: ''{error}''", + values: { error: error.message }, + } + ) + : i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorBulkDataRetentionNotification', + { + defaultMessage: + 'There was an error updating the retention period. Try again later.', + } + ); notificationService.showDangerToast(errorMessage); } From d19c660c5b978b6ffadeca70ba9b4dbded0acba3 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 15:34:07 +0000 Subject: [PATCH 04/30] Add help text with maximum data retention displayed --- .../edit_data_retention_modal.tsx | 56 ++++++++++++++----- .../api/data_streams/register_get_route.ts | 5 ++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 38c25196bed91..a3aeb9eb4e3d4 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -56,7 +56,10 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ }) => { const lifecycle = dataStreams[0]?.lifecycle; - const { history } = useAppContext(); + const { + history, + plugins: { cloud }, + } = useAppContext(); const isSingleDataStream = dataStreams.length === 1; const dataStreamNames = dataStreams.map(({ name }: DataStream) => name as string); const globalMaxRetention = deserializeGlobalMaxRetention(lifecycle?.globalMaxRetention); @@ -198,19 +201,21 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ )} - {enableProjectLevelRetentionChecks && lifecycle?.globalMaxRetention && ( - <> - - - - )} + {enableProjectLevelRetentionChecks && + isSingleDataStream && + lifecycle?.globalMaxRetention && ( + <> + + + + )} {enableTogglingDataRetention && ( = ({ } + helpText={ + !isSingleDataStream && + globalMaxRetention && ( + + {i18n.translate( + 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.manageProjectSettingsLinkText', + { + defaultMessage: 'Manage project settings.', + } + )} + + ), + }} + /> + ) + } componentProps={{ fullWidth: !isSingleDataStream, euiFieldProps: { diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index cd47b8cc9e0bb..8444783b25c91 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -146,6 +146,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: try { const { data_streams: dataStreams } = await getDataStreams(client); + const dataStreamNames = dataStreams.map((dataStream) => dataStream.name); let dataStreamsStats; let dataStreamsPrivileges; @@ -168,11 +169,15 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: const { index_templates: indexTemplates } = await client.asCurrentUser.indices.getIndexTemplate(); + const lifecycle = await getDataStreamLifecycle(client, dataStreams[0].name); + const globalMaxRetention = lifecycle?.global_retention?.max_retention; + const enhancedDataStreams = enhanceDataStreams({ dataStreams, dataStreamsStats, meteringStats, dataStreamsPrivileges, + globalMaxRetention, indexTemplates, }); From a7888acffa26b665b26ef31e905a22ede7d19e5c Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 16:14:28 +0000 Subject: [PATCH 05/30] Add affected data streams callout --- .../edit_data_retention_modal.tsx | 78 +++++++++++++++---- .../edit_data_retention_modal/validations.ts | 5 +- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index a3aeb9eb4e3d4..c078251bf49a7 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -17,10 +17,12 @@ import { EuiSpacer, EuiLink, EuiText, + EuiCallOut, } from '@elastic/eui'; import { has } from 'lodash'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { isRetentionBiggerThan } from './validations'; import { editDataRetentionFormSchema } from './schema'; import { useForm, @@ -128,7 +130,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ const successMessage = isSingleDataStream ? i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successDataRetentionNotification', { defaultMessage: 'Data retention {disabledDataRetention, plural, one { disabled } other { updated } }', @@ -136,7 +138,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ } ) : i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successBulkDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successBulkDataRetentionNotification', { defaultMessage: 'Data retention has been updated for {dataStreamCount, plural, one {one data stream} other {{dataStreamCount} data streams}}.', @@ -151,14 +153,14 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ if (error) { const errorMessage = isSingleDataStream ? i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorDataRetentionNotification', { defaultMessage: "Error updating data retention: ''{error}''", values: { error: error.message }, } ) : i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorBulkDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorBulkDataRetentionNotification', { defaultMessage: 'There was an error updating the retention period. Try again later.', @@ -171,17 +173,30 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ }); }; + const affectedDataStreams = dataStreams + .filter( + (ds: DataStream) => + formData.dataRetention && + formData.timeUnit && + (!ds.lifecycle?.data_retention || + isRetentionBiggerThan( + ds.lifecycle.data_retention, + `${formData.dataRetention}${formData.timeUnit}` + )) + ) + .map(({ name }: DataStream) => name); + return ( onClose()} data-test-subj="editDataRetentionModal" - css={{ minWidth: 450 }} + css={{ minWidth: isSingleDataStream ? 450 : 650, maxWidth: 650 }} >
@@ -206,7 +221,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ lifecycle?.globalMaxRetention && ( <> = ({ {i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.learnMoreLinkText', { defaultMessage: 'How does this work?', } @@ -248,7 +263,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ !isSingleDataStream && globalMaxRetention && ( = ({ manageSettingsLink: ( {i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.manageProjectSettingsLinkText', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.manageProjectSettingsLinkText', { defaultMessage: 'Manage project settings.', } @@ -286,7 +301,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ euiFieldProps={{ 'data-test-subj': 'timeUnit', 'aria-label': i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.unitsAriaLabel', { defaultMessage: 'Time unit', } @@ -303,7 +318,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ component={ToggleField} data-test-subj="infiniteRetentionPeriod" label={i18n.translate( - 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.infiniteRetentionPeriodField', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.infiniteRetentionPeriodField', { defaultMessage: 'Keep data {withProjectLevelRetention, plural, one {up to maximum retention period} other {indefinitely}}', @@ -318,12 +333,47 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ /> + + {affectedDataStreams.length > 0 && ( + +

+ +

+ {affectedDataStreams.length <= 10 && ( +

+ {affectedDataStreams.join(', ')}, + }} + /> +

+ )} +
+ )} onClose()}> @@ -337,7 +387,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ onClick={onSubmitForm} > diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/validations.ts b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/validations.ts index 8486f01fb5b44..cebc73c1548d3 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/validations.ts +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/validations.ts @@ -40,7 +40,10 @@ const convertToSeconds = (value: string) => { } }; -const isRetentionBiggerThan = (valueA: string, valueB: string) => { +/* +TODO: add documentation + */ +export const isRetentionBiggerThan = (valueA: string, valueB: string) => { const secondsA = convertToSeconds(valueA); const secondsB = convertToSeconds(valueB); From 3ca38c6cb11443704be098d1db0a658647ba3c0e Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 16:24:40 +0000 Subject: [PATCH 06/30] Only display delete button for deletable data streams --- .../data_stream_table/data_stream_table.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index bb2e72d371a85..75c502468cad4 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -298,14 +298,17 @@ export const DataStreamTable: React.FunctionComponent = ({ icon: 'pencil', onClick: () => setDataStreamsToEditDataRetention(selection), }, - { + ]; + + if (selection.every((dataStream: DataStream) => dataStream.privileges.delete_index)) { + dataStreamActions.push({ name: i18n.translate('xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel', { defaultMessage: 'Delete data streams', }), icon: 'trash', onClick: () => setDataStreamsToDelete(selection.map(({ name }: DataStream) => name)), - }, - ]; + }); + } const searchConfig = { query: filters, From 5e34c641341691fa6cbc4a59a84ee8256f9cc5e2 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 16:56:48 +0000 Subject: [PATCH 07/30] Fix type errors --- .../data_stream_detail_panel/data_stream_detail_panel.tsx | 2 +- .../edit_data_retention_modal/edit_data_retention_modal.tsx | 3 ++- .../edit_data_retention_modal/mixed_indices_callout.tsx | 2 +- .../data_stream_list/edit_data_retention_modal/validations.ts | 2 +- .../server/routes/api/data_streams/register_get_route.ts | 3 ++- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx index 10ef17c566241..45606d0d35abf 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx @@ -550,7 +550,7 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ }} ilmPolicyName={dataStream?.ilmPolicyName} ilmPolicyLink={ilmPolicyLink} - dataStream={dataStream} + dataStreams={[dataStream]} /> )} diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index c078251bf49a7..2c75c26159616 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -179,6 +179,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ formData.dataRetention && formData.timeUnit && (!ds.lifecycle?.data_retention || + ds.lifecycle?.data_retention === -1 || isRetentionBiggerThan( ds.lifecycle.data_retention, `${formData.dataRetention}${formData.timeUnit}` @@ -204,7 +205,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({
- {isSingleDataStream && isDSLWithILMIndices(dataStreams[0]) && ( + {isSingleDataStream && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( <> { }; /* -TODO: add documentation +True if the first retention period is bigger than the latter one. */ export const isRetentionBiggerThan = (valueA: string, valueB: string) => { const secondsA = convertToSeconds(valueA); diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index 8444783b25c91..d03c79e4f698c 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -146,7 +146,6 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: try { const { data_streams: dataStreams } = await getDataStreams(client); - const dataStreamNames = dataStreams.map((dataStream) => dataStream.name); let dataStreamsStats; let dataStreamsPrivileges; @@ -169,7 +168,9 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: const { index_templates: indexTemplates } = await client.asCurrentUser.indices.getIndexTemplate(); + // Only take the lifecycle of the first data stream since all data streams have the same global retention period const lifecycle = await getDataStreamLifecycle(client, dataStreams[0].name); + // @ts-ignore - TS doesn't know about the `global_retention` property yet const globalMaxRetention = lifecycle?.global_retention?.max_retention; const enhancedDataStreams = enhanceDataStreams({ From 94fd0a12aa34b4905bb4a884cfa4724b1cec236e Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 5 Dec 2024 17:01:08 +0000 Subject: [PATCH 08/30] Update i18n translations --- x-pack/plugins/translations/translations/fr-FR.json | 7 ------- x-pack/plugins/translations/translations/ja-JP.json | 7 ------- x-pack/plugins/translations/translations/zh-CN.json | 6 ------ 3 files changed, 20 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index fa5b37eb1eb16..d976543737ee3 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -22420,7 +22420,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "Supprimer", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "Conservation des données", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "Les données sont conservées au moins pour cette durée avant leur suppression automatique. La valeur de rétention de données s'applique uniquement aux données gérées directement par le flux de données. {canDisableDataRetention, plural, one {Si certaines données sont sujettes à une politique de gestion du cycle de vie de l'index, alors la valeur de conservation des données réglée pour le flux de données ne s'applique par à ces données.} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "Supprimer {count, plural, one {le flux de données} other {les flux de données} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "Intégrité", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "Masqué", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "Index", @@ -22436,22 +22435,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "Statistiques incluses", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "L'inclusion de statistiques peut augmenter le temps de rechargement", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "En savoir plus.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "Annuler", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "Activer la conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "Conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "Une valeur positive est requise.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "Une valeur de conservation des données est requise.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "Erreur lors de la mise à niveau de la conservation des données : \"{error}\"", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "Stratégie ILM", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "Afin de modifier la conservation des données pour ce flux de données, vous devez modifier le {link} associé.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "Ce flux de données et les index associés sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "Comment ça fonctionne ?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "Enregistrer", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "Un index ou plus sont gérés par une politique ILM ({viewAllIndicesLink}). La mise à niveau de la conservation des données pour ce flux de données n'aura pas d'incidence sur ces index. À la place, vous devrez mettre à niveau la politique {ilmPolicyLink}.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "Certains index sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "Conservation des données {disabledDataRetention, plural, one { désactivée } other { mise à niveau } }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "Unité de temps", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "Unité de temps", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "afficher les index", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "Gérer", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "La valeur doit être un nombre entier.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ca9edb8931403..c7bf60ed8101f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -22391,7 +22391,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "削除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "データ保持", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "データは少なくともこの期間保存された後、自動的に削除されます。データ保持値は、データストリームによって直接管理されたデータにのみ適用されます。{canDisableDataRetention, plural, one {一部のデータにインデックスライフサイクル管理ポリシーが適用される場合、データストリームに設定されたデータ保持値はそのデータに適用されません。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "{count, plural, other {個のデータストリーム}}を削除", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "ヘルス", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "非表示", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "インデックス", @@ -22407,22 +22406,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "統計情報を含める", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "統計情報を含めると、再読み込み時間が長くなることがあります", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "詳細情報", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "データ保持を有効化", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "データ保持", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "正の値が必要です。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "データ保持値が必要です。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "データ保持の更新エラー:''{error}''", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILMポリシー", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "このデータストリームのデータ保持を編集するには、関連する{link}を編集する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "このデータストリームと関連するインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "仕組み", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "ILMポリシー({viewAllIndicesLink})によって1つ以上のインデックスが管理されます。このデータストリームのデータ保持を更新しても、これらのインデックスには影響しません。代わりに、{ilmPolicyLink}ポリシーを更新する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "一部のインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "データ保持が{disabledDataRetention, plural, one {無効化されました} other {更新されました} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "時間単位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "時間単位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "インデックスを表示", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "値は整数でなければなりません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d297ff942df01..c30c1062a286a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -22009,7 +22009,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "删除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "数据保留", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "会至少在这个时长内保留数据,然后自动将其删除。数据保留值仅适用于由数据流直接管理的数据。{canDisableDataRetention, plural, one {如果某些数据受索引生命周期管理策略约束,则为数据流设置的数据保留值不适用于该数据。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "删除{count, plural, other {数据流} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "运行状况", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "隐藏", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "索引", @@ -22025,7 +22024,6 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "包含统计信息", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "包含统计信息可能会延长重新加载时间", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "了解详情。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "取消", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "启用数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "需要提供正值。", @@ -22033,13 +22031,9 @@ "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILM 策略", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "要编辑此数据流的数据保留,必须编辑其关联 {link}。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "此数据流及其关联索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "工作原理?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "一个或多个索引由 ILM 策略管理 ({viewAllIndicesLink})。更新此数据流的数据保留不会影响到这些索引。相反,您必须更新 {ilmPolicyLink} 策略。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "某些索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "数据保留{disabledDataRetention, plural, one {已禁用} other {已更新} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "时间单位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "时间单位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "查看索引", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "此值应为整数。", From 05c9961a4c13a8977787cac3d33d3a35b1cc8893 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Mon, 9 Dec 2024 09:06:37 +0000 Subject: [PATCH 09/30] Update and add api_integration tests --- .../index_management/data_streams.ts | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts index 2976d4eac03b4..6ea9c601f6cc3 100644 --- a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts +++ b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts @@ -182,17 +182,38 @@ export default function ({ getService }: FtrProviderContext) { }); describe('Update', () => { - const testDataStreamName = 'test-data-stream'; + const testDataStreamName1 = 'test-data-stream1'; + const testDataStreamName2 = 'test-data-stream2'; - before(async () => await createDataStream(testDataStreamName)); - after(async () => await deleteDataStream(testDataStreamName)); + before(async () => { + await createDataStream(testDataStreamName1); + await createDataStream(testDataStreamName2); + }); + after(async () => { + await deleteDataStream(testDataStreamName1); + await deleteDataStream(testDataStreamName2); + }); it('updates the data retention of a DS', async () => { const { body } = await supertest - .put(`${API_BASE_PATH}/data_streams/${testDataStreamName}/data_retention`) + .put(`${API_BASE_PATH}/data_streams/data_retention`) .set('kbn-xsrf', 'xxx') .send({ dataRetention: '7d', + dataStreams: [testDataStreamName1], + }) + .expect(200); + + expect(body).to.eql({ success: true }); + }); + + it('updates the data retention of multiple DS', async () => { + const { body } = await supertest + .put(`${API_BASE_PATH}/data_streams/data_retention`) + .set('kbn-xsrf', 'xxx') + .send({ + dataRetention: '7d', + dataStreams: [testDataStreamName1, testDataStreamName2], }) .expect(200); @@ -201,9 +222,11 @@ export default function ({ getService }: FtrProviderContext) { it('sets data retention to infinite', async () => { const { body } = await supertest - .put(`${API_BASE_PATH}/data_streams/${testDataStreamName}/data_retention`) + .put(`${API_BASE_PATH}/data_streams/data_retention`) .set('kbn-xsrf', 'xxx') - .send({}) + .send({ + dataStreams: [testDataStreamName1], + }) .expect(200); expect(body).to.eql({ success: true }); @@ -211,14 +234,14 @@ export default function ({ getService }: FtrProviderContext) { it('can disable lifecycle for a given policy', async () => { const { body } = await supertest - .put(`${API_BASE_PATH}/data_streams/${testDataStreamName}/data_retention`) + .put(`${API_BASE_PATH}/data_streams/data_retention`) .set('kbn-xsrf', 'xxx') - .send({ enabled: false }) + .send({ enabled: false, dataStreams: [testDataStreamName1] }) .expect(200); expect(body).to.eql({ success: true }); - const datastream = await getDatastream(testDataStreamName); + const datastream = await getDatastream(testDataStreamName1); expect(datastream.lifecycle).to.be(undefined); }); }); From a467f74c1ed7913db3f0cb40666f7ff54677fb8b Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Mon, 9 Dec 2024 09:07:10 +0000 Subject: [PATCH 10/30] Fix jest tests --- .../home/data_streams_tab.helpers.ts | 6 ++++++ .../home/data_streams_tab.test.ts | 21 ++++++++++++------- .../api/data_streams/data_streams.test.ts | 12 +++++------ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index 608d2ce5390da..fcd937b26f6eb 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -37,6 +37,7 @@ export interface DataStreamsTabTestBed extends TestBed { clickDeleteDataStreamButton: () => void; clickEditDataRetentionButton: () => void; clickDetailPanelIndexTemplateLink: () => void; + clickManageDataStreamsButton: () => void; }; findDeleteActionAt: (index: number) => ReactWrapper; findDeleteConfirmationModal: () => ReactWrapper; @@ -210,6 +211,10 @@ export const setup = async ( component.update(); }; + const clickManageDataStreamsButton = () => { + testBed.find('dataStreamActionsPopoverButton').simulate('click'); + } + const findDetailPanel = () => { const { find } = testBed; return find('dataStreamDetailPanel'); @@ -258,6 +263,7 @@ export const setup = async ( clickDeleteDataStreamButton, clickEditDataRetentionButton, clickDetailPanelIndexTemplateLink, + clickManageDataStreamsButton, }, findDeleteActionAt, findDeleteConfirmationModal, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index 3bc122ad867f6..6910751fb876c 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -557,8 +557,10 @@ describe('Data Streams tab', () => { testBed.component.update(); expect(httpSetup.put).toHaveBeenLastCalledWith( - `${API_BASE_PATH}/data_streams/dataStream1/data_retention`, - expect.objectContaining({ body: JSON.stringify({ dataRetention: '7h' }) }) + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ + body: JSON.stringify({ dataRetention: '7h', dataStreams: ['dataStream1'] }), + }) ); }); @@ -583,8 +585,10 @@ describe('Data Streams tab', () => { testBed.component.update(); expect(httpSetup.put).toHaveBeenLastCalledWith( - `${API_BASE_PATH}/data_streams/dataStream1/data_retention`, - expect.objectContaining({ body: JSON.stringify({ enabled: false }) }) + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ + body: JSON.stringify({ enabled: false, dataStreams: ['dataStream1'] }), + }) ); }); @@ -609,8 +613,8 @@ describe('Data Streams tab', () => { testBed.component.update(); expect(httpSetup.put).toHaveBeenLastCalledWith( - `${API_BASE_PATH}/data_streams/dataStream1/data_retention`, - expect.objectContaining({ body: JSON.stringify({}) }) + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ body: JSON.stringify({ dataStreams: ['dataStream1'] }) }) ); }); }); @@ -1028,17 +1032,20 @@ describe('Data Streams tab', () => { test('displays/hides delete action depending on data streams privileges', async () => { const { - actions: { selectDataStream }, + actions: { selectDataStream, clickManageDataStreamsButton }, find, } = testBed; selectDataStream('dataStreamNoDelete', true); + clickManageDataStreamsButton(); expect(find('deleteDataStreamsButton').exists()).toBeFalsy(); selectDataStream('dataStreamWithDelete', true); + clickManageDataStreamsButton(); expect(find('deleteDataStreamsButton').exists()).toBeFalsy(); selectDataStream('dataStreamNoDelete', false); + clickManageDataStreamsButton(); expect(find('deleteDataStreamsButton').exists()).toBeTruthy(); }); diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/data_streams.test.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/data_streams.test.ts index bb1df7bf51518..a8143304f2b92 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/data_streams.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/data_streams.test.ts @@ -25,15 +25,14 @@ describe('Data streams API', () => { jest.resetAllMocks(); }); - describe('Update data retention for DS - PUT /internal/index_management/{name}/data_retention', () => { + describe('Update data retention for DS - PUT /internal/index_management/data_retention', () => { const updateDataLifecycle = router.getMockESApiFn('indices.putDataLifecycle'); it('updates data lifecycle for a given data stream', async () => { const mockRequest: RequestMock = { method: 'put', - path: addBasePath('/data_streams/{name}/data_retention'), - params: { name: 'foo' }, - body: { dataRetention: '7d' }, + path: addBasePath('/data_streams/data_retention'), + body: { dataRetention: '7d', dataStreams: ['foo'] }, }; updateDataLifecycle.mockResolvedValue({ success: true }); @@ -48,9 +47,8 @@ describe('Data streams API', () => { it('should return an error if it fails', async () => { const mockRequest: RequestMock = { method: 'put', - path: addBasePath('/data_streams/{name}/data_retention'), - params: { name: 'foo' }, - body: { dataRetention: '7d' }, + path: addBasePath('/data_streams/data_retention'), + body: { dataRetention: '7d', dataStreams: ['foo'] }, }; const error = new Error('Oh no!'); From fb839e4ac2bc51e4ca83ff478c0676a0fd20f4f4 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:17:22 +0000 Subject: [PATCH 11/30] [CI] Auto-commit changed files from 'node scripts/yarn_deduplicate' --- x-pack/plugins/index_management/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/index_management/tsconfig.json b/x-pack/plugins/index_management/tsconfig.json index eac67aa620973..080b3020523c1 100644 --- a/x-pack/plugins/index_management/tsconfig.json +++ b/x-pack/plugins/index_management/tsconfig.json @@ -55,6 +55,7 @@ "@kbn/ml-error-utils", "@kbn/unsaved-changes-prompt", "@kbn/shared-ux-table-persist", + "@kbn/core-application-browser", ], "exclude": ["target/**/*"] } From a8946ed531e229d554ddbb1f241b3c3a52a93ce8 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:39:00 +0000 Subject: [PATCH 12/30] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../client_integration/home/data_streams_tab.helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index fcd937b26f6eb..a767e069423e0 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -213,7 +213,7 @@ export const setup = async ( const clickManageDataStreamsButton = () => { testBed.find('dataStreamActionsPopoverButton').simulate('click'); - } + }; const findDetailPanel = () => { const { find } = testBed; From 812a79bbba03fe7241aac6986de791c16c5bed06 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Wed, 11 Dec 2024 13:47:45 +0000 Subject: [PATCH 13/30] Only show error callout when infinite data retention is switched off --- .../edit_data_retention_modal/edit_data_retention_modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 2c75c26159616..c08c47842313f 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -335,7 +335,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {affectedDataStreams.length > 0 && ( + {affectedDataStreams.length > 0 && !formData.infiniteRetentionPeriod && ( Date: Wed, 11 Dec 2024 14:15:01 +0000 Subject: [PATCH 14/30] Make delete button red --- .../data_stream_list/data_stream_table/data_stream_table.tsx | 1 + x-pack/plugins/index_management/public/index.scss | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index 75c502468cad4..40e6e0033fea6 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -307,6 +307,7 @@ export const DataStreamTable: React.FunctionComponent = ({ }), icon: 'trash', onClick: () => setDataStreamsToDelete(selection.map(({ name }: DataStream) => name)), + className: 'dataStreamsBulkDeleteButton', }); } diff --git a/x-pack/plugins/index_management/public/index.scss b/x-pack/plugins/index_management/public/index.scss index a8952764cc39b..be46c14176133 100644 --- a/x-pack/plugins/index_management/public/index.scss +++ b/x-pack/plugins/index_management/public/index.scss @@ -20,3 +20,7 @@ word-break: break-all; } } + +.dataStreamsBulkDeleteButton { + color: $euiColorDangerText; +} From fe0e1e134c7458a595c10c694f34993ac91dd3cc Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 10:50:22 +0000 Subject: [PATCH 15/30] Make project settings link load in a new tab --- .../edit_data_retention_modal/edit_data_retention_modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index c08c47842313f..259385cc90220 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -270,7 +270,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ maxRetention: globalMaxRetention.size, unitText: globalMaxRetention.unitText, manageSettingsLink: ( - + {i18n.translate( 'xpack.idxMgmt.dataStreams.editDataRetentionModal.manageProjectSettingsLinkText', { From 51a2fb2f840fe55e13157f45a4eaa06e38e80604 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 10:55:16 +0000 Subject: [PATCH 16/30] Fix width issue --- .../data_stream_detail_panel.tsx | 1 + .../data_stream_table/data_stream_table.tsx | 1 + .../edit_data_retention_modal.tsx | 19 ++++++++++--------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx index 45606d0d35abf..0f09a47f43880 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx @@ -551,6 +551,7 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ ilmPolicyName={dataStream?.ilmPolicyName} ilmPolicyLink={ilmPolicyLink} dataStreams={[dataStream]} + isBulkEdit={false} /> )} diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index 40e6e0033fea6..a6da8c4f24fe2 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -394,6 +394,7 @@ export const DataStreamTable: React.FunctionComponent = ({ } }} dataStreams={dataStreamsToEditDataRetention} + isBulkEdit={true} /> ) : null} {dataStreamsToDelete && dataStreamsToDelete.length > 0 ? ( diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 259385cc90220..71e420e78dd7d 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -48,6 +48,7 @@ interface Props { ilmPolicyName?: string; ilmPolicyLink?: string; onClose: (data?: { hasUpdatedDataRetention: boolean }) => void; + isBulkEdit: boolean; } export const EditDataRetentionModal: React.FunctionComponent = ({ @@ -55,6 +56,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ ilmPolicyName, ilmPolicyLink, onClose, + isBulkEdit, }) => { const lifecycle = dataStreams[0]?.lifecycle; @@ -62,10 +64,9 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ history, plugins: { cloud }, } = useAppContext(); - const isSingleDataStream = dataStreams.length === 1; const dataStreamNames = dataStreams.map(({ name }: DataStream) => name as string); const globalMaxRetention = deserializeGlobalMaxRetention(lifecycle?.globalMaxRetention); - const { size, unit } = isSingleDataStream + const { size, unit } = isBulkEdit ? splitSizeAndUnits(lifecycle?.data_retention as string) : { size: undefined, unit: undefined }; @@ -78,12 +79,12 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ defaultValue: { dataRetention: size, timeUnit: unit || 'd', - dataRetentionEnabled: isSingleDataStream ? lifecycle?.enabled : true, + dataRetentionEnabled: isBulkEdit ? lifecycle?.enabled : true, // 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: - isSingleDataStream && lifecycle?.enabled && !lifecycle?.data_retention, + isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, }, schema: editDataRetentionFormSchema, id: 'editDataRetentionForm', @@ -191,7 +192,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ onClose()} data-test-subj="editDataRetentionModal" - css={{ minWidth: isSingleDataStream ? 450 : 650, maxWidth: 650 }} + css={{ minWidth: isBulkEdit ? 650 : 450, maxWidth: 650 }} > @@ -205,7 +206,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {isSingleDataStream && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( + {isBulkEdit && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( <> = ({ )} {enableProjectLevelRetentionChecks && - isSingleDataStream && + isBulkEdit && lifecycle?.globalMaxRetention && ( <> = ({ } helpText={ - !isSingleDataStream && + !isBulkEdit && globalMaxRetention && ( = ({ ) } componentProps={{ - fullWidth: !isSingleDataStream, + fullWidth: isBulkEdit, euiFieldProps: { disabled: formData.infiniteRetentionPeriod || From 134dc1d8626caae13e66d233490b23229b26bb94 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 10:59:56 +0000 Subject: [PATCH 17/30] Fix logic for finding affected data streams --- .../edit_data_retention_modal.tsx | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 71e420e78dd7d..86b58e3e8d54d 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -83,8 +83,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ // 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: - isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, + infiniteRetentionPeriod: isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, }, schema: editDataRetentionFormSchema, id: 'editDataRetentionForm', @@ -179,12 +178,16 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ (ds: DataStream) => formData.dataRetention && formData.timeUnit && - (!ds.lifecycle?.data_retention || - ds.lifecycle?.data_retention === -1 || + ((ds.lifecycle?.data_retention && isRetentionBiggerThan( ds.lifecycle.data_retention, `${formData.dataRetention}${formData.timeUnit}` - )) + )) || + (ds.lifecycle?.effective_retention && + isRetentionBiggerThan( + ds.lifecycle.effective_retention, + `${formData.dataRetention}${formData.timeUnit}` + ))) ) .map(({ name }: DataStream) => name); @@ -218,21 +221,19 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ )} - {enableProjectLevelRetentionChecks && - isBulkEdit && - lifecycle?.globalMaxRetention && ( - <> - - - - )} + {enableProjectLevelRetentionChecks && isBulkEdit && lifecycle?.globalMaxRetention && ( + <> + + + + )} {enableTogglingDataRetention && ( Date: Thu, 12 Dec 2024 11:20:47 +0000 Subject: [PATCH 18/30] Fix logic for bulk or single edit --- .../edit_data_retention_modal.tsx | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 86b58e3e8d54d..689969469c102 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -67,8 +67,8 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ const dataStreamNames = dataStreams.map(({ name }: DataStream) => name as string); const globalMaxRetention = deserializeGlobalMaxRetention(lifecycle?.globalMaxRetention); const { size, unit } = isBulkEdit - ? splitSizeAndUnits(lifecycle?.data_retention as string) - : { size: undefined, unit: undefined }; + ? { size: undefined, unit: undefined } + : splitSizeAndUnits(lifecycle?.data_retention as string); const { services: { notificationService }, @@ -79,11 +79,11 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ defaultValue: { dataRetention: size, timeUnit: unit || 'd', - dataRetentionEnabled: isBulkEdit ? lifecycle?.enabled : true, + dataRetentionEnabled: isBulkEdit ? true : lifecycle?.enabled, // 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: isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, + infiniteRetentionPeriod: !isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, }, schema: editDataRetentionFormSchema, id: 'editDataRetentionForm', @@ -128,42 +128,43 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ return onClose({ hasUpdatedDataRetention: true }); } - const successMessage = isSingleDataStream + const successMessage = isBulkEdit ? i18n.translate( - 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successBulkDataRetentionNotification', { defaultMessage: - 'Data retention {disabledDataRetention, plural, one { disabled } other { updated } }', - values: { disabledDataRetention: !data.dataRetentionEnabled ? 1 : 0 }, + 'Data retention has been updated for {dataStreamCount, plural, one {one data stream} other {{dataStreamCount} data streams}}.', + values: { dataStreamCount: dataStreams.length }, } ) : i18n.translate( - 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successBulkDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.successDataRetentionNotification', { defaultMessage: - 'Data retention has been updated for {dataStreamCount, plural, one {one data stream} other {{dataStreamCount} data streams}}.', - values: { dataStreamCount: dataStreams.length }, + 'Data retention {disabledDataRetention, plural, one { disabled } other { updated } }', + values: { disabledDataRetention: !data.dataRetentionEnabled ? 1 : 0 }, } ); + notificationService.showSuccessToast(successMessage); return onClose({ hasUpdatedDataRetention: true }); } if (error) { - const errorMessage = isSingleDataStream + const errorMessage = isBulkEdit ? i18n.translate( - 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorBulkDataRetentionNotification', { - defaultMessage: "Error updating data retention: ''{error}''", - values: { error: error.message }, + defaultMessage: + 'There was an error updating the retention period. Try again later.', } ) : i18n.translate( - 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorBulkDataRetentionNotification', + 'xpack.idxMgmt.dataStreams.editDataRetentionModal.errorDataRetentionNotification', { - defaultMessage: - 'There was an error updating the retention period. Try again later.', + defaultMessage: "Error updating data retention: ''{error}''", + values: { error: error.message }, } ); notificationService.showDangerToast(errorMessage); @@ -209,7 +210,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {isBulkEdit && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( + {!isBulkEdit && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( <> = ({ )} - {enableProjectLevelRetentionChecks && isBulkEdit && lifecycle?.globalMaxRetention && ( + {enableProjectLevelRetentionChecks && !isBulkEdit && lifecycle?.globalMaxRetention && ( <> = ({ } helpText={ - !isBulkEdit && + isBulkEdit && globalMaxRetention && ( Date: Thu, 12 Dec 2024 11:27:09 +0000 Subject: [PATCH 19/30] Revert translation changes to resolve merge conflicts --- x-pack/plugins/translations/translations/fr-FR.json | 7 +++++++ x-pack/plugins/translations/translations/ja-JP.json | 7 +++++++ x-pack/plugins/translations/translations/zh-CN.json | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index d976543737ee3..fa5b37eb1eb16 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -22420,6 +22420,7 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "Supprimer", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "Conservation des données", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "Les données sont conservées au moins pour cette durée avant leur suppression automatique. La valeur de rétention de données s'applique uniquement aux données gérées directement par le flux de données. {canDisableDataRetention, plural, one {Si certaines données sont sujettes à une politique de gestion du cycle de vie de l'index, alors la valeur de conservation des données réglée pour le flux de données ne s'applique par à ces données.} other {}}", + "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "Supprimer {count, plural, one {le flux de données} other {les flux de données} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "Intégrité", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "Masqué", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "Index", @@ -22435,16 +22436,22 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "Statistiques incluses", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "L'inclusion de statistiques peut augmenter le temps de rechargement", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "En savoir plus.", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "Annuler", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "Activer la conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "Conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "Une valeur positive est requise.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "Une valeur de conservation des données est requise.", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "Erreur lors de la mise à niveau de la conservation des données : \"{error}\"", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "Stratégie ILM", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "Afin de modifier la conservation des données pour ce flux de données, vous devez modifier le {link} associé.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "Ce flux de données et les index associés sont gérés par la stratégie ILM", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "Comment ça fonctionne ?", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "Enregistrer", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "Un index ou plus sont gérés par une politique ILM ({viewAllIndicesLink}). La mise à niveau de la conservation des données pour ce flux de données n'aura pas d'incidence sur ces index. À la place, vous devrez mettre à niveau la politique {ilmPolicyLink}.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "Certains index sont gérés par la stratégie ILM", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "Conservation des données {disabledDataRetention, plural, one { désactivée } other { mise à niveau } }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "Unité de temps", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "Unité de temps", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "afficher les index", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "Gérer", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "La valeur doit être un nombre entier.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c7bf60ed8101f..ca9edb8931403 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -22391,6 +22391,7 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "削除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "データ保持", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "データは少なくともこの期間保存された後、自動的に削除されます。データ保持値は、データストリームによって直接管理されたデータにのみ適用されます。{canDisableDataRetention, plural, one {一部のデータにインデックスライフサイクル管理ポリシーが適用される場合、データストリームに設定されたデータ保持値はそのデータに適用されません。} other {}}", + "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "{count, plural, other {個のデータストリーム}}を削除", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "ヘルス", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "非表示", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "インデックス", @@ -22406,16 +22407,22 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "統計情報を含める", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "統計情報を含めると、再読み込み時間が長くなることがあります", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "詳細情報", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "データ保持を有効化", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "データ保持", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "正の値が必要です。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "データ保持値が必要です。", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "データ保持の更新エラー:''{error}''", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILMポリシー", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "このデータストリームのデータ保持を編集するには、関連する{link}を編集する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "このデータストリームと関連するインデックスはILMによって管理されます。", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "仕組み", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "ILMポリシー({viewAllIndicesLink})によって1つ以上のインデックスが管理されます。このデータストリームのデータ保持を更新しても、これらのインデックスには影響しません。代わりに、{ilmPolicyLink}ポリシーを更新する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "一部のインデックスはILMによって管理されます。", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "データ保持が{disabledDataRetention, plural, one {無効化されました} other {更新されました} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "時間単位", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "時間単位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "インデックスを表示", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "値は整数でなければなりません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index c30c1062a286a..d297ff942df01 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -22009,6 +22009,7 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "删除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "数据保留", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "会至少在这个时长内保留数据,然后自动将其删除。数据保留值仅适用于由数据流直接管理的数据。{canDisableDataRetention, plural, one {如果某些数据受索引生命周期管理策略约束,则为数据流设置的数据保留值不适用于该数据。} other {}}", + "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "删除{count, plural, other {数据流} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "运行状况", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "隐藏", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "索引", @@ -22024,6 +22025,7 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "包含统计信息", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "包含统计信息可能会延长重新加载时间", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "了解详情。", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "取消", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "启用数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "需要提供正值。", @@ -22031,9 +22033,13 @@ "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILM 策略", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "要编辑此数据流的数据保留,必须编辑其关联 {link}。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "此数据流及其关联索引由 ILM 管理", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "工作原理?", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "一个或多个索引由 ILM 策略管理 ({viewAllIndicesLink})。更新此数据流的数据保留不会影响到这些索引。相反,您必须更新 {ilmPolicyLink} 策略。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "某些索引由 ILM 管理", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "数据保留{disabledDataRetention, plural, one {已禁用} other {已更新} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "时间单位", + "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "时间单位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "查看索引", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "此值应为整数。", From 8418e8c81a36d325372820542c83a901794b6535 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 13:02:13 +0000 Subject: [PATCH 20/30] Return i18n translations back --- x-pack/plugins/translations/translations/fr-FR.json | 7 ------- x-pack/plugins/translations/translations/ja-JP.json | 7 ------- x-pack/plugins/translations/translations/zh-CN.json | 6 ------ 3 files changed, 20 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index fa5b37eb1eb16..d976543737ee3 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -22420,7 +22420,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "Supprimer", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "Conservation des données", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "Les données sont conservées au moins pour cette durée avant leur suppression automatique. La valeur de rétention de données s'applique uniquement aux données gérées directement par le flux de données. {canDisableDataRetention, plural, one {Si certaines données sont sujettes à une politique de gestion du cycle de vie de l'index, alors la valeur de conservation des données réglée pour le flux de données ne s'applique par à ces données.} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "Supprimer {count, plural, one {le flux de données} other {les flux de données} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "Intégrité", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "Masqué", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "Index", @@ -22436,22 +22435,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "Statistiques incluses", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "L'inclusion de statistiques peut augmenter le temps de rechargement", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "En savoir plus.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "Annuler", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "Activer la conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "Conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "Une valeur positive est requise.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "Une valeur de conservation des données est requise.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "Erreur lors de la mise à niveau de la conservation des données : \"{error}\"", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "Stratégie ILM", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "Afin de modifier la conservation des données pour ce flux de données, vous devez modifier le {link} associé.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "Ce flux de données et les index associés sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "Comment ça fonctionne ?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "Enregistrer", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "Un index ou plus sont gérés par une politique ILM ({viewAllIndicesLink}). La mise à niveau de la conservation des données pour ce flux de données n'aura pas d'incidence sur ces index. À la place, vous devrez mettre à niveau la politique {ilmPolicyLink}.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "Certains index sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "Conservation des données {disabledDataRetention, plural, one { désactivée } other { mise à niveau } }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "Unité de temps", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "Unité de temps", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "afficher les index", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "Gérer", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "La valeur doit être un nombre entier.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ca9edb8931403..c7bf60ed8101f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -22391,7 +22391,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "削除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "データ保持", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "データは少なくともこの期間保存された後、自動的に削除されます。データ保持値は、データストリームによって直接管理されたデータにのみ適用されます。{canDisableDataRetention, plural, one {一部のデータにインデックスライフサイクル管理ポリシーが適用される場合、データストリームに設定されたデータ保持値はそのデータに適用されません。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "{count, plural, other {個のデータストリーム}}を削除", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "ヘルス", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "非表示", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "インデックス", @@ -22407,22 +22406,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "統計情報を含める", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "統計情報を含めると、再読み込み時間が長くなることがあります", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "詳細情報", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "データ保持を有効化", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "データ保持", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "正の値が必要です。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "データ保持値が必要です。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "データ保持の更新エラー:''{error}''", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILMポリシー", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "このデータストリームのデータ保持を編集するには、関連する{link}を編集する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "このデータストリームと関連するインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "仕組み", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "ILMポリシー({viewAllIndicesLink})によって1つ以上のインデックスが管理されます。このデータストリームのデータ保持を更新しても、これらのインデックスには影響しません。代わりに、{ilmPolicyLink}ポリシーを更新する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "一部のインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "データ保持が{disabledDataRetention, plural, one {無効化されました} other {更新されました} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "時間単位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "時間単位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "インデックスを表示", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "値は整数でなければなりません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d297ff942df01..c30c1062a286a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -22009,7 +22009,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "删除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "数据保留", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "会至少在这个时长内保留数据,然后自动将其删除。数据保留值仅适用于由数据流直接管理的数据。{canDisableDataRetention, plural, one {如果某些数据受索引生命周期管理策略约束,则为数据流设置的数据保留值不适用于该数据。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "删除{count, plural, other {数据流} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "运行状况", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "隐藏", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "索引", @@ -22025,7 +22024,6 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "包含统计信息", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "包含统计信息可能会延长重新加载时间", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "了解详情。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "取消", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "启用数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "需要提供正值。", @@ -22033,13 +22031,9 @@ "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILM 策略", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "要编辑此数据流的数据保留,必须编辑其关联 {link}。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "此数据流及其关联索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "工作原理?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "一个或多个索引由 ILM 策略管理 ({viewAllIndicesLink})。更新此数据流的数据保留不会影响到这些索引。相反,您必须更新 {ilmPolicyLink} 策略。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "某些索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "数据保留{disabledDataRetention, plural, one {已禁用} other {已更新} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "时间单位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "时间单位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "查看索引", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "此值应为整数。", From 277838a47b39403682c89e5f165a4c9c7b4dc0b1 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 13:21:04 +0000 Subject: [PATCH 21/30] Fix type error --- .../edit_data_retention_modal/edit_data_retention_modal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 689969469c102..e88c25a487df1 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -179,7 +179,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ (ds: DataStream) => formData.dataRetention && formData.timeUnit && - ((ds.lifecycle?.data_retention && + ((typeof ds.lifecycle?.data_retention === 'string' && isRetentionBiggerThan( ds.lifecycle.data_retention, `${formData.dataRetention}${formData.timeUnit}` From f95bbd7221f581b5aef743f05b9706f985b4ac55 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 12 Dec 2024 16:27:03 +0000 Subject: [PATCH 22/30] Add some fixes --- .../edit_data_retention_modal.tsx | 29 +++++++++++-------- .../translations/translations/fr-FR.json | 7 +++++ .../translations/translations/ja-JP.json | 7 +++++ .../translations/translations/zh-CN.json | 6 ++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index e88c25a487df1..8b7fa7a58f669 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -59,6 +59,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ isBulkEdit, }) => { const lifecycle = dataStreams[0]?.lifecycle; + const isSingleDataStream = dataStreams.length === 1; const { history, @@ -66,9 +67,9 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ } = useAppContext(); const dataStreamNames = dataStreams.map(({ name }: DataStream) => name as string); const globalMaxRetention = deserializeGlobalMaxRetention(lifecycle?.globalMaxRetention); - const { size, unit } = isBulkEdit - ? { size: undefined, unit: undefined } - : splitSizeAndUnits(lifecycle?.data_retention as string); + const { size, unit } = isSingleDataStream + ? splitSizeAndUnits(lifecycle?.data_retention as string) + : { size: undefined, unit: undefined }; const { services: { notificationService }, @@ -79,11 +80,12 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ defaultValue: { dataRetention: size, timeUnit: unit || 'd', - dataRetentionEnabled: isBulkEdit ? true : lifecycle?.enabled, + dataRetentionEnabled: isSingleDataStream ? lifecycle?.enabled : true, // 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: !isBulkEdit && lifecycle?.enabled && !lifecycle?.data_retention, + infiniteRetentionPeriod: + isSingleDataStream && lifecycle?.enabled && !lifecycle?.data_retention, }, schema: editDataRetentionFormSchema, id: 'editDataRetentionForm', @@ -179,11 +181,14 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ (ds: DataStream) => formData.dataRetention && formData.timeUnit && - ((typeof ds.lifecycle?.data_retention === 'string' && - isRetentionBiggerThan( - ds.lifecycle.data_retention, - `${formData.dataRetention}${formData.timeUnit}` - )) || + ((ds.lifecycle?.enabled && + !ds.lifecycle?.data_retention && + !ds.lifecycle?.effective_retention) || + (typeof ds.lifecycle?.data_retention === 'string' && + isRetentionBiggerThan( + ds.lifecycle.data_retention, + `${formData.dataRetention}${formData.timeUnit}` + )) || (ds.lifecycle?.effective_retention && isRetentionBiggerThan( ds.lifecycle.effective_retention, @@ -203,7 +208,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ @@ -265,7 +270,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ } helpText={ isBulkEdit && - globalMaxRetention && ( + lifecycle?.globalMaxRetention && ( Date: Mon, 16 Dec 2024 16:06:56 +0000 Subject: [PATCH 23/30] Fix i18n errors --- .../plugins/private/translations/translations/fr-FR.json | 7 ------- .../plugins/private/translations/translations/ja-JP.json | 7 ------- .../plugins/private/translations/translations/zh-CN.json | 6 ------ 3 files changed, 20 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index e55adb9fe6df6..da59754334b7d 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -22201,7 +22201,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "Supprimer", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "Conservation des données", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "Les données sont conservées au moins pour cette durée avant leur suppression automatique. La valeur de rétention de données s'applique uniquement aux données gérées directement par le flux de données. {canDisableDataRetention, plural, one {Si certaines données sont sujettes à une politique de gestion du cycle de vie de l'index, alors la valeur de conservation des données réglée pour le flux de données ne s'applique par à ces données.} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "Supprimer {count, plural, one {le flux de données} other {les flux de données} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "Intégrité", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "Masqué", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "Index", @@ -22217,22 +22216,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "Statistiques incluses", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "L'inclusion de statistiques peut augmenter le temps de rechargement", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "En savoir plus.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "Annuler", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "Activer la conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "Conservation des données", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "Une valeur positive est requise.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "Une valeur de conservation des données est requise.", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "Erreur lors de la mise à niveau de la conservation des données : \"{error}\"", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "Stratégie ILM", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "Afin de modifier la conservation des données pour ce flux de données, vous devez modifier le {link} associé.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "Ce flux de données et les index associés sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "Comment ça fonctionne ?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "Enregistrer", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "Un index ou plus sont gérés par une politique ILM ({viewAllIndicesLink}). La mise à niveau de la conservation des données pour ce flux de données n'aura pas d'incidence sur ces index. À la place, vous devrez mettre à niveau la politique {ilmPolicyLink}.", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "Certains index sont gérés par la stratégie ILM", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "Conservation des données {disabledDataRetention, plural, one { désactivée } other { mise à niveau } }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "Unité de temps", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "Unité de temps", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "afficher les index", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "Gérer", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "La valeur doit être un nombre entier.", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 18a4ea7485487..90c065708820b 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -22059,7 +22059,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "削除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "データ保持", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "データは少なくともこの期間保存された後、自動的に削除されます。データ保持値は、データストリームによって直接管理されたデータにのみ適用されます。{canDisableDataRetention, plural, one {一部のデータにインデックスライフサイクル管理ポリシーが適用される場合、データストリームに設定されたデータ保持値はそのデータに適用されません。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "{count, plural, other {個のデータストリーム}}を削除", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "ヘルス", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "非表示", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "インデックス", @@ -22075,22 +22074,16 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "統計情報を含める", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "統計情報を含めると、再読み込み時間が長くなることがあります", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "詳細情報", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "データ保持を有効化", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "データ保持", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "正の値が必要です。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError": "データ保持値が必要です。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.errorDataRetentionNotification": "データ保持の更新エラー:''{error}''", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILMポリシー", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "このデータストリームのデータ保持を編集するには、関連する{link}を編集する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "このデータストリームと関連するインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "仕組み", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "ILMポリシー({viewAllIndicesLink})によって1つ以上のインデックスが管理されます。このデータストリームのデータ保持を更新しても、これらのインデックスには影響しません。代わりに、{ilmPolicyLink}ポリシーを更新する必要があります。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "一部のインデックスはILMによって管理されます。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "データ保持が{disabledDataRetention, plural, one {無効化されました} other {更新されました} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "時間単位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "時間単位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "インデックスを表示", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "値は整数でなければなりません。", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 285f889c557b2..edefc1da1c554 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -21710,7 +21710,6 @@ "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "删除", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTitle": "数据保留", "xpack.idxMgmt.dataStreamList.table.dataRetentionColumnTooltip": "会至少在这个时长内保留数据,然后自动将其删除。数据保留值仅适用于由数据流直接管理的数据。{canDisableDataRetention, plural, one {如果某些数据受索引生命周期管理策略约束,则为数据流设置的数据保留值不适用于该数据。} other {}}", - "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "删除{count, plural, other {数据流} }", "xpack.idxMgmt.dataStreamList.table.healthColumnTitle": "运行状况", "xpack.idxMgmt.dataStreamList.table.hiddenDataStreamBadge": "隐藏", "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "索引", @@ -21726,7 +21725,6 @@ "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchLabel": "包含统计信息", "xpack.idxMgmt.dataStreamListControls.includeStatsSwitchToolTip": "包含统计信息可能会延长重新加载时间", "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "了解详情。", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.cancelButtonLabel": "取消", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionEnabledField": "启用数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionField": "数据保留", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldNonNegativeError": "需要提供正值。", @@ -21734,13 +21732,9 @@ "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMButtonLabel": "ILM 策略", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMDescription": "要编辑此数据流的数据保留,必须编辑其关联 {link}。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.fullyManagedByILMTitle": "此数据流及其关联索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.learnMoreLinkText": "工作原理?", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.saveButtonLabel": "保存", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMBody": "一个或多个索引由 ILM 策略管理 ({viewAllIndicesLink})。更新此数据流的数据保留不会影响到这些索引。相反,您必须更新 {ilmPolicyLink} 策略。", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.someManagedByILMTitle": "某些索引由 ILM 管理", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.successDataRetentionNotification": "数据保留{disabledDataRetention, plural, one {已禁用} other {已更新} }", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.timeUnitField": "时间单位", - "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.unitsAriaLabel": "时间单位", "xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.viewAllIndices": "查看索引", "xpack.idxMgmt.dataStreamsDetailsPanel.manageButtonLabel": "管理", "xpack.idxMgmt.dataStreamsDetailsPanel.stepLogistics.dataRetentionFieldDecimalError": "此值应为整数。", From 86baf7cefbb099d659b4b02c2909ca71c7896b87 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Wed, 18 Dec 2024 12:53:30 +0200 Subject: [PATCH 24/30] Fix jest tests --- .../data_stream_list/data_stream_table/data_stream_table.tsx | 2 ++ .../edit_data_retention_modal/edit_data_retention_modal.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index a6da8c4f24fe2..e419bda67aeae 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -297,6 +297,7 @@ export const DataStreamTable: React.FunctionComponent = ({ }), icon: 'pencil', onClick: () => setDataStreamsToEditDataRetention(selection), + 'data-test-subj': 'bulkEditDataRetentionButton', }, ]; @@ -308,6 +309,7 @@ export const DataStreamTable: React.FunctionComponent = ({ icon: 'trash', onClick: () => setDataStreamsToDelete(selection.map(({ name }: DataStream) => name)), className: 'dataStreamsBulkDeleteButton', + 'data-test-subj': 'deleteDataStreamsButton', }); } diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 8b7fa7a58f669..28d8c05599335 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -215,7 +215,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {!isBulkEdit && ilmPolicyLink && isDSLWithILMIndices(dataStreams[0]) && ( + {!isBulkEdit && isDSLWithILMIndices(dataStreams[0]) && ( <> Date: Wed, 18 Dec 2024 12:56:19 +0200 Subject: [PATCH 25/30] Fix serverless api integration tests --- .../test_suites/common/index_management/datastreams.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts index 12151f1b169db..099e1b9b3c1a6 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts @@ -135,11 +135,12 @@ export default function ({ getService }: FtrProviderContext) { it('updates the data retention of a DS', async () => { const { body, status } = await supertestWithoutAuth - .put(`${API_BASE_PATH}/data_streams/${testDataStreamName}/data_retention`) + .put(`${API_BASE_PATH}/data_streams/data_retention`) .set(internalReqHeader) .set(roleAuthc.apiKeyHeader) .send({ dataRetention: '7d', + dataStreams: [testDataStreamName], }); svlCommonApi.assertResponseStatusCode(200, status, body); @@ -148,10 +149,12 @@ export default function ({ getService }: FtrProviderContext) { it('sets data retention to infinite', async () => { const { body, status } = await supertestWithoutAuth - .put(`${API_BASE_PATH}/data_streams/${testDataStreamName}/data_retention`) + .put(`${API_BASE_PATH}/data_streams/data_retention`) .set(internalReqHeader) .set(roleAuthc.apiKeyHeader) - .send({}); + .send({ + dataStreams: [testDataStreamName], + }); svlCommonApi.assertResponseStatusCode(200, status, body); // Providing an infinite retention might not be allowed for a given project, From dc21c91141313893300c5c29f9d6481fcccf7605 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Wed, 18 Dec 2024 13:00:42 +0200 Subject: [PATCH 26/30] Fix type errors --- .../edit_data_retention_modal/mixed_indices_callout.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx index 09dc7f0b08d07..a316edcee49d8 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx @@ -16,7 +16,7 @@ import { useAppContext } from '../../../../app_context'; interface MixedIndicesCalloutProps { history: ScopedHistory; - ilmPolicyLink: string; + ilmPolicyLink?: string; ilmPolicyName?: string; dataStreamName: string; } @@ -42,14 +42,14 @@ export const MixedIndicesCallout = ({

core.application.navigateToUrl(ilmPolicyLink)} > - {ilmPolicyName} + {` (${ilmPolicyName})`} ), viewAllIndicesLink: ( From 208bc58ce153eddf6fed89032c8a66153f11cd50 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Wed, 18 Dec 2024 15:28:24 +0200 Subject: [PATCH 27/30] Fix jest test --- .../__jest__/client_integration/home/data_streams_tab.test.ts | 1 + .../edit_data_retention_modal/mixed_indices_callout.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index 6910751fb876c..7a1a71e641713 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -668,6 +668,7 @@ describe('Data Streams tab', () => { enabled: true, data_retention: '7d', }, + ilmPolicyName: 'testILM', indices: [ { managedBy: 'Index Lifecycle Management', diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx index a316edcee49d8..da9dd84b4247e 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/mixed_indices_callout.tsx @@ -42,14 +42,14 @@ export const MixedIndicesCallout = ({

core.application.navigateToUrl(ilmPolicyLink)} > - {` (${ilmPolicyName})`} + {ilmPolicyName} ), viewAllIndicesLink: ( From 4ebb1763aa44d51a334ac3cb66821c35cafb1e87 Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Wed, 18 Dec 2024 20:19:33 +0200 Subject: [PATCH 28/30] Fix width change and validations --- .../home/data_streams_tab.helpers.ts | 6 + .../home/data_streams_tab.test.ts | 150 ++++++++++++++++++ .../edit_data_retention_modal.tsx | 2 +- .../edit_data_retention_modal/schema.ts | 18 ++- 4 files changed, 169 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index a767e069423e0..99940ad8847b1 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -38,6 +38,7 @@ export interface DataStreamsTabTestBed extends TestBed { clickEditDataRetentionButton: () => void; clickDetailPanelIndexTemplateLink: () => void; clickManageDataStreamsButton: () => void; + clickBulkEditDataRetentionButton: () => void; }; findDeleteActionAt: (index: number) => ReactWrapper; findDeleteConfirmationModal: () => ReactWrapper; @@ -215,6 +216,10 @@ export const setup = async ( testBed.find('dataStreamActionsPopoverButton').simulate('click'); }; + const clickBulkEditDataRetentionButton = () => { + testBed.find('bulkEditDataRetentionButton').simulate('click'); + }; + const findDetailPanel = () => { const { find } = testBed; return find('dataStreamDetailPanel'); @@ -264,6 +269,7 @@ export const setup = async ( clickEditDataRetentionButton, clickDetailPanelIndexTemplateLink, clickManageDataStreamsButton, + clickBulkEditDataRetentionButton }, findDeleteActionAt, findDeleteConfirmationModal, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index 7a1a71e641713..c6388ad0273ca 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -449,6 +449,156 @@ describe('Data Streams tab', () => { }); }); + describe('bulk update data retention', () => { + beforeAll(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(); + }); + + test('can set data retention period for mutliple data streams', async () => { + const { + actions: { + selectDataStream, + clickManageDataStreamsButton, + clickBulkEditDataRetentionButton, + }, + } = testBed; + + selectDataStream('dataStream1', true); + selectDataStream('dataStream2', true); + clickManageDataStreamsButton(); + + clickBulkEditDataRetentionButton(); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream1', { + success: true, + }); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream2', { + success: true, + }); + + // set data retention value + testBed.form.setInputValue('dataRetentionValue', '7'); + // Set data retention unit + testBed.find('show-filters-button').simulate('click'); + testBed.find('filter-option-h').simulate('click'); + + await act(async () => { + testBed.find('saveButton').simulate('click'); + }); + testBed.component.update(); + + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ + body: JSON.stringify({ + dataRetention: '7h', + dataStreams: ['dataStream1', 'dataStream2'], + }), + }) + ); + }); + + test('can disable lifecycle', async () => { + const { + actions: { + selectDataStream, + clickManageDataStreamsButton, + clickBulkEditDataRetentionButton, + }, + } = testBed; + + selectDataStream('dataStream1', true); + selectDataStream('dataStream2', true); + clickManageDataStreamsButton(); + + clickBulkEditDataRetentionButton(); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream1', { + success: true, + }); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream2', { + success: true, + }); + + testBed.form.toggleEuiSwitch('dataRetentionEnabledField.input'); + + await act(async () => { + testBed.find('saveButton').simulate('click'); + }); + testBed.component.update(); + + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ + body: JSON.stringify({ enabled: false, dataStreams: ['dataStream1', 'dataStream2'] }), + }) + ); + }); + + test('allows to set infinite retention period', async () => { + const { + actions: { + selectDataStream, + clickManageDataStreamsButton, + clickBulkEditDataRetentionButton, + }, + } = testBed; + + selectDataStream('dataStream1', true); + selectDataStream('dataStream2', true); + clickManageDataStreamsButton(); + + clickBulkEditDataRetentionButton(); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream1', { + success: true, + }); + + httpRequestsMockHelpers.setEditDataRetentionResponse('dataStream2', { + success: true, + }); + + testBed.form.toggleEuiSwitch('infiniteRetentionPeriod.input'); + + await act(async () => { + testBed.find('saveButton').simulate('click'); + }); + testBed.component.update(); + + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/data_streams/data_retention`, + expect.objectContaining({ body: JSON.stringify({ dataStreams: ['dataStream1', 'dataStream2'] }) }) + ); + }); + }); + describe('detail panel', () => { test('opens when the data stream name in the table is clicked', async () => { const { actions, findDetailPanel, findDetailPanelTitle } = testBed; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx index 28d8c05599335..55d8348400f5f 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/edit_data_retention_modal/edit_data_retention_modal.tsx @@ -343,7 +343,7 @@ export const EditDataRetentionModal: React.FunctionComponent = ({ - {affectedDataStreams.length > 0 && !formData.infiniteRetentionPeriod && ( + {isBulkEdit && affectedDataStreams.length > 0 && !formData.infiniteRetentionPeriod && ( { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!formData.infiniteRetentionPeriod) { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false and dataRetentionEnabled is set to true + if (formData.dataRetentionEnabled !== false && !formData.infiniteRetentionPeriod) { // If project level data retention is enabled, we need to enforce the global max retention const { globalMaxRetention, enableProjectLevelRetentionChecks } = customData.value as any; @@ -46,8 +46,11 @@ export const editDataRetentionFormSchema: FormSchema = { }, { validator: (args) => { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!args.formData.infiniteRetentionPeriod) { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false and dataRetentionEnabled is set to true + if ( + args.formData.dataRetentionEnabled !== false && + !args.formData.infiniteRetentionPeriod + ) { return fieldValidators.emptyField( i18n.translate( 'xpack.idxMgmt.dataStreamsDetailsPanel.editDataRetentionModal.dataRetentionFieldRequiredError', @@ -61,8 +64,11 @@ export const editDataRetentionFormSchema: FormSchema = { }, { validator: (args) => { - // We only need to validate the data retention field if infiniteRetentionPeriod is set to false - if (!args.formData.infiniteRetentionPeriod) { + // We only need to validate the data retention field if infiniteRetentionPeriod is set to false and dataRetentionEnabled is set to true + if ( + args.formData.dataRetentionEnabled !== false && + !args.formData.infiniteRetentionPeriod + ) { return fieldValidators.numberGreaterThanField({ than: 0, allowEquality: false, From 06012ca8512320a201d0d1df226d87211c17de5b Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:44:25 +0000 Subject: [PATCH 29/30] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../client_integration/home/data_streams_tab.helpers.ts | 2 +- .../__jest__/client_integration/home/data_streams_tab.test.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index 99940ad8847b1..b75d1c507cc7a 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -269,7 +269,7 @@ export const setup = async ( clickEditDataRetentionButton, clickDetailPanelIndexTemplateLink, clickManageDataStreamsButton, - clickBulkEditDataRetentionButton + clickBulkEditDataRetentionButton, }, findDeleteActionAt, findDeleteConfirmationModal, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index c6388ad0273ca..d3368371de336 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -594,7 +594,9 @@ describe('Data Streams tab', () => { expect(httpSetup.put).toHaveBeenLastCalledWith( `${API_BASE_PATH}/data_streams/data_retention`, - expect.objectContaining({ body: JSON.stringify({ dataStreams: ['dataStream1', 'dataStream2'] }) }) + expect.objectContaining({ + body: JSON.stringify({ dataStreams: ['dataStream1', 'dataStream2'] }), + }) ); }); }); From 429e8912af2eb180b1c2317fa554defd2625d48d Mon Sep 17 00:00:00 2001 From: Elena Stoeva Date: Thu, 19 Dec 2024 12:51:32 +0200 Subject: [PATCH 30/30] Add more FTRs --- .../data_streams_tab/data_streams_tab.ts | 184 ++++++++++++------ .../page_objects/index_management_page.ts | 11 ++ 2 files changed, 131 insertions(+), 64 deletions(-) diff --git a/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts b/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts index 97ceeefbee9bd..0a6101b71ca5c 100644 --- a/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts +++ b/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts @@ -17,38 +17,42 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const security = getService('security'); const testSubjects = getService('testSubjects'); - const TEST_DS_NAME = 'test-ds-1'; + const TEST_DS_NAME_1 = 'test-ds-1'; + const TEST_DS_NAME_2 = 'test-ds-2'; + const TEST_DATA_STREAM_NAMES = [TEST_DS_NAME_1, TEST_DS_NAME_2]; describe('Data streams tab', function () { before(async () => { await log.debug('Creating required data stream'); try { - await es.indices.putIndexTemplate({ - name: `${TEST_DS_NAME}_index_template`, - index_patterns: [TEST_DS_NAME], - data_stream: {}, - _meta: { - description: `Template for ${TEST_DS_NAME} testing index`, - }, - template: { - settings: { mode: undefined }, - mappings: { - properties: { - '@timestamp': { - type: 'date', + for (const dataStreamName of TEST_DATA_STREAM_NAMES) { + await es.indices.putIndexTemplate({ + name: `${dataStreamName}_index_template`, + index_patterns: [dataStreamName], + data_stream: {}, + _meta: { + description: `Template for ${dataStreamName} testing index`, + }, + template: { + settings: { mode: undefined }, + mappings: { + properties: { + '@timestamp': { + type: 'date', + }, }, }, + lifecycle: { + // @ts-expect-error @elastic/elasticsearch enabled prop is not typed yet + enabled: true, + }, }, - lifecycle: { - // @ts-expect-error @elastic/elasticsearch enabled prop is not typed yet - enabled: true, - }, - }, - }); + }); - await es.indices.createDataStream({ - name: TEST_DS_NAME, - }); + await es.indices.createDataStream({ + name: dataStreamName, + }); + } } catch (e) { log.debug('[Setup error] Error creating test data stream'); throw e; @@ -66,10 +70,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await log.debug('Cleaning up created data stream'); try { - await es.indices.deleteDataStream({ name: TEST_DS_NAME }); - await es.indices.deleteIndexTemplate({ - name: `${TEST_DS_NAME}_index_template`, - }); + for (const dataStreamName of TEST_DATA_STREAM_NAMES) { + await es.indices.deleteDataStream({ name: dataStreamName }); + await es.indices.deleteIndexTemplate({ + name: `${dataStreamName}_index_template`, + }); + } } catch (e) { log.debug('[Teardown error] Error deleting test data stream'); throw e; @@ -78,10 +84,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('shows the details flyout when clicking on a data stream', async () => { // Open details flyout - await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); + await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME_1); // Verify url is stateful const url = await browser.getCurrentUrl(); - expect(url).to.contain(`/data_streams/${TEST_DS_NAME}`); + expect(url).to.contain(`/data_streams/${TEST_DS_NAME_1}`); // Assert that flyout is opened expect(await testSubjects.exists('dataStreamDetailPanel')).to.be(true); // Close flyout @@ -91,7 +97,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('shows the correct index mode in the details flyout', function () { it('standard index mode', async () => { // Open details flyout of existing data stream - it has standard index mode - await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); + await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME_1); // Check that index mode detail exists and its label is "Standard" expect(await testSubjects.exists('indexModeDetail')).to.be(true); expect(await testSubjects.getVisibleText('indexModeDetail')).to.be('Standard'); @@ -129,44 +135,94 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - it('allows to update data retention', async () => { - // Open details flyout - await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); - // Open the edit retention dialog - await testSubjects.click('manageDataStreamButton'); - await testSubjects.click('editDataRetentionButton'); - - // Disable infinite retention - await testSubjects.click('infiniteRetentionPeriod > input'); - // Set the retention to 7 hours - await testSubjects.setValue('dataRetentionValue', '7'); - await testSubjects.click('show-filters-button'); - await testSubjects.click('filter-option-h'); - - // Submit the form - await testSubjects.click('saveButton'); - - // Expect to see a success toast - const successToast = await toasts.getElementByIndex(1); - expect(await successToast.getVisibleText()).to.contain('Data retention updated'); - }); + describe('data retention modal', function () { + describe('from details panel', function () { + it('allows to update data retention', async () => { + // Open details flyout + await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME_1); + // Open the edit retention dialog + await testSubjects.click('manageDataStreamButton'); + await testSubjects.click('editDataRetentionButton'); + + // Disable infinite retention + await testSubjects.click('infiniteRetentionPeriod > input'); + // Set the retention to 7 hours + await testSubjects.setValue('dataRetentionValue', '7'); + await testSubjects.click('show-filters-button'); + await testSubjects.click('filter-option-h'); + + // Submit the form + await testSubjects.click('saveButton'); + + // Expect to see a success toast + const successToast = await toasts.getElementByIndex(1); + expect(await successToast.getVisibleText()).to.contain('Data retention updated'); + // Clear up toasts for next test + await toasts.dismissAll(); + }); - it('allows to disable data retention', async () => { - // Open details flyout - await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); - // Open the edit retention dialog - await testSubjects.click('manageDataStreamButton'); - await testSubjects.click('editDataRetentionButton'); + it('allows to disable data retention', async () => { + // Open details flyout + await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME_1); + // Open the edit retention dialog + await testSubjects.click('manageDataStreamButton'); + await testSubjects.click('editDataRetentionButton'); - // Disable infinite retention - await testSubjects.click('dataRetentionEnabledField > input'); + // Disable infinite retention + await testSubjects.click('dataRetentionEnabledField > input'); - // Submit the form - await testSubjects.click('saveButton'); + // Submit the form + await testSubjects.click('saveButton'); - // Expect to see a success toast - const successToast = await toasts.getElementByIndex(1); - expect(await successToast.getVisibleText()).to.contain('Data retention disabled'); + // Expect to see a success toast + const successToast = await toasts.getElementByIndex(1); + expect(await successToast.getVisibleText()).to.contain('Data retention disabled'); + // Clear up toasts for next test + await toasts.dismissAll(); + }); + }); + + describe('bulk edit modal', function () { + it('allows to update data retention', async () => { + // Select and manage mutliple data streams + await pageObjects.indexManagement.clickBulkEditDataRetention(TEST_DATA_STREAM_NAMES); + + // Set the retention to 7 hours + await testSubjects.setValue('dataRetentionValue', '7'); + await testSubjects.click('show-filters-button'); + await testSubjects.click('filter-option-h'); + + // Submit the form + await testSubjects.click('saveButton'); + + // Expect to see a success toast + const successToast = await toasts.getElementByIndex(1); + expect(await successToast.getVisibleText()).to.contain( + 'Data retention has been updated for 2 data streams.' + ); + // Clear up toasts for next test + await toasts.dismissAll(); + }); + + it('allows to disable data retention', async () => { + // Select and manage mutliple data streams + await pageObjects.indexManagement.clickBulkEditDataRetention(TEST_DATA_STREAM_NAMES); + + // Disable infinite retention + await testSubjects.click('dataRetentionEnabledField > input'); + + // Submit the form + await testSubjects.click('saveButton'); + + // Expect to see a success toast + const successToast = await toasts.getElementByIndex(1); + expect(await successToast.getVisibleText()).to.contain( + 'Data retention has been updated for 2 data streams.' + ); + // Clear up toasts for next test + await toasts.dismissAll(); + }); + }); }); }); }; diff --git a/x-pack/test/functional/page_objects/index_management_page.ts b/x-pack/test/functional/page_objects/index_management_page.ts index e0e2a555540be..207bf2281c080 100644 --- a/x-pack/test/functional/page_objects/index_management_page.ts +++ b/x-pack/test/functional/page_objects/index_management_page.ts @@ -38,6 +38,17 @@ export function IndexManagementPageProvider({ getService }: FtrProviderContext) await policyDetailsLinks[indexOfRow].click(); }, + async clickBulkEditDataRetention(dataStreamNames: string[]): Promise { + for (const dsName of dataStreamNames) { + const checkbox = await testSubjects.find(`checkboxSelectRow-${dsName}`); + if (!(await checkbox.isSelected())) { + await checkbox.click(); + } + } + await testSubjects.click('dataStreamActionsPopoverButton'); + await testSubjects.click('bulkEditDataRetentionButton'); + }, + async clickDataStreamNameLink(name: string): Promise { await find.clickByLinkText(name); },