From 63d1e571f007a646a05c1eaeecc5a3f54072b01f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 8 Dec 2020 08:47:26 +0100 Subject: [PATCH] [ILM] Reposition form toggles (#85143) * merged toggleable field and described form component and moved toggle to left * moved all toggles to left, renamed DescribedFormField -> DescribedFormRow and added new ToggleFieldWithDescribedFormRow component * added new prop fieldNotices to render callouts in correct position on the left --- .../components/described_form_field.tsx | 33 ------- .../described_form_row/described_form_row.tsx | 95 +++++++++++++++++++ .../components/described_form_row/index.ts | 9 ++ .../toggle_field_with_described_form_row.tsx | 39 ++++++++ .../sections/edit_policy/components/index.ts | 2 +- .../phases/cold_phase/cold_phase.tsx | 29 +++--- .../components/phases/hot_phase/hot_phase.tsx | 29 ++---- .../phases/shared_fields/forcemerge_field.tsx | 6 +- .../searchable_snapshot_field.tsx | 8 +- .../phases/warm_phase/warm_phase.tsx | 10 +- .../components/toggleable_field.tsx | 47 --------- 11 files changed, 179 insertions(+), 128 deletions(-) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_field.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/index.ts create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/toggle_field_with_described_form_row.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/toggleable_field.tsx diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_field.tsx deleted file mode 100644 index f5d13a443c883..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_field.tsx +++ /dev/null @@ -1,33 +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 { EuiDescribedFormGroup, EuiDescribedFormGroupProps } from '@elastic/eui'; - -import { ToggleableField, Props as ToggleableFieldProps } from './toggleable_field'; - -type Props = EuiDescribedFormGroupProps & { - children: (() => JSX.Element) | JSX.Element | JSX.Element[] | undefined; - switchProps?: Omit; -}; - -export const DescribedFormField: FunctionComponent = ({ - children, - switchProps, - ...restDescribedFormProps -}) => { - return ( - - {switchProps ? ( - {children} - ) : typeof children === 'function' ? ( - children() - ) : ( - children - )} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx new file mode 100644 index 0000000000000..98c63437659fd --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx @@ -0,0 +1,95 @@ +/* + * 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 { + EuiDescribedFormGroup, + EuiDescribedFormGroupProps, + EuiSwitchProps, + EuiSwitch, + EuiSpacer, +} from '@elastic/eui'; + +export interface SwitchProps + extends Omit { + /** + * use initialValue to specify an uncontrolled component + */ + initialValue?: boolean; + + /** + * checked and onChange together specify a controlled component + */ + checked?: boolean; + onChange?: (nextValue: boolean) => void; +} + +export type Props = EuiDescribedFormGroupProps & { + children: (() => JSX.Element) | JSX.Element | JSX.Element[] | undefined; + + switchProps?: SwitchProps; + + /** + * Use this prop to pass down components that should be rendered below the toggle like + * warnings or notices. + */ + fieldNotices?: React.ReactNode; +}; + +export const DescribedFormRow: FunctionComponent = ({ + children, + switchProps, + description, + fieldNotices, + ...restDescribedFormProps +}) => { + if ( + switchProps && + !(typeof switchProps.checked === 'boolean' || typeof switchProps.initialValue === 'boolean') + ) { + throw new Error('Must specify controlled, uncontrolled component. See SwitchProps interface!'); + } + const [uncontrolledIsContentVisible, setUncontrolledIsContentVisible] = useState( + () => switchProps?.initialValue ?? false + ); + const isContentVisible = Boolean(switchProps?.checked ?? uncontrolledIsContentVisible); + + const renderToggle = () => { + if (!switchProps) { + return null; + } + const { onChange, checked, initialValue, ...restSwitchProps } = switchProps; + + return ( + { + const nextValue = e.target.checked; + setUncontrolledIsContentVisible(nextValue); + if (onChange) { + onChange(nextValue); + } + }} + /> + ); + }; + return ( + + {description} + + {renderToggle()} + {fieldNotices} + + } + > + {isContentVisible ? (typeof children === 'function' ? children() : children) : null} + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/index.ts new file mode 100644 index 0000000000000..89b77a213215e --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { DescribedFormRow } from './described_form_row'; + +export { ToggleFieldWithDescribedFormRow } from './toggle_field_with_described_form_row'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/toggle_field_with_described_form_row.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/toggle_field_with_described_form_row.tsx new file mode 100644 index 0000000000000..779dbe47914a1 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/toggle_field_with_described_form_row.tsx @@ -0,0 +1,39 @@ +/* + * 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 { UseField } from '../../../../../shared_imports'; + +import { + DescribedFormRow, + Props as DescribedFormRowProps, + SwitchProps, +} from './described_form_row'; + +type Props = Omit & { + switchProps: Omit & { path: string }; +}; + +export const ToggleFieldWithDescribedFormRow: FunctionComponent = ({ + switchProps, + ...passThroughProps +}) => ( + path={switchProps.path}> + {(field) => { + return ( + + ); + }} + +); 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 265996c650024..fa550214db477 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 @@ -9,7 +9,7 @@ export { ErrableFormRow } from './form_errors'; export { LearnMoreLink } from './learn_more_link'; export { OptionalLabel } from './optional_label'; export { PolicyJsonFlyout } from './policy_json_flyout'; -export { DescribedFormField } from './described_form_field'; +export { DescribedFormRow, ToggleFieldWithDescribedFormRow } from './described_form_row'; export { FieldLoadingError } from './field_loading_error'; 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 2f5be3e45cbe7..addad5e572b70 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 @@ -18,7 +18,12 @@ import { useFormData, UseField, ToggleField, NumericField } from '../../../../.. import { useEditPolicyContext } from '../../../edit_policy_context'; import { useConfigurationIssues } from '../../../form'; -import { LearnMoreLink, ActiveBadge, DescribedFormField } from '../../'; +import { + LearnMoreLink, + ActiveBadge, + DescribedFormRow, + ToggleFieldWithDescribedFormRow, +} from '../../'; import { MinAgeInputField, @@ -115,7 +120,7 @@ export const ColdPhase: FunctionComponent = () => { { /* Replicas section */ showReplicasField && ( - {i18n.translate('xpack.indexLifecycleMgmt.coldPhase.replicasTitle', { @@ -153,13 +158,13 @@ export const ColdPhase: FunctionComponent = () => { }, }} /> - + ) } {/* Freeze section */} {!isUsingSearchableSnapshotInHotPhase && ( - { } fullWidth titleSize="xs" + switchProps={{ + 'data-test-subj': 'freezeSwitch', + path: '_meta.cold.freezeEnabled', + }} > - - +
+ )} {/* Data tier allocation section */} { })} paddingSize="m" > - {i18n.translate('xpack.indexLifecycleMgmt.hotPhase.rolloverFieldTitle', { @@ -123,19 +117,12 @@ export const HotPhase: FunctionComponent = () => {

} + switchProps={{ + path: '_meta.hot.useRollover', + 'data-test-subj': 'rolloverSwitch', + }} fullWidth > - - key="_meta.hot.useRollover" - path="_meta.hot.useRollover" - component={ToggleField} - componentProps={{ - fullWidth: false, - euiFieldProps: { - 'data-test-subj': 'rolloverSwitch', - }, - }} - /> {isRolloverEnabled && ( <> @@ -246,7 +233,7 @@ export const HotPhase: FunctionComponent = () => { )} -
+ {license.canUseSearchableSnapshot() && } {isRolloverEnabled && !isUsingSearchableSnapshotInHotPhase && ( 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 fb7f93a42e491..dd5cc1fbc8c87 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 @@ -14,7 +14,7 @@ import { i18nTexts } from '../../../i18n_texts'; import { useEditPolicyContext } from '../../../edit_policy_context'; -import { LearnMoreLink, DescribedFormField } from '../../'; +import { LearnMoreLink, DescribedFormRow } from '../../'; interface Props { phase: 'hot' | 'warm'; @@ -28,7 +28,7 @@ export const ForcemergeField: React.FunctionComponent = ({ phase }) => { }, [policy, phase]); return ( - = ({ 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 e5ab5fb6a2c71..38eb743075411 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 @@ -29,7 +29,7 @@ import { useConfigurationIssues } from '../../../../form'; import { i18nTexts } from '../../../../i18n_texts'; -import { FieldLoadingError, DescribedFormField, LearnMoreLink } from '../../../index'; +import { FieldLoadingError, DescribedFormRow, LearnMoreLink } from '../../../index'; import { SearchableSnapshotDataProvider } from './searchable_snapshot_data_provider'; @@ -297,7 +297,7 @@ export const SearchableSnapshotField: FunctionComponent = ({ phase }) => }; return ( - = ({ phase }) => }} /> - {renderInfoCallout()} } + fieldNotices={renderInfoCallout()} fullWidth > {isDisabled ?
: renderField} - + ); }; 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 604a36c2d08e4..9ccfcd58f4d85 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 @@ -25,7 +25,7 @@ import { Phases } from '../../../../../../../common/types'; import { useEditPolicyContext } from '../../../edit_policy_context'; import { useConfigurationIssues } from '../../../form'; -import { LearnMoreLink, ActiveBadge, DescribedFormField } from '../../'; +import { LearnMoreLink, ActiveBadge, DescribedFormRow } from '../../'; import { useRolloverPath, @@ -141,7 +141,7 @@ export const WarmPhase: FunctionComponent = () => { )} paddingSize="m" > - {i18n.translate('xpack.indexLifecycleMgmt.warmPhase.replicasTitle', { @@ -177,9 +177,9 @@ export const WarmPhase: FunctionComponent = () => { }, }} /> - + {!isUsingSearchableSnapshotInHotPhase && ( - {
-
+ )} {!isUsingSearchableSnapshotInHotPhase && } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/toggleable_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/toggleable_field.tsx deleted file mode 100644 index fb5e636902780..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/toggleable_field.tsx +++ /dev/null @@ -1,47 +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, useState } from 'react'; -import { EuiSpacer, EuiSwitch, EuiSwitchProps } from '@elastic/eui'; - -export interface Props extends Omit { - children: (() => JSX.Element) | JSX.Element | JSX.Element[] | undefined; - checked?: boolean; - initialValue?: boolean; - onChange?: (nextValue: boolean) => void; -} - -export const ToggleableField: FunctionComponent = ({ - initialValue, - checked, - onChange, - children, - ...restProps -}) => { - const [uncontrolledIsContentVisible, setUncontrolledIsContentVisible] = useState( - initialValue ?? false - ); - - const isContentVisible = Boolean(checked ?? uncontrolledIsContentVisible); - - return ( - <> - { - const nextValue = e.target.checked; - setUncontrolledIsContentVisible(nextValue); - if (onChange) { - onChange(nextValue); - } - }} - /> - - {isContentVisible ? (typeof children === 'function' ? children() : children) : null} - - ); -};