Skip to content

Commit

Permalink
[ILM] Reposition form toggles (elastic#85143)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jloleysens committed Dec 8, 2020
1 parent 7367b17 commit 63d1e57
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 128 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<EuiSwitchProps, 'children' | 'checked' | 'value' | 'onChange'> {
/**
* 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<Props> = ({
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<boolean>(
() => switchProps?.initialValue ?? false
);
const isContentVisible = Boolean(switchProps?.checked ?? uncontrolledIsContentVisible);

const renderToggle = () => {
if (!switchProps) {
return null;
}
const { onChange, checked, initialValue, ...restSwitchProps } = switchProps;

return (
<EuiSwitch
{...restSwitchProps}
checked={isContentVisible}
onChange={(e) => {
const nextValue = e.target.checked;
setUncontrolledIsContentVisible(nextValue);
if (onChange) {
onChange(nextValue);
}
}}
/>
);
};
return (
<EuiDescribedFormGroup
{...restDescribedFormProps}
description={
<>
{description}
<EuiSpacer size="m" />
{renderToggle()}
{fieldNotices}
</>
}
>
{isContentVisible ? (typeof children === 'function' ? children() : children) : null}
</EuiDescribedFormGroup>
);
};
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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<DescribedFormRowProps, 'switchProps'> & {
switchProps: Omit<SwitchProps, 'label'> & { path: string };
};

export const ToggleFieldWithDescribedFormRow: FunctionComponent<Props> = ({
switchProps,
...passThroughProps
}) => (
<UseField<boolean> path={switchProps.path}>
{(field) => {
return (
<DescribedFormRow
{...passThroughProps}
switchProps={{
...switchProps,
label: field.label,
checked: field.value,
onChange: field.setValue,
}}
/>
);
}}
</UseField>
);
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -115,7 +120,7 @@ export const ColdPhase: FunctionComponent = () => {
{
/* Replicas section */
showReplicasField && (
<DescribedFormField
<DescribedFormRow
title={
<h3>
{i18n.translate('xpack.indexLifecycleMgmt.coldPhase.replicasTitle', {
Expand Down Expand Up @@ -153,13 +158,13 @@ export const ColdPhase: FunctionComponent = () => {
},
}}
/>
</DescribedFormField>
</DescribedFormRow>
)
}

{/* Freeze section */}
{!isUsingSearchableSnapshotInHotPhase && (
<EuiDescribedFormGroup
<ToggleFieldWithDescribedFormRow
title={
<h3>
<FormattedMessage
Expand All @@ -179,17 +184,13 @@ export const ColdPhase: FunctionComponent = () => {
}
fullWidth
titleSize="xs"
switchProps={{
'data-test-subj': 'freezeSwitch',
path: '_meta.cold.freezeEnabled',
}}
>
<UseField
path="_meta.cold.freezeEnabled"
component={ToggleField}
componentProps={{
euiFieldProps: {
'data-test-subj': 'freezeSwitch',
},
}}
/>
</EuiDescribedFormGroup>
<div />
</ToggleFieldWithDescribedFormRow>
)}
{/* Data tier allocation section */}
<DataTierAllocationField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,7 @@ import {

import { Phases } from '../../../../../../../common/types';

import {
useFormData,
UseField,
SelectField,
ToggleField,
NumericField,
} from '../../../../../../shared_imports';
import { useFormData, UseField, SelectField, NumericField } from '../../../../../../shared_imports';

import { i18nTexts } from '../../../i18n_texts';

Expand All @@ -36,7 +30,7 @@ import { useEditPolicyContext } from '../../../edit_policy_context';

import { ROLLOVER_FORM_PATHS } from '../../../constants';

import { LearnMoreLink, ActiveBadge, DescribedFormField } from '../../';
import { LearnMoreLink, ActiveBadge, ToggleFieldWithDescribedFormRow } from '../../';

import {
ForcemergeField,
Expand Down Expand Up @@ -95,7 +89,7 @@ export const HotPhase: FunctionComponent = () => {
})}
paddingSize="m"
>
<DescribedFormField
<ToggleFieldWithDescribedFormRow
title={
<h3>
{i18n.translate('xpack.indexLifecycleMgmt.hotPhase.rolloverFieldTitle', {
Expand Down Expand Up @@ -123,19 +117,12 @@ export const HotPhase: FunctionComponent = () => {
</p>
</EuiTextColor>
}
switchProps={{
path: '_meta.hot.useRollover',
'data-test-subj': 'rolloverSwitch',
}}
fullWidth
>
<UseField<boolean>
key="_meta.hot.useRollover"
path="_meta.hot.useRollover"
component={ToggleField}
componentProps={{
fullWidth: false,
euiFieldProps: {
'data-test-subj': 'rolloverSwitch',
},
}}
/>
{isRolloverEnabled && (
<>
<EuiSpacer size="m" />
Expand Down Expand Up @@ -246,7 +233,7 @@ export const HotPhase: FunctionComponent = () => {
</EuiFlexGroup>
</>
)}
</DescribedFormField>
</ToggleFieldWithDescribedFormRow>
{license.canUseSearchableSnapshot() && <SearchableSnapshotField phase="hot" />}
{isRolloverEnabled && !isUsingSearchableSnapshotInHotPhase && (
<ForcemergeField phase="hot" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -28,7 +28,7 @@ export const ForcemergeField: React.FunctionComponent<Props> = ({ phase }) => {
}, [policy, phase]);

return (
<DescribedFormField
<DescribedFormRow
title={
<h3>
<FormattedMessage
Expand Down Expand Up @@ -82,6 +82,6 @@ export const ForcemergeField: React.FunctionComponent<Props> = ({ phase }) => {
}}
/>
</div>
</DescribedFormField>
</DescribedFormRow>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -297,7 +297,7 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({ phase }) =>
};

return (
<DescribedFormField
<DescribedFormRow
data-test-subj={`searchableSnapshotField-${phase}`}
switchProps={{
checked: isFieldToggleChecked,
Expand Down Expand Up @@ -327,12 +327,12 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({ phase }) =>
}}
/>
</EuiTextColor>
{renderInfoCallout()}
</>
}
fieldNotices={renderInfoCallout()}
fullWidth
>
{isDisabled ? <div /> : renderField}
</DescribedFormField>
</DescribedFormRow>
);
};
Loading

0 comments on commit 63d1e57

Please sign in to comment.