diff --git a/SingularityUI/app/views/globalSearch.coffee b/SingularityUI/app/views/globalSearch.coffee index c7de79a75c..54e44cc92a 100644 --- a/SingularityUI/app/views/globalSearch.coffee +++ b/SingularityUI/app/views/globalSearch.coffee @@ -46,13 +46,11 @@ class GlobalSearchView extends View @lastSearchQuery = query - fuse = new Fuse( - @requests.toJSON() - keys: ["request.id"] - threshold: 0.6 - id: "request.id" - maxPatternLength: 128) - results = fuse.search(query) + options = + extract: (o) -> + o.id + res = fuzzy.filter(query, @requests.toJSON(), options) + results = _.pluck(_.pluck(_.sortBy(res, (r) => r.score).reverse(), 'original'), 'id') process results.slice(0, 10) diff --git a/SingularityUI/app/views/requests.coffee b/SingularityUI/app/views/requests.coffee index ae39ea78d5..8da825eaad 100644 --- a/SingularityUI/app/views/requests.coffee +++ b/SingularityUI/app/views/requests.coffee @@ -50,8 +50,18 @@ class RequestsView extends View @bodyTemplate = @bodyTemplateMap[@state] @listenTo @collection, 'sync', @render - # So we don't spam it with every keystroke - @searchChange = _.debounce @searchChange, 200 + @fuzzySearch = _.memoize(@fuzzySearch) + + fuzzySearch: (filter, requests) => + id = + extract: (o) -> + o.id + user = + extract: (o) -> + o.requestDeployState?.activeDeploy?.user or '' + res1 = fuzzy.filter(filter, requests, id) + res2 = fuzzy.filter(filter, requests, user) + _.pluck(_.sortBy(_.union(res1, res2), (r) => r.score), 'original') # Returns the array of requests that need to be rendered filterCollection: => @@ -59,13 +69,7 @@ class RequestsView extends View # Only show requests that match the search query if @searchFilter - searchFilter = @searchFilter.toLowerCase().split("@")[0] - fuse = new Fuse( - requests - keys: ["request.id", "requestDeployState.activeDeploy.user", "request.owners"] - threshold: 0.4 - maxPatternLength: 128) - requests = fuse.search(searchFilter).reverse() + requests = @fuzzySearch(@searchFilter, requests) # Only show requests that match the clicky filters if @state in @haveSubfilter and @subFilter isnt 'all' diff --git a/SingularityUI/app/views/tasks.coffee b/SingularityUI/app/views/tasks.coffee index 39327f0961..014691e8b1 100644 --- a/SingularityUI/app/views/tasks.coffee +++ b/SingularityUI/app/views/tasks.coffee @@ -44,7 +44,18 @@ class TasksView extends View @listenTo @cleaningTasks, 'change', @render @listenTo @taskKillRecords, 'change', @render - @searchChange = _.debounce @searchChange, 200 + @fuzzySearch = _.memoize(@fuzzySearch) + + fuzzySearch: (filter, tasks) => + host = + extract: (o) -> + "#{o.host}" + id = + extract: (o) -> + "#{o.id}" + res1 = fuzzy.filter(filter, tasks, host) + res2 = fuzzy.filter(filter, tasks, id) + _.pluck(_.sortBy(_.union(res1, res2), (r) => r.score), 'original') # Returns the array of tasks that need to be rendered filterCollection: => @@ -52,9 +63,8 @@ class TasksView extends View # Only show tasks that match the search query if @searchFilter - tasks = _.filter tasks, (task) => - searchField = "#{ task.id }#{ task.host }".toLowerCase().replace(/-/g, '_') - searchField.toLowerCase().indexOf(@searchFilter.toLowerCase().replace(/-/g, '_')) isnt -1 + tasks = @fuzzySearch(@searchFilter, tasks) + # Sort the table if the user clicked on the table heading things if @sortAttribute? tasks = _.sortBy tasks, (task) => diff --git a/SingularityUI/bower.json b/SingularityUI/bower.json index 858eac2b76..f7239608e7 100644 --- a/SingularityUI/bower.json +++ b/SingularityUI/bower.json @@ -37,7 +37,7 @@ "datatables": "~1.10.7", "datatables-bootstrap3-plugin": "~0.4.0", "select2": "~3.5.2", - "fuse.js": "~1.2.2" + "fuzzy": "~0.1.1" }, "resolutions": { "backbone": "~1.1.2",