Merge pull request #11107 from kialam/fix-10785-ee-revert-button

Wrap ExecutionEnv Lookup in SettingGroup component.
This commit is contained in:
kialam
2021-09-23 14:17:45 -04:00
committed by GitHub
6 changed files with 46 additions and 52 deletions

View File

@@ -24,9 +24,7 @@ function ExecutionEnvironmentLookup({
id, id,
globallyAvailable, globallyAvailable,
helperTextInvalid, helperTextInvalid,
isDefaultEnvironment,
isDisabled, isDisabled,
isGlobalDefaultEnvironment,
isValid, isValid,
onBlur, onBlur,
onChange, onChange,
@@ -37,9 +35,9 @@ function ExecutionEnvironmentLookup({
validate, validate,
value, value,
fieldName, fieldName,
overrideLabel,
}) { }) {
const location = useLocation(); const location = useLocation();
const { const {
request: fetchProject, request: fetchProject,
error: fetchProjectError, error: fetchProjectError,
@@ -198,15 +196,9 @@ function ExecutionEnvironmentLookup({
</> </>
); );
const renderLabel = ( const renderLabel = () => {
globalDefaultEnvironment, if (overrideLabel) {
defaultExecutionEnvironment return null;
) => {
if (globalDefaultEnvironment) {
return t`Global Default Execution Environment`;
}
if (defaultExecutionEnvironment) {
return t`Default Execution Environment`;
} }
return t`Execution Environment`; return t`Execution Environment`;
}; };
@@ -214,7 +206,7 @@ function ExecutionEnvironmentLookup({
return ( return (
<FormGroup <FormGroup
fieldId={id} fieldId={id}
label={renderLabel(isGlobalDefaultEnvironment, isDefaultEnvironment)} label={renderLabel()}
labelIcon={popoverContent && <Popover content={popoverContent} />} labelIcon={popoverContent && <Popover content={popoverContent} />}
helperTextInvalid={helperTextInvalid} helperTextInvalid={helperTextInvalid}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
@@ -235,24 +227,22 @@ ExecutionEnvironmentLookup.propTypes = {
value: ExecutionEnvironment, value: ExecutionEnvironment,
popoverContent: string, popoverContent: string,
onChange: func.isRequired, onChange: func.isRequired,
isDefaultEnvironment: bool,
isGlobalDefaultEnvironment: bool,
projectId: oneOfType([number, string]), projectId: oneOfType([number, string]),
organizationId: oneOfType([number, string]), organizationId: oneOfType([number, string]),
validate: func, validate: func,
fieldName: string, fieldName: string,
overrideLabel: bool,
}; };
ExecutionEnvironmentLookup.defaultProps = { ExecutionEnvironmentLookup.defaultProps = {
id: 'execution-environments', id: 'execution-environments',
popoverContent: '', popoverContent: '',
isDefaultEnvironment: false,
isGlobalDefaultEnvironment: false,
value: null, value: null,
projectId: null, projectId: null,
organizationId: null, organizationId: null,
validate: () => undefined, validate: () => undefined,
fieldName: 'execution_environment', fieldName: 'execution_environment',
overrideLabel: false,
}; };
export default ExecutionEnvironmentLookup; export default ExecutionEnvironmentLookup;

View File

@@ -54,7 +54,6 @@ describe('ExecutionEnvironmentLookup', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<Formik> <Formik>
<ExecutionEnvironmentLookup <ExecutionEnvironmentLookup
isDefaultEnvironment
value={executionEnvironment} value={executionEnvironment}
onChange={() => {}} onChange={() => {}}
/> />
@@ -64,12 +63,9 @@ describe('ExecutionEnvironmentLookup', () => {
wrapper.update(); wrapper.update();
expect(ExecutionEnvironmentsAPI.read).toHaveBeenCalledTimes(1); expect(ExecutionEnvironmentsAPI.read).toHaveBeenCalledTimes(1);
expect(wrapper.find('ExecutionEnvironmentLookup')).toHaveLength(1); expect(wrapper.find('ExecutionEnvironmentLookup')).toHaveLength(1);
expect(
wrapper.find('FormGroup[label="Default Execution Environment"]').length
).toBe(1);
expect( expect(
wrapper.find('FormGroup[label="Execution Environment"]').length wrapper.find('FormGroup[label="Execution Environment"]').length
).toBe(0); ).toBe(1);
}); });
test('should fetch execution environments', async () => { test('should fetch execution environments', async () => {

View File

@@ -54,7 +54,6 @@ function Lookup(props) {
} = props; } = props;
const [typedText, setTypedText] = useState(''); const [typedText, setTypedText] = useState('');
const debounceRequest = useDebounce(onDebounce, 1000); const debounceRequest = useDebounce(onDebounce, 1000);
useField({ useField({
name: fieldName, name: fieldName,
validate: (val) => { validate: (val) => {
@@ -79,6 +78,8 @@ function Lookup(props) {
dispatch({ type: 'SET_VALUE', value }); dispatch({ type: 'SET_VALUE', value });
if (value?.name) { if (value?.name) {
setTypedText(value.name); setTypedText(value.name);
} else {
setTypedText('');
} }
}, [value, multiple]); }, [value, multiple]);

View File

@@ -1,6 +1,5 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { t } from '@lingui/macro';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { Form } from '@patternfly/react-core'; import { Form } from '@patternfly/react-core';
import { CardBody } from 'components/Card'; import { CardBody } from 'components/Card';
@@ -8,7 +7,6 @@ import ContentError from 'components/ContentError';
import ContentLoading from 'components/ContentLoading'; import ContentLoading from 'components/ContentLoading';
import { FormSubmitError } from 'components/FormField'; import { FormSubmitError } from 'components/FormField';
import { FormColumnLayout } from 'components/FormLayout'; import { FormColumnLayout } from 'components/FormLayout';
import { ExecutionEnvironmentLookup } from 'components/Lookup';
import { useSettings } from 'contexts/Settings'; import { useSettings } from 'contexts/Settings';
import useModal from 'hooks/useModal'; import useModal from 'hooks/useModal';
import useRequest from 'hooks/useRequest'; import useRequest from 'hooks/useRequest';
@@ -16,6 +14,7 @@ import { SettingsAPI, ExecutionEnvironmentsAPI } from 'api';
import { import {
BooleanField, BooleanField,
EncryptedField, EncryptedField,
ExecutionEnvField,
InputField, InputField,
ObjectField, ObjectField,
RevertAllAlert, RevertAllAlert,
@@ -174,32 +173,9 @@ function MiscSystemEdit() {
name="ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC" name="ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC"
config={system.ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC} config={system.ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC}
/> />
<ExecutionEnvironmentLookup <ExecutionEnvField
helperTextInvalid={ name="DEFAULT_EXECUTION_ENVIRONMENT"
formik.errors.DEFAULT_EXECUTION_ENVIRONMENT config={system.DEFAULT_EXECUTION_ENVIRONMENT}
}
isValid={
!formik.touched.DEFAULT_EXECUTION_ENVIRONMENT ||
!formik.errors.DEFAULT_EXECUTION_ENVIRONMENT
}
onBlur={() =>
formik.setFieldTouched('DEFAULT_EXECUTION_ENVIRONMENT')
}
value={formik.values.DEFAULT_EXECUTION_ENVIRONMENT}
onChange={(value) => {
formik.setFieldValue(
'DEFAULT_EXECUTION_ENVIRONMENT',
value
);
formik.setFieldTouched(
'DEFAULT_EXECUTION_ENVIRONMENT',
true,
false
);
}}
popoverContent={t`The Execution Environment to be used when one has not been configured for a job template.`}
isGlobalDefaultEnvironment
fieldName="DEFAULT_EXECUTION_ENVIRONMENT"
/> />
<InputField <InputField
name="TOWER_URL_BASE" name="TOWER_URL_BASE"

View File

@@ -17,6 +17,7 @@ import FileUploadIcon from '@patternfly/react-icons/dist/js/icons/file-upload-ic
import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons'; import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons';
import styled from 'styled-components'; import styled from 'styled-components';
import AnsibleSelect from 'components/AnsibleSelect'; import AnsibleSelect from 'components/AnsibleSelect';
import { ExecutionEnvironmentLookup } from 'components/Lookup';
import CodeEditor from 'components/CodeEditor'; import CodeEditor from 'components/CodeEditor';
import { PasswordInput } from 'components/FormField'; import { PasswordInput } from 'components/FormField';
import { FormFullWidthLayout } from 'components/FormLayout'; import { FormFullWidthLayout } from 'components/FormLayout';
@@ -229,6 +230,35 @@ EncryptedField.propTypes = {
config: shape({}).isRequired, config: shape({}).isRequired,
}; };
const ExecutionEnvField = ({ name, config, isRequired = false }) => {
const [field, meta, helpers] = useField({ name });
return config ? (
<SettingGroup
defaultValue={config.default ?? ''}
fieldId={name}
helperTextInvalid={meta.error}
isRequired={isRequired}
label={config.label}
popoverContent={config.help_text}
isDisabled={field.value === null}
onRevertCallback={() => helpers.setValue(config.default)}
>
<ExecutionEnvironmentLookup
value={field.value}
onChange={(value) => {
helpers.setValue(value, false);
}}
overrideLabel
fieldName={name}
/>
</SettingGroup>
) : null;
};
ExecutionEnvField.propTypes = {
name: string.isRequired,
config: shape({}).isRequired,
};
const InputAlertField = ({ name, config }) => { const InputAlertField = ({ name, config }) => {
const [field, meta] = useField({ name }); const [field, meta] = useField({ name });
const isValid = !(meta.touched && meta.error); const isValid = !(meta.touched && meta.error);
@@ -341,7 +371,6 @@ const InputField = ({ name, config, type = 'text', isRequired = false }) => {
]; ];
const [field, meta] = useField({ name, validate: combine(validators) }); const [field, meta] = useField({ name, validate: combine(validators) });
const isValid = !(meta.touched && meta.error); const isValid = !(meta.touched && meta.error);
return config ? ( return config ? (
<SettingGroup <SettingGroup
defaultValue={config.default ?? ''} defaultValue={config.default ?? ''}
@@ -517,6 +546,7 @@ export {
BooleanField, BooleanField,
ChoiceField, ChoiceField,
EncryptedField, EncryptedField,
ExecutionEnvField,
FileUploadField, FileUploadField,
InputField, InputField,
ObjectField, ObjectField,

View File

@@ -5,6 +5,7 @@ export {
BooleanField, BooleanField,
ChoiceField, ChoiceField,
EncryptedField, EncryptedField,
ExecutionEnvField,
InputField, InputField,
ObjectField, ObjectField,
InputAlertField, InputAlertField,