From d931ed61e4c989f44b1340f88848a2e4828f9727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 27 Jan 2021 17:59:44 +0100 Subject: [PATCH] [ILM] Policy phases redesign (#88671) * Phases redesign * Title and name field layout * Active highlight wip * Copy comments * Updated data allocation dropdown * Min age error message * Fixed tests * Fixed edit policy integration tests * Fixed more tests * Cleaned up test files * Use hotProperty instead of a string * Clean up in phase component * Fixed i18n files * Updated optional fields * Updated aria attributes after running axe tests * Added review suggestions * Reversed data allocation field changes * Fixed type error * Reversed on/off label and prepend input label * Deleted property consts from phases components * Removed not needed i18n consts and added i18n where missing * Fixed merge conflicts with master Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../client_integration/app/app.test.ts | 39 +- .../edit_policy/edit_policy.helpers.tsx | 46 +- .../edit_policy/edit_policy.test.ts | 38 +- .../__jest__/components/edit_policy.test.tsx | 14 +- .../public/application/constants/policy.ts | 27 +- .../active_highlight/active_highlight.scss | 16 + .../active_highlight/active_highlight.tsx | 17 + .../index.ts | 2 +- .../sections/edit_policy/components/index.ts | 1 + .../phases/cold_phase/cold_phase.tsx | 197 ++------ .../phases/delete_phase/delete_phase.tsx | 4 +- .../components/phases/hot_phase/hot_phase.tsx | 434 ++++++++---------- .../edit_policy/components/phases/index.ts | 2 + .../edit_policy/components/phases/phase.tsx | 119 +++++ .../phases/shared_fields/forcemerge_field.tsx | 58 +-- .../components/phases/shared_fields/index.ts | 8 +- ...put_field.tsx => index_priority_field.tsx} | 49 +- .../shared_fields/min_age_field/index.ts | 7 + .../min_age_field/min_age_field.tsx | 158 +++++++ .../util.ts | 0 .../min_age_input_field.tsx | 205 --------- .../phases/shared_fields/replicas_field.tsx | 59 +++ .../phases/shared_fields/shrink_field.tsx | 36 +- .../phases/warm_phase/warm_phase.tsx | 170 +------ .../sections/edit_policy/edit_policy.tsx | 356 +++++++------- .../form/deserializer_and_serializer.test.ts | 9 - .../sections/edit_policy/form/schema.ts | 57 ++- .../edit_policy/form/serializer/serializer.ts | 28 +- .../sections/edit_policy/i18n_texts.ts | 29 +- .../lib/absolute_timing_to_relative_timing.ts | 7 +- .../application/services/ui_metric.test.ts | 10 +- .../public/application/services/ui_metric.ts | 9 +- .../public/shared_imports.ts | 1 + .../translations/translations/ja-JP.json | 33 -- .../translations/translations/zh-CN.json | 33 -- 35 files changed, 1030 insertions(+), 1248 deletions(-) create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.scss create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.tsx rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/{phases/shared_fields/min_age_input_field => active_highlight}/index.ts (80%) create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/phase.tsx rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/{set_priority_input_field.tsx => index_priority_field.tsx} (50%) create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/index.ts create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/min_age_field.tsx rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/{min_age_input_field => min_age_field}/util.ts (100%) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/replicas_field.tsx diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index 1ffbae39d370..1b49416ebbbe 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -21,6 +21,9 @@ const PERCENT_SIGN_NAME = 'test%'; const PERCENT_SIGN_WITH_OTHER_CHARS_NAME = 'test%#'; const PERCENT_SIGN_25_SEQUENCE = 'test%25'; +const createPolicyTitle = 'Create Policy'; +const editPolicyTitle = 'Edit Policy'; + window.scrollTo = jest.fn(); jest.mock('@elastic/eui', () => { @@ -52,7 +55,7 @@ describe('', () => { await actions.clickCreatePolicyButton(); component.update(); - expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyTitle').text()).toBe(createPolicyTitle); expect(testBed.find('policyNameField').props().value).toBe(''); }); @@ -68,7 +71,7 @@ describe('', () => { await actions.clickCreatePolicyButton(); component.update(); - expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyTitle').text()).toBe(createPolicyTitle); expect(testBed.find('policyNameField').props().value).toBe(''); }); }); @@ -89,9 +92,7 @@ describe('', () => { await actions.clickPolicyNameLink(); component.update(); - expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` - ); + expect(testBed.find('policyTitle').text()).toBe(`${editPolicyTitle} ${SPECIAL_CHARS_NAME}`); }); test('loading edit policy page url works', async () => { @@ -102,9 +103,7 @@ describe('', () => { const { component } = testBed; component.update(); - expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` - ); + expect(testBed.find('policyTitle').text()).toBe(`${editPolicyTitle} ${SPECIAL_CHARS_NAME}`); }); // using double encoding to counteract react-router's v5 internal decodeURI call @@ -117,9 +116,7 @@ describe('', () => { const { component } = testBed; component.update(); - expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` - ); + expect(testBed.find('policyTitle').text()).toBe(`${editPolicyTitle} ${SPECIAL_CHARS_NAME}`); }); }); @@ -136,9 +133,7 @@ describe('', () => { const { component } = testBed; component.update(); - expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` - ); + expect(testBed.find('policyTitle').text()).toBe(`${editPolicyTitle} ${PERCENT_SIGN_NAME}`); }); test('loading edit policy page url with double encoding works', async () => { @@ -149,9 +144,7 @@ describe('', () => { const { component } = testBed; component.update(); - expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` - ); + expect(testBed.find('policyTitle').text()).toBe(`${editPolicyTitle} ${PERCENT_SIGN_NAME}`); }); }); @@ -174,7 +167,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + `${editPolicyTitle} ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); @@ -188,7 +181,7 @@ describe('', () => { // known issue https://github.com/elastic/kibana/issues/82440 expect(testBed.find('policyTitle').text()).not.toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + `${editPolicyTitle} ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); @@ -203,7 +196,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + `${editPolicyTitle} ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); }); @@ -225,7 +218,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + `${editPolicyTitle} ${PERCENT_SIGN_25_SEQUENCE}` ); }); @@ -239,7 +232,7 @@ describe('', () => { // known issue https://github.com/elastic/kibana/issues/82440 expect(testBed.find('policyTitle').text()).not.toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + `${editPolicyTitle} ${PERCENT_SIGN_25_SEQUENCE}` ); }); @@ -254,7 +247,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + `${editPolicyTitle} ${PERCENT_SIGN_25_SEQUENCE}` ); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx index 72a0372628a2..64b654b03023 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx @@ -89,6 +89,13 @@ export const setup = async (arg?: { appServicesContext: Partial async (checked: boolean) => { + await act(async () => { + form.selectCheckBox(dataTestSubject, checked); + }); + component.update(); + }; + function createFormSetValueAction(dataTestSubject: string) { return async (value: V) => { await act(async () => { @@ -146,17 +153,21 @@ export const setup = async (arg?: { appServicesContext: Partial exists(toggleSelector), toggleForceMerge: createFormToggleAction(toggleSelector), setForcemergeSegmentsCount: createFormSetValueAction(`${phase}-selectedForceMergeSegments`), - setBestCompression: createFormToggleAction(`${phase}-bestCompression`), + setBestCompression: createFormCheckboxAction(`${phase}-bestCompression`), }; }; - const setIndexPriority = (phase: Phases) => - createFormSetValueAction(`${phase}-phaseIndexPriority`); + const createIndexPriorityActions = (phase: Phases) => { + const toggleSelector = `${phase}-indexPrioritySwitch`; + return { + indexPriorityExists: () => exists(toggleSelector), + toggleIndexPriority: createFormToggleAction(toggleSelector), + setIndexPriority: createFormSetValueAction(`${phase}-indexPriority`), + }; + }; const enable = (phase: Phases) => createFormToggleAction(`enablePhaseSwitch-${phase}`); - const warmPhaseOnRollover = createFormToggleAction(`warm-warmPhaseOnRollover`); - const setMinAgeValue = (phase: Phases) => createFormSetValueAction(`${phase}-selectedMinimumAge`); const setMinAgeUnits = (phase: Phases) => @@ -190,13 +201,15 @@ export const setup = async (arg?: { appServicesContext: Partial async (value: string) => { - await createFormToggleAction(`${phase}-shrinkSwitch`)(true); - await createFormSetValueAction(`${phase}-selectedPrimaryShardCount`)(value); + const createShrinkActions = (phase: Phases) => { + const toggleSelector = `${phase}-shrinkSwitch`; + return { + shrinkExists: () => exists(toggleSelector), + toggleShrink: createFormToggleAction(toggleSelector), + setShrink: createFormSetValueAction(`${phase}-primaryShardCount`), + }; }; - const shrinkExists = (phase: Phases) => () => exists(`${phase}-shrinkSwitch`); - const setFreeze = createFormToggleAction('freezeSwitch'); const freezeExists = () => exists('freezeSwitch'); @@ -250,25 +263,22 @@ export const setup = async (arg?: { appServicesContext: Partial', () => { max_size: '50gb', unknown_setting: 123, // Made up setting that should stay preserved }, - set_priority: { - priority: 100, - }, }, min_age: '0ms', }, @@ -126,8 +123,10 @@ describe('', () => { await actions.hot.toggleForceMerge(true); await actions.hot.setForcemergeSegmentsCount('123'); await actions.hot.setBestCompression(true); + await actions.hot.toggleShrink(true); await actions.hot.setShrink('2'); await actions.hot.setReadonly(true); + await actions.hot.toggleIndexPriority(true); await actions.hot.setIndexPriority('123'); await actions.savePolicy(); @@ -186,13 +185,7 @@ describe('', () => { const hotActions = policy.phases.hot.actions; const rolloverAction = hotActions.rollover; expect(rolloverAction).toBe(undefined); - expect(hotActions).toMatchInlineSnapshot(` - Object { - "set_priority": Object { - "priority": 100, - }, - } - `); + expect(hotActions).toMatchInlineSnapshot(`Object {}`); }); test('enabling searchable snapshot should hide force merge, freeze and shrink in subsequent phases', async () => { @@ -260,6 +253,7 @@ describe('', () => { "priority": 50, }, }, + "min_age": "0ms", } `); }); @@ -270,6 +264,7 @@ describe('', () => { await actions.warm.setDataAllocation('node_attrs'); await actions.warm.setSelectedNodeAttribute('test:123'); await actions.warm.setReplicas('123'); + await actions.warm.toggleShrink(true); await actions.warm.setShrink('123'); await actions.warm.toggleForceMerge(true); await actions.warm.setForcemergeSegmentsCount('123'); @@ -290,9 +285,6 @@ describe('', () => { "max_age": "30d", "max_size": "50gb", }, - "set_priority": Object { - "priority": 100, - }, }, "min_age": "0ms", }, @@ -316,24 +308,12 @@ describe('', () => { "number_of_shards": 123, }, }, + "min_age": "0ms", }, }, } `); }); - - test('setting warm phase on rollover to "false"', async () => { - const { actions } = testBed; - await actions.warm.enable(true); - await actions.warm.warmPhaseOnRollover(false); - await actions.warm.setMinAgeValue('123'); - await actions.warm.setMinAgeUnits('d'); - await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhaseMinAge = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm - .min_age; - expect(warmPhaseMinAge).toBe('123d'); - }); }); describe('policy with include and exclude', () => { @@ -458,9 +438,6 @@ describe('', () => { "max_age": "30d", "max_size": "50gb", }, - "set_priority": Object { - "priority": 100, - }, }, "min_age": "0ms", }, @@ -662,9 +639,6 @@ describe('', () => { "allocate": Object { "number_of_replicas": 123, }, - "set_priority": Object { - "priority": 50, - }, } `); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx index 6aa6c3177ca5..d847c3a7f976 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx @@ -157,7 +157,7 @@ const setPhaseIndexPriority = async ( phase: string, priority: string | number ) => { - const priorityInput = findTestSubject(rendered, `${phase}-phaseIndexPriority`); + const priorityInput = findTestSubject(rendered, `${phase}-indexPriority`); await act(async () => { priorityInput.simulate('change', { target: { value: priority } }); }); @@ -324,9 +324,6 @@ describe('edit policy', () => { max_age: '30d', max_size: '50gb', }, - set_priority: { - priority: 100, - }, }, min_age: '0ms', }, @@ -451,6 +448,7 @@ describe('edit policy', () => { const rendered = mountWithIntl(component); await noRollover(rendered); await setPolicyName(rendered, 'mypolicy'); + await setPhaseIndexPriority(rendered, 'hot', '-1'); waitForFormLibValidation(rendered); expectedErrorMessages(rendered, [i18nTexts.editPolicy.errors.nonNegativeNumberRequired]); @@ -512,7 +510,7 @@ describe('edit policy', () => { }); rendered.update(); await setPhaseAfter(rendered, 'warm', '1'); - const shrinkInput = findTestSubject(rendered, 'warm-selectedPrimaryShardCount'); + const shrinkInput = findTestSubject(rendered, 'warm-primaryShardCount'); await act(async () => { shrinkInput.simulate('change', { target: { value: '0' } }); }); @@ -529,7 +527,7 @@ describe('edit policy', () => { findTestSubject(rendered, 'warm-shrinkSwitch').simulate('click'); }); rendered.update(); - const shrinkInput = findTestSubject(rendered, 'warm-selectedPrimaryShardCount'); + const shrinkInput = findTestSubject(rendered, 'warm-primaryShardCount'); await act(async () => { shrinkInput.simulate('change', { target: { value: '-1' } }); }); @@ -845,7 +843,7 @@ describe('edit policy', () => { await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); - // Assert that only the custom and off options exist + // Assert that default, custom and 'none' options exist findTestSubject(rendered, 'dataTierSelect').simulate('click'); expect(findTestSubject(rendered, 'defaultDataAllocationOption').exists()).toBeTruthy(); expect(findTestSubject(rendered, 'customDataAllocationOption').exists()).toBeTruthy(); @@ -885,7 +883,7 @@ describe('edit policy', () => { await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); - // Assert that only the custom and off options exist + // Assert that default, custom and 'none' options exist findTestSubject(rendered, 'dataTierSelect').simulate('click'); expect(findTestSubject(rendered, 'defaultDataAllocationOption').exists()).toBeFalsy(); expect(findTestSubject(rendered, 'customDataAllocationOption').exists()).toBeTruthy(); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts index a892a7a031a8..6eae59ec4e6e 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts @@ -4,16 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - SerializedPhase, - DeletePhase, - SerializedPolicy, - RolloverAction, -} from '../../../common/types'; +import { SerializedPolicy, RolloverAction } from '../../../common/types'; -export const defaultSetPriority: string = '100'; - -export const defaultPhaseIndexPriority: string = '50'; +export const defaultIndexPriority = { + hot: '100', + warm: '50', + cold: '0', +}; export const defaultRolloverAction: RolloverAction = { max_age: '30d', @@ -30,15 +27,3 @@ export const defaultPolicy: SerializedPolicy = { }, }, }; - -export const defaultNewDeletePhase: DeletePhase = { - phaseEnabled: false, - selectedMinimumAge: '0', - selectedMinimumAgeUnits: 'd', - waitForSnapshotPolicy: '', -}; - -export const serializedPhaseInitialization: SerializedPhase = { - min_age: '0ms', - actions: {}, -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.scss b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.scss new file mode 100644 index 000000000000..96ca0c3a6106 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.scss @@ -0,0 +1,16 @@ +.ilmActivePhaseHighlight { + border-left: $euiBorderWidthThin solid $euiColorLightShade; + height: 100%; + + &.hotPhase.active { + border-left-color: $euiColorVis9_behindText; + } + + &.warmPhase.active { + border-left-color: $euiColorVis5_behindText; + } + + &.coldPhase.active { + border-left-color: $euiColorVis1_behindText; + } +} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.tsx new file mode 100644 index 000000000000..64db9e1ec548 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/active_highlight.tsx @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; + +import './active_highlight.scss'; + +interface Props { + phase: 'hot' | 'warm' | 'cold'; + enabled: boolean; +} +export const ActiveHighlight: FunctionComponent = ({ phase, enabled }) => { + return
; +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/index.ts similarity index 80% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/index.ts rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/index.ts index 0228a524f812..a1db0c3997ed 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/active_highlight/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { MinAgeInputField } from './min_age_input_field'; +export { ActiveHighlight } from './active_highlight'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts index d22206d7ae4d..960b632d70bd 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts @@ -11,6 +11,7 @@ export { OptionalLabel } from './optional_label'; export { PolicyJsonFlyout } from './policy_json_flyout'; export { DescribedFormRow, ToggleFieldWithDescribedFormRow } from './described_form_row'; export { FieldLoadingError } from './field_loading_error'; +export { ActiveHighlight } from './active_highlight'; export { Timeline } from './timeline'; export * from './phases'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx index 4e1ec76c52a7..976f584ef4d3 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx @@ -9,28 +9,21 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { get } from 'lodash'; -import { EuiDescribedFormGroup, EuiTextColor, EuiAccordion } from '@elastic/eui'; +import { EuiTextColor } from '@elastic/eui'; -import { Phases } from '../../../../../../../common/types'; +import { useFormData } from '../../../../../../shared_imports'; -import { useFormData, UseField, ToggleField, NumericField } from '../../../../../../shared_imports'; - -import { useEditPolicyContext } from '../../../edit_policy_context'; import { useConfigurationIssues } from '../../../form'; -import { - LearnMoreLink, - ActiveBadge, - DescribedFormRow, - ToggleFieldWithDescribedFormRow, -} from '../../'; +import { LearnMoreLink, ToggleFieldWithDescribedFormRow } from '../../'; import { - MinAgeInputField, DataTierAllocationField, - SetPriorityInputField, SearchableSnapshotField, + IndexPriorityField, + ReplicasField, } from '../shared_fields'; +import { Phase } from '../phase'; const i18nTexts = { dataTierAllocation: { @@ -41,166 +34,64 @@ const i18nTexts = { }, }; -const coldProperty: keyof Phases = 'cold'; - const formFieldPaths = { enabled: '_meta.cold.enabled', searchableSnapshot: 'phases.cold.actions.searchable_snapshot.snapshot_repository', }; export const ColdPhase: FunctionComponent = () => { - const { policy } = useEditPolicyContext(); const { isUsingSearchableSnapshotInHotPhase } = useConfigurationIssues(); const [formData] = useFormData({ - watch: [formFieldPaths.enabled, formFieldPaths.searchableSnapshot], + watch: [formFieldPaths.searchableSnapshot], }); - const enabled = get(formData, formFieldPaths.enabled); const showReplicasField = get(formData, formFieldPaths.searchableSnapshot) == null; return ( -
- <> - {/* Section title group; containing min age */} - + + + {showReplicasField && } + + {/* Freeze section */} + {!isUsingSearchableSnapshotInHotPhase && ( + -

- -

{' '} - {enabled && } -
- } - titleSize="s" - description={ - <> -

- -

- + - + + } + description={ + + {' '} + + } fullWidth + titleSize="xs" + switchProps={{ + 'data-test-subj': 'freezeSwitch', + path: '_meta.cold.freezeEnabled', + }} > - {enabled && } - - {enabled && ( - <> - +
+ + )} - - { - /* Replicas section */ - showReplicasField && ( - - {i18n.translate('xpack.indexLifecycleMgmt.coldPhase.replicasTitle', { - defaultMessage: 'Replicas', - })} - - } - description={i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasDescription', - { - defaultMessage: - 'Set the number of replicas. Remains the same as the previous phase by default.', - } - )} - switchProps={{ - 'data-test-subj': 'cold-setReplicasSwitch', - label: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel', - { defaultMessage: 'Set replicas' } - ), - initialValue: - policy.phases.cold?.actions?.allocate?.number_of_replicas != null, - }} - fullWidth - > - - - ) - } + {/* Data tier allocation section */} + - {/* Freeze section */} - {!isUsingSearchableSnapshotInHotPhase && ( - - - - } - description={ - - {' '} - - - } - fullWidth - titleSize="xs" - switchProps={{ - 'data-test-subj': 'freezeSwitch', - path: '_meta.cold.freezeEnabled', - }} - > -
- - )} - {/* Data tier allocation section */} - - - - - )} - -
+ + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/delete_phase/delete_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/delete_phase/delete_phase.tsx index 37323b97edc9..5c43bb413eb5 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/delete_phase/delete_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/delete_phase/delete_phase.tsx @@ -13,7 +13,7 @@ import { useFormData, UseField, ToggleField } from '../../../../../../shared_imp import { ActiveBadge, LearnMoreLink, OptionalLabel } from '../../index'; -import { MinAgeInputField, SnapshotPoliciesField } from '../shared_fields'; +import { MinAgeField, SnapshotPoliciesField } from '../shared_fields'; const formFieldPaths = { enabled: '_meta.delete.enabled', @@ -63,7 +63,7 @@ export const DeletePhase: FunctionComponent = () => { } fullWidth > - {enabled && } + {enabled && } {enabled ? ( { const { license } = useEditPolicyContext(); const [formData] = useFormData({ @@ -56,245 +51,210 @@ export const HotPhase: FunctionComponent = () => { const [showEmptyRolloverFieldsError, setShowEmptyRolloverFieldsError] = useState(false); return ( - <> - + -

- -

{' '} - -
+

+ {i18n.translate('xpack.indexLifecycleMgmt.hotPhase.rolloverFieldTitle', { + defaultMessage: 'Rollover', + })} +

} description={ -

- -

- } - > -
- - - - - {i18n.translate('xpack.indexLifecycleMgmt.hotPhase.rolloverFieldTitle', { - defaultMessage: 'Rollover', - })} - - } - description={ - <> - -

- {' '} - + +

+ {' '} + + } + docPath="ilm-rollover.html" + /> +

+
+ + path={isUsingDefaultRolloverPath}> + {(field) => ( + <> + field.setValue(e.target.checked)} + data-test-subj="useDefaultRolloverSwitch" + /> +   + } - docPath="ilm-rollover.html" /> -

- - - path={isUsingDefaultRolloverPath}> - {(field) => ( - <> - field.setValue(e.target.checked)} - data-test-subj="useDefaultRolloverSwitch" - /> -   - - } - /> - - )} - - - } - fullWidth - > - {isUsingDefaultRollover === false ? ( -
- path="_meta.hot.customRollover.enabled"> - {(field) => ( - <> - field.setValue(e.target.checked)} - data-test-subj="rolloverSwitch" - /> -   - - } - /> - - )} - - {isUsingRollover && ( - <> - - {showEmptyRolloverFieldsError && ( - <> - -
{i18nTexts.editPolicy.errors.rollOverConfigurationCallout.body}
-
- - - )} - - - - {(field) => { - const showErrorCallout = field.errors.some( - (e) => e.code === ROLLOVER_EMPTY_VALIDATION - ); - if (showErrorCallout !== showEmptyRolloverFieldsError) { - setShowEmptyRolloverFieldsError(showErrorCallout); - } - return ( - - ); - }} - - - - - - - - - - - - - - - - - - - - - )} -
- ) : ( -
- )} - - {isUsingRollover && ( - <> - {} - - {license.canUseSearchableSnapshot() && } - + + } + fullWidth + > + {isUsingDefaultRollover === false ? ( +
+ path="_meta.hot.customRollover.enabled"> + {(field) => ( + <> + field.setValue(e.target.checked)} + data-test-subj="rolloverSwitch" + /> +   + + } + /> + + )} + + {isUsingRollover && ( + <> + + {showEmptyRolloverFieldsError && ( + <> + +
{i18nTexts.editPolicy.errors.rollOverConfigurationCallout.body}
+
+ + + )} + + + + {(field) => { + const showErrorCallout = field.errors.some( + (e) => e.code === ROLLOVER_EMPTY_VALIDATION + ); + if (showErrorCallout !== showEmptyRolloverFieldsError) { + setShowEmptyRolloverFieldsError(showErrorCallout); + } + return ( + + ); + }} + + + + + + + + + + + + + + + + + + + + + + + )} +
+ ) : ( +
)} - - - + + {isUsingRollover && ( + <> + {} + + {license.canUseSearchableSnapshot() && } + + + )} + + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/index.ts index 076c16e87e8d..c2c7e6a76907 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/index.ts @@ -11,3 +11,5 @@ export { WarmPhase } from './warm_phase'; export { ColdPhase } from './cold_phase'; export { DeletePhase } from './delete_phase'; + +export { Phase } from './phase'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/phase.tsx new file mode 100644 index 000000000000..6de18f1c1d3c --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/phase.tsx @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent, useState } from 'react'; + +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiTitle, + EuiSpacer, + EuiText, + EuiButtonEmpty, +} from '@elastic/eui'; +import { get } from 'lodash'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { ToggleField, UseField, useFormData } from '../../../../../shared_imports'; +import { i18nTexts } from '../../i18n_texts'; + +import { ActiveHighlight } from '../active_highlight'; +import { MinAgeField } from './shared_fields'; + +interface Props { + phase: 'hot' | 'warm' | 'cold'; +} + +export const Phase: FunctionComponent = ({ children, phase }) => { + const enabledPath = `_meta.${phase}.enabled`; + const [formData] = useFormData({ + watch: [enabledPath], + }); + + // hot phase is always enabled + const enabled = get(formData, enabledPath) || phase === 'hot'; + + const [isShowingSettings, setShowingSettings] = useState(false); + return ( + + + + + + + + + + {phase !== 'hot' && ( + + + + )} + + +

{i18nTexts.editPolicy.titles[phase]}

+
+
+
+
+ {enabled && ( + + + + {phase !== 'hot' && } + + + { + setShowingSettings(!isShowingSettings); + }} + size="xs" + iconType="controlsVertical" + iconSide="left" + aria-controls={`${phase}-phaseContent`} + > + + + + + + )} +
+ + + {i18nTexts.editPolicy.descriptions[phase]} + + + {enabled && ( +
+ + {children} +
+ )} +
+
+
+ ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/forcemerge_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/forcemerge_field.tsx index 8776dbbbc755..8d6807c90dae 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/forcemerge_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/forcemerge_field.tsx @@ -6,9 +6,8 @@ import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiSpacer, EuiTextColor } from '@elastic/eui'; -import { UseField, ToggleField, NumericField } from '../../../../../../shared_imports'; +import { UseField, CheckBoxField, NumericField } from '../../../../../../shared_imports'; import { i18nTexts } from '../../../i18n_texts'; @@ -38,50 +37,43 @@ export const ForcemergeField: React.FunctionComponent = ({ phase }) => { } description={ - + <> {' '} - + } titleSize="xs" fullWidth switchProps={{ - 'aria-label': i18nTexts.editPolicy.forceMergeEnabledFieldLabel, - 'data-test-subj': `${phase}-forceMergeSwitch`, - 'aria-controls': 'forcemergeContent', label: i18nTexts.editPolicy.forceMergeEnabledFieldLabel, + 'data-test-subj': `${phase}-forceMergeSwitch`, initialValue: initialToggleValue, }} > - -
- - -
+ + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts index 15167672265f..710df7e95f8f 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts @@ -8,9 +8,7 @@ export { DataTierAllocationField } from './data_tier_allocation_field'; export { ForcemergeField } from './forcemerge_field'; -export { SetPriorityInputField } from './set_priority_input_field'; - -export { MinAgeInputField } from './min_age_input_field'; +export { MinAgeField } from './min_age_field'; export { SnapshotPoliciesField } from './snapshot_policies_field'; @@ -19,3 +17,7 @@ export { ShrinkField } from './shrink_field'; export { SearchableSnapshotField } from './searchable_snapshot_field'; export { ReadonlyField } from './readonly_field'; + +export { ReplicasField } from './replicas_field'; + +export { IndexPriorityField } from './index_priority_field'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/set_priority_input_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index_priority_field.tsx similarity index 50% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/set_priority_input_field.tsx rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index_priority_field.tsx index 328587a379b7..570033812c24 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/set_priority_input_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index_priority_field.tsx @@ -4,23 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FunctionComponent } from 'react'; +import React, { FunctionComponent, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiTextColor, EuiDescribedFormGroup } from '@elastic/eui'; - -import { Phases } from '../../../../../../../common/types'; +import { i18n } from '@kbn/i18n'; +import { EuiSpacer, EuiTextColor } from '@elastic/eui'; import { UseField, NumericField } from '../../../../../../shared_imports'; - -import { LearnMoreLink } from '../..'; +import { LearnMoreLink, DescribedFormRow } from '../..'; +import { useEditPolicyContext } from '../../../edit_policy_context'; interface Props { - phase: keyof Phases & string; + phase: 'hot' | 'warm' | 'cold'; } -export const SetPriorityInputField: FunctionComponent = ({ phase }) => { +export const IndexPriorityField: FunctionComponent = ({ phase }) => { + const { policy, isNewPolicy } = useEditPolicyContext(); + + const initialToggleValue = useMemo(() => { + return ( + isNewPolicy || // enable index priority for new policies + !policy.phases[phase]?.actions || // enable index priority for new phases + policy.phases[phase]?.actions?.set_priority != null // enable index priority if it's set + ); + }, [isNewPolicy, policy.phases, phase]); + return ( - = ({ phase }) => { } titleSize="xs" fullWidth + switchProps={{ + label: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.indexPriority.indexPriorityEnabledFieldLabel', + { + defaultMessage: 'Set index priority', + } + ), + 'data-test-subj': `${phase}-indexPrioritySwitch`, + initialValue: initialToggleValue, + }} > + - + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/index.ts new file mode 100644 index 000000000000..43ef0cf5d9b7 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { MinAgeField } from './min_age_field'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/min_age_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/min_age_field.tsx new file mode 100644 index 000000000000..8a84b7fa0e76 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/min_age_field.tsx @@ -0,0 +1,158 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + EuiFieldNumber, + EuiFieldNumberProps, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiSelect, + EuiText, +} from '@elastic/eui'; + +import { UseField, getFieldValidityAndErrorMessage } from '../../../../../../../shared_imports'; + +import { getUnitsAriaLabelForPhase, getTimingLabelForPhase } from './util'; + +type PhaseWithMinAgeAction = 'warm' | 'cold' | 'delete'; + +const i18nTexts = { + daysOptionLabel: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.daysOptionLabel', { + defaultMessage: 'days', + }), + + hoursOptionLabel: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.hoursOptionLabel', { + defaultMessage: 'hours', + }), + minutesOptionLabel: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.minutesOptionLabel', { + defaultMessage: 'minutes', + }), + + secondsOptionLabel: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.secondsOptionLabel', { + defaultMessage: 'seconds', + }), + millisecondsOptionLabel: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.milliSecondsOptionLabel', + { + defaultMessage: 'milliseconds', + } + ), + + microsecondsOptionLabel: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.microSecondsOptionLabel', + { + defaultMessage: 'microseconds', + } + ), + + nanosecondsOptionLabel: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.nanoSecondsOptionLabel', + { + defaultMessage: 'nanoseconds', + } + ), +}; + +interface Props { + phase: PhaseWithMinAgeAction; +} + +export const MinAgeField: FunctionComponent = ({ phase }): React.ReactElement => { + return ( + + {(field) => { + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + return ( + + + + + + + + + + + + + + + {(unitField) => { + const { isInvalid: isUnitFieldInvalid } = getFieldValidityAndErrorMessage( + unitField + ); + return ( + { + unitField.setValue(e.target.value); + }} + isInvalid={isUnitFieldInvalid} + append={'old'} + data-test-subj={`${phase}-selectedMinimumAgeUnits`} + aria-label={getUnitsAriaLabelForPhase(phase)} + options={[ + { + value: 'd', + text: i18nTexts.daysOptionLabel, + }, + { + value: 'h', + text: i18nTexts.hoursOptionLabel, + }, + { + value: 'm', + text: i18nTexts.minutesOptionLabel, + }, + { + value: 's', + text: i18nTexts.secondsOptionLabel, + }, + { + value: 'ms', + text: i18nTexts.millisecondsOptionLabel, + }, + { + value: 'micros', + text: i18nTexts.microsecondsOptionLabel, + }, + { + value: 'nanos', + text: i18nTexts.nanosecondsOptionLabel, + }, + ]} + /> + ); + }} + + + + + + + ); + }} + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/util.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/util.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/util.ts rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_field/util.ts diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx deleted file mode 100644 index 59086ce57225..000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import React, { FunctionComponent } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; - -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; - -import { UseField, NumericField, SelectField } from '../../../../../../../shared_imports'; - -import { LearnMoreLink } from '../../../learn_more_link'; -import { useConfigurationIssues } from '../../../../form'; - -import { getUnitsAriaLabelForPhase, getTimingLabelForPhase } from './util'; - -type PhaseWithMinAgeAction = 'warm' | 'cold' | 'delete'; - -interface Props { - phase: PhaseWithMinAgeAction; -} - -export const MinAgeInputField: FunctionComponent = ({ phase }): React.ReactElement => { - const { isUsingRollover: rolloverEnabled } = useConfigurationIssues(); - - let daysOptionLabel; - let hoursOptionLabel; - let minutesOptionLabel; - let secondsOptionLabel; - let millisecondsOptionLabel; - let microsecondsOptionLabel; - let nanosecondsOptionLabel; - - if (rolloverEnabled) { - daysOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverDaysOptionLabel', - { - defaultMessage: 'days from rollover', - } - ); - - hoursOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverHoursOptionLabel', - { - defaultMessage: 'hours from rollover', - } - ); - minutesOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverMinutesOptionLabel', - { - defaultMessage: 'minutes from rollover', - } - ); - - secondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverSecondsOptionLabel', - { - defaultMessage: 'seconds from rollover', - } - ); - millisecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverMilliSecondsOptionLabel', - { - defaultMessage: 'milliseconds from rollover', - } - ); - - microsecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverMicroSecondsOptionLabel', - { - defaultMessage: 'microseconds from rollover', - } - ); - - nanosecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.rolloverNanoSecondsOptionLabel', - { - defaultMessage: 'nanoseconds from rollover', - } - ); - } else { - daysOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationDaysOptionLabel', - { - defaultMessage: 'days from index creation', - } - ); - - hoursOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationHoursOptionLabel', - { - defaultMessage: 'hours from index creation', - } - ); - - minutesOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationMinutesOptionLabel', - { - defaultMessage: 'minutes from index creation', - } - ); - - secondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel', - { - defaultMessage: 'seconds from index creation', - } - ); - - millisecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationMilliSecondsOptionLabel', - { - defaultMessage: 'milliseconds from index creation', - } - ); - - microsecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationMicroSecondsOptionLabel', - { - defaultMessage: 'microseconds from index creation', - } - ); - - nanosecondsOptionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel', - { - defaultMessage: 'nanoseconds from index creation', - } - ); - } - - return ( - - - - } - /> - ), - euiFieldProps: { - 'data-test-subj': `${phase}-selectedMinimumAge`, - min: 0, - }, - }} - /> - - - - - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/replicas_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/replicas_field.tsx new file mode 100644 index 000000000000..6d8e019ff8a0 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/replicas_field.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { UseField, NumericField } from '../../../../../../shared_imports'; +import { useEditPolicyContext } from '../../../edit_policy_context'; +import { DescribedFormRow } from '../../described_form_row'; + +interface Props { + phase: 'warm' | 'cold'; +} + +export const ReplicasField: FunctionComponent = ({ phase }) => { + const { policy } = useEditPolicyContext(); + const initialValue = policy.phases[phase]?.actions?.allocate?.number_of_replicas != null; + return ( + + {i18n.translate('xpack.indexLifecycleMgmt.numberOfReplicas.formRowTitle', { + defaultMessage: 'Replicas', + })} + + } + description={i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.numberOfReplicas.formRowDescription', + { + defaultMessage: + 'Set the number of replicas. Remains the same as the previous phase by default.', + } + )} + switchProps={{ + 'data-test-subj': `${phase}-setReplicasSwitch`, + label: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.numberOfReplicas.switchLabel', { + defaultMessage: 'Set replicas', + }), + initialValue, + }} + fullWidth + > + + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/shrink_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/shrink_field.tsx index c5fc31d9839b..da200e9e68d1 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/shrink_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/shrink_field.tsx @@ -42,32 +42,28 @@ export const ShrinkField: FunctionComponent = ({ phase }) => { } titleSize="xs" switchProps={{ - 'aria-controls': 'shrinkContent', 'data-test-subj': `${phase}-shrinkSwitch`, label: i18nTexts.editPolicy.shrinkLabel, - 'aria-label': i18nTexts.editPolicy.shrinkLabel, initialValue: Boolean(policy.phases[phase]?.actions?.shrink), }} fullWidth > -
- - - - - - -
+ + + + + + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx index 77078e94d7e9..47255da08df7 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx @@ -5,30 +5,21 @@ */ import React, { FunctionComponent } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; -import { EuiSpacer, EuiDescribedFormGroup, EuiAccordion } from '@elastic/eui'; - -import { useFormData, UseField, ToggleField, NumericField } from '../../../../../../shared_imports'; - -import { Phases } from '../../../../../../../common/types'; - -import { useEditPolicyContext } from '../../../edit_policy_context'; import { useConfigurationIssues } from '../../../form'; -import { ActiveBadge, DescribedFormRow } from '../../'; - import { - MinAgeInputField, ForcemergeField, - SetPriorityInputField, + IndexPriorityField, DataTierAllocationField, ShrinkField, ReadonlyField, + ReplicasField, } from '../shared_fields'; +import { Phase } from '../phase'; + const i18nTexts = { dataTierAllocation: { description: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.description', { @@ -37,153 +28,26 @@ const i18nTexts = { }, }; -const warmProperty: keyof Phases = 'warm'; - -const formFieldPaths = { - enabled: '_meta.warm.enabled', - warmPhaseOnRollover: '_meta.warm.warmPhaseOnRollover', -}; - export const WarmPhase: FunctionComponent = () => { - const { policy } = useEditPolicyContext(); - const { isUsingSearchableSnapshotInHotPhase, isUsingRollover } = useConfigurationIssues(); - const [formData] = useFormData({ - watch: [formFieldPaths.enabled, formFieldPaths.warmPhaseOnRollover], - }); - - const enabled = get(formData, formFieldPaths.enabled); - const warmPhaseOnRollover = get(formData, formFieldPaths.warmPhaseOnRollover); + const { isUsingSearchableSnapshotInHotPhase } = useConfigurationIssues(); return ( -
- <> - -

- -

{' '} - {enabled && } -
- } - titleSize="s" - description={ - <> -

- -

- - - } - fullWidth - > - <> - {enabled && ( - <> - {isUsingRollover && ( - - )} - {(!warmPhaseOnRollover || !isUsingRollover) && ( - <> - - - - )} - - )} - - + + - {enabled && ( - - - {i18n.translate('xpack.indexLifecycleMgmt.warmPhase.replicasTitle', { - defaultMessage: 'Replicas', - })} - - } - description={i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasDescription', - { - defaultMessage: - 'Set the number of replicas. Remains the same as the previous phase by default.', - } - )} - switchProps={{ - 'data-test-subj': 'warm-setReplicasSwitch', - label: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.warmPhase.numberOfReplicas.switchLabel', - { defaultMessage: 'Set replicas' } - ), - initialValue: policy.phases.warm?.actions?.allocate?.number_of_replicas != null, - }} - fullWidth - > - - + {!isUsingSearchableSnapshotInHotPhase && } - {!isUsingSearchableSnapshotInHotPhase && } + {!isUsingSearchableSnapshotInHotPhase && } - {!isUsingSearchableSnapshotInHotPhase && } + - + {/* Data tier allocation section */} + - {/* Data tier allocation section */} - - - - )} - -
+ + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx index 228a0f9fdb94..b1cf41773de3 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, useEffect, useState, useMemo } from 'react'; +import React, { Fragment, useEffect, useMemo, useState } from 'react'; import { get } from 'lodash'; import { RouteComponentProps } from 'react-router-dom'; @@ -16,7 +16,6 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiButtonEmpty, - EuiDescribedFormGroup, EuiFlexGroup, EuiFlexItem, EuiFormRow, @@ -24,33 +23,35 @@ import { EuiPage, EuiPageBody, EuiPageContent, + EuiPageContentHeader, + EuiPageContentHeaderSection, EuiSpacer, EuiSwitch, EuiText, EuiTitle, } from '@elastic/eui'; -import { useForm, UseField, TextField, useFormData } from '../../../shared_imports'; +import { TextField, UseField, useForm, useFormData } from '../../../shared_imports'; import { toasts } from '../../services/notification'; import { savePolicy } from './save_policy'; import { - LearnMoreLink, - PolicyJsonFlyout, ColdPhase, DeletePhase, HotPhase, + PolicyJsonFlyout, WarmPhase, Timeline, } from './components'; -import { schema, deserializer, createSerializer, createPolicyNameValidations, Form } from './form'; +import { createPolicyNameValidations, createSerializer, deserializer, Form, schema } from './form'; import { useEditPolicyContext } from './edit_policy_context'; import { FormInternal } from './types'; +import { createDocLink } from '../../services/documentation'; export interface Props { history: RouteComponentProps['history']; @@ -75,7 +76,7 @@ export const EditPolicy: React.FunctionComponent = ({ history }) => { return createSerializer(isNewPolicy ? undefined : currentPolicy); }, [isNewPolicy, currentPolicy]); - const [saveAsNew, setSaveAsNew] = useState(isNewPolicy); + const [saveAsNew, setSaveAsNew] = useState(false); const originalPolicyName: string = isNewPolicy ? '' : policyName!; const { form } = useForm({ @@ -116,7 +117,7 @@ export const EditPolicy: React.FunctionComponent = ({ history }) => { ); } else { const success = await savePolicy( - { ...policy, name: saveAsNew ? currentPolicyName : originalPolicyName }, + { ...policy, name: saveAsNew || isNewPolicy ? currentPolicyName : originalPolicyName }, isNewPolicy || saveAsNew ); if (success) { @@ -132,216 +133,187 @@ export const EditPolicy: React.FunctionComponent = ({ history }) => { return ( - - -

- {isNewPolicy - ? i18n.translate('xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage', { - defaultMessage: 'Create an index lifecycle policy', - }) - : i18n.translate('xpack.indexLifecycleMgmt.editPolicy.editPolicyMessage', { - defaultMessage: 'Edit index lifecycle policy {originalPolicyName}', - values: { originalPolicyName }, - })} -

-
- -
-
- - -

- {' '} - + + + +

+ {isNewPolicy + ? i18n.translate('xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage', { + defaultMessage: 'Create Policy', + }) + : i18n.translate('xpack.indexLifecycleMgmt.editPolicy.editPolicyMessage', { + defaultMessage: 'Edit Policy {originalPolicyName}', + values: { originalPolicyName }, + })} +

+ + + + + + + + + + {isNewPolicy ? null : ( + + +

+ - } - /> -

-
- - - - {isNewPolicy ? null : ( - - -

- - - - .{' '} - -

-
- - - - { - setSaveAsNew(e.target.checked); - }} - label={ - - - - } /> - -
- )} +

+
+ - {saveAsNew || isNewPolicy ? ( - - + + { + setSaveAsNew(e.target.checked); + }} + label={ + -
- } - titleSize="s" - fullWidth - > - - path={policyNamePath} - config={{ - label: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.policyNameLabel', { - defaultMessage: 'Policy name', - }), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage', - { - defaultMessage: - 'A policy name cannot start with an underscore and cannot contain a comma or a space.', - } - ), - validations: policyNameValidations, - }} - component={TextField} - componentProps={{ - fullWidth: false, - euiFieldProps: { - 'data-test-subj': 'policyNameField', - }, - }} + } /> - - ) : null} + + + )} - + {saveAsNew || isNewPolicy ? ( + + path={policyNamePath} + config={{ + label: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.policyNameLabel', { + defaultMessage: 'Policy name', + }), + helpText: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage', + { + defaultMessage: + 'A policy name cannot start with an underscore and cannot contain a comma or a space.', + } + ), + validations: policyNameValidations, + }} + component={TextField} + componentProps={{ + fullWidth: false, + euiFieldProps: { + 'data-test-subj': 'policyNameField', + }, + }} + /> + ) : null} - + - + - + - + - + - + - + - + - + - + - - - - - - {saveAsNew ? ( - - ) : ( - - )} - - + - - + + + + {isShowingPolicyJsonFlyout ? ( + + ) : ( + + )} + + + + + + + + + + + + + + {saveAsNew ? ( - - - - + ) : ( + + )} + + + + + - - - {isShowingPolicyJsonFlyout ? ( - - ) : ( - - )} - - - - - {isShowingPolicyJsonFlyout ? ( - setIsShowingPolicyJsonFlyout(false)} - /> - ) : null} - -
+ {isShowingPolicyJsonFlyout ? ( + setIsShowingPolicyJsonFlyout(false)} + /> + ) : null} + diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts index b5abf51c2902..44512c2a511e 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts @@ -260,15 +260,6 @@ describe('deserializer and serializer', () => { expect(result.phases.hot!.actions.readonly).toBeUndefined(); }); - it('removes min_age from warm when rollover is enabled', () => { - formInternal._meta.hot.customRollover.enabled = true; - formInternal._meta.warm.warmPhaseOnRollover = true; - - const result = serializer(formInternal); - - expect(result.phases.warm!.min_age).toBeUndefined(); - }); - it('adds default rollover configuration when enabled, but previously not configured', () => { delete formInternal.phases.hot!.actions.rollover; formInternal._meta.hot.isUsingDefaultRollover = true; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts index 4bdf902d27b6..9883c2de0685 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts @@ -7,13 +7,13 @@ import { i18n } from '@kbn/i18n'; import { FormSchema, fieldValidators } from '../../../../shared_imports'; -import { defaultSetPriority, defaultPhaseIndexPriority } from '../../../constants'; +import { defaultIndexPriority } from '../../../constants'; import { ROLLOVER_FORM_PATHS } from '../constants'; -const rolloverFormPaths = Object.values(ROLLOVER_FORM_PATHS); - import { FormInternal } from '../types'; +const rolloverFormPaths = Object.values(ROLLOVER_FORM_PATHS); + import { ifExistsNumberGreaterThanZero, ifExistsNumberNonNegative, @@ -54,7 +54,6 @@ export const schema: FormSchema = { }, bestCompression: { label: i18nTexts.editPolicy.bestCompressionFieldLabel, - helpText: i18nTexts.editPolicy.bestCompressionFieldHelpText, }, readonlyEnabled: { defaultValue: false, @@ -69,18 +68,11 @@ export const schema: FormSchema = { { defaultMessage: 'Activate warm phase' } ), }, - warmPhaseOnRollover: { - defaultValue: true, - label: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel', { - defaultMessage: 'Move to warm phase on rollover', - }), - }, minAgeUnit: { defaultValue: 'ms', }, bestCompression: { label: i18nTexts.editPolicy.bestCompressionFieldLabel, - helpText: i18nTexts.editPolicy.bestCompressionFieldHelpText, }, dataTierAllocationType: { label: i18nTexts.editPolicy.allocationTypeOptionsFieldLabel, @@ -218,9 +210,14 @@ export const schema: FormSchema = { }, set_priority: { priority: { - defaultValue: defaultSetPriority as any, - label: i18nTexts.editPolicy.setPriorityFieldLabel, - validations: [{ validator: ifExistsNumberNonNegative }], + defaultValue: defaultIndexPriority.hot as any, + label: i18nTexts.editPolicy.indexPriorityFieldLabel, + validations: [ + { + validator: emptyField(i18nTexts.editPolicy.errors.numberRequired), + }, + { validator: ifExistsNumberNonNegative }, + ], serializer: serializers.stringToNumber, }, }, @@ -239,9 +236,12 @@ export const schema: FormSchema = { allocate: { number_of_replicas: { label: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel', { - defaultMessage: 'Number of replicas (optional)', + defaultMessage: 'Number of replicas', }), validations: [ + { + validator: emptyField(i18nTexts.editPolicy.errors.numberRequired), + }, { validator: ifExistsNumberNonNegative, }, @@ -289,9 +289,14 @@ export const schema: FormSchema = { }, set_priority: { priority: { - defaultValue: defaultPhaseIndexPriority as any, - label: i18nTexts.editPolicy.setPriorityFieldLabel, - validations: [{ validator: ifExistsNumberNonNegative }], + defaultValue: defaultIndexPriority.warm as any, + label: i18nTexts.editPolicy.indexPriorityFieldLabel, + validations: [ + { + validator: emptyField(i18nTexts.editPolicy.errors.numberRequired), + }, + { validator: ifExistsNumberNonNegative }, + ], serializer: serializers.stringToNumber, }, }, @@ -310,9 +315,12 @@ export const schema: FormSchema = { allocate: { number_of_replicas: { label: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasLabel', { - defaultMessage: 'Number of replicas (optional)', + defaultMessage: 'Number of replicas', }), validations: [ + { + validator: emptyField(i18nTexts.editPolicy.errors.numberRequired), + }, { validator: ifExistsNumberNonNegative, }, @@ -322,9 +330,14 @@ export const schema: FormSchema = { }, set_priority: { priority: { - defaultValue: '0' as any, - label: i18nTexts.editPolicy.setPriorityFieldLabel, - validations: [{ validator: ifExistsNumberNonNegative }], + defaultValue: defaultIndexPriority.cold as any, + label: i18nTexts.editPolicy.indexPriorityFieldLabel, + validations: [ + { + validator: emptyField(i18nTexts.editPolicy.errors.numberRequired), + }, + { validator: ifExistsNumberNonNegative }, + ], serializer: serializers.stringToNumber, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts index f718073afa35..f7cdecdc352f 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts @@ -20,9 +20,7 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( ): SerializedPolicy => { const { _meta, ...updatedPolicy } = data; - if (!updatedPolicy.phases || !updatedPolicy.phases.hot) { - updatedPolicy.phases = { hot: { actions: {} } }; - } + updatedPolicy.phases = { hot: { actions: {} }, ...updatedPolicy.phases }; return produce(originalPolicy ?? defaultPolicy, (draft) => { // Copy over all updated fields @@ -32,7 +30,7 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( * Important shared values for serialization */ const isUsingRollover = Boolean( - _meta.hot.isUsingDefaultRollover || _meta.hot.customRollover.enabled + _meta.hot?.isUsingDefaultRollover || _meta.hot?.customRollover.enabled ); // Next copy over all meta fields and delete any fields that have been removed @@ -53,7 +51,7 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( * HOT PHASE ROLLOVER */ if (isUsingRollover) { - if (_meta.hot.isUsingDefaultRollover) { + if (_meta.hot?.isUsingDefaultRollover) { hotPhaseActions.rollover = cloneDeep(defaultRolloverAction); } else { // Rollover may not exist if editing an existing policy with initially no rollover configured @@ -63,7 +61,7 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( // We are using user-defined, custom rollover settings. if (updatedPolicy.phases.hot!.actions.rollover?.max_age) { - hotPhaseActions.rollover.max_age = `${hotPhaseActions.rollover.max_age}${_meta.hot.customRollover.maxAgeUnit}`; + hotPhaseActions.rollover.max_age = `${hotPhaseActions.rollover.max_age}${_meta.hot?.customRollover.maxAgeUnit}`; } else { delete hotPhaseActions.rollover.max_age; } @@ -73,7 +71,7 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( } if (updatedPolicy.phases.hot!.actions.rollover?.max_size) { - hotPhaseActions.rollover.max_size = `${hotPhaseActions.rollover.max_size}${_meta.hot.customRollover.maxStorageSizeUnit}`; + hotPhaseActions.rollover.max_size = `${hotPhaseActions.rollover.max_size}${_meta.hot?.customRollover.maxStorageSizeUnit}`; } else { delete hotPhaseActions.rollover.max_size; } @@ -84,20 +82,20 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( */ if (!updatedPolicy.phases.hot!.actions?.forcemerge) { delete hotPhaseActions.forcemerge; - } else if (_meta.hot.bestCompression) { + } else if (_meta.hot?.bestCompression) { hotPhaseActions.forcemerge!.index_codec = 'best_compression'; } else { delete hotPhaseActions.forcemerge!.index_codec; } - if (_meta.hot.bestCompression && hotPhaseActions.forcemerge) { + if (_meta.hot?.bestCompression && hotPhaseActions.forcemerge) { hotPhaseActions.forcemerge.index_codec = 'best_compression'; } /** * HOT PHASE READ-ONLY */ - if (_meta.hot.readonlyEnabled) { + if (_meta.hot?.readonlyEnabled) { hotPhaseActions.readonly = hotPhaseActions.readonly ?? {}; } else { delete hotPhaseActions.readonly; @@ -140,17 +138,9 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( /** * WARM PHASE MIN AGE * - * If warm phase on rollover is enabled, delete min age field - * An index lifecycle switches to warm phase when rollover occurs, so you cannot specify a warm phase time - * They are mutually exclusive */ - if ( - (!isUsingRollover || !_meta.warm.warmPhaseOnRollover) && - updatedPolicy.phases.warm?.min_age - ) { + if (updatedPolicy.phases.warm?.min_age) { warmPhase.min_age = `${updatedPolicy.phases.warm!.min_age}${_meta.warm.minAgeUnit}`; - } else { - delete warmPhase.min_age; } /** diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/i18n_texts.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/i18n_texts.ts index f30a40fdd2bb..71085a6d7a2b 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/i18n_texts.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/i18n_texts.ts @@ -40,10 +40,10 @@ export const i18nTexts = { defaultMessage: 'Number of segments', } ), - setPriorityFieldLabel: i18n.translate( + indexPriorityFieldLabel: i18n.translate( 'xpack.indexLifecycleMgmt.editPolicy.indexPriorityLabel', { - defaultMessage: 'Index priority (optional)', + defaultMessage: 'Index priority', } ), bestCompressionFieldLabel: i18n.translate( @@ -170,5 +170,30 @@ export const i18nTexts = { } ), }, + titles: { + hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseTitle', { + defaultMessage: 'Hot phase', + }), + warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseTitle', { + defaultMessage: 'Warm phase', + }), + cold: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseTitle', { + defaultMessage: 'Cold phase', + }), + }, + descriptions: { + hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseDescription', { + defaultMessage: + 'This phase is required. You are actively querying and writing to your index. For faster updates, you can roll over the index when it gets too big or too old.', + }), + warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescription', { + defaultMessage: + 'You are still querying your index, but it is read-only. You can allocate shards to less performant hardware. For faster searches, you can reduce the number of shards and force merge segments.', + }), + cold: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseDescription', { + defaultMessage: + 'You are querying your index less frequently, so you can allocate shards on significantly less performant hardware. Because your queries are slower, you can reduce the number of replicas.', + }), + }, }, }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.ts index c77b171a56be..2f37608b2d7a 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.ts @@ -70,9 +70,10 @@ export interface PhaseAgeInMilliseconds { const phaseOrder: Phase[] = ['hot', 'warm', 'cold', 'delete']; const getMinAge = (phase: MinAgePhase, formData: FormInternal) => ({ - min_age: formData.phases[phase]?.min_age - ? formData.phases[phase]!.min_age! + formData._meta[phase].minAgeUnit - : '0ms', + min_age: + formData.phases && formData.phases[phase]?.min_age + ? formData.phases[phase]!.min_age! + formData._meta[phase].minAgeUnit + : '0ms', }); const formDataToAbsoluteTimings = (formData: FormInternal): AbsoluteTimings => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts index 2f1c7798e7a4..4b22d1c8448b 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts @@ -9,7 +9,7 @@ import { UIM_CONFIG_WARM_PHASE, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_FREEZE_INDEX, - defaultPhaseIndexPriority, + defaultIndexPriority, } from '../constants/'; import { getUiMetricsForPhases } from './ui_metric'; @@ -22,7 +22,7 @@ describe('getUiMetricsForPhases', () => { min_age: '0ms', actions: { set_priority: { - priority: parseInt(defaultPhaseIndexPriority, 10), + priority: parseInt(defaultIndexPriority.cold, 10), }, }, }, @@ -37,7 +37,7 @@ describe('getUiMetricsForPhases', () => { min_age: '0ms', actions: { set_priority: { - priority: parseInt(defaultPhaseIndexPriority, 10), + priority: parseInt(defaultIndexPriority.warm, 10), }, }, }, @@ -52,7 +52,7 @@ describe('getUiMetricsForPhases', () => { min_age: '0ms', actions: { set_priority: { - priority: parseInt(defaultPhaseIndexPriority, 10) + 1, + priority: parseInt(defaultIndexPriority.warm, 10) + 1, }, }, }, @@ -68,7 +68,7 @@ describe('getUiMetricsForPhases', () => { actions: { freeze: {}, set_priority: { - priority: parseInt(defaultPhaseIndexPriority, 10), + priority: parseInt(defaultIndexPriority.cold, 10), }, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts index bcf4b6cf1da0..ffdcf927a5b6 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts @@ -19,8 +19,7 @@ import { UIM_CONFIG_FREEZE_INDEX, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_WARM_PHASE, - defaultSetPriority, - defaultPhaseIndexPriority, + defaultIndexPriority, } from '../constants'; import { Phases } from '../../../common/types'; @@ -50,17 +49,17 @@ export function getUiMetricsForPhases(phases: Phases): string[] { const isHotPhasePriorityChanged = phases.hot && phases.hot.actions.set_priority && - phases.hot.actions.set_priority.priority !== parseInt(defaultSetPriority, 10); + phases.hot.actions.set_priority.priority !== parseInt(defaultIndexPriority.hot, 10); const isWarmPhasePriorityChanged = phases.warm && phases.warm.actions.set_priority && - phases.warm.actions.set_priority.priority !== parseInt(defaultPhaseIndexPriority, 10); + phases.warm.actions.set_priority.priority !== parseInt(defaultIndexPriority.warm, 10); const isColdPhasePriorityChanged = phases.cold && phases.cold.actions.set_priority && - phases.cold.actions.set_priority.priority !== parseInt(defaultPhaseIndexPriority, 10); + phases.cold.actions.set_priority.priority !== parseInt(defaultIndexPriority.cold, 10); // If the priority is different than the default, we'll consider it a user interaction, // even if the user has set it to undefined. return ( diff --git a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts index 4cb5d9523940..fdb25dec6f1f 100644 --- a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts +++ b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts @@ -31,6 +31,7 @@ export { SuperSelectField, ComboBoxField, TextField, + CheckBoxField, } from '../../../../src/plugins/es_ui_shared/static/forms/components'; export { attemptToURIDecode } from '../../../../src/plugins/es_ui_shared/public'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index da9228335a3f..e2506cb6ca8f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9416,9 +9416,7 @@ "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle": "コールドティアに割り当てられているノードがありません", "xpack.indexLifecycleMgmt.coldPhase.dataTier.description": "頻度が低い読み取り専用アクセス用に最適化されたノードにデータを移動します。安価なハードウェアのコールドフェーズにデータを格納します。", "xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel": "インデックスを凍結", - "xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasDescription": "レプリカの数を設定します。デフォルトでは前のフェーズと同じです。", "xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasLabel": "レプリカ数(任意)", - "xpack.indexLifecycleMgmt.coldPhase.replicasTitle": "レプリカ", "xpack.indexLifecycleMgmt.common.dataTier.title": "データ割り当て", "xpack.indexLifecycleMgmt.confirmDelete.cancelButton": "キャンセル", "xpack.indexLifecycleMgmt.confirmDelete.deleteButton": "削除", @@ -9431,11 +9429,8 @@ "xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.title": "コールドティアを作成", "xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription": "属性に基づく割り当てを使用するには、elasticsearch.yml でカスタムノード属性を定義します。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.activateColdPhaseSwitchLabel": "コールドフェーズを有効にする", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseDescriptionText": "インデックスへのクエリの頻度を減らすことで、大幅に性能が低いハードウェアにシャードを割り当てることができます。クエリが遅いため、複製の数を減らすことができます。", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseLabel": "コールドフェーズ", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeIndexExplanationText": "インデックスを読み取り専用にし、メモリー消費量を最小化します。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeText": "凍結", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel": "レプリカを設定", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.helpText": "ノード属性に基づいてデータを移動します。", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.input": "カスタム", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.helpText": "コールドティアのノードにデータを移動します。", @@ -9452,13 +9447,6 @@ "xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage": "インデックスライフサイクルポリシーを作成します", "xpack.indexLifecycleMgmt.editPolicy.createSearchableSnapshotLink": "スナップショットリポジドリを作成", "xpack.indexLifecycleMgmt.editPolicy.createSnapshotRepositoryLink": "新しいスナップショットリポジドリを作成", - "xpack.indexLifecycleMgmt.editPolicy.creationDaysOptionLabel": "インデックスの作成からの経過日数", - "xpack.indexLifecycleMgmt.editPolicy.creationHoursOptionLabel": "インデックスの作成からの経過時間数", - "xpack.indexLifecycleMgmt.editPolicy.creationMicroSecondsOptionLabel": "インデックスの作成からの経過時間(マイクロ秒)", - "xpack.indexLifecycleMgmt.editPolicy.creationMilliSecondsOptionLabel": "インデックスの作成からの経過時間(ミリ秒)", - "xpack.indexLifecycleMgmt.editPolicy.creationMinutesOptionLabel": "インデックスの作成からの経過時間(分)", - "xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel": "インデックスの作成からの経過時間(ナノ秒)", - "xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel": "インデックスの作成からの経過時間(秒)", "xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.allocationFieldLabel": "データティアオプション", "xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.nodeAllocationFieldLabel": "ノード属性を選択", "xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel": "コールド", @@ -9499,23 +9487,17 @@ "xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage": "このページのエラーを修正してください。", "xpack.indexLifecycleMgmt.editPolicy.hidePolicyJsonButto": "リクエストを非表示", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.enableRolloverTipContent": "現在のインデックスが定義された条件のいずれかを満たすときに、新しいインデックスにロールオーバーします。", - "xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseDescriptionMessage": "このフェーズは必須です。アクティブにクエリを実行しインデックスに書き込んでいます。 更新を高速化するため、大きくなりすぎたり古くなりすぎたりした際にインデックスをロールオーバーできます。", - "xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseLabel": "ホットフェーズ", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.learnAboutRolloverLinkText": "詳細", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.rolloverDefaultsTipContent": "インデックスが 30 日経過するか、50 GB に達したらロールオーバーします。", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.rolloverDescriptionMessage": "効率的なストレージと高いパフォーマンスのための時系列データの自動ロールアウト。", "xpack.indexLifecycleMgmt.editPolicy.indexPriorityLabel": "インデックス優先度(任意)", "xpack.indexLifecycleMgmt.editPolicy.indexPriorityText": "インデックスの優先順位", - "xpack.indexLifecycleMgmt.editPolicy.learnAboutIndexLifecycleManagementLinkText": "インデックスライフサイクルの詳細をご覧ください。", "xpack.indexLifecycleMgmt.editPolicy.learnAboutIndexTemplatesLink": "インデックステンプレートの詳細をご覧ください", "xpack.indexLifecycleMgmt.editPolicy.learnAboutShardAllocationLink": "シャード割り当ての詳細をご覧ください", - "xpack.indexLifecycleMgmt.editPolicy.learnAboutTimingText": "タイミングの詳細をご覧ください", "xpack.indexLifecycleMgmt.editPolicy.lifecyclePoliciesLoadingFailedTitle": "既存のライフサイクルポリシーを読み込めません", "xpack.indexLifecycleMgmt.editPolicy.lifecyclePoliciesReloadButton": "再試行", - "xpack.indexLifecycleMgmt.editPolicy.lifecyclePolicyDescriptionText": "インデックスへのアクティブな書き込みから削除までの、インデックスライフサイクルの 4 つのフェーズを自動化するには、インデックスポリシーを使用します。", "xpack.indexLifecycleMgmt.editPolicy.loadSnapshotRepositoriesErrorBody": "このフィールドを更新し、既存のスナップショットリポジトリの名前を入力します。", "xpack.indexLifecycleMgmt.editPolicy.loadSnapshotRepositoriesErrorTitle": "スナップショットリポジトリを読み込めません", - "xpack.indexLifecycleMgmt.editPolicy.nameLabel": "名前", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "ノード属性を使用して、シャード割り当てを制御します。{learnMoreLink}。", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "割り当て構成を修正しない", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "ノードデータを読み込めません", @@ -9542,13 +9524,6 @@ "xpack.indexLifecycleMgmt.editPolicy.readonlyDescription": "有効にすると、インデックスおよびインデックスメタデータを読み取り専用にします。無効にすると、書き込みとメタデータの変更を許可します。", "xpack.indexLifecycleMgmt.editPolicy.readonlyTitle": "読み取り専用", "xpack.indexLifecycleMgmt.editPolicy.reloadSnapshotRepositoriesLabel": "スナップショットリポジドリの再読み込み", - "xpack.indexLifecycleMgmt.editPolicy.rolloverDaysOptionLabel": "ロールオーバーからの経過日数", - "xpack.indexLifecycleMgmt.editPolicy.rolloverHoursOptionLabel": "ロールオーバーからの経過時間数", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMicroSecondsOptionLabel": "ロールオーバーからの経過時間(マイクロ秒)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMilliSecondsOptionLabel": "ロールオーバーからの経過時間(ミリ秒)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMinutesOptionLabel": "ロールオーバーからの経過時間数(分)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverNanoSecondsOptionLabel": "ロールオーバーからの経過時間(ナノ秒)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverSecondsOptionLabel": "ロールオーバーからの経過時間(秒)", "xpack.indexLifecycleMgmt.editPolicy.saveAsNewButton": "新規ポリシーとして保存します", "xpack.indexLifecycleMgmt.editPolicy.saveAsNewPolicyMessage": "新規ポリシーとして保存します", "xpack.indexLifecycleMgmt.editPolicy.saveButton": "ポリシーを保存", @@ -9573,15 +9548,11 @@ "xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription": "属性に基づく割り当てを使用するには、elasticsearch.yml でカスタムノード属性を定義します。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "ウォームフェーズを有効にする", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "ノードの再起動後にインデックスを復元する優先順位を設定します。優先順位の高いインデックスは優先順位の低いインデックスよりも先に復元されます。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.numberOfReplicas.switchLabel": "レプリカを設定", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescriptionMessage": "まだインデックスにクエリを実行中ですが、読み取り専用です。性能の低いハードウェアにシャードを割り当てることができます。検索を高速化するために、シャードの数を減らしセグメントを結合することができます。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseLabel": "ウォームフェーズ", "xpack.indexLifecycleMgmt.featureCatalogueDescription": "ライフサイクルポリシーを定義し、インデックス年齢として自動的に処理を実行します。", "xpack.indexLifecycleMgmt.featureCatalogueTitle": "インデックスライフサイクルを管理", "xpack.indexLifecycleMgmt.forcemerge.bestCompressionLabel": "格納されたフィールドを圧縮", "xpack.indexLifecycleMgmt.forcemerge.enableLabel": "データを強制結合", "xpack.indexLifecycleMgmt.forceMerge.numberOfSegmentsLabel": "セグメントの数", - "xpack.indexLifecycleMgmt.hotPhase.advancedSettingsButton": "高度な設定", "xpack.indexLifecycleMgmt.hotPhase.bytesLabel": "バイト", "xpack.indexLifecycleMgmt.hotPhase.daysLabel": "日", "xpack.indexLifecycleMgmt.hotPhase.enableRolloverLabel": "ロールオーバーを有効にする", @@ -9705,7 +9676,6 @@ "xpack.indexLifecycleMgmt.shrink.indexFieldLabel": "インデックスを縮小", "xpack.indexLifecycleMgmt.shrink.numberOfPrimaryShardsLabel": "プライマリシャードの数", "xpack.indexLifecycleMgmt.templateNotFoundMessage": "テンプレート{name}が見つかりません。", - "xpack.indexLifecycleMgmt.warmPhase.advancedSettingsButton": "高度な設定", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody": "ロールに基づく割り当てを使用するには、1つ以上のノードを、ウォームまたはホットティアに割り当てます。使用可能なノードがない場合、ポリシーは割り当てを完了できません。", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle": "ウォームティアに割り当てられているノードがありません", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold": "このポリシーはコールドフェーズのデータを{tier}ティアノードに移動します。", @@ -9713,10 +9683,7 @@ "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm": "このポリシーはウォームフェーズのデータを{tier}ティアノードに移動します。", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "ウォームティアに割り当てられているノードがありません", "xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "頻度が低い読み取り専用アクセス用に最適化されたノードにデータを移動します。", - "xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "ロールオーバー時にウォームフェーズに変更", - "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasDescription": "レプリカの数を設定します。デフォルトでは前のフェーズと同じです。", "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "レプリカ数(任意)", - "xpack.indexLifecycleMgmt.warmPhase.replicasTitle": "レプリカ", "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "なし(グループなし)", "xpack.infra.alerting.alertFlyout.groupByLabel": "グループ分けの条件", "xpack.infra.alerting.alertsButton": "アラート", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 679edaf9e0cd..7b8ea35baf0f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9440,9 +9440,7 @@ "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle": "没有分配到冷层的节点", "xpack.indexLifecycleMgmt.coldPhase.dataTier.description": "将数据移到针对不太频繁的只读访问优化的节点。将处于冷阶段的数据存储在成本较低的硬件上。", "xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel": "冻结索引", - "xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasDescription": "设置副本数目。默认情况下仍与上一阶段相同。", "xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasLabel": "副本分片数(可选)", - "xpack.indexLifecycleMgmt.coldPhase.replicasTitle": "副本分片", "xpack.indexLifecycleMgmt.common.dataTier.title": "数据分配", "xpack.indexLifecycleMgmt.confirmDelete.cancelButton": "取消", "xpack.indexLifecycleMgmt.confirmDelete.deleteButton": "删除", @@ -9455,11 +9453,8 @@ "xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.title": "创建冷层", "xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription": "在 elasticsearch.yml 中定义定制节点属性,以使用基于属性的分配。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.activateColdPhaseSwitchLabel": "激活冷阶段", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseDescriptionText": "您查询自己索引的频率较低,因此您可以在效率较低的硬件上分配分片。因为您的查询较为缓慢,所以您可以减少副本分片数目。", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseLabel": "冷阶段", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeIndexExplanationText": "使索引只读,并最大限度减小其内存占用。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeText": "冻结", - "xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel": "设置副本", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.helpText": "根据节点属性移动数据。", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.input": "定制", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.helpText": "将数据移到冷层中的节点。", @@ -9476,13 +9471,6 @@ "xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage": "创建索引生命周期策略", "xpack.indexLifecycleMgmt.editPolicy.createSearchableSnapshotLink": "创建快照库", "xpack.indexLifecycleMgmt.editPolicy.createSnapshotRepositoryLink": "创建新的快照库", - "xpack.indexLifecycleMgmt.editPolicy.creationDaysOptionLabel": "天(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationHoursOptionLabel": "小时(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationMicroSecondsOptionLabel": "微秒(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationMilliSecondsOptionLabel": "毫秒(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationMinutesOptionLabel": "分钟(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel": "纳秒(自索引创建)", - "xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel": "秒(自索引创建)", "xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.allocationFieldLabel": "数据层选项", "xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.nodeAllocationFieldLabel": "选择节点属性", "xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel": "冷", @@ -9523,23 +9511,17 @@ "xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage": "请修复此页面上的错误。", "xpack.indexLifecycleMgmt.editPolicy.hidePolicyJsonButto": "隐藏请求", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.enableRolloverTipContent": "在当前索引满足定义的条件之一时,滚动更新到新索引。", - "xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseDescriptionMessage": "此阶段为必需。您正频繁地查询并写到您的索引。 为了获取更快的更新,在索引变得过大或过旧时,您可以滚动更新索引。", - "xpack.indexLifecycleMgmt.editPolicy.hotPhase.hotPhaseLabel": "热阶段", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.learnAboutRolloverLinkText": "了解详情", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.rolloverDefaultsTipContent": "当索引已存在 30 天或达到 50 GB 时滚动更新。", "xpack.indexLifecycleMgmt.editPolicy.hotPhase.rolloverDescriptionMessage": "自动滚动更新时间序列数据,以实现高效存储和更高性能。", "xpack.indexLifecycleMgmt.editPolicy.indexPriorityLabel": "索引优先级(可选)", "xpack.indexLifecycleMgmt.editPolicy.indexPriorityText": "索引优先级", - "xpack.indexLifecycleMgmt.editPolicy.learnAboutIndexLifecycleManagementLinkText": "了解索引生命周期。", "xpack.indexLifecycleMgmt.editPolicy.learnAboutIndexTemplatesLink": "了解索引模板", "xpack.indexLifecycleMgmt.editPolicy.learnAboutShardAllocationLink": "了解分片分配", - "xpack.indexLifecycleMgmt.editPolicy.learnAboutTimingText": "了解计时", "xpack.indexLifecycleMgmt.editPolicy.lifecyclePoliciesLoadingFailedTitle": "无法加载现有生命周期策略", "xpack.indexLifecycleMgmt.editPolicy.lifecyclePoliciesReloadButton": "重试", - "xpack.indexLifecycleMgmt.editPolicy.lifecyclePolicyDescriptionText": "使用索引策略自动化索引生命周期的四个阶段,从频繁地写入到索引到删除索引。", "xpack.indexLifecycleMgmt.editPolicy.loadSnapshotRepositoriesErrorBody": "刷新此字段并输入现有快照储存库的名称。", "xpack.indexLifecycleMgmt.editPolicy.loadSnapshotRepositoriesErrorTitle": "无法加载快照存储库", - "xpack.indexLifecycleMgmt.editPolicy.nameLabel": "名称", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "使用节点属性控制分片分配。{learnMoreLink}。", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "切勿修改分配配置", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "无法加载节点数据", @@ -9566,13 +9548,6 @@ "xpack.indexLifecycleMgmt.editPolicy.readonlyDescription": "启用以使索引及索引元数据只读;禁用以允许写入和元数据更改。", "xpack.indexLifecycleMgmt.editPolicy.readonlyTitle": "只读", "xpack.indexLifecycleMgmt.editPolicy.reloadSnapshotRepositoriesLabel": "重新加载快照存储库", - "xpack.indexLifecycleMgmt.editPolicy.rolloverDaysOptionLabel": "天(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverHoursOptionLabel": "小时(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMicroSecondsOptionLabel": "微秒(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMilliSecondsOptionLabel": "毫秒(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverMinutesOptionLabel": "分钟(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverNanoSecondsOptionLabel": "纳秒(自滚动更新)", - "xpack.indexLifecycleMgmt.editPolicy.rolloverSecondsOptionLabel": "秒(自滚动更新)", "xpack.indexLifecycleMgmt.editPolicy.saveAsNewButton": "另存为新策略", "xpack.indexLifecycleMgmt.editPolicy.saveAsNewPolicyMessage": "另存为新策略", "xpack.indexLifecycleMgmt.editPolicy.saveButton": "保存策略", @@ -9597,15 +9572,11 @@ "xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription": "在 elasticsearch.yml 中定义定制节点属性,以使用基于属性的分配。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "激活温阶段", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "设置在节点重新启动后恢复索引的优先级。较高优先级的索引会在较低优先级的索引之前恢复。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.numberOfReplicas.switchLabel": "设置副本", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescriptionMessage": "您仍在查询自己的索引,但其为只读。您可以将分片分配给效率较低的硬件。为了获取更快的搜索,您可以减少分片数目并强制合并段。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseLabel": "温阶段", "xpack.indexLifecycleMgmt.featureCatalogueDescription": "定义生命周期策略,以随着索引老化自动执行操作。", "xpack.indexLifecycleMgmt.featureCatalogueTitle": "管理索引生命周期", "xpack.indexLifecycleMgmt.forcemerge.bestCompressionLabel": "压缩已存储字段", "xpack.indexLifecycleMgmt.forcemerge.enableLabel": "强制合并数据", "xpack.indexLifecycleMgmt.forceMerge.numberOfSegmentsLabel": "分段数目", - "xpack.indexLifecycleMgmt.hotPhase.advancedSettingsButton": "高级设置", "xpack.indexLifecycleMgmt.hotPhase.bytesLabel": "字节", "xpack.indexLifecycleMgmt.hotPhase.daysLabel": "天", "xpack.indexLifecycleMgmt.hotPhase.enableRolloverLabel": "启用滚动更新", @@ -9731,7 +9702,6 @@ "xpack.indexLifecycleMgmt.shrink.indexFieldLabel": "缩小索引", "xpack.indexLifecycleMgmt.shrink.numberOfPrimaryShardsLabel": "主分片数目", "xpack.indexLifecycleMgmt.templateNotFoundMessage": "找不到模板 {name}。", - "xpack.indexLifecycleMgmt.warmPhase.advancedSettingsButton": "高级设置", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody": "至少将一个节点分配到温层或冷层,以使用基于角色的分配。如果没有可用节点,则策略无法完成分配。", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle": "没有分配到温层的节点", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold": "此策略会改为将冷阶段的数据移到{tier}层节点。", @@ -9739,10 +9709,7 @@ "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm": "此策略会改为将温阶段的数据移到{tier}层节点。", "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "没有分配到温层的节点", "xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "将数据移到针对不太频繁的只读访问优化的节点。", - "xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "滚动更新时移到温阶段", - "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasDescription": "设置副本数目。默认情况下仍与上一阶段相同。", "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "副本分片数(可选)", - "xpack.indexLifecycleMgmt.warmPhase.replicasTitle": "副本分片", "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "无内容(未分组)", "xpack.infra.alerting.alertFlyout.groupByLabel": "分组依据", "xpack.infra.alerting.alertsButton": "告警",