diff --git a/CRM/Admin/Form.php b/CRM/Admin/Form.php index da05b0a1128..cc3186887fc 100644 --- a/CRM/Admin/Form.php +++ b/CRM/Admin/Form.php @@ -90,6 +90,7 @@ public function preProcess() { * @return array */ public function setDefaultValues() { + // Fetch defaults from the db if (isset($this->_id) && empty($this->_values)) { $this->_values = array(); $params = array('id' => $this->_id); @@ -98,6 +99,15 @@ public function setDefaultValues() { } $defaults = $this->_values; + // Allow defaults to be set from the url + if (empty($this->_id) && $this->_action & CRM_Core_Action::ADD) { + foreach ($_GET as $key => $val) { + if ($this->elementExists($key)) { + $defaults[$key] = $val; + } + } + } + if ($this->_action == CRM_Core_Action::DELETE && isset($defaults['name']) ) { diff --git a/CRM/Admin/Form/RelationshipType.php b/CRM/Admin/Form/RelationshipType.php index 13e6815a606..b74ba659b8e 100644 --- a/CRM/Admin/Form/RelationshipType.php +++ b/CRM/Admin/Form/RelationshipType.php @@ -137,7 +137,6 @@ public function postProcess() { CRM_Core_Session::setStatus(ts('Selected Relationship type has been deleted.'), ts('Record Deleted'), 'success'); } else { - $params = array(); $ids = array(); // store the submitted values in an array @@ -163,7 +162,9 @@ public function postProcess() { $params['contact_sub_type_a'] = $cTypeA[1] ? $cTypeA[1] : 'NULL'; $params['contact_sub_type_b'] = $cTypeB[1] ? $cTypeB[1] : 'NULL'; - CRM_Contact_BAO_RelationshipType::add($params, $ids); + $result = CRM_Contact_BAO_RelationshipType::add($params, $ids); + + $this->ajaxResponse['relationshipType'] = $result->toArray(); CRM_Core_Session::setStatus(ts('The Relationship Type has been saved.'), ts('Saved'), 'success'); } diff --git a/ang/crmCaseType.css b/ang/crmCaseType.css index fa8edc12723..d5fa1d62208 100644 --- a/ang/crmCaseType.css +++ b/ang/crmCaseType.css @@ -2,7 +2,7 @@ vertical-align: middle; cursor: move; } -.crmCaseType .crm-i { +.crmCaseType .fa-trash { margin: 0.4em 0.2em 0 0; cursor: pointer; } diff --git a/ang/crmCaseType.js b/ang/crmCaseType.js index 31f85c9b2f6..d1765d5c4ca 100644 --- a/ang/crmCaseType.js +++ b/ang/crmCaseType.js @@ -61,12 +61,14 @@ }]; reqs.actTypes = ['OptionValue', 'get', { option_group_id: 'activity_type', + sequential: 1, options: { sort: 'name', limit: 0 } }]; reqs.relTypes = ['RelationshipType', 'get', { + sequential: 1, options: { sort: CRM.crmCaseType.REL_TYPE_CNAME, limit: 0 @@ -91,14 +93,6 @@ restrict: 'AE', template: '', link: function(scope, element, attrs) { - /// Format list of options for select2's "data" - var getFormattedOptions = function() { - return { - results: _.map(scope[attrs.crmOptions], function(option){ - return {id: option, text: option}; - }) - }; - }; var input = $('input', element); @@ -108,11 +102,12 @@ scope[attrs.crmVar] = ''; }; - $(input).select2({ - data: getFormattedOptions, + $(input).crmSelect2({ + data: scope[attrs.crmOptions], createSearchChoice: function(term) { - return {id: term, text: term}; + return {id: term, text: term + ' (' + ts('new') + ')'}; }, + createSearchChoicePosition: 'bottom', placeholder: attrs.placeholder }); $(input).on('select2-selecting', function(e) { @@ -123,7 +118,7 @@ }); scope.$watch(attrs.crmOptions, function(value) { - $(input).select2('data', getFormattedOptions); + $(input).select2('data', scope[attrs.crmOptions]); $(input).select2('val', ''); }); } @@ -131,14 +126,18 @@ }); crmCaseType.controller('CaseTypeCtrl', function($scope, crmApi, apiCalls) { - var ts = $scope.ts = CRM.ts(null); + // CRM_Case_XMLProcessor::REL_TYPE_CNAME + var REL_TYPE_CNAME = CRM.crmCaseType.REL_TYPE_CNAME, + + ts = $scope.ts = CRM.ts(null); $scope.activityStatuses = apiCalls.actStatuses.values; $scope.caseStatuses = _.indexBy(apiCalls.caseStatuses.values, 'name'); - $scope.activityTypes = apiCalls.actTypes.values; - $scope.activityTypeNames = _.pluck(apiCalls.actTypes.values, 'name'); - $scope.activityTypes = apiCalls.actTypes.values; - $scope.relationshipTypeNames = _.pluck(apiCalls.relTypes.values, CRM.crmCaseType.REL_TYPE_CNAME); // CRM_Case_XMLProcessor::REL_TYPE_CNAME + $scope.activityTypes = _.indexBy(apiCalls.actTypes.values, 'name'); + $scope.activityTypeOptions = _.map(apiCalls.actTypes.values, formatActivityTypeOption); + $scope.relationshipTypeOptions = _.map(apiCalls.relTypes.values, function(type) { + return {id: type[REL_TYPE_CNAME], text: type.label_b_a}; + }); $scope.locks = {caseTypeName: true, activitySetName: true}; $scope.workflows = { @@ -175,17 +174,38 @@ }); }; - /// Add a new activity entry to an activity-set - $scope.addActivity = function(activitySet, activityType) { + function formatActivityTypeOption(type) { + return {id: type.name, text: type.label, icon: type.icon}; + } + + function addActivityToSet(activitySet, activityTypeName) { activitySet.activityTypes.push({ - name: activityType, + name: activityTypeName, status: 'Scheduled', reference_activity: 'Open Case', reference_offset: '1', reference_select: 'newest' }); - if (!_.contains($scope.activityTypeNames, activityType)) { - $scope.activityTypeNames.push(activityType); + } + + function createActivity(name, callback) { + CRM.loadForm(CRM.url('civicrm/admin/options/activity_type', {action: 'add', reset: 1, label: name, component_id: 7})) + .on('crmFormSuccess', function(e, data) { + $scope.activityTypes[data.optionValue.name] = data.optionValue; + $scope.activityTypeOptions.push(formatActivityTypeOption(data.optionValue)); + callback(data.optionValue); + $scope.$digest(); + }); + } + + // Add a new activity entry to an activity-set + $scope.addActivity = function(activitySet, activityType) { + if ($scope.activityTypes[activityType]) { + addActivityToSet(activitySet, activityType); + } else { + createActivity(activityType, function(newActivity) { + addActivityToSet(activitySet, newActivity.name); + }); } }; @@ -193,13 +213,14 @@ $scope.addActivityType = function(activityType) { var names = _.pluck($scope.caseType.definition.activityTypes, 'name'); if (!_.contains(names, activityType)) { - $scope.caseType.definition.activityTypes.push({ - name: activityType - }); - - } - if (!_.contains($scope.activityTypeNames, activityType)) { - $scope.activityTypeNames.push(activityType); + // Add an activity type that exists + if ($scope.activityTypes[activityType]) { + $scope.caseType.definition.activityTypes.push({name: activityType}); + } else { + createActivity(activityType, function(newActivity) { + $scope.caseType.definition.activityTypes.push({name: newActivity.name}); + }); + } } }; @@ -207,12 +228,16 @@ $scope.addRole = function(roles, roleName) { var names = _.pluck($scope.caseType.definition.caseRoles, 'name'); if (!_.contains(names, roleName)) { - roles.push({ - name: roleName - }); - } - if (!_.contains($scope.relationshipTypeNames, roleName)) { - $scope.relationshipTypeNames.push(roleName); + if (_.where($scope.relationshipTypeOptions, {id: roleName}).length) { + roles.push({name: roleName}); + } else { + CRM.loadForm(CRM.url('civicrm/admin/reltype', {action: 'add', reset: 1, label_a_b: roleName, label_b_a: roleName})) + .on('crmFormSuccess', function(e, data) { + roles.push({name: data.relationshipType[REL_TYPE_CNAME]}); + $scope.relationshipTypeOptions.push({id: data.relationshipType[REL_TYPE_CNAME], text: data.relationshipType.label_b_a}); + $scope.$digest(); + }); + } } }; diff --git a/ang/crmCaseType/activityTypesTable.html b/ang/crmCaseType/activityTypesTable.html index 966f9754882..a5d94e07e05 100644 --- a/ang/crmCaseType/activityTypesTable.html +++ b/ang/crmCaseType/activityTypesTable.html @@ -5,6 +5,7 @@ + @@ -15,10 +16,13 @@ + + + @@ -14,6 +15,9 @@ + + @@ -18,6 +19,9 @@ + {/if} diff --git a/tests/karma/unit/crmCaseTypeSpec.js b/tests/karma/unit/crmCaseTypeSpec.js index 3b5d630723a..3c20dc32c3f 100644 --- a/tests/karma/unit/crmCaseTypeSpec.js +++ b/tests/karma/unit/crmCaseTypeSpec.js @@ -6,6 +6,7 @@ describe('crmCaseType', function() { CRM.resourceUrls = { 'civicrm': '' }; + // CRM_Case_XMLProcessor::REL_TYPE_CNAME CRM.crmCaseType = { 'REL_TYPE_CNAME': 'label_b_a' }; @@ -30,9 +31,9 @@ describe('crmCaseType', function() { compile = $compile; timeout = $timeout; apiCalls = { - 'actStatuses': { - 'values': { - "272": { + actStatuses: { + values: [ + { "id": "272", "option_group_id": "25", "label": "Scheduled", @@ -45,7 +46,7 @@ describe('crmCaseType', function() { "is_reserved": "1", "is_active": "1" }, - "273": { + { "id": "273", "option_group_id": "25", "label": "Completed", @@ -57,11 +58,42 @@ describe('crmCaseType', function() { "is_reserved": "1", "is_active": "1" } - } + ] }, - 'actTypes': { - 'values': { - "784": { + caseStatuses: { + values: [ + { + "id": "290", + "option_group_id": "28", + "label": "Ongoing", + "value": "1", + "name": "Open", + "grouping": "Opened", + "filter": "0", + "is_default": "1", + "weight": "1", + "is_optgroup": "0", + "is_reserved": "1", + "is_active": "1" + }, + { + "id": "291", + "option_group_id": "28", + "label": "Resolved", + "value": "2", + "name": "Closed", + "grouping": "Closed", + "filter": "0", + "weight": "2", + "is_optgroup": "0", + "is_reserved": "1", + "is_active": "1" + } + ] + }, + actTypes: { + values: [ + { "id": "784", "option_group_id": "2", "label": "ADC referral", @@ -75,7 +107,7 @@ describe('crmCaseType', function() { "is_active": "1", "component_id": "7" }, - "32": { + { "id": "32", "option_group_id": "2", "label": "Add Client To Case", @@ -90,11 +122,11 @@ describe('crmCaseType', function() { "is_active": "1", "component_id": "7" } - } + ] }, - 'relTypes': { - 'values' : { - "14": { + relTypes: { + values: [ + { "id": "14", "name_a_b": "Benefits Specialist is", "label_a_b": "Benefits Specialist is", @@ -106,7 +138,7 @@ describe('crmCaseType', function() { "is_reserved": "0", "is_active": "1" }, - "9": { + { "id": "9", "name_a_b": "Case Coordinator is", "label_a_b": "Case Coordinator is", @@ -118,9 +150,9 @@ describe('crmCaseType', function() { "is_reserved": "0", "is_active": "1" } - } + ] }, - "caseType": { + caseType: { "id": "1", "name": "housing_support", "title": "Housing Support", @@ -167,11 +199,11 @@ describe('crmCaseType', function() { })); it('should load activity statuses', function() { - expect(scope.activityStatuses).toEqualData([apiCalls.actStatuses.values['272'], apiCalls.actStatuses.values['273']]); + expect(scope.activityStatuses).toEqualData(apiCalls.actStatuses.values); }); it('should load activity types', function() { - expect(scope.activityTypes).toEqualData(apiCalls.actTypes.values); + expect(scope.activityTypes['ADC referral']).toEqualData(apiCalls.actTypes.values[0]); }); it('addActivitySet should add an activitySet to the case type', function() {
{{ts('Activity Type')}} {{ts('Max Instances')}}
+ + {{ activityType.name }} - + @@ -28,9 +32,10 @@
{{ts('Activity')}}
+ + {{ activity.name }} @@ -26,7 +30,7 @@
{{ts('Activity')}} {{ts('Status')}} {{ts('Reference')}}
+ + {{ activity.name }} @@ -43,7 +47,7 @@ {$form.value.label} {$form.value.html}
+ {if $action == 2} {ts}Changing the Value field will unlink records which have been marked with this option. This change can not be undone except by restoring the previous value.{/ts} + {/if}