Fixed issue where search actions were sending two requests. Cleaned up and organized smart search controller

This commit is contained in:
mabashian
2018-06-12 11:57:24 -04:00
parent ee6902bbbb
commit 36732d8113

View File

@@ -16,10 +16,99 @@ function SmartSearchController (
let queryset;
let transitionSuccessListener;
configService.getConfig()
.then(config => init(config));
const compareParams = (a, b) => {
for (let key in a) {
if (!(key in b) || a[key].toString() !== b[key].toString()) {
return false;
}
}
for (let key in b) {
if (!(key in a)) {
return false;
}
}
return true;
};
function init (config) {
const generateSearchTags = () => {
const { singleSearchParam } = $scope;
$scope.searchTags = qs.createSearchTagsFromQueryset(queryset, defaults, singleSearchParam);
};
const listenForTransitionSuccess = () => {
transitionSuccessListener = $transitions.onSuccess({}, trans => {
// State has changed - check to see if this is a param change
if (trans.from().name === trans.to().name) {
if (!compareParams(trans.params('from')[searchKey], trans.params('to')[searchKey])) {
// Params are not the same - we need to update the search. This should only
// happen when the user hits the forward/back browser navigation buttons.
queryset = trans.params('to')[searchKey];
qs.search(path, queryset).then((res) => {
$scope.dataset = res.data;
$scope.collection = res.data.results;
$scope.$emit('updateDataset', res.data);
});
$scope.searchTerm = null;
generateSearchTags();
}
}
});
};
const isAnsibleFactField = (termParts) => {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
return rootField === 'ansible_facts';
};
const revertSearch = (queryToBeRestored) => {
queryset = queryToBeRestored;
// https://ui-router.github.io/docs/latest/interfaces/params.paramdeclaration.html#dynamic
// This transition will not reload controllers/resolves/views
// but will register new $stateParams[$scope.iterator + '_search'] terms
if (!$scope.querySet) {
transitionSuccessListener();
$state.go('.', { [searchKey]: queryset })
.then(() => listenForTransitionSuccess());
}
qs.search(path, queryset).then((res) => {
if ($scope.querySet) {
$scope.querySet = queryset;
}
$scope.dataset = res.data;
$scope.collection = res.data.results;
});
$scope.searchTerm = null;
generateSearchTags();
};
const isFilterableBaseField = (termParts) => {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
const listName = $scope.list.name;
const baseFieldPath = `models.${listName}.base.${rootField}`;
const isBaseField = _.has($scope, `${baseFieldPath}`);
const isFilterable = _.get($scope, `${baseFieldPath}.filterable`);
const isBaseModelRelatedSearchTermField = (_.get($scope, `${baseFieldPath}.type`) === 'field');
return isBaseField && !isBaseModelRelatedSearchTermField && isFilterable;
};
const isRelatedField = (termParts) => {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
const listName = $scope.list.name;
const baseRelatedTypePath = `models.${listName}.base.${rootField}.type`;
const isRelatedSearchTermField = (_.contains($scope.models[listName].related, rootField));
const isBaseModelRelatedSearchTermField = (_.get($scope, baseRelatedTypePath) === 'field');
return (isRelatedSearchTermField || isBaseModelRelatedSearchTermField);
};
configService.getConfig()
.then(config => {
let version;
try {
@@ -52,7 +141,7 @@ function SmartSearchController (
.then((data) => {
$scope.models = data.models;
$scope.options = data.options.data;
$scope.keyFields = _.reduce(data.models[$scope.djangoModel].base, function(result, value, key) {
$scope.keyFields = _.reduce(data.models[$scope.djangoModel].base, (result, value, key) => {
if (value.filterable) {
result.push(key);
}
@@ -63,43 +152,6 @@ function SmartSearchController (
}
});
function compareParams (a, b) {
for (let key in a) {
if (!(key in b) || a[key].toString() !== b[key].toString()) {
return false;
}
}
for (let key in b) {
if (!(key in a)) {
return false;
}
}
return true;
}
if (transitionSuccessListener) {
transitionSuccessListener();
}
transitionSuccessListener = $transitions.onSuccess({}, trans => {
// State has changed - check to see if this is a param change
if (trans.from().name === trans.to().name) {
if (!compareParams(trans.params('from')[searchKey], trans.params('to')[searchKey])) {
// Params are not the same - we need to update the search. This should only
// happen when the user hits the forward/back browser navigation buttons.
queryset = trans.params('to')[searchKey];
qs.search(path, queryset).then((res) => {
$scope.dataset = res.data;
$scope.collection = res.data.results;
$scope.$emit('updateDataset', res.data);
});
$scope.searchTerm = null;
generateSearchTags();
}
}
});
$scope.$on('$destroy', transitionSuccessListener);
$scope.$watch('disableSearch', disableSearch => {
if (disableSearch) {
@@ -108,66 +160,15 @@ function SmartSearchController (
$scope.searchPlaceholder = i18n._('Search');
}
});
}
function generateSearchTags () {
const { singleSearchParam } = $scope;
$scope.searchTags = qs.createSearchTagsFromQueryset(queryset, defaults, singleSearchParam);
}
function revertSearch (queryToBeRestored) {
queryset = queryToBeRestored;
// https://ui-router.github.io/docs/latest/interfaces/params.paramdeclaration.html#dynamic
// This transition will not reload controllers/resolves/views
// but will register new $stateParams[$scope.iterator + '_search'] terms
if (!$scope.querySet) {
$state.go('.', { [searchKey]: queryset });
}
qs.search(path, queryset).then((res) => {
if ($scope.querySet) {
$scope.querySet = queryset;
}
$scope.dataset = res.data;
$scope.collection = res.data.results;
listenForTransitionSuccess();
});
$scope.searchTerm = null;
generateSearchTags();
}
$scope.toggleKeyPane = () => {
$scope.showKeyPane = !$scope.showKeyPane;
};
function isAnsibleFactField (termParts) {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
return rootField === 'ansible_facts';
}
function isFilterableBaseField (termParts) {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
const listName = $scope.list.name;
const baseFieldPath = `models.${listName}.base.${rootField}`;
const isBaseField = _.has($scope, `${baseFieldPath}`);
const isFilterable = _.get($scope, `${baseFieldPath}.filterable`);
const isBaseModelRelatedSearchTermField = (_.get($scope, `${baseFieldPath}.type`) === 'field');
return isBaseField && !isBaseModelRelatedSearchTermField && isFilterable;
}
function isRelatedField (termParts) {
const rootField = termParts[0].split('.')[0].replace(/^-/, '');
const listName = $scope.list.name;
const baseRelatedTypePath = `models.${listName}.base.${rootField}.type`;
const isRelatedSearchTermField = (_.contains($scope.models[listName].related, rootField));
const isBaseModelRelatedSearchTermField = (_.get($scope, baseRelatedTypePath) === 'field');
return (isRelatedSearchTermField || isBaseModelRelatedSearchTermField);
}
$scope.addTerms = terms => {
const { singleSearchParam } = $scope;
const unmodifiedQueryset = _.clone(queryset);
@@ -182,11 +183,13 @@ function SmartSearchController (
// This transition will not reload controllers/resolves/views but will register new
// $stateParams[searchKey] terms.
if (!$scope.querySet) {
transitionSuccessListener();
$state.go('.', { [searchKey]: queryset })
.then(() => {
// same as above in $scope.remove. For some reason deleting the page
// from the queryset works for all lists except lists in modals.
delete $stateParams[searchKey].page;
listenForTransitionSuccess();
});
}
@@ -212,6 +215,7 @@ function SmartSearchController (
queryset = qs.removeTermsFromQueryset(queryset, term, isFilterableBaseField, isRelatedField, isAnsibleFactField, singleSearchParam);
if (!$scope.querySet) {
transitionSuccessListener();
$state.go('.', { [searchKey]: queryset })
.then(() => {
// for some reason deleting a tag from a list in a modal does not
@@ -219,6 +223,7 @@ function SmartSearchController (
// that that happened and remove it if it didn't.
const clearedParams = qs.removeTermsFromQueryset($stateParams[searchKey], term, isFilterableBaseField, isRelatedField, isAnsibleFactField, singleSearchParam);
$stateParams[searchKey] = clearedParams;
listenForTransitionSuccess();
});
}
@@ -246,7 +251,9 @@ function SmartSearchController (
queryset = cleared;
if (!$scope.querySet) {
$state.go('.', { [searchKey]: queryset });
transitionSuccessListener();
$state.go('.', { [searchKey]: queryset })
.then(() => listenForTransitionSuccess());
}
qs.search(path, queryset)