moves and renames new field component. adresses console errors, removes unneeded props adds back isVaid prop on formfield

This commit is contained in:
Alex Corey 2021-04-26 17:40:43 -04:00
parent dbc235cfb6
commit 783a0963ff
8 changed files with 95 additions and 88 deletions

View File

@ -29,6 +29,7 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
validated={isValid ? 'default' : 'error'}
label={label}
labelIcon={<Popover content={tooltip} maxWidth={tooltipMaxWidth} />}
>

View File

@ -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';

View File

@ -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 }) {
<FormGroup
label={label}
isRequired
name="formattedChoices"
id="formattedChoices"
helperText={
!formattedChoicesField.value[0].choice.trim().length
? t`Type answer then click checkbox on right to select answer as default.`
@ -64,10 +66,10 @@ function TextAndCheckboxField({ label, tooltip }) {
validated={isValid ? 'default' : 'error'}
labelIcon={<Popover content={tooltip} />}
>
{formattedChoicesField.value.map(({ choice, isDefault }, i) => (
<InputGroup>
{formattedChoicesField.value.map(({ choice, isDefault, id }, i) => (
<InputGroup key={id}>
<TextInput
aria-label={choice}
aria-label={choice || t`new choice`}
onKeyUp={e => {
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);
}}
/>
<Button
variant="control"
aria-label={t`Click to toggle default value`}
ouiaId={choice}
isDisabled={!choice.trim()}
onClick={() => {
const newValues = formattedChoicesField.value.map((cfv, index) =>
i === index
? { choice: cfv.choice, isDefault: !cfv.isDefault }
: cfv
const newValues = formattedChoicesField.value.map(
(choiceField, index) =>
i === index
? {
choice: choiceField.choice,
isDefault: !choiceField.isDefault,
id: choiceField.id,
}
: choiceField
);
const singleSelectValues = formattedChoicesField.value.map(
(cfv, index) =>
(choiceField, index) =>
i === index
? { choice: cfv.choice, isDefault: !cfv.isDefault }
: { choice: cfv.choice, isDefault: false }
? {
choice: choiceField.choice,
isDefault: !choiceField.isDefault,
id: choiceField.id,
}
: {
choice: choiceField.choice,
isDefault: false,
id: choiceField.id,
}
);
return typeField.value === 'multiplechoice'
? formattedChoicesHelpers.setValue(singleSelectValues)
: formattedChoicesHelpers.setValue(newValues);
}}
>
<CheckIcon isSelected={isDefault} />
<CheckIcon selected={isDefault} />
</Button>
</InputGroup>
))}
@ -133,4 +151,4 @@ function TextAndCheckboxField({ label, tooltip }) {
);
}
export default TextAndCheckboxField;
export default MultipleChoiceField;

View File

@ -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('<TextAndCheckboxField/>', () => {
describe('<MultipleChoiceField/>', () => {
test('should activate default values, multiselect', async () => {
let wrapper;
@ -20,7 +20,7 @@ describe('<TextAndCheckboxField/>', () => {
type: 'multiselect',
}}
>
<TextAndCheckboxField id="question-options" name="choices" />
<MultipleChoiceField id="question-options" name="choices" />
</Formik>
);
});
@ -29,7 +29,7 @@ describe('<TextAndCheckboxField/>', () => {
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('<TextAndCheckboxField/>', () => {
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('<TextAndCheckboxField/>', () => {
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('<TextAndCheckboxField/>', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
.prop('isSelected')
.prop('selected')
).toBe(true);
});
@ -85,14 +85,14 @@ describe('<TextAndCheckboxField/>', () => {
<Formik
initialValues={{
formattedChoices: [
{ choice: 'alex', isDefault: true },
{ choice: 'apollo', isDefault: false },
{ choice: 'athena', isDefault: false },
{ choice: 'alex', isDefault: true, id: 1 },
{ choice: 'apollo', isDefault: false, id: 2 },
{ choice: 'athena', isDefault: false, id: 3 },
],
type: 'multiplechoice',
}}
>
<TextAndCheckboxField id="question-options" name="choices" />
<MultipleChoiceField id="question-options" name="choices" />
</Formik>
);
});
@ -101,7 +101,7 @@ describe('<TextAndCheckboxField/>', () => {
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('<TextAndCheckboxField/>', () => {
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('<TextAndCheckboxField/>', () => {
wrapper.update();
await act(async () =>
wrapper
.find('TextAndCheckboxField')
.find('MultipleChoiceField')
.find('TextInput')
.at(2)
.prop('onChange')('spencer')
@ -138,13 +138,13 @@ describe('<TextAndCheckboxField/>', () => {
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);
});
});

View File

@ -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);

View File

@ -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([

View File

@ -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) && (
<TextAndCheckboxField
id="question-options"
name="choices"
<MultipleChoiceField
label={t`Multiple Choice Options`}
validate={required()}
tooltip={
<>
<span>{t`Refer to the`} </span>
@ -236,7 +233,6 @@ function SurveyQuestionForm({
{t`for more information.`}
</>
}
isRequired
/>
)}
</FormColumnLayout>

View File

@ -149,13 +149,13 @@ describe('<SurveyQuestionForm />', () => {
});
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('<SurveyQuestionForm />', () => {
});
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
wrapper
.find('Button[ouiaId="alex"]')
.find('CheckIcon')
.prop('isSelected')
.prop('selected')
).toBe(false);
});
@ -325,7 +325,7 @@ describe('<SurveyQuestionForm />', () => {
await selectType(wrapper, 'multiplechoice');
await act(async () =>
wrapper
.find('TextAndCheckboxField')
.find('MultipleChoiceField')
.find('TextInput')
.at(0)
.prop('onChange')('alex')
@ -335,7 +335,7 @@ describe('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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('<SurveyQuestionForm />', () => {
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);
});
});