Merge pull request #5772 from AlexSCorey/4515-MultiSelectGenerateLabels

JT Form Generate Labels

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
softwarefactory-project-zuul[bot] 2020-01-27 21:19:09 +00:00 committed by GitHub
commit 7d74999851
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 36 deletions

View File

@ -13,7 +13,6 @@ class JobTemplates extends InstanceGroupsMixin(NotificationsMixin(Base)) {
this.disassociateLabel = this.disassociateLabel.bind(this);
this.readCredentials = this.readCredentials.bind(this);
this.readAccessList = this.readAccessList.bind(this);
this.generateLabel = this.generateLabel.bind(this);
}
launch(id, data) {
@ -24,8 +23,11 @@ class JobTemplates extends InstanceGroupsMixin(NotificationsMixin(Base)) {
return this.http.get(`${this.baseUrl}${id}/launch/`);
}
associateLabel(id, label) {
return this.http.post(`${this.baseUrl}${id}/labels/`, label);
associateLabel(id, label, orgId) {
return this.http.post(`${this.baseUrl}${id}/labels/`, {
name: label.name,
organization: orgId,
});
}
disassociateLabel(id, label) {
@ -35,15 +37,10 @@ class JobTemplates extends InstanceGroupsMixin(NotificationsMixin(Base)) {
});
}
generateLabel(id, label, orgId) {
return this.http.post(`${this.baseUrl}${id}/labels/`, {
name: label.name,
organization: orgId,
});
}
readCredentials(id, params) {
return this.http.get(`${this.baseUrl}${id}/credentials/`, { params });
return this.http.get(`${this.baseUrl}${id}/credentials/`, {
params,
});
}
associateCredentials(id, credentialId) {
@ -60,7 +57,9 @@ class JobTemplates extends InstanceGroupsMixin(NotificationsMixin(Base)) {
}
readAccessList(id, params) {
return this.http.get(`${this.baseUrl}${id}/access_list/`, { params });
return this.http.get(`${this.baseUrl}${id}/access_list/`, {
params,
});
}
}

View File

@ -36,16 +36,10 @@ function JobTemplateAdd() {
}
function submitLabels(templateId, labels = [], organizationId) {
const associationPromises = labels
.filter(label => !label.isNew)
.map(label => JobTemplatesAPI.associateLabel(templateId, label));
const creationPromises = labels
.filter(label => label.isNew)
.map(label =>
JobTemplatesAPI.generateLabel(templateId, label, organizationId)
);
return Promise.all([...associationPromises, ...creationPromises]);
const associationPromises = labels.map(label =>
JobTemplatesAPI.associateLabel(templateId, label, organizationId)
);
return Promise.all([...associationPromises]);
}
function submitInstanceGroups(templateId, addedGroups = []) {

View File

@ -127,19 +127,13 @@ class JobTemplateEdit extends Component {
const disassociationPromises = removed.map(label =>
JobTemplatesAPI.disassociateLabel(template.id, label)
);
const associationPromises = added
.filter(label => !label.isNew)
.map(label => JobTemplatesAPI.associateLabel(template.id, label));
const creationPromises = added
.filter(label => label.isNew)
.map(label =>
JobTemplatesAPI.generateLabel(template.id, label, organizationId)
);
const associationPromises = added.map(label => {
return JobTemplatesAPI.associateLabel(template.id, label, organizationId);
});
const results = await Promise.all([
...disassociationPromises,
...associationPromises,
...creationPromises,
]);
return results;
}

View File

@ -195,8 +195,8 @@ describe('<JobTemplateEdit />', () => {
inventory: 1,
};
const labels = [
{ id: 3, name: 'Foo', isNew: true },
{ id: 4, name: 'Bar', isNew: true },
{ id: 3, name: 'Foo' },
{ id: 4, name: 'Bar' },
{ id: 5, name: 'Maple' },
{ id: 6, name: 'Tree' },
];
@ -230,8 +230,7 @@ describe('<JobTemplateEdit />', () => {
delete expected.type;
expect(JobTemplatesAPI.update).toHaveBeenCalledWith(1, expected);
expect(JobTemplatesAPI.disassociateLabel).toHaveBeenCalledTimes(2);
expect(JobTemplatesAPI.associateLabel).toHaveBeenCalledTimes(2);
expect(JobTemplatesAPI.generateLabel).toHaveBeenCalledTimes(2);
expect(JobTemplatesAPI.associateLabel).toHaveBeenCalledTimes(4);
});
test('should navigate to job template detail when cancel is clicked', async () => {

View File

@ -57,13 +57,26 @@ function LabelSelect({ value, placeholder, onChange, onError }) {
<Select
variant={SelectVariant.typeaheadMulti}
onToggle={toggleExpanded}
onSelect={onSelect}
onSelect={(e, item) => {
if (typeof item === 'string') {
item = { id: item, name: item };
}
onSelect(e, item);
}}
onClear={() => onChange([])}
onFilter={event => {
const str = event.target.value.toLowerCase();
const matches = options.filter(o => o.name.toLowerCase().includes(str));
return renderOptions(matches);
}}
isCreatable
onCreateOption={label => {
label = label.trim();
if (!options.includes(label)) {
setOptions(options.concat({ name: label, id: label }));
}
return label;
}}
selections={selections}
isExpanded={isExpanded}
ariaLabelledBy="label-select"

View File

@ -56,4 +56,20 @@ describe('<LabelSelect />', () => {
const selectOptions = wrapper.find('SelectOption');
expect(selectOptions).toHaveLength(4);
});
test('Generate a label ', async () => {
let wrapper;
const onChange = jest.fn();
LabelsAPI.read.mockReturnValueOnce({
data: {
options,
},
});
await act(async () => {
wrapper = mount(
<LabelSelect value={[]} onError={() => {}} onChange={onChange} />
);
});
await wrapper.find('Select').invoke('onSelect')({}, 'foo');
expect(onChange).toBeCalledWith([{ id: 'foo', name: 'foo' }]);
});
});