Also includes some cleanup of the crmSearchAdminLinkSelect component, making it more self-contained
}
};
- // Return all possible links to main entity or join entities
- this.getLinks = function() {
- var links = _.cloneDeep(searchMeta.getEntity(ctrl.savedSearch.api_entity).paths || []);
- _.each(ctrl.savedSearch.api_params.join, function(join) {
- var joinName = join[0].split(' AS '),
- joinEntity = searchMeta.getEntity(joinName[0]);
- _.each(joinEntity.paths, function(path) {
- var link = _.cloneDeep(path);
- link.path = link.path.replace(/\[/g, '[' + joinName[1] + '.');
- links.push(link);
- });
- });
- return links;
- };
-
this.preview = this.stale = false;
this.previewDisplay = function() {
angular.module('crmSearchAdmin').component('crmSearchAdminLinkSelect', {
bindings: {
column: '<',
- links: '<'
+ apiEntity: '<',
+ apiParams: '<'
},
templateUrl: '~/crmSearchAdmin/crmSearchAdminLinkSelect.html',
- controller: function ($scope, $element, $timeout) {
+ controller: function ($scope, $element, $timeout, searchMeta) {
var ts = $scope.ts = CRM.ts(),
ctrl = this;
+ // Return all possible links to main entity or join entities
+ function getLinks() {
+ var links = _.cloneDeep(searchMeta.getEntity(ctrl.apiEntity).paths || []);
+ _.each(ctrl.apiParams.join, function(join) {
+ var joinName = join[0].split(' AS '),
+ joinEntity = searchMeta.getEntity(joinName[0]);
+ _.each(joinEntity.paths, function(path) {
+ var link = _.cloneDeep(path);
+ link.path = link.path.replace(/\[/g, '[' + joinName[1] + '.');
+ links.push(link);
+ });
+ });
+ return links;
+ }
+
function onChange() {
var val = $('select', $element).val();
if (val !== ctrl.column.link) {
}
this.$onInit = function() {
+ this.links = getLinks();
+
$('select', $element).on('change', function() {
$scope.$apply(onChange);
});
{{ ts('Other...') }}
</option>
</select>
-<input class="form-control" type="text" ng-model="$ctrl.column.link" ng-model-options="{updateOn: 'blur'}" ng-show="$ctrl.column.link && !$ctrl.getLink($ctrl.column.link)" />
+<div class="form-group" ng-if="$ctrl.column.link && !$ctrl.getLink($ctrl.column.link)">
+ <input class="form-control" type="text" ng-model="$ctrl.column.link" ng-model-options="{updateOn: 'blur'}" />
+ <crm-search-admin-token-select api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams" model="$ctrl.column" field="link"></crm-search-admin-token-select>
+</div>
--- /dev/null
+(function(angular, $, _) {
+ "use strict";
+
+ angular.module('crmSearchAdmin').component('crmSearchAdminTokenSelect', {
+ bindings: {
+ apiEntity: '<',
+ apiParams: '<',
+ model: '<',
+ field: '@'
+ },
+ templateUrl: '~/crmSearchAdmin/crmSearchAdminTokenSelect.html',
+ controller: function ($scope, $element, searchMeta) {
+ var ts = $scope.ts = CRM.ts(),
+ ctrl = this;
+
+ this.initTokens = function() {
+ ctrl.tokens = ctrl.tokens || getTokens();
+ };
+
+ this.insertToken = function(key) {
+ ctrl.model[ctrl.field] = (ctrl.model[ctrl.field] || '') + ctrl.tokens[key].token;
+ };
+
+ function getTokens() {
+ var tokens = {
+ id: {
+ token: '[id]',
+ label: searchMeta.getField('id', ctrl.apiEntity).label
+ }
+ };
+ _.each(ctrl.apiParams.join, function(joinParams) {
+ var info = searchMeta.parseExpr(joinParams[0].split(' AS ')[1] + '.id');
+ tokens[info.alias] = {
+ token: '[' + info.alias + ']',
+ label: info.field ? info.field.label : info.alias
+ };
+ });
+ _.each(ctrl.apiParams.select, function(expr) {
+ var info = searchMeta.parseExpr(expr);
+ tokens[info.alias] = {
+ token: '[' + info.alias + ']',
+ label: info.field ? info.field.label : info.alias
+ };
+ });
+ return tokens;
+ }
+
+ }
+ });
+
+})(angular, CRM.$, CRM._);
--- /dev/null
+<div class="btn-group btn-group-xs">
+ <button type="button" class="btn btn-default-outline dropdown-toggle" ng-click="$ctrl.initTokens()" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ {{:: ts('Tokens') }} <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu">
+ <li ng-repeat="(id, token) in $ctrl.tokens" >
+ <a href ng-click="$ctrl.insertToken(id)">{{ token.label }}</a>
+ </li>
+ </ul>
+</div>
};
}
ctrl.hiddenColumns = ctrl.crmSearchAdminDisplay.initColumns();
- ctrl.links = ctrl.crmSearchAdminDisplay.getLinks();
};
}
</div>
<div class="form-inline">
<label>{{:: ts('Link:') }}</label>
- <crm-search-admin-link-select column="col" links="$ctrl.links"></crm-search-admin-link-select>
+ <crm-search-admin-link-select column="col" api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams"></crm-search-admin-link-select>
</div>
<div class="form-inline">
<label>{{:: ts('Tooltip:') }}</label>
<input class="form-control" type="text" ng-model="col.title" />
+ <crm-search-admin-token-select api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams" model="col" field="title"></crm-search-admin-token-select>
</div>
</fieldset>
</fieldset>
};
}
ctrl.hiddenColumns = ctrl.crmSearchAdminDisplay.initColumns();
- ctrl.links = ctrl.crmSearchAdminDisplay.getLinks();
};
}
</div>
<div class="form-inline">
<label>{{:: ts('Link:') }}</label>
- <crm-search-admin-link-select column="col" links="$ctrl.links"></crm-search-admin-link-select>
+ <crm-search-admin-link-select column="col" api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams"></crm-search-admin-link-select>
</div>
<div class="form-inline">
<label>{{:: ts('Tooltip:') }}</label>
<input class="form-control" type="text" ng-model="col.title" />
+ <crm-search-admin-token-select api-entity="$ctrl.apiEntity" api-params="$ctrl.apiParams" model="col" field="title"></crm-search-admin-token-select>
</div>
</fieldset>
</fieldset>
angular.module('crmSearchDisplay', CRM.angRequires('crmSearchDisplay'))
.factory('searchDisplayUtils', function() {
- function getUrl(link, row) {
- var url = replaceTokens(link, row);
- if (url.slice(0, 1) !== '/' && url.slice(0, 4) !== 'http') {
- url = CRM.url(url);
- }
- return _.escape(url);
- }
function replaceTokens(str, data) {
+ if (!str) {
+ return '';
+ }
_.each(data, function(value, key) {
str = str.replace('[' + key + ']', value);
});
return str;
}
+ function getUrl(link, row) {
+ var url = replaceTokens(link, row);
+ if (url.slice(0, 1) !== '/' && url.slice(0, 4) !== 'http') {
+ url = CRM.url(url);
+ }
+ return _.escape(url);
+ }
+
function formatSearchValue(row, col, value) {
var type = col.dataType,
result = value;
formatSearchValue: formatSearchValue,
canAggregate: canAggregate,
prepareColumns: prepareColumns,
- prepareParams: prepareParams
+ prepareParams: prepareParams,
+ replaceTokens: replaceTokens
};
});
this.apiParams = _.cloneDeep(this.apiParams);
this.apiParams.limit = parseInt(this.settings.limit || 0, 10);
this.columns = searchDisplayUtils.prepareColumns(this.settings.columns, this.apiParams);
+ $scope.displayUtils = searchDisplayUtils;
};
this.getResults = function() {
<li ng-repeat="row in $ctrl.results">
- <div ng-repeat="col in $ctrl.columns" ng-bind-html="formatResult(row, col)" title="{{:: col.title }}" class="{{:: col.break ? '' : 'crm-inline-block' }}">
+ <div ng-repeat="col in $ctrl.columns" ng-bind-html="formatResult(row, col)" title="{{:: displayUtils.replaceTokens(col.title, row) }}" class="{{:: col.break ? '' : 'crm-inline-block' }}">
</div>
</li>
this.apiParams = _.cloneDeep(this.apiParams);
this.apiParams.limit = parseInt(this.settings.limit || 0, 10);
this.columns = searchDisplayUtils.prepareColumns(this.settings.columns, this.apiParams);
+ $scope.displayUtils = searchDisplayUtils;
};
this.getResults = function() {
<td ng-if="$ctrl.settings.actions">
<input type="checkbox" ng-checked="isRowSelected(row)" ng-click="selectRow(row)" ng-disabled="!(!loadingAllRows && row.id)">
</td>
- <td ng-repeat="col in $ctrl.columns" ng-bind-html="formatResult(row, col)" title="{{:: col.title }}" class="{{:: col.alignment }}">
+ <td ng-repeat="col in $ctrl.columns" ng-bind-html="formatResult(row, col)" title="{{:: displayUtils.replaceTokens(col.title, row) }}" class="{{:: col.alignment }}">
</td>
<td></td>
</tr>