mirror of
https://github.com/ansible/awx.git
synced 2026-05-12 20:07:37 -02:30
Merge pull request #9662 from jakemcdermott/fix-9636
Fix cred type display on form initialization SUMMARY For #9636 and #8828 Reviewed-by: Kersom <None>
This commit is contained in:
@@ -158,7 +158,7 @@ function CredentialEdit({ credential }) {
|
|||||||
}, {});
|
}, {});
|
||||||
return { credentialTypes: creds, loadedInputSources: inputSources };
|
return { credentialTypes: creds, loadedInputSources: inputSources };
|
||||||
}, [credId, me.id]),
|
}, [credId, me.id]),
|
||||||
{ credentialTypes: {}, loadedInputSources: {} }
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -178,7 +178,7 @@ function CredentialEdit({ credential }) {
|
|||||||
return <ContentError error={error} />;
|
return <ContentError error={error} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading || !credentialTypes) {
|
||||||
return <ContentLoading />;
|
return <ContentLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
import { shape } from 'prop-types';
|
import { shape } from 'prop-types';
|
||||||
import { Formik, useField, useFormikContext } from 'formik';
|
import { Formik, useField, useFormikContext } from 'formik';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
@@ -11,6 +12,7 @@ import {
|
|||||||
Select as PFSelect,
|
Select as PFSelect,
|
||||||
SelectOption as PFSelectOption,
|
SelectOption as PFSelectOption,
|
||||||
SelectVariant,
|
SelectVariant,
|
||||||
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import FormField, { FormSubmitError } from '../../../components/FormField';
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
@@ -27,6 +29,7 @@ const Select = styled(PFSelect)`
|
|||||||
ul {
|
ul {
|
||||||
max-width: 495px;
|
max-width: 495px;
|
||||||
}
|
}
|
||||||
|
${props => (props.isDisabled ? `cursor: not-allowed` : null)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SelectOption = styled(PFSelectOption)`
|
const SelectOption = styled(PFSelectOption)`
|
||||||
@@ -35,7 +38,8 @@ const SelectOption = styled(PFSelectOption)`
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function CredentialFormFields({ i18n, credentialTypes }) {
|
function CredentialFormFields({ i18n, initialTypeId, credentialTypes }) {
|
||||||
|
const { pathname } = useLocation();
|
||||||
const { setFieldValue, initialValues, setFieldTouched } = useFormikContext();
|
const { setFieldValue, initialValues, setFieldTouched } = useFormikContext();
|
||||||
const [isSelectOpen, setIsSelectOpen] = useState(false);
|
const [isSelectOpen, setIsSelectOpen] = useState(false);
|
||||||
const [credTypeField, credTypeMeta, credTypeHelpers] = useField({
|
const [credTypeField, credTypeMeta, credTypeHelpers] = useField({
|
||||||
@@ -43,9 +47,10 @@ function CredentialFormFields({ i18n, credentialTypes }) {
|
|||||||
validate: required(i18n._(t`Select a value for this field`), i18n),
|
validate: required(i18n._(t`Select a value for this field`), i18n),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [credentialTypeId, setCredentialTypeId] = useState(initialTypeId);
|
||||||
|
|
||||||
const isGalaxyCredential =
|
const isGalaxyCredential =
|
||||||
!!credTypeField.value &&
|
!!credentialTypeId && credentialTypes[credentialTypeId]?.kind === 'galaxy';
|
||||||
credentialTypes[credTypeField.value]?.kind === 'galaxy';
|
|
||||||
|
|
||||||
const [orgField, orgMeta, orgHelpers] = useField({
|
const [orgField, orgMeta, orgHelpers] = useField({
|
||||||
name: 'organization',
|
name: 'organization',
|
||||||
@@ -67,42 +72,58 @@ function CredentialFormFields({ i18n, credentialTypes }) {
|
|||||||
})
|
})
|
||||||
.sort((a, b) => (a.label.toLowerCase() > b.label.toLowerCase() ? 1 : -1));
|
.sort((a, b) => (a.label.toLowerCase() > b.label.toLowerCase() ? 1 : -1));
|
||||||
|
|
||||||
const resetSubFormFields = newCredentialType => {
|
const resetSubFormFields = useCallback(
|
||||||
const fields = credentialTypes[newCredentialType].inputs.fields || [];
|
newCredentialTypeId => {
|
||||||
fields.forEach(
|
const fields = credentialTypes[newCredentialTypeId].inputs.fields || [];
|
||||||
({ ask_at_runtime, type, id, choices, default: defaultValue }) => {
|
fields.forEach(
|
||||||
if (parseInt(newCredentialType, 10) === initialValues.credential_type) {
|
({ ask_at_runtime, type, id, choices, default: defaultValue }) => {
|
||||||
setFieldValue(`inputs.${id}`, initialValues.inputs[id]);
|
if (parseInt(newCredentialTypeId, 10) === initialTypeId) {
|
||||||
if (ask_at_runtime) {
|
setFieldValue(`inputs.${id}`, initialValues.inputs[id]);
|
||||||
setFieldValue(
|
if (ask_at_runtime) {
|
||||||
`passwordPrompts.${id}`,
|
setFieldValue(
|
||||||
initialValues.passwordPrompts[id]
|
`passwordPrompts.${id}`,
|
||||||
);
|
initialValues.passwordPrompts[id]
|
||||||
}
|
);
|
||||||
} else {
|
}
|
||||||
switch (type) {
|
} else {
|
||||||
case 'string':
|
switch (type) {
|
||||||
setFieldValue(`inputs.${id}`, defaultValue || '');
|
case 'string':
|
||||||
break;
|
setFieldValue(`inputs.${id}`, defaultValue || '');
|
||||||
case 'boolean':
|
break;
|
||||||
setFieldValue(`inputs.${id}`, defaultValue || false);
|
case 'boolean':
|
||||||
break;
|
setFieldValue(`inputs.${id}`, defaultValue || false);
|
||||||
default:
|
break;
|
||||||
break;
|
default:
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (choices) {
|
if (choices) {
|
||||||
setFieldValue(`inputs.${id}`, defaultValue);
|
setFieldValue(`inputs.${id}`, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ask_at_runtime) {
|
if (ask_at_runtime) {
|
||||||
setFieldValue(`passwordPrompts.${id}`, false);
|
setFieldValue(`passwordPrompts.${id}`, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
setFieldTouched(`inputs.${id}`, false);
|
||||||
}
|
}
|
||||||
setFieldTouched(`inputs.${id}`, false);
|
);
|
||||||
}
|
},
|
||||||
);
|
[
|
||||||
};
|
credentialTypes,
|
||||||
|
initialTypeId,
|
||||||
|
initialValues.inputs,
|
||||||
|
initialValues.passwordPrompts,
|
||||||
|
setFieldTouched,
|
||||||
|
setFieldValue,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (credentialTypeId) {
|
||||||
|
resetSubFormFields(credentialTypeId);
|
||||||
|
}
|
||||||
|
}, [resetSubFormFields, credentialTypeId]);
|
||||||
|
|
||||||
const onOrganizationChange = useCallback(
|
const onOrganizationChange = useCallback(
|
||||||
value => {
|
value => {
|
||||||
@@ -111,6 +132,38 @@ function CredentialFormFields({ i18n, credentialTypes }) {
|
|||||||
[setFieldValue]
|
[setFieldValue]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isCredentialTypeDisabled = pathname.includes('edit');
|
||||||
|
const credentialTypeSelect = (
|
||||||
|
<Select
|
||||||
|
isDisabled={isCredentialTypeDisabled}
|
||||||
|
ouiaId="CredentialForm-credential_type"
|
||||||
|
aria-label={i18n._(t`Credential Type`)}
|
||||||
|
isOpen={isSelectOpen}
|
||||||
|
variant={SelectVariant.typeahead}
|
||||||
|
onToggle={setIsSelectOpen}
|
||||||
|
onSelect={(event, value) => {
|
||||||
|
setCredentialTypeId(value);
|
||||||
|
credTypeHelpers.setValue(value);
|
||||||
|
setIsSelectOpen(false);
|
||||||
|
}}
|
||||||
|
selections={credTypeField.value}
|
||||||
|
placeholder={i18n._(t`Select a credential Type`)}
|
||||||
|
isCreatable={false}
|
||||||
|
maxHeight="300px"
|
||||||
|
width="100%"
|
||||||
|
>
|
||||||
|
{credentialTypeOptions.map(credType => (
|
||||||
|
<SelectOption
|
||||||
|
key={credType.value}
|
||||||
|
value={credType.value}
|
||||||
|
dataCy={`${credType.id}-credential-type-select-option`}
|
||||||
|
>
|
||||||
|
{credType.label}
|
||||||
|
</SelectOption>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
<FormField
|
||||||
@@ -147,39 +200,24 @@ function CredentialFormFields({ i18n, credentialTypes }) {
|
|||||||
}
|
}
|
||||||
label={i18n._(t`Credential Type`)}
|
label={i18n._(t`Credential Type`)}
|
||||||
>
|
>
|
||||||
<Select
|
{isCredentialTypeDisabled ? (
|
||||||
ouiaId="CredentialForm-credential_type"
|
<Tooltip
|
||||||
aria-label={i18n._(t`Credential Type`)}
|
content={i18n._(
|
||||||
isOpen={isSelectOpen}
|
`You cannot change the credential type of a credential,
|
||||||
variant={SelectVariant.typeahead}
|
as it may break the functionality of the resources using it.`
|
||||||
onToggle={setIsSelectOpen}
|
)}
|
||||||
onSelect={(event, value) => {
|
>
|
||||||
credTypeHelpers.setValue(value);
|
{credentialTypeSelect}
|
||||||
resetSubFormFields(value);
|
</Tooltip>
|
||||||
setIsSelectOpen(false);
|
) : (
|
||||||
}}
|
credentialTypeSelect
|
||||||
selections={credTypeField.value}
|
)}
|
||||||
placeholder={i18n._(t`Select a credential Type`)}
|
|
||||||
isCreatable={false}
|
|
||||||
maxHeight="300px"
|
|
||||||
width="100%"
|
|
||||||
>
|
|
||||||
{credentialTypeOptions.map(credType => (
|
|
||||||
<SelectOption
|
|
||||||
key={credType.value}
|
|
||||||
value={credType.value}
|
|
||||||
dataCy={`${credType.id}-credential-type-select-option`}
|
|
||||||
>
|
|
||||||
{credType.label}
|
|
||||||
</SelectOption>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
{credTypeField.value !== undefined &&
|
{credentialTypeId !== undefined &&
|
||||||
credTypeField.value !== '' &&
|
credentialTypeId !== '' &&
|
||||||
credentialTypes[credTypeField.value]?.inputs?.fields && (
|
credentialTypes[credentialTypeId]?.inputs?.fields && (
|
||||||
<TypeInputsSubForm
|
<TypeInputsSubForm
|
||||||
credentialType={credentialTypes[credTypeField.value]}
|
credentialType={credentialTypes[credentialTypeId]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -197,12 +235,14 @@ function CredentialForm({
|
|||||||
isOrgLookupDisabled,
|
isOrgLookupDisabled,
|
||||||
...rest
|
...rest
|
||||||
}) {
|
}) {
|
||||||
|
const initialTypeId = credential?.credential_type;
|
||||||
|
|
||||||
const [showExternalTestModal, setShowExternalTestModal] = useState(false);
|
const [showExternalTestModal, setShowExternalTestModal] = useState(false);
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
name: credential.name || '',
|
name: credential.name || '',
|
||||||
description: credential.description || '',
|
description: credential.description || '',
|
||||||
organization: credential?.summary_fields?.organization || null,
|
organization: credential?.summary_fields?.organization || null,
|
||||||
credential_type: credential?.credential_type || '',
|
credential_type: credentialTypes[initialTypeId]?.name || '',
|
||||||
inputs: credential?.inputs || {},
|
inputs: credential?.inputs || {},
|
||||||
passwordPrompts: {},
|
passwordPrompts: {},
|
||||||
isOrgLookupDisabled: isOrgLookupDisabled || false,
|
isOrgLookupDisabled: isOrgLookupDisabled || false,
|
||||||
@@ -253,7 +293,14 @@ function CredentialForm({
|
|||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
onSubmit={values => {
|
onSubmit={values => {
|
||||||
onSubmit(values);
|
const { credential_type, ...actualValues } = values;
|
||||||
|
// credential_type could be the raw id or the displayed name value.
|
||||||
|
// If it's the name, replace it with the id before making the request.
|
||||||
|
actualValues.credential_type =
|
||||||
|
Object.keys(credentialTypes).find(
|
||||||
|
key => credentialTypes[key].name === credential_type
|
||||||
|
) || credential_type;
|
||||||
|
onSubmit(actualValues);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{formik => (
|
{formik => (
|
||||||
@@ -261,6 +308,7 @@ function CredentialForm({
|
|||||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||||
<FormColumnLayout>
|
<FormColumnLayout>
|
||||||
<CredentialFormFields
|
<CredentialFormFields
|
||||||
|
initialTypeId={initialTypeId}
|
||||||
credentialTypes={credentialTypes}
|
credentialTypes={credentialTypes}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|||||||
Reference in New Issue
Block a user