-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Jkmarx/file browser refactor services (#1787)
* Refactor main factory file according to style guide. * Update main factory test and remove unneccessary variables. * Update smaller services according to style guide. (#1788) * Update smaller services according to style guide. * Jkmarx/generalize attribute filter (#1790) * Move uiSelectedFields to service. * Add assay filter service. * Move methods to assay-filters-ctrl * Update initialize events. * Add and update unit test for ctrl. * Fix bug related to url query. * Remove broadcast and use watcher. * Remove console. * Update unit test. * Add ctrl comments. * Fix scope and remove unneccessary variable. * fix bug due to url query generation. * Add comments and unit test. * Add unit test and comments.
- Loading branch information
Showing
21 changed files
with
1,602 additions
and
1,205 deletions.
There are no files selected for viewing
212 changes: 212 additions & 0 deletions
212
refinery/ui/source/js/file-browser/ctrls/assay-filters-ctrl.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/** | ||
* Assay Filters Ctrl | ||
* @namespace AssayFiltersCtrl | ||
* @desc Main ctrl for the assay filters, which can be used for a ui-grid | ||
* displaying data from solr. Updates a files param to display data | ||
* when user select filters or when in url query. | ||
* @memberOf refineryFileBrowser | ||
*/ | ||
(function () { | ||
'use strict'; | ||
|
||
angular | ||
.module('refineryFileBrowser') | ||
.controller('AssayFiltersCtrl', AssayFiltersCtrl); | ||
|
||
AssayFiltersCtrl.$inject = [ | ||
'$location', | ||
'$scope', | ||
'$timeout', | ||
'_', | ||
'assayFiltersService', | ||
'filesLoadingService', | ||
'fileParamService', | ||
'resetGridService', | ||
'selectedFilterService' | ||
]; | ||
|
||
function AssayFiltersCtrl ( | ||
$location, | ||
$scope, | ||
$timeout, | ||
_, | ||
assayFiltersService, | ||
filesLoadingService, | ||
fileParamService, | ||
resetGridService, | ||
selectedFilterService | ||
) { | ||
var vm = this; | ||
vm.attributeFilter = assayFiltersService.attributeFilter; | ||
vm.analysisFilter = assayFiltersService.analysisFilter; | ||
vm.attributeSelectionUpdate = attributeSelectionUpdate; | ||
vm.queryKeys = Object.keys($location.search()); // used for pre-set filters in url query | ||
vm.refreshSelectedFieldFromQuery = refreshSelectedFieldFromQuery; | ||
/** Used by ui to select/deselect, attributes have an object of filter fields | ||
* attributeInternalName: {fieldName: boolean, fieldName: boolean} */ | ||
vm.uiSelectedFields = {}; | ||
vm.updateFiltersFromUrlQuery = updateFiltersFromUrlQuery; | ||
vm.updateFilterDOM = false; | ||
|
||
activate(); | ||
/* | ||
* --------------------------------------------------------- | ||
* Methods | ||
* --------------------------------------------------------- | ||
*/ | ||
function activate () { | ||
// Only on a new page load/new data set do we expect the attribute filters | ||
// to be empty | ||
if (_.isEmpty(assayFiltersService.attributeFilter)) { | ||
// Requires waiting for the api response which should update the | ||
// service's attribute filter and unbind. | ||
var watchOnce = $scope.$watchCollection( | ||
function () { | ||
return assayFiltersService.attributeFilter; | ||
}, | ||
function () { | ||
// no need to update filters if there are no url queries | ||
if (Object.keys($location.search()).length === 0) { | ||
watchOnce(); // unbind watcher | ||
} | ||
if (!_.isEmpty(assayFiltersService.attributeFilter)) { | ||
updateFiltersFromUrlQuery(); | ||
// drop panels in ui from query | ||
vm.updateFilterDOM = true; | ||
// update data in grid | ||
resetGridService.setRefreshGridFlag(true); | ||
watchOnce(); // unbind watcher | ||
} | ||
} | ||
); | ||
} else { | ||
// Else is for soft loads (example tabbing) | ||
// updates view model's selected attribute filters | ||
angular.forEach( | ||
selectedFilterService.attributeSelectedFields, | ||
function (fieldArr, attributeInternalName) { | ||
for (var i = 0; i < fieldArr.length; i++) { | ||
if (_.isEmpty(vm.uiSelectedFields) || | ||
!vm.uiSelectedFields.hasOwnProperty(attributeInternalName)) { | ||
vm.uiSelectedFields[attributeInternalName] = {}; | ||
} | ||
vm.uiSelectedFields[attributeInternalName][fieldArr[i]] = true; | ||
// update url with selected fields(filters) | ||
var encodedAttribute = selectedFilterService | ||
.stringifyAndEncodeAttributeObj(attributeInternalName, fieldArr[i]); | ||
selectedFilterService.updateUrlQuery(encodedAttribute, true); | ||
} | ||
}); | ||
// for attribute filter directive, drop panels in query | ||
vm.updateFilterDOM = true; | ||
// updates url with the selected filters (ex: tabbing) | ||
if (Object.keys($location.search()).length > 0) { | ||
updateFiltersFromUrlQuery(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @name attributeSelectionUpdate | ||
* @desc Used by ui, updates which attribute filters are selected and ui-grid data | ||
* @memberOf refineryFileBrowser.AssayFiltersCtrl | ||
* @param {string} internalName - solr name for attribute | ||
* @param {string} field - value for the attributes | ||
**/ | ||
function attributeSelectionUpdate (internalName, field) { | ||
selectedFilterService.updateSelectedFilters( | ||
vm.uiSelectedFields[internalName], internalName, field | ||
); | ||
fileParamService.setParamFilterAttribute(selectedFilterService.attributeSelectedFields); | ||
// refresh grid | ||
resetGridService.setRefreshGridFlag(true); | ||
} | ||
|
||
/** | ||
* @name refreshSelectedFieldFromQuery | ||
* @desc helper method, upon refresh/load add fields to select data objs from query | ||
* @memberOf refineryFileBrowser.AssayFiltersCtrl | ||
* @param {object} attributeObj - combination of attribute and analysis | ||
* object from solr | ||
**/ | ||
function refreshSelectedFieldFromQuery (attributeObj) { | ||
// stringify/encode attributeInternalName:fieldName for url query comparison | ||
angular.forEach(attributeObj.facetObj, function (fieldObj) { | ||
var encodedField = selectedFilterService.stringifyAndEncodeAttributeObj( | ||
attributeObj.internal_name, | ||
fieldObj.name | ||
); | ||
|
||
if (vm.queryKeys.indexOf(encodedField) > -1) { | ||
if (!vm.uiSelectedFields.hasOwnProperty(attributeObj.internal_name)) { | ||
vm.uiSelectedFields[attributeObj.internal_name] = {}; | ||
} | ||
vm.uiSelectedFields[attributeObj.internal_name][fieldObj.name] = true; | ||
selectedFilterService.updateSelectedFilters( | ||
vm.uiSelectedFields[attributeObj.internal_name], | ||
attributeObj.internal_name, | ||
fieldObj.name | ||
); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* @name updateFiltersFromUrlQuery | ||
* @desc checks url for params to update the filter | ||
* @memberOf refineryFileBrowser.AssayFiltersCtrl | ||
**/ | ||
function updateFiltersFromUrlQuery () { | ||
var allFilters = {}; | ||
// Merge attribute and analysis filter data obj | ||
angular.copy(vm.attributeFilter, allFilters); | ||
if (typeof vm.analysisFilter.Analysis !== 'undefined') { | ||
angular.copy(vm.analysisFilter, allFilters.Analysis); | ||
} | ||
|
||
angular.forEach(allFilters, function (attributeObj) { | ||
vm.refreshSelectedFieldFromQuery(attributeObj); | ||
}); | ||
fileParamService.setParamFilterAttribute( | ||
selectedFilterService.attributeSelectedFields | ||
); | ||
} | ||
|
||
/* | ||
* --------------------------------------------------------- | ||
* Watchers | ||
* --------------------------------------------------------- | ||
*/ | ||
// When the filters are updated (ex when a new analysis runs) | ||
$scope.$watchCollection( | ||
function () { | ||
return assayFiltersService.analysisFilter; | ||
}, | ||
function () { | ||
vm.analysisFilter = assayFiltersService.analysisFilter; | ||
vm.attributeFilter = assayFiltersService.attributeFilter; | ||
} | ||
); | ||
|
||
// Reset grid flag if set to true, grid, params, filters, and nodes resets | ||
$scope.$watch( | ||
function () { | ||
return resetGridService.resetGridFlag; | ||
}, | ||
function () { | ||
if (resetGridService.resetGridFlag) { | ||
// Have to set selected Fields in control due to service scope | ||
angular.forEach(vm.uiSelectedFields, function (fieldsObj, attributeInternalName) { | ||
angular.forEach(fieldsObj, function (value, fieldName) { | ||
// initialize the uiSelectObj for easier indexing | ||
vm.uiSelectedFields[attributeInternalName][fieldName] = false; | ||
}); | ||
selectedFilterService.resetAttributeFilter(fieldsObj); | ||
}); | ||
fileParamService.resetParamFilterAttribute = {}; | ||
resetGridService.setResetGridFlag(false); | ||
} | ||
} | ||
); | ||
} | ||
})(); |
94 changes: 94 additions & 0 deletions
94
refinery/ui/source/js/file-browser/ctrls/assay-filters-ctrl.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
describe('Controller: AssayFiltersCtrl', function () { | ||
var ctrl; | ||
var scope; | ||
var service; | ||
|
||
beforeEach(module('refineryApp')); | ||
beforeEach(module('refineryFileBrowser')); | ||
beforeEach(inject(function ( | ||
$controller, | ||
$rootScope, | ||
$window, | ||
mockParamsFactory, | ||
selectedFilterService | ||
) { | ||
scope = $rootScope.$new(); | ||
ctrl = $controller('AssayFiltersCtrl', { | ||
$scope: scope | ||
}); | ||
service = selectedFilterService; | ||
$window.externalAssayUuid = mockParamsFactory.generateUuid(); | ||
})); | ||
|
||
it('AssayFiltersCtrl ctrl should exist', function () { | ||
expect(ctrl).toBeDefined(); | ||
}); | ||
|
||
it('Data & UI displays variables should exist for views', function () { | ||
expect(ctrl.attributeFilter).toEqual({}); | ||
expect(ctrl.analysisFilter).toEqual({}); | ||
expect(ctrl.updateFilterDOM).toEqual(false); | ||
expect(ctrl.uiSelectedFields).toEqual({}); | ||
}); | ||
|
||
it('QueryKeys to be set should exist for views', function () { | ||
expect(ctrl.queryKeys).toEqual([]); | ||
}); | ||
|
||
it('Test updateFiltersFromUrlQuery', function () { | ||
ctrl.analysisFilter.Analysis = undefined; | ||
ctrl.attributeFilter = { | ||
Title: { | ||
facet_obj: [ | ||
{ | ||
count: 129, | ||
name: 'Device independent graphical display description' | ||
}, { | ||
count: 18, | ||
name: 'Graphics Facilities at Ames Research Center' | ||
}], | ||
internal_name: 'Title_Characteristics_92_46_s' | ||
} | ||
}; | ||
service.attributeSelectedFields = { | ||
REFINERY_ANALYSIS_UUID_92_46_s: ['N/A', 'Test Workflow', '3'] | ||
}; | ||
spyOn(scope, '$broadcast'); | ||
spyOn(ctrl, 'refreshSelectedFieldFromQuery'); | ||
expect(ctrl.refreshSelectedFieldFromQuery).not.toHaveBeenCalled(); | ||
ctrl.updateFiltersFromUrlQuery(); | ||
expect(ctrl.refreshSelectedFieldFromQuery).toHaveBeenCalled(); | ||
}); | ||
|
||
it('Test RefreshSelectedFieldFromQuery', function () { | ||
var attributeObj = { | ||
facetObj: [ | ||
{ | ||
count: 133, | ||
name: 'March' | ||
}, | ||
{ | ||
count: 24, | ||
name: 'April' | ||
} | ||
], | ||
internal_name: 'Month_Characteristics_92_46_s' | ||
}; | ||
ctrl.queryKeys = ['{"Month_Characteristics_92_46_s":"March"}', | ||
'{"Month_Characteristics_92_46_s":"April"}', + | ||
'{"Author_Characteristics_82_36_s":"Conner"}']; | ||
|
||
expect(service.attributeSelectedFields.Month_Characteristics_92_46_s) | ||
.not.toBeDefined(); | ||
expect(ctrl.uiSelectedFields.Month_Characteristics_92_46_s).not.toBeDefined(); | ||
ctrl.refreshSelectedFieldFromQuery(attributeObj); | ||
expect(ctrl.uiSelectedFields.Month_Characteristics_92_46_s.March).toEqual(true); | ||
expect(ctrl.uiSelectedFields.Month_Characteristics_92_46_s.June).not.toBeDefined(); | ||
expect(service.attributeSelectedFields.Month_Characteristics_92_46_s) | ||
.toEqual(['March', 'April']); | ||
}); | ||
}); | ||
})(); |
Oops, something went wrong.