Skip to content

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
DeletePhase,
HotPhase,
WarmPhase,
FrozenPhase,
} from '../services/policies/types';

export const defaultNewHotPhase: HotPhase = {
Expand Down Expand Up @@ -47,6 +48,16 @@ export const defaultNewColdPhase: ColdPhase = {
phaseIndexPriority: '0',
};

export const defaultNewFrozenPhase: FrozenPhase = {
phaseEnabled: false,
selectedMinimumAge: '0',
selectedMinimumAgeUnits: 'd',
selectedNodeAttrs: '',
selectedReplicaCount: '',
freezeEnabled: false,
phaseIndexPriority: '0',
};

export const defaultNewDeletePhase: DeletePhase = {
phaseEnabled: false,
selectedMinimumAge: '0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ function getTimingLabelForPhase(phase: keyof Phases) {
defaultMessage: 'Timing for cold phase',
});

case 'frozen':
return i18n.translate('xpack.indexLifecycleMgmt.editPolicy.phaseFrozen.minimumAgeLabel', {
defaultMessage: 'Timing for frozen phase',
});

case 'delete':
return i18n.translate('xpack.indexLifecycleMgmt.editPolicy.phaseDelete.minimumAgeLabel', {
defaultMessage: 'Timing for delete phase',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {

import { toasts } from '../../services/notification';

import { Policy, PolicyFromES } from '../../services/policies/types';
import { Phases, Policy, PolicyFromES } from '../../services/policies/types';
import {
validatePolicy,
ValidationErrors,
Expand All @@ -42,7 +42,7 @@ import {
} from '../../services/policies/policy_serialization';

import { ErrableFormRow, LearnMoreLink, PolicyJsonFlyout } from './components';
import { ColdPhase, DeletePhase, HotPhase, WarmPhase } from './phases';
import { ColdPhase, DeletePhase, FrozenPhase, HotPhase, WarmPhase } from './phases';

interface Props {
policies: PolicyFromES[];
Expand Down Expand Up @@ -118,7 +118,7 @@ export const EditPolicy: React.FunctionComponent<Props> = ({
setIsShowingPolicyJsonFlyout(!isShowingPolicyJsonFlyout);
};

const setPhaseData = (phase: 'hot' | 'warm' | 'cold' | 'delete', key: string, value: any) => {
const setPhaseData = (phase: keyof Phases, key: string, value: any) => {
setPolicy({
...policy,
phases: {
Expand Down Expand Up @@ -303,6 +303,16 @@ export const EditPolicy: React.FunctionComponent<Props> = ({

<EuiHorizontalRule />

<FrozenPhase
errors={errors?.frozen}
isShowingErrors={isShowingErrors && !!errors && Object.keys(errors.frozen).length > 0}
setPhaseData={(key, value) => setPhaseData('frozen', key, value)}
phaseData={policy.phases.frozen}
hotPhaseRolloverEnabled={policy.phases.hot.rolloverEnabled}
/>

<EuiHorizontalRule />

<DeletePhase
errors={errors?.delete}
isShowingErrors={isShowingErrors && !!errors && Object.keys(errors.delete).length > 0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@elastic/eui';

import { ColdPhase as ColdPhaseInterface, Phases } from '../../../services/policies/types';
import { PhaseValidationErrors, propertyof } from '../../../services/policies/policy_validation';
import { PhaseValidationErrors } from '../../../services/policies/policy_validation';

import {
LearnMoreLink,
Expand All @@ -36,9 +36,8 @@ const freezeLabel = i18n.translate('xpack.indexLifecycleMgmt.coldPhase.freezeInd
defaultMessage: 'Freeze index',
});

const coldProperty = propertyof<Phases>('cold');
const phaseProperty = (propertyName: keyof ColdPhaseInterface) =>
propertyof<ColdPhaseInterface>(propertyName);
const coldProperty: keyof Phases = 'cold';
const phaseProperty = (propertyName: keyof ColdPhaseInterface) => propertyName;

interface Props {
setPhaseData: (key: keyof ColdPhaseInterface & string, value: string | boolean) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { EuiDescribedFormGroup, EuiSwitch, EuiTextColor, EuiFormRow } from '@elastic/eui';

import { DeletePhase as DeletePhaseInterface, Phases } from '../../../services/policies/types';
import { PhaseValidationErrors, propertyof } from '../../../services/policies/policy_validation';
import { PhaseValidationErrors } from '../../../services/policies/policy_validation';

import {
ActiveBadge,
Expand All @@ -20,9 +20,8 @@ import {
SnapshotPolicies,
} from '../components';

const deleteProperty = propertyof<Phases>('delete');
const phaseProperty = (propertyName: keyof DeletePhaseInterface) =>
propertyof<DeletePhaseInterface>(propertyName);
const deleteProperty: keyof Phases = 'delete';
const phaseProperty = (propertyName: keyof DeletePhaseInterface) => propertyName;

interface Props {
setPhaseData: (key: keyof DeletePhaseInterface & string, value: string | boolean) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* 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, { PureComponent, Fragment } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';

import {
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiFieldNumber,
EuiDescribedFormGroup,
EuiSwitch,
EuiTextColor,
} from '@elastic/eui';

import { FrozenPhase as FrozenPhaseInterface, Phases } from '../../../services/policies/types';
import { PhaseValidationErrors } from '../../../services/policies/policy_validation';

import {
LearnMoreLink,
ActiveBadge,
PhaseErrorMessage,
OptionalLabel,
ErrableFormRow,
MinAgeInput,
NodeAllocation,
SetPriorityInput,
} from '../components';

const freezeLabel = i18n.translate('xpack.indexLifecycleMgmt.frozenPhase.freezeIndexLabel', {
defaultMessage: 'Freeze index',
});

const frozenProperty: keyof Phases = 'frozen';
const phaseProperty = (propertyName: keyof FrozenPhaseInterface) => propertyName;

interface Props {
setPhaseData: (key: keyof FrozenPhaseInterface & string, value: string | boolean) => void;
phaseData: FrozenPhaseInterface;
isShowingErrors: boolean;
errors?: PhaseValidationErrors<FrozenPhaseInterface>;
hotPhaseRolloverEnabled: boolean;
}
export class FrozenPhase extends PureComponent<Props> {
render() {
const {
setPhaseData,
phaseData,
errors,
isShowingErrors,
hotPhaseRolloverEnabled,
} = this.props;

return (
<div id="frozenPhaseContent" aria-live="polite" role="region">
<EuiDescribedFormGroup
title={
<div>
<h2 className="eui-displayInlineBlock eui-alignMiddle">
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseLabel"
defaultMessage="Frozen phase"
/>
</h2>{' '}
{phaseData.phaseEnabled && !isShowingErrors ? <ActiveBadge /> : null}
<PhaseErrorMessage isShowingErrors={isShowingErrors} />
</div>
}
titleSize="s"
description={
<Fragment>
<p>
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseDescriptionText"
defaultMessage="You are querying your index very infrequently, so you can allocate shards
on the least performant hardware.
Because your queries are slower, you can reduce the number of replicas."
/>
</p>
<EuiSwitch
data-test-subj="enablePhaseSwitch-frozen"
label={
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.activateWarmPhaseSwitchLabel"
defaultMessage="Activate frozen phase"
/>
}
id={`${frozenProperty}-${phaseProperty('phaseEnabled')}`}
checked={phaseData.phaseEnabled}
onChange={(e) => {
setPhaseData(phaseProperty('phaseEnabled'), e.target.checked);
}}
aria-controls="frozenPhaseContent"
/>
</Fragment>
}
fullWidth
>
<Fragment>
{phaseData.phaseEnabled ? (
<Fragment>
<MinAgeInput<FrozenPhaseInterface>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MinAgeInput's props are currently typed to accept warm, cold and delete phases. I'm not sure why the type check is not picking it up, but it might be good to add frozen phase to props generics.

errors={errors}
phaseData={phaseData}
phase={frozenProperty}
isShowingErrors={isShowingErrors}
setPhaseData={setPhaseData}
rolloverEnabled={hotPhaseRolloverEnabled}
/>
<EuiSpacer />

<NodeAllocation<FrozenPhaseInterface>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here, the props generics don't include frozen phase, but type check is not showing it.

phase={frozenProperty}
setPhaseData={setPhaseData}
errors={errors}
phaseData={phaseData}
isShowingErrors={isShowingErrors}
/>

<EuiFlexGroup>
<EuiFlexItem grow={false} style={{ maxWidth: 188 }}>
<ErrableFormRow
id={`${frozenProperty}-${phaseProperty('freezeEnabled')}`}
label={
<Fragment>
<FormattedMessage
id="xpack.indexLifecycleMgmt.frozenPhase.numberOfReplicasLabel"
defaultMessage="Number of replicas"
/>
<OptionalLabel />
</Fragment>
}
isShowingErrors={isShowingErrors}
errors={errors?.freezeEnabled}
helpText={i18n.translate(
'xpack.indexLifecycleMgmt.frozenPhase.replicaCountHelpText',
{
defaultMessage: 'By default, the number of replicas remains the same.',
}
)}
>
<EuiFieldNumber
id={`${frozenProperty}-${phaseProperty('selectedReplicaCount')}`}
value={phaseData.selectedReplicaCount}
onChange={(e) => {
setPhaseData(phaseProperty('selectedReplicaCount'), e.target.value);
}}
min={0}
/>
</ErrableFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</Fragment>
) : (
<div />
)}
</Fragment>
</EuiDescribedFormGroup>
{phaseData.phaseEnabled ? (
<Fragment>
<EuiDescribedFormGroup
title={
<h3>
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.freezeText"
defaultMessage="Freeze"
/>
</h3>
}
description={
<EuiTextColor color="subdued">
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.freezeIndexExplanationText"
defaultMessage="A frozen index has little overhead on the cluster and is blocked for write operations.
You can search a frozen index, but expect queries to be slower."
/>{' '}
<LearnMoreLink docPath="frozen-indices.html" />
</EuiTextColor>
}
fullWidth
titleSize="xs"
>
<EuiSwitch
data-test-subj="freezeSwitch"
checked={phaseData.freezeEnabled}
onChange={(e) => {
setPhaseData(phaseProperty('freezeEnabled'), e.target.checked);
}}
label={freezeLabel}
aria-label={freezeLabel}
/>
</EuiDescribedFormGroup>
<SetPriorityInput<FrozenPhaseInterface>
errors={errors}
phaseData={phaseData}
phase={frozenProperty}
isShowingErrors={isShowingErrors}
setPhaseData={setPhaseData}
/>
</Fragment>
) : null}
</div>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@elastic/eui';

import { HotPhase as HotPhaseInterface, Phases } from '../../../services/policies/types';
import { PhaseValidationErrors, propertyof } from '../../../services/policies/policy_validation';
import { PhaseValidationErrors } from '../../../services/policies/policy_validation';

import {
LearnMoreLink,
Expand Down Expand Up @@ -112,9 +112,8 @@ const maxAgeUnits = [
}),
},
];
const hotProperty = propertyof<Phases>('hot');
const phaseProperty = (propertyName: keyof HotPhaseInterface) =>
propertyof<HotPhaseInterface>(propertyName);
const hotProperty: keyof Phases = 'hot';
const phaseProperty = (propertyName: keyof HotPhaseInterface) => propertyName;

interface Props {
errors?: PhaseValidationErrors<HotPhaseInterface>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
export { HotPhase } from './hot_phase';
export { WarmPhase } from './warm_phase';
export { ColdPhase } from './cold_phase';
export { FrozenPhase } from './frozen_phase';
export { DeletePhase } from './delete_phase';
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
} from '../components';

import { Phases, WarmPhase as WarmPhaseInterface } from '../../../services/policies/types';
import { PhaseValidationErrors, propertyof } from '../../../services/policies/policy_validation';
import { PhaseValidationErrors } from '../../../services/policies/policy_validation';

const shrinkLabel = i18n.translate('xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel', {
defaultMessage: 'Shrink index',
Expand All @@ -47,9 +47,8 @@ const forcemergeLabel = i18n.translate('xpack.indexLifecycleMgmt.warmPhase.force
defaultMessage: 'Force merge data',
});

const warmProperty = propertyof<Phases>('warm');
const phaseProperty = (propertyName: keyof WarmPhaseInterface) =>
propertyof<WarmPhaseInterface>(propertyName);
const warmProperty: keyof Phases = 'warm';
const phaseProperty = (propertyName: keyof WarmPhaseInterface) => propertyName;

interface Props {
setPhaseData: (key: keyof WarmPhaseInterface & string, value: boolean | string) => void;
Expand Down
Loading