$loader->setModules(['search']);
$loader->setPageName('civicrm/search');
$loader->useApp([
- 'defaultRoute' => '/Contact',
+ 'defaultRoute' => '/create/Contact',
]);
$loader->load();
parent::run();
"use strict";
// Shared between router and searchMeta service
- var searchEntity;
+ var searchEntity,
+ // For loading saved search
+ savedSearch,
+ undefined;
// Declare module and route/controller/services
angular.module('search', CRM.angRequires('search'))
.config(function($routeProvider) {
- $routeProvider.when('/:entity', {
+ $routeProvider.when('/:mode/:entity/:name?', {
controller: 'searchRoute',
- template: '<div id="bootstrap-theme" class="crm-search"><crm-search entity="entity"></crm-search></div>',
- reloadOnSearch: false
+ template: '<div id="bootstrap-theme" class="crm-search"><crm-search ng-if="$ctrl.mode === \'create\'" entity="$ctrl.entity" load=":: $ctrl.savedSearch"></crm-search></div>',
+ reloadOnSearch: false,
+ resolve: {
+ // For paths like /load/Group/MySmartGroup, load the group, stash it in the savedSearch variable, and then redirect
+ // For paths like /create/Contact, return the stashed savedSearch if present
+ savedSearch: function($route, $location, $timeout, crmApi4) {
+ var retrievedSearch = savedSearch,
+ params = $route.current.params;
+ savedSearch = undefined;
+ switch (params.mode) {
+ case 'create':
+ return retrievedSearch;
+
+ case 'load':
+ // In theory savedSearches could be attached to something other than groups, but for now that's not supported
+ if (params.entity !== 'Group' || !params.name) {
+ throw 'Failed to load ' + params.entity;
+ }
+ return crmApi4(params.entity, 'get', {
+ select: ['id', 'title', 'saved_search_id', 'saved_search.api_entity', 'saved_search.api_params'],
+ where: [['name', '=', params.name]]
+ }, 0).then(function(retrieved) {
+ savedSearch = {
+ type: params.entity,
+ id: retrieved.id,
+ title: retrieved.title,
+ saved_search_id: retrieved.saved_search_id,
+ api_params: retrieved['saved_search.api_params']
+ };
+ $timeout(function() {
+ $location.url('/create/' + retrieved['saved_search.api_entity']);
+ });
+ });
+ }
+ }
+ }
});
})
// Controller binds entity to route
- .controller('searchRoute', function($scope, $routeParams, $location) {
- searchEntity = $scope.entity = $routeParams.entity;
+ .controller('searchRoute', function($scope, $routeParams, $location, savedSearch) {
+ searchEntity = this.entity = $routeParams.entity;
+ this.mode = $routeParams.mode;
+ this.savedSearch = savedSearch;
+ $scope.$ctrl = this;
// Changing entity will refresh the angular page
- $scope.$watch('entity', function(newEntity, oldEntity) {
+ $scope.$watch('$ctrl.entity', function(newEntity, oldEntity) {
if (newEntity && oldEntity && newEntity !== oldEntity) {
- $location.url('/' + newEntity);
+ $location.url('/create/' + newEntity);
}
});
})
(function(angular, $, _) {
"use strict";
- angular.module('search').controller('SaveSmartGroup', function ($scope, crmApi4, dialogService) {
+ angular.module('search').controller('SaveSmartGroup', function ($scope, $element, crmApi4, dialogService) {
var ts = $scope.ts = CRM.ts(),
model = $scope.model;
$scope.groupEntityRefParams = {
administerReservedGroups: CRM.checkPerm('administer reserved groups')
};
$scope.groupFields = _.indexBy(_.find(CRM.vars.search.schema, {name: 'Group'}).fields, 'name');
- $scope.$watch('model.id', function (id) {
- if (id) {
- _.assign(model, $('#api-save-search-select-group').select2('data').extra);
+ $element.on('change', '#api-save-search-select-group', function() {
+ if ($(this).val()) {
+ $scope.$apply(function() {
+ var group = $('#api-save-search-select-group').select2('data').extra;
+ model.saved_search_id = group.saved_search_id;
+ model.description = group.description || '';
+ model.group_type = group.group_type || [];
+ model.visibility = group.visibility;
+ });
}
});
$scope.cancel = function () {
angular.module('search').component('crmSearch', {
bindings: {
- entity: '='
+ entity: '=',
+ load: '<'
},
templateUrl: '~/search/crmSearch.html',
controller: function($scope, $element, $timeout, crmApi4, dialogService, searchMeta, formatForSelect2) {
ctrl.stale = true;
}
}
+ if (ctrl.load) {
+ ctrl.load.saved = false;
+ }
}
function onChangeOrderBy() {
function onChangeFilters() {
ctrl.stale = true;
ctrl.selectedRows.length = 0;
+ if (ctrl.load) {
+ ctrl.load.saved = false;
+ }
if (ctrl.autoSearch) {
ctrl.refreshAll();
}
}
$scope.$watch('$ctrl.params.having', onChangeFilters, true);
+ if (this.load) {
+ this.params = this.load.api_params;
+ $timeout(function() {
+ ctrl.load.saved = true;
+ });
+ }
+
loadFieldOptions();
};
description: '',
visibility: 'User and User Admin Only',
group_type: [],
- id: null,
+ id: ctrl.load ? ctrl.load.id : null,
entity: ctrl.entity,
- params: angular.extend({}, ctrl.params, {version: 4, select: [selectField]})
+ params: angular.extend({}, ctrl.params, {version: 4})
};
delete model.params.orderBy;
var options = CRM.utils.adjustDialogDefaults({
autoOpen: false,
title: ts('Save smart group')
});
- dialogService.open('saveSearchDialog', '~/search/saveSmartGroup.html', model, options);
+ dialogService.open('saveSearchDialog', '~/search/saveSmartGroup.html', model, options)
+ .then(function() {
+ if (ctrl.load) {
+ ctrl.load.saved = true;
+ }
+ });
};
}
});
<div>
<div class="form-inline">
<label for="crm-search-main-entity">{{:: ts('Search for') }}</label>
- <input id="crm-search-main-entity" class="form-control" ng-model="$ctrl.entity" crm-ui-select="::{allowClear: false, data: entities}" ng-change="changeEntity()" />
+ <input id="crm-search-main-entity" class="form-control" ng-model="$ctrl.entity" crm-ui-select="::{allowClear: false, data: entities}" />
</div>
<div ng-if=":: $ctrl.paramExists('join')">
<fieldset ng-repeat="join in $ctrl.params.join">
</fieldset>
</div>
<div>
+ <div class="navbar-form clearfix" ng-if="$ctrl.load">
+ <div class="form-group pull-right">
+ <label>{{ $ctrl.load.title }}</label>
+ <button class="btn btn-default" ng-disabled="$ctrl.load.saved" ng-click="saveGroup()">{{ $ctrl.load.saved ? ts('Saved') : ts('Save') }}</button>
+ </div>
+ </div>
<fieldset class="api4-clause-fieldset" crm-search-clause="{format: 'string', clauses: $ctrl.params.where, op: 'AND', label: ts('Where'), fields: fieldsForWhere}">
</fieldset>
<fieldset ng-if="$ctrl.paramExists('having') && $ctrl.params.groupBy.length" class="api4-clause-fieldset" crm-search-clause="{format: 'string', clauses: $ctrl.params.having, op: 'AND', label: ts('Filter'), fields: fieldsForHaving}">