mirror of
https://github.com/nasa/openmct.git
synced 2025-06-30 12:43:04 +00:00
Compare commits
5 Commits
eval-sourc
...
open91
Author | SHA1 | Date | |
---|---|---|---|
2a19945870 | |||
e4639091e5 | |||
a55607dc23 | |||
9593855c3f | |||
e045ce223b |
@ -13,7 +13,7 @@
|
|||||||
{
|
{
|
||||||
"key": "SearchController",
|
"key": "SearchController",
|
||||||
"implementation": "controllers/SearchController.js",
|
"implementation": "controllers/SearchController.js",
|
||||||
"depends": [ "$scope", "searchService" ]
|
"depends": [ "$scope", "searchService", "throttle" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SearchMenuController",
|
"key": "SearchMenuController",
|
||||||
|
@ -30,7 +30,7 @@ define(function () {
|
|||||||
var INITIAL_LOAD_NUMBER = 20,
|
var INITIAL_LOAD_NUMBER = 20,
|
||||||
LOAD_INCREMENT = 20;
|
LOAD_INCREMENT = 20;
|
||||||
|
|
||||||
function SearchController($scope, searchService) {
|
function SearchController($scope, searchService, throttle) {
|
||||||
// numResults is the amount of results to display. Will get increased.
|
// numResults is the amount of results to display. Will get increased.
|
||||||
// fullResults holds the most recent complete searchService response object
|
// fullResults holds the most recent complete searchService response object
|
||||||
var numResults = INITIAL_LOAD_NUMBER,
|
var numResults = INITIAL_LOAD_NUMBER,
|
||||||
@ -88,15 +88,6 @@ define(function () {
|
|||||||
function search(maxResults) {
|
function search(maxResults) {
|
||||||
var inputText = $scope.ngModel.input;
|
var inputText = $scope.ngModel.input;
|
||||||
|
|
||||||
if (inputText !== '' && inputText !== undefined) {
|
|
||||||
// We are starting to load.
|
|
||||||
$scope.loading = true;
|
|
||||||
|
|
||||||
// Update whether the file tree should be displayed
|
|
||||||
// Hide tree only when starting search
|
|
||||||
$scope.ngModel.search = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!maxResults) {
|
if (!maxResults) {
|
||||||
// Reset 'load more'
|
// Reset 'load more'
|
||||||
numResults = INITIAL_LOAD_NUMBER;
|
numResults = INITIAL_LOAD_NUMBER;
|
||||||
@ -129,7 +120,21 @@ define(function () {
|
|||||||
* that this function should return. If not provided, search
|
* that this function should return. If not provided, search
|
||||||
* service default will be used.
|
* service default will be used.
|
||||||
*/
|
*/
|
||||||
search: search,
|
search: function (maxResults) {
|
||||||
|
// Show that we are loading before starting the throttled function
|
||||||
|
// so that the user knows the input was detected.
|
||||||
|
if ($scope.ngModel.input !== '' && $scope.ngModel.input !== undefined) {
|
||||||
|
// We are starting to load.
|
||||||
|
$scope.loading = true;
|
||||||
|
|
||||||
|
// Update whether the file tree should be displayed
|
||||||
|
// Hide tree only when starting search
|
||||||
|
$scope.ngModel.search = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call a throttled search
|
||||||
|
return throttle(search)(maxResults);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if there are more search results to display. If the answer is
|
* Checks to see if there are more search results to display. If the answer is
|
||||||
|
@ -79,27 +79,28 @@ define(
|
|||||||
// Handles responses from the web worker. Namely, the results of
|
// Handles responses from the web worker. Namely, the results of
|
||||||
// a search request.
|
// a search request.
|
||||||
function handleResponse(event) {
|
function handleResponse(event) {
|
||||||
var ids = [],
|
var ids = [];
|
||||||
id;
|
|
||||||
|
|
||||||
// If we have the results from a search
|
// If we have the results from a search
|
||||||
if (event.data.request === 'search') {
|
if (event.data.request === 'search') {
|
||||||
// Convert the ids given from the web worker into domain objects
|
|
||||||
for (id in event.data.results) {
|
|
||||||
ids.push(id);
|
|
||||||
}
|
|
||||||
objectService.getObjects(ids).then(function (objects) {
|
|
||||||
var searchResults = [],
|
|
||||||
id;
|
|
||||||
|
|
||||||
// Create searchResult objects
|
// Get the ids into an array
|
||||||
for (id in objects) {
|
event.data.results.forEach(function (result) {
|
||||||
searchResults.push({
|
ids.push(result.id);
|
||||||
object: objects[id],
|
});
|
||||||
id: id,
|
|
||||||
score: event.data.results[id]
|
// Get domainObjects with the ids
|
||||||
|
objectService.getObjects(ids).then(function (objects) {
|
||||||
|
var searchResults = [];
|
||||||
|
|
||||||
|
// Create searchResult objects with the gotten domainObjects
|
||||||
|
event.data.results.forEach(function (result) {
|
||||||
|
searchResults.push({
|
||||||
|
object: objects[result.id],
|
||||||
|
id: result.id,
|
||||||
|
score: result.score
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Resove the promise corresponding to this
|
// Resove the promise corresponding to this
|
||||||
pendingQueries[event.data.timestamp].resolve({
|
pendingQueries[event.data.timestamp].resolve({
|
||||||
|
@ -93,14 +93,14 @@
|
|||||||
* * timestamp: The time identifier from when the query was made
|
* * timestamp: The time identifier from when the query was made
|
||||||
*/
|
*/
|
||||||
function search(data) {
|
function search(data) {
|
||||||
// This results dictionary will have domain object ID keys which
|
// This results array will have domain object IDs and scores together
|
||||||
// point to the value the domain object's score.
|
// [{score: number, id: string}]
|
||||||
var results = {},
|
var results = [],
|
||||||
input = data.input.toLocaleLowerCase(),
|
input = data.input.toLocaleLowerCase(),
|
||||||
terms = convertToTerms(input),
|
terms = convertToTerms(input),
|
||||||
message = {
|
message = {
|
||||||
request: 'search',
|
request: 'search',
|
||||||
results: {},
|
results: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
timestamp: data.timestamp,
|
timestamp: data.timestamp,
|
||||||
timedOut: false
|
timedOut: false
|
||||||
@ -111,6 +111,7 @@
|
|||||||
|
|
||||||
// If the user input is empty, we want to have no search results.
|
// If the user input is empty, we want to have no search results.
|
||||||
if (input !== '') {
|
if (input !== '') {
|
||||||
|
// Start getting search results
|
||||||
for (i = 0; i < indexedItems.length; i += 1) {
|
for (i = 0; i < indexedItems.length; i += 1) {
|
||||||
// If this is taking too long, then stop
|
// If this is taking too long, then stop
|
||||||
if (Date.now() > data.timestamp + data.timeout) {
|
if (Date.now() > data.timestamp + data.timeout) {
|
||||||
@ -121,23 +122,26 @@
|
|||||||
// Score and add items
|
// Score and add items
|
||||||
score = scoreItem(indexedItems[i], input, terms);
|
score = scoreItem(indexedItems[i], input, terms);
|
||||||
if (score > 0) {
|
if (score > 0) {
|
||||||
results[indexedItems[i].id] = score;
|
results.push({id: indexedItems[i].id, score: score});
|
||||||
message.total += 1;
|
message.total += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate results if there are more than maxResults
|
// Sort the results by score
|
||||||
if (message.total > data.maxResults) {
|
results.sort(function (a, b) {
|
||||||
i = 0;
|
if (a.score > b.score) {
|
||||||
for (id in results) {
|
return -1;
|
||||||
message.results[id] = results[id];
|
} else if (b.score > a.score) {
|
||||||
i += 1;
|
return 1;
|
||||||
if (i >= data.maxResults) {
|
} else {
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
// TODO: This seems inefficient.
|
|
||||||
|
// Truncate results if there are more than maxNumber
|
||||||
|
if (message.total > data.maxNumber) {
|
||||||
|
message.results = results.slice(0, data.maxNumber);
|
||||||
} else {
|
} else {
|
||||||
message.results = results;
|
message.results = results;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ define(
|
|||||||
describe("The search controller", function () {
|
describe("The search controller", function () {
|
||||||
var mockScope,
|
var mockScope,
|
||||||
mockSearchService,
|
mockSearchService,
|
||||||
|
mockThrottle,
|
||||||
mockPromise,
|
mockPromise,
|
||||||
mockSearchResult,
|
mockSearchResult,
|
||||||
mockDomainObject,
|
mockDomainObject,
|
||||||
@ -73,6 +74,11 @@ define(
|
|||||||
);
|
);
|
||||||
mockSearchService.query.andReturn(mockPromise);
|
mockSearchService.query.andReturn(mockPromise);
|
||||||
|
|
||||||
|
mockThrottle = jasmine.createSpy('throttle');
|
||||||
|
mockThrottle.andCallFake(function (fn) {
|
||||||
|
return fn;
|
||||||
|
});
|
||||||
|
|
||||||
mockTypes = [{key: 'mock.type', name: 'Mock Type', glyph: '?'}];
|
mockTypes = [{key: 'mock.type', name: 'Mock Type', glyph: '?'}];
|
||||||
|
|
||||||
mockSearchResult = jasmine.createSpyObj(
|
mockSearchResult = jasmine.createSpyObj(
|
||||||
@ -86,7 +92,7 @@ define(
|
|||||||
mockSearchResult.object = mockDomainObject;
|
mockSearchResult.object = mockDomainObject;
|
||||||
mockDomainObject.getModel.andReturn({name: 'Mock Object', type: 'mock.type'});
|
mockDomainObject.getModel.andReturn({name: 'Mock Object', type: 'mock.type'});
|
||||||
|
|
||||||
controller = new SearchController(mockScope, mockSearchService, mockTypes);
|
controller = new SearchController(mockScope, mockSearchService, mockThrottle);
|
||||||
controller.search();
|
controller.search();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -172,10 +172,10 @@ define(
|
|||||||
event = {
|
event = {
|
||||||
data: {
|
data: {
|
||||||
request: "search",
|
request: "search",
|
||||||
results: {
|
results: [
|
||||||
1: 1,
|
{id: 1, score: 1},
|
||||||
2: 2
|
{id: 2, score: 2}
|
||||||
},
|
],
|
||||||
total: 2,
|
total: 2,
|
||||||
timedOut: false,
|
timedOut: false,
|
||||||
timestamp: timestamp
|
timestamp: timestamp
|
||||||
|
@ -35,7 +35,17 @@ define(
|
|||||||
numObjects = 5;
|
numObjects = 5;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var i;
|
// See first it()
|
||||||
|
});
|
||||||
|
|
||||||
|
it("searches can reach all objects", function () {
|
||||||
|
var flag = false,
|
||||||
|
workerOutput,
|
||||||
|
resultsLength = 0,
|
||||||
|
i;
|
||||||
|
|
||||||
|
// This for loop is being done only once in the first it() becuase
|
||||||
|
// duplicate checking is done outside fo the worker
|
||||||
for (i = 0; i < numObjects; i += 1) {
|
for (i = 0; i < numObjects; i += 1) {
|
||||||
worker.postMessage(
|
worker.postMessage(
|
||||||
{
|
{
|
||||||
@ -49,12 +59,6 @@ define(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
it("searches can reach all objects", function () {
|
|
||||||
var flag = false,
|
|
||||||
workerOutput,
|
|
||||||
resultsLength = 0;
|
|
||||||
|
|
||||||
// Search something that should return all objects
|
// Search something that should return all objects
|
||||||
runs(function () {
|
runs(function () {
|
||||||
@ -70,12 +74,8 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
worker.onmessage = function (event) {
|
worker.onmessage = function (event) {
|
||||||
var id;
|
|
||||||
|
|
||||||
workerOutput = event.data;
|
workerOutput = event.data;
|
||||||
for (id in workerOutput.results) {
|
resultsLength = event.data.results.length;
|
||||||
resultsLength += 1;
|
|
||||||
}
|
|
||||||
flag = true;
|
flag = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,12 +108,8 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
worker.onmessage = function (event) {
|
worker.onmessage = function (event) {
|
||||||
var id;
|
|
||||||
|
|
||||||
workerOutput = event.data;
|
workerOutput = event.data;
|
||||||
for (id in workerOutput.results) {
|
resultsLength = event.data.results.length;
|
||||||
resultsLength += 1;
|
|
||||||
}
|
|
||||||
flag = true;
|
flag = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +120,6 @@ define(
|
|||||||
runs(function () {
|
runs(function () {
|
||||||
expect(workerOutput).toBeDefined();
|
expect(workerOutput).toBeDefined();
|
||||||
expect(resultsLength).toEqual(1);
|
expect(resultsLength).toEqual(1);
|
||||||
expect(workerOutput.results[2]).toBeDefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user