Merge pull request #4511 from AlexSCorey/multiSelecBug

Allows user to hit enter to create label, fixes console errors.

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
This commit is contained in:
softwarefactory-project-zuul[bot]
2019-08-27 22:43:16 +00:00
committed by GitHub
4 changed files with 63 additions and 24 deletions

View File

@@ -86,7 +86,7 @@ class MultiSelect extends Component {
this.handleSelection(e, option); this.handleSelection(e, option);
} }
} else { } else {
this.setState({ isExpanded: false }); this.setState({ input: '', isExpanded: false });
} }
} }
@@ -105,17 +105,30 @@ class MultiSelect extends Component {
handleAddItem(event) { handleAddItem(event) {
const { input, chipItems } = this.state; const { input, chipItems } = this.state;
const { onAddNewItem } = this.props; const { onAddNewItem } = this.props;
const newChip = { name: input, id: Math.random() }; const isIncluded = chipItems.some(chipItem => chipItem.name === input);
if (event.key !== 'Tab') {
if (!input) {
return; return;
} }
this.setState({
chipItems: chipItems.concat(newChip),
isExpanded: false,
input: '',
});
onAddNewItem(input); if (isIncluded) {
// This event.preventDefault prevents the form from submitting
// if the user tries to create 2 chips of the same name
event.preventDefault();
this.setState({ input: '', isExpanded: false });
return;
}
if (event.key === 'Enter') {
event.preventDefault();
this.setState({
chipItems: chipItems.concat({ name: input, id: input }),
isExpanded: false,
input: '',
});
onAddNewItem(input);
} else if (event.key === 'Tab') {
this.setState({ input: '' });
}
} }
handleInputChange(e) { handleInputChange(e) {

View File

@@ -40,10 +40,10 @@ describe('<MultiSelect />', () => {
const component = wrapper.find('MultiSelect'); const component = wrapper.find('MultiSelect');
component component
.find('input[aria-label="labels"]') .find('input[aria-label="labels"]')
.simulate('keydown', { key: 'Tab' }); .simulate('keydown', { key: 'Enter' });
component.update(); component.update();
await sleep(1); await sleep(1);
expect(component.state().chipItems.length).toBe(3); expect(component.state().chipItems.length).toBe(2);
}); });
test('handleAddItem adds a chip only when Tab is pressed', () => { test('handleAddItem adds a chip only when Tab is pressed', () => {
const onAddNewItem = jest.fn(); const onAddNewItem = jest.fn();
@@ -57,7 +57,7 @@ describe('<MultiSelect />', () => {
); );
const event = { const event = {
preventDefault: () => {}, preventDefault: () => {},
key: 'Tab', key: 'Enter',
}; };
const component = wrapper.find('MultiSelect'); const component = wrapper.find('MultiSelect');

View File

@@ -14,21 +14,47 @@ import JobTemplateForm from '../shared/JobTemplateForm';
import { JobTemplatesAPI } from '@api'; import { JobTemplatesAPI } from '@api';
function JobTemplateAdd({ history, i18n }) { function JobTemplateAdd({ history, i18n }) {
const [error, setError] = useState(null); const [formSubmitError, setFormSubmitError] = useState(null);
const handleSubmit = async values => { async function handleSubmit(values) {
setError(null); const { newLabels, removedLabels } = values;
delete values.newLabels;
delete values.removedLabels;
setFormSubmitError(null);
try { try {
const { data } = await JobTemplatesAPI.create(values); const {
history.push(`/templates/${data.type}/${data.id}/details`); data: { id, type },
} catch (err) { } = await JobTemplatesAPI.create(values);
setError(err); await Promise.all([submitLabels(id, newLabels, removedLabels)]);
history.push(`/templates/${type}/${id}/details`);
} catch (error) {
setFormSubmitError(error);
} }
}; }
const handleCancel = () => { async function submitLabels(id, newLabels = [], removedLabels = []) {
const disassociationPromises = removedLabels.map(label =>
JobTemplatesAPI.disassociateLabel(id, label)
);
const associationPromises = newLabels
.filter(label => !label.organization)
.map(label => JobTemplatesAPI.associateLabel(id, label));
const creationPromises = newLabels
.filter(label => label.organization)
.map(label => JobTemplatesAPI.generateLabel(id, label));
const results = await Promise.all([
...disassociationPromises,
...associationPromises,
...creationPromises,
]);
return results;
}
function handleCancel() {
history.push(`/templates`); history.push(`/templates`);
}; }
return ( return (
<PageSection> <PageSection>
@@ -44,7 +70,7 @@ function JobTemplateAdd({ history, i18n }) {
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
/> />
</CardBody> </CardBody>
{error ? <div>error</div> : ''} {formSubmitError ? <div>formSubmitError</div> : ''}
</Card> </Card>
</PageSection> </PageSection>
); );

View File

@@ -158,7 +158,7 @@ describe('<JobTemplateForm />', () => {
_JobTemplateForm.prototype, _JobTemplateForm.prototype,
'handleNewLabel' 'handleNewLabel'
); );
const event = { key: 'Tab' }; const event = { key: 'Enter', preventDefault: () => {} };
const wrapper = mountWithContexts( const wrapper = mountWithContexts(
<JobTemplateForm <JobTemplateForm
template={mockData} template={mockData}