From b1603dbd2eefe10b40ae1e46bcaa6dbc619ab7d2 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 19 Nov 2020 16:47:56 -0500 Subject: [PATCH] Search kit: Fix issues with variable pollution and clean up shared display code --- .../ang/crmSearchAdmin/compose/results.html | 2 +- .../crmSearchAdmin.component.js | 3 +- ext/search/ang/crmSearchDisplay.module.js | 55 +++++++++++++++++-- .../crmSearchDisplayList.component.js | 39 +++---------- .../crmSearchDisplayTable.component.js | 50 ++++------------- 5 files changed, 71 insertions(+), 78 deletions(-) diff --git a/ext/search/ang/crmSearchAdmin/compose/results.html b/ext/search/ang/crmSearchAdmin/compose/results.html index 3cda603bc8..4a00a8b1ae 100644 --- a/ext/search/ang/crmSearchAdmin/compose/results.html +++ b/ext/search/ang/crmSearchAdmin/compose/results.html @@ -4,7 +4,7 @@ - + {{ $ctrl.getFieldLabel(col) }} diff --git a/ext/search/ang/crmSearchAdmin/crmSearchAdmin.component.js b/ext/search/ang/crmSearchAdmin/crmSearchAdmin.component.js index 61786f261d..a62dc05a2c 100644 --- a/ext/search/ang/crmSearchAdmin/crmSearchAdmin.component.js +++ b/ext/search/ang/crmSearchAdmin/crmSearchAdmin.component.js @@ -43,6 +43,7 @@ $scope.$bindToRoute({ param: 'params', expr: '$ctrl.savedSearch.api_params', + deep: true, default: { version: 4, select: getDefaultSelect(), @@ -277,7 +278,7 @@ */ $scope.setOrderBy = function(col, $event) { var dir = $scope.getOrderBy(col) === 'fa-sort-asc' ? 'DESC' : 'ASC'; - if (!$event.shiftKey) { + if (!$event.shiftKey || !ctrl.savedSearch.api_params.orderBy) { ctrl.savedSearch.api_params.orderBy = {}; } ctrl.savedSearch.api_params.orderBy[col] = dir; diff --git a/ext/search/ang/crmSearchDisplay.module.js b/ext/search/ang/crmSearchDisplay.module.js index 9e2134e713..d9f5bf2152 100644 --- a/ext/search/ang/crmSearchDisplay.module.js +++ b/ext/search/ang/crmSearchDisplay.module.js @@ -4,7 +4,7 @@ // Declare module angular.module('crmSearchDisplay', CRM.angRequires('crmSearchDisplay')) - .factory('formatSearchValue', function() { + .factory('searchDisplayUtils', function() { function getUrl(link, row) { var url = replaceTokens(link, row); if (url.slice(0, 1) !== '/' && url.slice(0, 4) !== 'http') { @@ -20,7 +20,7 @@ return str; } - return function formatSearchValue(row, col, value) { + function formatSearchValue(row, col, value) { var type = col.dataType, result = value; if (_.isArray(value)) { @@ -42,11 +42,9 @@ result = '' + result + ''; } return result; - }; - }) + } - .factory('searchDisplayFieldCanAggregate', function() { - return function searchDisplayFieldCanAggregate(fieldName, prefix, apiParams) { + function canAggregate(fieldName, prefix, apiParams) { // If the query does not use grouping, never if (!apiParams.groupBy.length) { return false; @@ -57,6 +55,51 @@ } // If the entity this column belongs to is being grouped by id, then also no return apiParams.groupBy.indexOf(prefix + 'id') < 0; + } + + function prepareColumns(columns, apiParams) { + columns = _.cloneDeep(columns); + _.each(columns, function(col, num) { + var index = apiParams.select.indexOf(col.expr); + if (_.includes(col.expr, '(') && !_.includes(col.expr, ' AS ')) { + col.expr += ' AS column_' + num; + apiParams.select[index] += ' AS column_' + num; + } + col.key = _.last(col.expr.split(' AS ')); + }); + return columns; + } + + function prepareParams(apiParams, filters, page) { + var params = _.cloneDeep(apiParams); + if (_.isEmpty(params.where)) { + params.where = []; + } + // Select the ids of joined entities (helps with displaying links) + _.each(params.join, function(join) { + var joinEntity = join[0].split(' AS ')[1], + idField = joinEntity + '.id'; + if (!_.includes(params.select, idField) && !searchDisplayUtils.canAggregate('id', joinEntity + '.', params)) { + params.select.push(idField); + } + }); + _.each(filters, function(value, key) { + if (value) { + params.where.push([key, 'CONTAINS', value]); + } + }); + if (page) { + params.offset = (page - 1) * apiParams.limit; + params.select.push('row_count'); + } + return params; + } + + return { + formatSearchValue: formatSearchValue, + canAggregate: canAggregate, + prepareColumns: prepareColumns, + prepareParams: prepareParams }; }); diff --git a/ext/search/ang/crmSearchDisplayList/crmSearchDisplayList.component.js b/ext/search/ang/crmSearchDisplayList/crmSearchDisplayList.component.js index d5e9fa8ca7..caf250af11 100644 --- a/ext/search/ang/crmSearchDisplayList/crmSearchDisplayList.component.js +++ b/ext/search/ang/crmSearchDisplayList/crmSearchDisplayList.component.js @@ -9,45 +9,20 @@ filters: '<' }, templateUrl: '~/crmSearchDisplayList/crmSearchDisplayList.html', - controller: function($scope, crmApi4, formatSearchValue, searchDisplayFieldCanAggregate) { + controller: function($scope, crmApi4, searchDisplayUtils) { var ts = $scope.ts = CRM.ts(), ctrl = this; this.page = 1; this.$onInit = function() { - this.limit = parseInt(ctrl.settings.limit || 0, 10); - ctrl.columns = _.cloneDeep(ctrl.settings.columns); - _.each(ctrl.columns, function(col, num) { - var index = ctrl.apiParams.select.indexOf(col.expr); - if (_.includes(col.expr, '(') && !_.includes(col.expr, ' AS ')) { - col.expr += ' AS column_' + num; - ctrl.apiParams.select[index] += ' AS column_' + num; - } - col.key = _.last(col.expr.split(' AS ')); - }); + this.apiParams = _.cloneDeep(this.apiParams); + this.apiParams.limit = parseInt(this.settings.limit || 0, 10); + this.columns = searchDisplayUtils.prepareColumns(this.settings.columns, this.apiParams); }; this.getResults = function() { - var params = _.merge(_.cloneDeep(ctrl.apiParams), {limit: ctrl.limit, offset: (ctrl.page - 1) * ctrl.limit}); - if (_.isEmpty(params.where)) { - params.where = []; - } - // Select the ids of joined entities (helps with displaying links) - _.each(params.join, function(join) { - var joinEntity = join[0].split(' AS ')[1], - idField = joinEntity + '.id'; - if (!_.includes(params.select, idField) && !searchDisplayFieldCanAggregate('id', joinEntity + '.', params)) { - params.select.push(idField); - } - }); - _.each(ctrl.filters, function(value, key) { - if (value) { - params.where.push([key, 'CONTAINS', value]); - } - }); - if (ctrl.settings.pager) { - params.select.push('row_count'); - } + var params = searchDisplayUtils.prepareParams(ctrl.apiParams, ctrl.filters, ctrl.settings.pager ? ctrl.page : null); + crmApi4(ctrl.apiEntity, 'get', params).then(function(results) { ctrl.results = results; ctrl.rowCount = results.count; @@ -58,7 +33,7 @@ $scope.formatResult = function(row, col) { var value = row[col.key], - formatted = formatSearchValue(row, col, value), + formatted = searchDisplayUtils.formatSearchValue(row, col, value), output = ''; if (formatted.length || (col.label && col.forceLabel)) { if (col.label && (formatted.length || col.forceLabel)) { diff --git a/ext/search/ang/crmSearchDisplayTable/crmSearchDisplayTable.component.js b/ext/search/ang/crmSearchDisplayTable/crmSearchDisplayTable.component.js index c9ebaeeda9..8ea65c7c9e 100644 --- a/ext/search/ang/crmSearchDisplayTable/crmSearchDisplayTable.component.js +++ b/ext/search/ang/crmSearchDisplayTable/crmSearchDisplayTable.component.js @@ -9,7 +9,7 @@ filters: '<' }, templateUrl: '~/crmSearchDisplayTable/crmSearchDisplayTable.html', - controller: function($scope, crmApi4, formatSearchValue, searchDisplayFieldCanAggregate) { + controller: function($scope, crmApi4, searchDisplayUtils) { var ts = $scope.ts = CRM.ts(), ctrl = this; @@ -18,40 +18,14 @@ this.allRowsSelected = false; this.$onInit = function() { - this.orderBy = _.cloneDeep(this.apiParams.orderBy || {}); - this.limit = parseInt(ctrl.settings.limit || 0, 10); - this.columns = _.cloneDeep(ctrl.settings.columns); - _.each(ctrl.columns, function(col, num) { - var index = ctrl.apiParams.select.indexOf(col.expr); - if (_.includes(col.expr, '(') && !_.includes(col.expr, ' AS ')) { - col.expr += ' AS column_' + num; - ctrl.apiParams.select[index] += ' AS column_' + num; - } - col.key = _.last(col.expr.split(' AS ')); - }); + this.apiParams = _.cloneDeep(this.apiParams); + this.apiParams.limit = parseInt(this.settings.limit || 0, 10); + this.columns = searchDisplayUtils.prepareColumns(this.settings.columns, this.apiParams); }; this.getResults = function() { - var params = _.merge(_.cloneDeep(ctrl.apiParams), {limit: ctrl.limit, offset: (ctrl.page - 1) * ctrl.limit, orderBy: ctrl.orderBy}); - if (_.isEmpty(params.where)) { - params.where = []; - } - // Select the ids of joined entities (helps with displaying links) - _.each(params.join, function(join) { - var joinEntity = join[0].split(' AS ')[1], - idField = joinEntity + '.id'; - if (!_.includes(params.select, idField) && !searchDisplayFieldCanAggregate('id', joinEntity + '.', params)) { - params.select.push(idField); - } - }); - _.each(ctrl.filters, function(value, key) { - if (value) { - params.where.push([key, 'CONTAINS', value]); - } - }); - if (ctrl.settings.pager) { - params.select.push('row_count'); - } + var params = searchDisplayUtils.prepareParams(ctrl.apiParams, ctrl.filters, ctrl.settings.pager ? ctrl.page : null); + crmApi4(ctrl.apiEntity, 'get', params).then(function(results) { ctrl.results = results; ctrl.rowCount = results.count; @@ -66,7 +40,7 @@ * @returns {string} */ $scope.getOrderBy = function(col) { - var dir = ctrl.orderBy && ctrl.orderBy[col.key]; + var dir = ctrl.apiParams.orderBy && ctrl.apiParams.orderBy[col.key]; if (dir) { return 'fa-sort-' + dir.toLowerCase(); } @@ -80,16 +54,16 @@ */ $scope.setOrderBy = function(col, $event) { var dir = $scope.getOrderBy(col) === 'fa-sort-asc' ? 'DESC' : 'ASC'; - if (!$event.shiftKey) { - ctrl.orderBy = {}; + if (!$event.shiftKey || !ctrl.apiParams.orderBy) { + ctrl.apiParams.orderBy = {}; } - ctrl.orderBy[col.key] = dir; + ctrl.apiParams.orderBy[col.key] = dir; ctrl.getResults(); }; $scope.formatResult = function(row, col) { var value = row[col.key]; - return formatSearchValue(row, col, value); + return searchDisplayUtils.formatSearchValue(row, col, value); }; $scope.selectAllRows = function() { @@ -101,7 +75,7 @@ } // Select all ctrl.allRowsSelected = true; - if (ctrl.page === 1 && ctrl.results[1].length < ctrl.limit) { + if (ctrl.page === 1 && ctrl.results[1].length < ctrl.apiParams.limit) { ctrl.selectedRows = _.pluck(ctrl.results[1], 'id'); return; } -- 2.25.1