diff --git a/awx/ui_next/src/components/FormField/FormField.jsx b/awx/ui_next/src/components/FormField/FormField.jsx
index 3bb6333339..b92d111c2f 100644
--- a/awx/ui_next/src/components/FormField/FormField.jsx
+++ b/awx/ui_next/src/components/FormField/FormField.jsx
@@ -29,6 +29,7 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
+ validated={isValid ? 'default' : 'error'}
label={label}
labelIcon={}
>
diff --git a/awx/ui_next/src/components/FormField/index.js b/awx/ui_next/src/components/FormField/index.js
index 63e127bcf1..bd1e65ef92 100644
--- a/awx/ui_next/src/components/FormField/index.js
+++ b/awx/ui_next/src/components/FormField/index.js
@@ -4,4 +4,3 @@ export { default as PasswordField } from './PasswordField';
export { default as PasswordInput } from './PasswordInput';
export { default as FormSubmitError } from './FormSubmitError';
export { default as ArrayTextField } from './ArrayTextField';
-export { default as TextAndCheckboxField } from './TextAndCheckboxField';
diff --git a/awx/ui_next/src/components/FormField/TextAndCheckboxField.jsx b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.jsx
similarity index 71%
rename from awx/ui_next/src/components/FormField/TextAndCheckboxField.jsx
rename to awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.jsx
index 3141b74408..b3f3a8689a 100644
--- a/awx/ui_next/src/components/FormField/TextAndCheckboxField.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.jsx
@@ -9,16 +9,16 @@ import {
} from '@patternfly/react-core';
import PFCheckIcon from '@patternfly/react-icons/dist/js/icons/check-icon';
import styled from 'styled-components';
-import Popover from '../Popover';
+import Popover from '../../../components/Popover';
const InputGroup = styled(PFInputGroup)`
padding-bottom: 5px;
`;
+
const CheckIcon = styled(PFCheckIcon)`
color: var(--pf-c-button--m-plain--disabled--Color);
${props =>
- props.isSelected &&
- `color: var(--pf-c-button--m-secondary--active--Color)`};
+ props.selected && `color: var(--pf-c-button--m-secondary--active--Color)`};
`;
const validate = () => {
@@ -33,7 +33,7 @@ const validate = () => {
return message;
};
};
-function TextAndCheckboxField({ label, tooltip }) {
+function MultipleChoiceField({ label, tooltip }) {
const [
formattedChoicesField,
formattedChoicesMeta,
@@ -50,6 +50,8 @@ function TextAndCheckboxField({ label, tooltip }) {
}
>
- {formattedChoicesField.value.map(({ choice, isDefault }, i) => (
-
+ {formattedChoicesField.value.map(({ choice, isDefault, id }, i) => (
+
{
if (
e.key === 'Enter' &&
@@ -78,6 +80,7 @@ function TextAndCheckboxField({ label, tooltip }) {
formattedChoicesField.value.concat({
choice: '',
isDefault: false,
+ id: i + 1,
})
);
}
@@ -96,36 +99,51 @@ function TextAndCheckboxField({ label, tooltip }) {
}}
value={choice}
onChange={value => {
- const newValues = formattedChoicesField.value.map((cfv, index) =>
- i === index ? { choice: value, isDefault: false } : cfv
+ const newValues = formattedChoicesField.value.map(
+ (choiceField, index) =>
+ i === index
+ ? { choice: value, isDefault: false, id: choiceField.id }
+ : choiceField
);
formattedChoicesHelpers.setValue(newValues);
}}
/>
-
))}
@@ -133,4 +151,4 @@ function TextAndCheckboxField({ label, tooltip }) {
);
}
-export default TextAndCheckboxField;
+export default MultipleChoiceField;
diff --git a/awx/ui_next/src/components/FormField/TextAndCheckboxField.test.jsx b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx
similarity index 74%
rename from awx/ui_next/src/components/FormField/TextAndCheckboxField.test.jsx
rename to awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx
index c420aca772..476506f180 100644
--- a/awx/ui_next/src/components/FormField/TextAndCheckboxField.test.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/MultipleChoiceField.test.jsx
@@ -1,10 +1,10 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Formik } from 'formik';
-import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
-import TextAndCheckboxField from './TextAndCheckboxField';
+import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
+import MultipleChoiceField from './MultipleChoiceField';
-describe('', () => {
+describe('', () => {
test('should activate default values, multiselect', async () => {
let wrapper;
@@ -20,7 +20,7 @@ describe('', () => {
type: 'multiselect',
}}
>
-
+
);
});
@@ -29,7 +29,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -37,22 +37,22 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onKeyUp')({ key: 'Enter' })
);
wrapper.update();
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
3
);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(2)
.prop('onChange')('spencer')
@@ -65,7 +65,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="spencer"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -73,7 +73,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
});
@@ -85,14 +85,14 @@ describe('', () => {
-
+
);
});
@@ -101,7 +101,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -109,14 +109,14 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
3
);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onKeyUp')({ key: 'Enter' })
@@ -124,7 +124,7 @@ describe('', () => {
wrapper.update();
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(2)
.prop('onChange')('spencer')
@@ -138,13 +138,13 @@ describe('', () => {
wrapper
.find('Button[ouiaId="spencer"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
expect(
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
});
});
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionAdd.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionAdd.jsx
index bbde906cff..f7a7c9d289 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionAdd.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionAdd.jsx
@@ -37,18 +37,11 @@ export default function SurveyQuestionAdd({ survey, updateSurvey }) {
: defaultAnswers.concat(`${choice}\n`);
}
});
- formData.default = defaultAnswers;
- formData.choices = choices;
+ formData.default = defaultAnswers.trim();
+ formData.choices = choices.trim();
}
delete formData.formattedChoices;
- if (formData.type === 'multiselect') {
- formData.default = formData.default
- .split('\n')
- .filter(v => v !== '' || '\n')
- .map(v => v.trim())
- .join('\n');
- }
const newSpec = survey.spec ? survey.spec.concat(formData) : [formData];
await updateSurvey(newSpec);
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.jsx
index 31c05240c3..16e0df584d 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionEdit.jsx
@@ -74,8 +74,8 @@ export default function SurveyQuestionEdit({ survey, updateSurvey }) {
: defaultAnswers.concat(`${choice}\n`);
}
});
- submittedData.default = defaultAnswers;
- submittedData.choices = choices;
+ submittedData.default = defaultAnswers.trim();
+ submittedData.choices = choices.trim();
}
await updateSurvey([
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.jsx
index ec245b2afb..b3c82cf6de 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.jsx
@@ -9,7 +9,6 @@ import FormField, {
CheckboxField,
PasswordField,
FormSubmitError,
- TextAndCheckboxField,
} from '../../../components/FormField';
import { useConfig } from '../../../contexts/Config';
import getDocsBaseUrl from '../../../util/getDocsBaseUrl';
@@ -23,6 +22,7 @@ import {
integer,
number as numberValidator,
} from '../../../util/validators';
+import MultipleChoiceField from './MultipleChoiceField';
function AnswerTypeField() {
const [field] = useField({
@@ -86,16 +86,16 @@ function SurveyQuestionForm({
max: question?.max || 1024,
default: question?.default || '',
choices: question?.choices || '',
- formattedChoices: [{ choice: '', isDefault: false }],
+ formattedChoices: [{ choice: '', isDefault: false, id: 0 }],
new_question: !question,
};
if (question?.type === 'multiselect' || question?.type === 'multiplechoice') {
- const newQuestions = question.choices.split('\n').map(c => {
+ const newQuestions = question.choices.split('\n').map((c, i) => {
if (question.default.split('\n').includes(c)) {
- return { choice: c, isDefault: true };
+ return { choice: c, isDefault: true, id: i };
}
- return { choice: c, isDefault: false };
+ return { choice: c, isDefault: false, id: i };
});
initialValues = {
@@ -218,11 +218,8 @@ function SurveyQuestionForm({
/>
)}
{['multiplechoice', 'multiselect'].includes(formik.values.type) && (
-
{t`Refer to the`}
@@ -236,7 +233,6 @@ function SurveyQuestionForm({
{t`for more information.`}
>
}
- isRequired
/>
)}
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.test.jsx
index 92b955a3fe..3318d4393b 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.test.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyQuestionForm.test.jsx
@@ -149,13 +149,13 @@ describe('', () => {
});
await selectType(wrapper, 'multiplechoice');
- expect(wrapper.find('TextAndCheckboxField').length).toBe(1);
- expect(wrapper.find('TextAndCheckboxField').find('TextInput').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').length).toBe(1);
+ expect(wrapper.find('MultipleChoiceField').find('TextInput').length).toBe(
1
);
expect(
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('Button[aria-label="Click to toggle default value"]').length
).toBe(1);
});
@@ -174,13 +174,13 @@ describe('', () => {
});
await selectType(wrapper, 'multiselect');
- expect(wrapper.find('TextAndCheckboxField').length).toBe(1);
- expect(wrapper.find('TextAndCheckboxField').find('TextInput').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').length).toBe(1);
+ expect(wrapper.find('MultipleChoiceField').find('TextInput').length).toBe(
1
);
expect(
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('Button[aria-label="Click to toggle default value"]').length
).toBe(1);
});
@@ -249,8 +249,8 @@ describe('', () => {
await selectType(wrapper, 'multiselect');
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onChange')('alex')
@@ -260,7 +260,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -268,28 +268,28 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onKeyUp')({ key: 'Enter' })
);
wrapper.update();
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
2
);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(1)
.prop('onChange')('spencer')
);
wrapper.update();
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
2
);
await act(() => wrapper.find('Button[ouiaId="spencer"]').prop('onClick')());
@@ -298,7 +298,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="spencer"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -306,7 +306,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
});
@@ -325,7 +325,7 @@ describe('', () => {
await selectType(wrapper, 'multiplechoice');
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onChange')('alex')
@@ -335,7 +335,7 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
await act(() => wrapper.find('Button[ouiaId="alex"]').prop('onClick')());
wrapper.update();
@@ -343,14 +343,14 @@ describe('', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
1
);
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onKeyUp')({ key: 'Enter' })
@@ -358,13 +358,13 @@ describe('', () => {
wrapper.update();
await act(async () =>
wrapper
- .find('TextAndCheckboxField')
+ .find('MultipleChoiceField')
.find('TextInput')
.at(1)
.prop('onChange')('spencer')
);
wrapper.update();
- expect(wrapper.find('TextAndCheckboxField').find('InputGroup').length).toBe(
+ expect(wrapper.find('MultipleChoiceField').find('InputGroup').length).toBe(
2
);
await act(() => wrapper.find('Button[ouiaId="spencer"]').prop('onClick')());
@@ -374,13 +374,13 @@ describe('', () => {
wrapper
.find('Button[ouiaId="spencer"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(true);
expect(
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
- .prop('isSelected')
+ .prop('selected')
).toBe(false);
});
});