From 783a0963ff6f8f494a4a1e4992c413da4e27aa5d Mon Sep 17 00:00:00 2001 From: Alex Corey Date: Mon, 26 Apr 2021 17:40:43 -0400 Subject: [PATCH] moves and renames new field component. adresses console errors, removes unneeded props adds back isVaid prop on formfield --- .../src/components/FormField/FormField.jsx | 1 + awx/ui_next/src/components/FormField/index.js | 1 - .../Template/Survey/MultipleChoiceField.jsx} | 56 ++++++++++++------- .../Survey/MultipleChoiceField.test.jsx} | 44 +++++++-------- .../Template/Survey/SurveyQuestionAdd.jsx | 11 +--- .../Template/Survey/SurveyQuestionEdit.jsx | 4 +- .../Template/Survey/SurveyQuestionForm.jsx | 16 ++---- .../Survey/SurveyQuestionForm.test.jsx | 50 ++++++++--------- 8 files changed, 95 insertions(+), 88 deletions(-) rename awx/ui_next/src/{components/FormField/TextAndCheckboxField.jsx => screens/Template/Survey/MultipleChoiceField.jsx} (71%) rename awx/ui_next/src/{components/FormField/TextAndCheckboxField.test.jsx => screens/Template/Survey/MultipleChoiceField.test.jsx} (74%) 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); }); });