CRM-19778 - Configuration ui for case statuses per case-type
authorColeman Watts <coleman@civicrm.org>
Fri, 20 Jan 2017 23:52:07 +0000 (18:52 -0500)
committerColeman Watts <coleman@civicrm.org>
Tue, 24 Jan 2017 15:52:08 +0000 (10:52 -0500)
CRM/Admin/Form/Options.php
CRM/Case/BAO/CaseType.php
ang/crmCaseType.js
ang/crmCaseType/activityTypesTable.html
ang/crmCaseType/edit.html
ang/crmCaseType/statusTable.html [new file with mode: 0644]

index 5752d341d1805a1fd3b0cbb284e7d06205c154ea..670a21688a3c503f6ceb2d010b4e7c60b2c58519 100644 (file)
@@ -488,6 +488,8 @@ class CRM_Admin_Form_Options extends CRM_Admin_Form {
             1 => $this->_gLabel,
             2 => $optionValue->label,
           )), ts('Saved'), 'success');
+
+      $this->ajaxResponse['optionValue'] = $optionValue->toArray();
     }
   }
 
index b06d7b3dc25a066e855f7c06af418c339c05d193..65a49863bfaf7022bfe71629b9bcfeded3365724 100644 (file)
@@ -130,6 +130,14 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType {
       $xmlFile .= "</ActivityTypes>\n";
     }
 
+    if (!empty($definition['statuses'])) {
+      $xmlFile .= "<Statuses>\n";
+      foreach ($definition['statuses'] as $value) {
+        $xmlFile .= "<Status>$value</Status>\n";
+      }
+      $xmlFile .= "</Statuses>\n";
+    }
+
     if (isset($definition['activitySets'])) {
       $xmlFile .= "<ActivitySets>\n";
       foreach ($definition['activitySets'] as $k => $val) {
@@ -224,6 +232,11 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType {
       }
     }
 
+    // set statuses
+    if (isset($xml->Statuses)) {
+      $definition['statuses'] = (array) $xml->Statuses->Status;
+    }
+
     // set activity sets
     if (isset($xml->ActivitySets)) {
       $definition['activitySets'] = array();
index e5aae2a3516ab068056a6c2f620bcf4fca969282..31f85c9b2f6d085ff1b31acbca60e01be15a143d 100644 (file)
           apiCalls: function($route, crmApi) {
             var reqs = {};
             reqs.actStatuses = ['OptionValue', 'get', {
-              option_group_id: 'activity_status'
+              option_group_id: 'activity_status',
+              sequential: 1,
+              options: {limit: 0}
+            }];
+            reqs.caseStatuses = ['OptionValue', 'get', {
+              option_group_id: 'case_status',
+              sequential: 1,
+              options: {limit: 0}
             }];
             reqs.actTypes = ['OptionValue', 'get', {
               option_group_id: 'activity_type',
   crmCaseType.controller('CaseTypeCtrl', function($scope, crmApi, apiCalls) {
     var ts = $scope.ts = CRM.ts(null);
 
-    $scope.activityStatuses = _.values(apiCalls.actStatuses.values);
+    $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.caseType.definition.activityTypes = $scope.caseType.definition.activityTypes || [];
     $scope.caseType.definition.activitySets = $scope.caseType.definition.activitySets || [];
     $scope.caseType.definition.caseRoles = $scope.caseType.definition.caseRoles || [];
-    window.ct = $scope.caseType;
+    $scope.caseType.definition.statuses = $scope.caseType.definition.statuses || [];
+
+    $scope.selectedStatuses = {};
+    _.each(apiCalls.caseStatuses.values, function (status) {
+      $scope.selectedStatuses[status.name] = !$scope.caseType.definition.statuses.length || $scope.caseType.definition.statuses.indexOf(status.name) > -1;
+    });
 
     $scope.addActivitySet = function(workflow) {
       var activitySet = {};
       return !$scope.caseType.id || $scope.caseType.is_forkable;
     };
 
+    $scope.newStatus = function() {
+      CRM.loadForm(CRM.url('civicrm/admin/options/case_status', {action: 'add', reset: 1}))
+        .on('crmFormSuccess', function(e, data) {
+          $scope.caseStatuses[data.optionValue.name] = data.optionValue;
+          $scope.selectedStatuses[data.optionValue.name] = true;
+          $scope.$digest();
+        });
+    };
+
     $scope.isNewActivitySetAllowed = function(workflow) {
       switch (workflow) {
         case 'timeline':
     };
 
     $scope.save = function() {
+      // Add selected statuses
+      var selectedStatuses = [];
+      _.each($scope.selectedStatuses, function(v, k) {
+        if (v) selectedStatuses.push(k);
+      });
+      // Ignore if ALL or NONE selected
+      $scope.caseType.definition.statuses = selectedStatuses.length == _.size($scope.selectedStatuses) ? [] : selectedStatuses;
       var result = crmApi('CaseType', 'create', $scope.caseType, true);
       result.then(function(data) {
         if (data.is_error === 0 || data.is_error == '0') {
index bceb0856db6197dee97520927559d5c5a5a04c34..966f9754882af97e8205f3e2ef10754fd49c0a37 100644 (file)
@@ -2,7 +2,7 @@
 Controller: CaseTypeCtrl
 Required vars: caseType
 -->
-<table>
+<table class="row-highlight">
   <thead>
   <tr>
     <th>{{ts('Activity Type')}}</th>
index b73e01caf17bbb7fe7da436ac5d47c11de506128..19bcae0d57d45250154730b0bfc0b26e4f8ff987 100644 (file)
@@ -28,6 +28,7 @@ Required vars: caseType
   <div ng-show="isForkable()" class="crmCaseType-acttab" ui-jq="tabs" ui-options="{show: true, hide: true}">
     <ul>
       <li><a href="#acttab-actType">{{ts('Activity Types')}}</a></li>
+      <li><a href="#acttab-statuses">{{ts('Statuses')}}</a></li>
       <li ng-repeat="activitySet in caseType.definition.activitySets">
         <a href="#acttab-{{$index}}">{{ activitySet.label }}</a>
         <span class="crm-i fa-trash" title="{{ts('Remove')}}"
@@ -46,9 +47,9 @@ Required vars: caseType
       </select>
     </ul>
 
-    <div id="acttab-actType">
-      <div ng-include="'~/crmCaseType/activityTypesTable.html'"></div>
-    </div>
+    <div id="acttab-actType" ng-include="'~/crmCaseType/activityTypesTable.html'"></div>
+
+    <div id="acttab-statuses" ng-include="'~/crmCaseType/statusTable.html'"></div>
 
     <div ng-repeat="activitySet in caseType.definition.activitySets" id="acttab-{{$index}}">
       <div ng-include="activityTableTemplate(activitySet)"></div>
diff --git a/ang/crmCaseType/statusTable.html b/ang/crmCaseType/statusTable.html
new file mode 100644 (file)
index 0000000..890989a
--- /dev/null
@@ -0,0 +1,35 @@
+<!--
+Controller: CaseTypeCtrl
+Required vars: selectedStatuses
+-->
+<table>
+  <thead>
+  <tr>
+    <th></th>
+    <th>{{ts('Name')}}</th>
+    <th>{{ts('Class')}}</th>
+  </tr>
+  </thead>
+
+  <tbody ng-model="selectedStatuses">
+  <tr ng-repeat="(status,sel) in selectedStatuses">
+    <td>
+      <input class="crm-form-checkbox" type="checkbox" ng-model="selectedStatuses[status]"/>
+    </td>
+    <td>
+      {{ caseStatuses[status].label }}
+    </td>
+    <td>
+      {{ caseStatuses[status].grouping }}
+    </td>
+  </tr>
+  </tbody>
+
+  <tfoot>
+  <tr>
+    <td></td>
+    <td><a class="crm-hover-button action-item" ng-click="newStatus()" href><i class="crm-i fa-plus"></i> {{ ts('New Status') }}</a></td>
+    <td></td>
+  </tr>
+  </tfoot>
+</table>