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 dc375f6370048..38049dd7c6cfa 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 @@ -278,7 +278,6 @@ export const setup = async (arg?: { appServicesContext: Partial exists('policyFormErrorsCallout'), timeline: { - hasRolloverIndicator: () => exists('timelineHotPhaseRolloverToolTip'), hasHotPhase: () => exists('ilmTimelineHotPhase'), hasWarmPhase: () => exists('ilmTimelineWarmPhase'), hasColdPhase: () => exists('ilmTimelineColdPhase'), diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index f2266741ec7d1..282daf780b86c 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -845,14 +845,6 @@ describe('', () => { expect(actions.timeline.hasColdPhase()).toBe(true); expect(actions.timeline.hasDeletePhase()).toBe(true); }); - - test('show and hide rollover indicator on timeline', async () => { - const { actions } = testBed; - expect(actions.timeline.hasRolloverIndicator()).toBe(true); - await actions.hot.toggleDefaultRollover(false); - await actions.hot.toggleRollover(false); - expect(actions.timeline.hasRolloverIndicator()).toBe(false); - }); }); describe('policy error notifications', () => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx index 74809965a52d9..c77493476b929 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx @@ -17,7 +17,7 @@ import { EuiTextColor, EuiSwitch, EuiIconTip, - EuiIcon, + EuiText, } from '@elastic/eui'; import { useFormData, SelectField, NumericField } from '../../../../../../shared_imports'; @@ -68,8 +68,20 @@ export const HotPhase: FunctionComponent = () => {

{' '} + defaultMessage="Start writing to a new index when the current index reaches a certain size, document count, or age. Enables you to optimize performance and manage resource usage when working with time series data." + /> +

+ + + +

+ + {i18n.translate( + 'xpack.indexLifecycleMgmt.rollover.rolloverOffsetsPhaseTimingDescriptionNote', + { defaultMessage: 'Note: ' } + )} + + {i18nTexts.editPolicy.rolloverOffsetsHotPhaseTiming}{' '} {

- -   - {i18nTexts.editPolicy.rolloverOffsetsHotPhaseTiming} - path={isUsingDefaultRolloverPath}> {(field) => ( <> - field.setValue(e.target.checked)} - data-test-subj="useDefaultRolloverSwitch" - /> -   - - } + + field.setValue(e.target.checked)} + data-test-subj="useDefaultRolloverSwitch" + /> + + + )} 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 bbdcbbf4759ef..8cb566ceae25a 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 @@ -45,7 +45,7 @@ export const ForcemergeField: React.FunctionComponent = ({ phase }) => { <> {' '} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx index 9251b08742476..c85201f708a2b 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx @@ -342,7 +342,7 @@ export const SearchableSnapshotField: FunctionComponent = ({ phase }) => , }} 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 b5fb79811ee2d..8ac387ba106b7 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 @@ -38,7 +38,7 @@ export const ShrinkField: FunctionComponent = ({ phase }) => { {' '} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/components/timeline_phase_text.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/components/timeline_phase_text.tsx index 3a9f33fa3d169..62b100b85cbe2 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/components/timeline_phase_text.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/components/timeline_phase_text.tsx @@ -12,8 +12,8 @@ export const TimelinePhaseText: FunctionComponent<{ phaseName: ReactNode | string; durationInPhase?: ReactNode | string; }> = ({ phaseName, durationInPhase }) => ( - - + + {phaseName} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.scss b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.scss index 7d65d2cd6b212..de49e665ed933 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.scss +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.scss @@ -1,11 +1,5 @@ $ilmTimelineBarHeight: $euiSizeS; -/* -* For theming we need to shade or tint to get the right color from the base EUI color -*/ -$ilmDeletePhaseBackgroundColor: tintOrShade($euiColorVis5_behindText, 80%,80%); -$ilmDeletePhaseColor: shadeOrTint($euiColorVis5, 40%, 40%); - .ilmTimeline { overflow: hidden; width: 100%; @@ -49,14 +43,16 @@ $ilmDeletePhaseColor: shadeOrTint($euiColorVis5, 40%, 40%); */ padding: $euiSizeM; margin-left: $euiSizeM; - background-color: $ilmDeletePhaseBackgroundColor; - color: $ilmDeletePhaseColor; - border-radius: calc(#{$euiSizeS} / 2); + background-color: $euiColorLightestShade; + color: $euiColorDarkShade; + border-radius: 50%; } &__colorBar { display: inline-block; height: $ilmTimelineBarHeight; + margin-top: $euiSizeS; + margin-bottom: $euiSizeXS; border-radius: calc(#{$ilmTimelineBarHeight} / 2); width: 100%; } @@ -84,8 +80,4 @@ $ilmDeletePhaseColor: shadeOrTint($euiColorVis5, 40%, 40%); background-color: $euiColorVis1; } } - - &__rolloverIcon { - display: inline-block; - } } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.tsx index 2d83009bd4df4..8097ab51eb59e 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/timeline/timeline.tsx @@ -8,14 +8,12 @@ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent, memo } from 'react'; - -import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiIconTip } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiText, EuiIconTip } from '@elastic/eui'; import { PhasesExceptDelete } from '../../../../../../common/types'; import { calculateRelativeFromAbsoluteMilliseconds, - normalizeTimingsToHumanReadable, PhaseAgeInMilliseconds, AbsoluteTimings, } from '../../lib'; @@ -48,6 +46,12 @@ const msTimeToOverallPercent = (ms: number, totalMs: number) => { const SCORE_BUFFER_AMOUNT = 50; const i18nTexts = { + title: i18n.translate('xpack.indexLifecycleMgmt.timeline.title', { + defaultMessage: 'Policy Summary', + }), + description: i18n.translate('xpack.indexLifecycleMgmt.timeline.description', { + defaultMessage: 'This policy moves data through the following phases.', + }), hotPhase: i18n.translate('xpack.indexLifecycleMgmt.timeline.hotPhaseSectionTitle', { defaultMessage: 'Hot phase', }), @@ -69,6 +73,11 @@ const i18nTexts = { defaultMessage: 'Policy deletes the index after lifecycle phases complete.', }), }, + foreverIcon: { + ariaLabel: i18n.translate('xpack.indexLifecycleMgmt.timeline.foreverIconToolTipContent', { + defaultMessage: 'Forever', + }), + }, }; const calculateWidths = (inputs: PhaseAgeInMilliseconds) => { @@ -118,27 +127,23 @@ export const Timeline: FunctionComponent = memo( }; const phaseAgeInMilliseconds = calculateRelativeFromAbsoluteMilliseconds(absoluteTimings); - const humanReadableTimings = normalizeTimingsToHumanReadable(phaseAgeInMilliseconds); const widths = calculateWidths(phaseAgeInMilliseconds); const getDurationInPhaseContent = (phase: PhasesExceptDelete): string | React.ReactNode => phaseAgeInMilliseconds.phases[phase] === Infinity ? ( - - ) : ( - humanReadableTimings[phase] - ); + + ) : null; return ( -

- {i18n.translate('xpack.indexLifecycleMgmt.timeline.title', { - defaultMessage: 'Policy Timeline', - })} -

+

{i18nTexts.title}

+ + {i18nTexts.description} +
= memo( >
- {i18nTexts.hotPhase} -   -
- -
- - ) : ( - i18nTexts.hotPhase - ) - } + phaseName={i18nTexts.hotPhase} durationInPhase={getDurationInPhaseContent('hot')} />
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 5deba8607cd52..3923cf93cd0d3 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 @@ -16,7 +16,7 @@ export const i18nTexts = { 'xpack.indexLifecycleMgmt.rollover.rolloverOffsetsPhaseTimingDescription', { defaultMessage: - 'How long it takes to reach the rollover criteria in the hot phase can vary. Data moves to the next phase when the time since rollover reaches the minimum age.', + 'How long it takes to reach the rollover criteria in the hot phase can vary.', } ), searchableSnapshotInHotPhase: { @@ -195,7 +195,7 @@ export const i18nTexts = { 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.', + 'You actively store and query data in the hot phase. All policies have a hot phase.', }), warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescription', { defaultMessage: diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.test.ts index 7ec20cc2a5966..8a9635e2db219 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/absolute_timing_to_relative_timing.test.ts @@ -11,7 +11,6 @@ import { deserializer } from '../form'; import { formDataToAbsoluteTimings, calculateRelativeFromAbsoluteMilliseconds, - absoluteTimingToRelativeTiming, } from './absolute_timing_to_relative_timing'; export const calculateRelativeTimingMs = flow( @@ -273,243 +272,4 @@ describe('Conversion of absolute policy timing to relative timing', () => { }); }); }); - - describe('absoluteTimingToRelativeTiming', () => { - describe('policy that never deletes data (keep forever)', () => { - test('always hot', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - }, - }) - ) - ).toEqual({ total: 'forever', hot: 'forever', warm: undefined, cold: undefined }); - }); - - test('hot, then always warm', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - warm: { - actions: {}, - }, - }, - }) - ) - ).toEqual({ total: 'forever', hot: 'less than a day', warm: 'forever', cold: undefined }); - }); - - test('hot, then warm, then always cold', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - warm: { - min_age: '1M', - actions: {}, - }, - cold: { - min_age: '34d', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: 'forever', - hot: '30 days', - warm: '4 days', - cold: 'forever', - }); - }); - - test('hot, then always cold', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - cold: { - min_age: '34d', - actions: {}, - }, - }, - }) - ) - ).toEqual({ total: 'forever', hot: '34 days', warm: undefined, cold: 'forever' }); - }); - }); - - describe('policy that deletes data', () => { - test('hot, then delete', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - delete: { - min_age: '1M', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: '30 days', - hot: '30 days', - warm: undefined, - cold: undefined, - }); - }); - - test('hot, then warm, then delete', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - warm: { - min_age: '24d', - actions: {}, - }, - delete: { - min_age: '1M', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: '30 days', - hot: '24 days', - warm: '6 days', - cold: undefined, - }); - }); - - test('hot, then warm, then cold, then delete', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - warm: { - min_age: '24d', - actions: {}, - }, - cold: { - min_age: '2M', - actions: {}, - }, - delete: { - min_age: '2d', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: '61 days', - hot: '24 days', - warm: '37 days', - cold: 'less than a day', - }); - }); - - test('hot, then cold, then delete', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - cold: { - min_age: '2M', - actions: {}, - }, - delete: { - min_age: '2d', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: '61 days', - hot: '61 days', - warm: undefined, - cold: 'less than a day', - }); - }); - - test('hot, then long warm, then short cold, then delete', () => { - expect( - absoluteTimingToRelativeTiming( - deserializer({ - name: 'test', - phases: { - hot: { - min_age: '0ms', - actions: {}, - }, - warm: { - min_age: '2M', - actions: {}, - }, - cold: { - min_age: '1d', - actions: {}, - }, - delete: { - min_age: '2d', - actions: {}, - }, - }, - }) - ) - ).toEqual({ - total: '61 days', - hot: '61 days', - warm: 'less than a day', - cold: 'less than a day', - }); - }); - }); - }); }); 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 73ff8c76b9233..2974a88c22343 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 @@ -21,8 +21,6 @@ */ import moment from 'moment'; -import { i18n } from '@kbn/i18n'; -import { flow } from 'fp-ts/function'; import { splitSizeAndUnits } from '../../../lib/policies'; @@ -34,21 +32,6 @@ type MinAgePhase = 'warm' | 'cold' | 'delete'; type Phase = 'hot' | MinAgePhase; -const i18nTexts = { - forever: i18n.translate('xpack.indexLifecycleMgmt.relativeTiming.forever', { - defaultMessage: 'forever', - }), - lessThanADay: i18n.translate('xpack.indexLifecycleMgmt.relativeTiming.lessThanADay', { - defaultMessage: 'less than a day', - }), - day: i18n.translate('xpack.indexLifecycleMgmt.relativeTiming.day', { - defaultMessage: 'day', - }), - days: i18n.translate('xpack.indexLifecycleMgmt.relativeTiming.days', { - defaultMessage: 'days', - }), -}; - const phaseOrder: Phase[] = ['hot', 'warm', 'cold', 'delete']; const getMinAge = (phase: MinAgePhase, formData: FormInternal) => ({ @@ -162,38 +145,3 @@ export const calculateRelativeFromAbsoluteMilliseconds = ( }; export type RelativePhaseTimingInMs = ReturnType; - -const millisecondsToDays = (milliseconds?: number): string | undefined => { - if (milliseconds == null) { - return; - } - if (!isFinite(milliseconds)) { - return i18nTexts.forever; - } - const days = milliseconds / 8.64e7; - return days < 1 - ? i18nTexts.lessThanADay - : `${Math.floor(days)} ${days === 1 ? i18nTexts.day : i18nTexts.days}`; -}; - -export const normalizeTimingsToHumanReadable = ({ - total, - phases, -}: PhaseAgeInMilliseconds): { total?: string; hot?: string; warm?: string; cold?: string } => { - return { - total: millisecondsToDays(total), - hot: millisecondsToDays(phases.hot), - warm: millisecondsToDays(phases.warm), - cold: millisecondsToDays(phases.cold), - }; -}; - -/** - * Given {@link FormInternal}, extract the min_age values for each phase and calculate - * human readable strings for communicating how long data will remain in a phase. - */ -export const absoluteTimingToRelativeTiming = flow( - formDataToAbsoluteTimings, - calculateRelativeFromAbsoluteMilliseconds, - normalizeTimingsToHumanReadable -); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/index.ts index 396318a1d78cf..af4757a7b7105 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/lib/index.ts @@ -6,9 +6,7 @@ */ export { - absoluteTimingToRelativeTiming, calculateRelativeFromAbsoluteMilliseconds, - normalizeTimingsToHumanReadable, formDataToAbsoluteTimings, AbsoluteTimings, PhaseAgeInMilliseconds,