open-vault/ui/app/components/search-select.js
2018-12-10 11:44:37 -05:00

96 lines
2.7 KiB
JavaScript

import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import { computed } from '@ember/object';
export default Component.extend({
'data-test-component': 'search-select',
classNames: ['field', 'search-select'],
store: service(),
/*
* @public
* @param Function
*
* Function called when any of the inputs change
* accepts a single param `value`
*
*/
onChange: () => {},
/*
* @public
* @param String | Array
* A comma-separated string or an array of strings.
* Defaults to an empty array.
*
*/
inputValue: computed(function() {
return [];
}),
selectedOptions: null, //list of selected options
options: null, //all possible options
shouldUseFallback: false,
shouldRenderName: false,
init() {
this._super(...arguments);
this.set('selectedOptions', this.inputValue || []);
},
fetchOptions: task(function*() {
for (let modelType of this.models) {
if (modelType.includes('identity')) {
this.set('shouldRenderName', true);
}
try {
let options = yield this.store.query(modelType, {});
options = options.toArray().map(option => {
option.searchText = `${option.name} ${option.id}`;
return option;
});
let formattedOptions = this.selectedOptions.map(option => {
let matchingOption = options.findBy('id', option);
options.removeObject(matchingOption);
return { id: option, name: matchingOption.name, searchText: matchingOption.searchText };
});
this.set('selectedOptions', formattedOptions);
if (this.options) {
options = this.options.concat(options);
}
this.set('options', options);
} catch (err) {
if (err.httpStatus === 404) {
//leave options alone, it's okay
return;
}
if (err.httpStatus === 403) {
this.set('shouldUseFallback', true);
return;
}
throw err;
}
}
}).on('didInsertElement'),
handleChange() {
if (this.selectedOptions.length && typeof this.selectedOptions.firstObject === 'object') {
this.onChange(Array.from(this.selectedOptions, option => option.id));
} else {
this.onChange(this.selectedOptions);
}
},
actions: {
onChange(val) {
this.onChange(val);
},
selectOption(option) {
this.selectedOptions.pushObject(option);
this.options.removeObject(option);
this.handleChange();
},
discardSelection(selected) {
this.selectedOptions.removeObject(selected);
this.options.pushObject(selected);
this.handleChange();
},
},
});