import React from 'react'; import { bool, oneOf, shape, string } from 'prop-types'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import { useField } from 'formik'; import { FormGroup as PFFormGroup, InputGroup, TextInput, Switch, } from '@patternfly/react-core'; import styled from 'styled-components'; import AnsibleSelect from '../../../components/AnsibleSelect'; import CodeMirrorInput from '../../../components/CodeMirrorInput'; import { PasswordInput } from '../../../components/FormField'; import { FormFullWidthLayout } from '../../../components/FormLayout'; import Popover from '../../../components/Popover'; import { combine, required, url, integer, minMaxValue, } from '../../../util/validators'; import RevertButton from './RevertButton'; const FormGroup = styled(PFFormGroup)` .pf-c-form__group-label { display: inline-flex; align-items: center; width: 100%; } `; const SettingGroup = withI18n()( ({ i18n, children, defaultValue, fieldId, helperTextInvalid, isDisabled, isRequired, label, popoverContent, validated, }) => ( } > {children} ) ); const BooleanField = withI18n()( ({ i18n, ariaLabel = '', name, config, disabled = false }) => { const [field, meta, helpers] = useField(name); return config ? ( helpers.setValue(checked)} aria-label={ariaLabel || config.label} /> ) : null; } ); BooleanField.propTypes = { name: string.isRequired, config: shape({}).isRequired, ariaLabel: string, disabled: bool, }; const ChoiceField = withI18n()(({ i18n, name, config, isRequired = false }) => { const validate = isRequired ? required(null, i18n) : null; const [field, meta] = useField({ name, validate }); const isValid = !meta.error || !meta.touched; return config ? ( ({ label, value: value ?? '', key: value ?? index, })), ]} /> ) : null; }); ChoiceField.propTypes = { name: string.isRequired, config: shape({}).isRequired, isRequired: bool, }; const EncryptedField = withI18n()( ({ i18n, name, config, isRequired = false }) => { const validate = isRequired ? required(null, i18n) : null; const [, meta] = useField({ name, validate }); const isValid = !(meta.touched && meta.error); return config ? ( ) : null; } ); EncryptedField.propTypes = { name: string.isRequired, config: shape({}).isRequired, isRequired: bool, }; const InputField = withI18n()( ({ i18n, name, config, type = 'text', isRequired = false }) => { const min_value = config?.min_value ?? Number.MIN_SAFE_INTEGER; const max_value = config?.max_value ?? Number.MAX_SAFE_INTEGER; const validators = [ ...(isRequired ? [required(null, i18n)] : []), ...(type === 'url' ? [url(i18n)] : []), ...(type === 'number' ? [integer(i18n), minMaxValue(min_value, max_value, i18n)] : []), ]; const [field, meta] = useField({ name, validate: combine(validators) }); const isValid = !(meta.touched && meta.error); return config ? ( { field.onChange(event); }} /> ) : null; } ); InputField.propTypes = { name: string.isRequired, config: shape({}).isRequired, type: oneOf(['text', 'number', 'url']), isRequired: bool, }; const ObjectField = withI18n()(({ i18n, name, config, isRequired = false }) => { const validate = isRequired ? required(null, i18n) : null; const [field, meta, helpers] = useField({ name, validate }); const isValid = !(meta.touched && meta.error); const emptyDefault = config?.type === 'list' ? '[]' : '{}'; const defaultRevertValue = config?.default ? JSON.stringify(config.default, null, 2) : emptyDefault; return config ? ( { helpers.setValue(value); }} mode="javascript" /> ) : null; }); ObjectField.propTypes = { name: string.isRequired, config: shape({}).isRequired, isRequired: bool, }; export { BooleanField, ChoiceField, EncryptedField, InputField, ObjectField };