diff options
Diffstat (limited to 'ui/imports/ui/components/search-auto-complete-list/search-auto-complete-list.js')
-rw-r--r-- | ui/imports/ui/components/search-auto-complete-list/search-auto-complete-list.js | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/ui/imports/ui/components/search-auto-complete-list/search-auto-complete-list.js b/ui/imports/ui/components/search-auto-complete-list/search-auto-complete-list.js new file mode 100644 index 0000000..cfc706b --- /dev/null +++ b/ui/imports/ui/components/search-auto-complete-list/search-auto-complete-list.js @@ -0,0 +1,167 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +/* + * Template Component: SearchAutoCompleteList + */ + +//import { Meteor } from 'meteor/meteor'; +import * as R from 'ramda'; +import { Template } from 'meteor/templating'; +import { ReactiveDict } from 'meteor/reactive-dict'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import { EJSON } from 'meteor/ejson'; +import { _idFieldDef } from '/imports/lib/simple-schema-utils'; + +//import { store } from '/imports/ui/store/store'; + +import '../auto-search-result-line/auto-search-result-line'; + +import './search-auto-complete-list.html'; + +/* + * Lifecycles + */ + +Template.SearchAutoCompleteList.onCreated(function() { + let instance = this; + + instance.state = new ReactiveDict(); + instance.state.setDefault({ + isOpen: false, + envId: null, + searchTerm: null, + results: [], + }); + + instance.currentData = new ReactiveVar(null, EJSON.equals); + instance.autorun((function(_this) { + return function(_computation) { + return _this.currentData.set(Template.currentData()); + }; + })(instance)); + + instance.autorun(function () { + let data = instance.currentData.get(); + + new SimpleSchema({ + isOpen: { type: Boolean }, + envId: R.merge(_idFieldDef, { optional: true }), + searchTerm: { type: String, optional: true }, + onResultSelected: { type: Function }, + onCloseReq: { type: Function }, + }).validate(data); + + instance.state.set('isOpen', data.isOpen); + instance.state.set('envId', data.envId); + instance.state.set('searchTerm', data.searchTerm); + + instance.onCloseReq = R.defaultTo(() => console.log('close requested'), data.onCloseReq); + }); + + instance.opCounter = 0; + + instance.autorun(function () { + let envId = instance.state.get('envId'); + let searchTerm = instance.state.get('searchTerm'); + performSearch(searchTerm, envId, + function getLastOpCounter() { + return instance.opCounter; + }, + function setLastOpCounter(opCounter) { + instance.opCounter = opCounter; + } + ).then(function (results) { + instance.state.set('results', results); + }); + }); + +}); + +/* +Template.SearchAutoCompleteList.rendered = function() { +}; +*/ + +Template.SearchAutoCompleteList.onDestroyed(() => { +}); + +/* + * Events + */ + +Template.SearchAutoCompleteList.events({ + 'click .sm-backdrop': function (event, instance) { + instance.onCloseReq(); + } +}); // end - events + +/* + * Helpers + */ + +Template.SearchAutoCompleteList.helpers({ + searchResults: function () { + let instance = Template.instance(); + return instance.state.get('results'); + }, + + createAutoSearchResultLineArgs: function (resultItem) { + let instance = Template.instance(); + + return { + namePath: resultItem.name_path, + objectName: resultItem.object_name, + objectType: resultItem.type, + environment: resultItem.environment, + onClick() { + instance.data.onResultSelected(resultItem); + } + }; + }, + +}); // end - helpers + +function performSearch( + searchTerm, + envId, + getLastOpCounterFn, + setLastOpCounterFn +) { + return new Promise((resolve, reject) => { + let results = []; + let opCounter = getLastOpCounterFn() + 1; + setLastOpCounterFn(opCounter); + + Meteor.apply('inventorySearch', [ + searchTerm, envId, opCounter, + ], { + wait: false + }, function (err, res) { + if (err) { + console.error(R.toString(err)); + reject(err); + return; + } + + let currentOpCounter = getLastOpCounterFn(); + if (res.opCounter !== currentOpCounter) { + reject('stale search result'); + return; + } + + R.forEach((resultItem) => { + results = R.append(resultItem, results); + }, res.searchResults); + + resolve(results); + return; + }); + }); +} |