--CRM-15055, code changes to handle separate membership
[civicrm-core.git] / js / angular-crmCaseType.js
index 5670a92dc16f0fb7993d603e85e6bdb979688d5e..ea2ca50d48740ca70393d3534a642bf7b76ba7be 100644 (file)
@@ -4,25 +4,36 @@
     return CRM.resourceUrls['civicrm'] + '/partials/crmCaseType/' + relPath;
   };
 
-  var crmCaseType = angular.module('crmCaseType', ['ngRoute', 'ui.utils']);
-
-  var newCaseTypeDefinitionTemplate = {
-    activityTypes: [
-      {name: 'Open Case', max_instances: 1 }
-    ],
-    activitySets: [
-      {
-        name: 'standard_timeline',
-        label: 'Standard Timeline',
-        timeline: '1', // Angular won't bind checkbox correctly with numeric 1
-        activityTypes: [
-          {name: 'Open Case', status: 'Completed' }
-        ]
-      }
-    ],
-    caseRoles: [
-      { name: 'Case Coordinator', creator: '1', manager: '1'}
-    ]
+  var crmCaseType = angular.module('crmCaseType', ['ngRoute', 'ui.utils', 'crmUi', 'unsavedChanges']);
+
+  // Note: This template will be passed to cloneDeep(), so don't put any funny stuff in here!
+  var newCaseTypeTemplate = {
+    title: "",
+    name: "",
+    is_active: "1",
+    weight: "1",
+    definition: {
+      activityTypes: [
+        {name: 'Open Case', max_instances: 1},
+        {name: 'Email'},
+        {name: 'Follow up'},
+        {name: 'Meeting'},
+        {name: 'Phone Call'}
+      ],
+      activitySets: [
+        {
+          name: 'standard_timeline',
+          label: 'Standard Timeline',
+          timeline: '1', // Angular won't bind checkbox correctly with numeric 1
+          activityTypes: [
+            {name: 'Open Case', status: 'Completed' }
+          ]
+        }
+      ],
+      caseRoles: [
+        { name: 'Case Coordinator', creator: '1', manager: '1'}
+      ]
+    }
   };
 
   crmCaseType.config(['$routeProvider',
         templateUrl: partialUrl('edit.html'),
         controller: 'CaseTypeCtrl',
         resolve: {
-          selectedCaseType: function($route, crmApi) {
-            if ( $route.current.params.id !== 'new') {
-              return crmApi('CaseType', 'getsingle', {id: $route.current.params.id});
-            }
-            else {
-              return { title: "", name: "", is_active: "1", weight: "1",
-                definition: _.extend({}, newCaseTypeDefinitionTemplate) };
+          apiCalls: function($route, crmApi) {
+            var reqs = {};
+            reqs.actStatuses = ['OptionValue', 'get', {
+              option_group_id: 'activity_status'
+            }];
+            reqs.actTypes = ['OptionValue', 'get', {
+              option_group_id: 'activity_type',
+              options: {
+                sort: 'name',
+                limit: 0
+              }
+            }];
+            reqs.relTypes = ['RelationshipType', 'get', {
+              options: {
+                sort: CRM.crmCaseType.REL_TYPE_CNAME,
+                limit: 0
+              }
+            }];
+            if ($route.current.params.id !== 'new') {
+              reqs.caseType = ['CaseType', 'getsingle', {
+                id: $route.current.params.id
+              }];
             }
+            return crmApi(reqs);
           }
         }
       });
     };
   });
 
-  crmCaseType.controller('CaseTypeCtrl', function($scope, crmApi, selectedCaseType) {
+  crmCaseType.controller('CaseTypeCtrl', function($scope, crmApi, apiCalls) {
     $scope.partialUrl = partialUrl;
 
-    $scope.activityStatuses = CRM.crmCaseType.actStatuses;
-    $scope.activityTypes = CRM.crmCaseType.actTypes;
-    $scope.activityTypeNames = _.pluck(CRM.crmCaseType.actTypes, 'name');
-    $scope.relationshipTypeNames = _.pluck(CRM.crmCaseType.relTypes, 'label_b_a'); // label_b_a is CRM_Case_XMLProcessor::REL_TYPE_CNAME
+    $scope.activityStatuses = _.values(apiCalls.actStatuses.values);
+    $scope.activityTypes = apiCalls.actTypes.values;
+    $scope.activityTypeNames = _.pluck(apiCalls.actTypes.values, 'name');
+    $scope.relationshipTypeNames = _.pluck(apiCalls.relTypes.values, CRM.crmCaseType.REL_TYPE_CNAME); // CRM_Case_XMLProcessor::REL_TYPE_CNAME
+    $scope.locks = {caseTypeName: true, activitySetName: true};
 
     $scope.workflows = {
       'timeline': 'Timeline',
       'sequence': 'Sequence'
     };
 
-    $scope.caseType = selectedCaseType;
+    $scope.caseType = apiCalls.caseType ? apiCalls.caseType : _.cloneDeep(newCaseTypeTemplate);
     $scope.caseType.definition = $scope.caseType.definition || [];
     $scope.caseType.definition.activityTypes = $scope.caseType.definition.activityTypes || [];
     $scope.caseType.definition.activitySets = $scope.caseType.definition.activitySets || [];
     /// Add a new activity entry to an activity-set
     $scope.addActivity = function(activitySet, activityType) {
       activitySet.activityTypes.push({
-        name: activityType
+        name: activityType,
+        status: 'Scheduled',
+        reference_activity: 'Open Case',
+        reference_offset: '1',
+        reference_select: 'newest'
       });
       if (!_.contains($scope.activityTypeNames, activityType)) {
         $scope.activityTypeNames.push(activityType);
       }
     };
 
+    $scope.isForkable = function() {
+      return !$scope.caseType.id || $scope.caseType.is_forkable
+    };
+
     $scope.isNewActivitySetAllowed = function(workflow) {
       switch (workflow) {
         case 'timeline':
       }
     };
 
+    $scope.isActivityRemovable = function(activitySet, activity) {
+      if (activitySet.name == 'standard_timeline' && activity.name == 'Open Case') {
+        return false;
+      } else {
+        return true;
+      }
+    };
+
+    $scope.isValidName = function(name) {
+      return !name || name.match(/^[a-zA-Z0-9_]+$/);
+    };
+
     $scope.getWorkflowName = function(activitySet) {
       var result = 'Unknown';
       _.each($scope.workflows, function(value, key) {
       result.success(function(data) {
         if (data.is_error == 0) {
           $scope.caseType.id = data.id;
+          window.location.href = '#/caseType';
         }
       });
     };
         $('.crmCaseType-acttab').tabs('refresh');
       });
     });
+
+    var updateCaseTypeName = function () {
+      if (!$scope.caseType.id && $scope.locks.caseTypeName) {
+        // Should we do some filtering? Lowercase? Strip whitespace?
+        var t = $scope.caseType.title ? $scope.caseType.title : '';
+        $scope.caseType.name = t.replace(/ /g, '_').replace(/[^a-zA-Z0-9_]/g, '').toLowerCase();
+      }
+    };
+    $scope.$watch('locks.caseTypeName', updateCaseTypeName);
+    $scope.$watch('caseType.title', updateCaseTypeName);
+
+    if (!$scope.isForkable()) {
+      CRM.alert(ts('The CiviCase XML file for this case-type prohibits editing the definition.'));
+    }
   });
 
   crmCaseType.controller('CaseTypeListCtrl', function($scope, crmApi, caseTypes) {
     $scope.caseTypes = caseTypes.values;
+    $scope.toggleCaseType = function (caseType) {
+      caseType.is_active = (caseType.is_active == '1') ? '0' : '1';
+      crmApi('CaseType', 'create', caseType, true)
+        .then(function (data) {
+          if (data.is_error) {
+            caseType.is_active = (caseType.is_active == '1') ? '0' : '1'; // revert
+            $scope.$digest();
+          }
+        });
+    };
+    $scope.deleteCaseType = function (caseType) {
+      crmApi('CaseType', 'delete', {id: caseType.id}, {
+        error: function (data) {
+          CRM.alert(data.error_message, ts('Error'));
+        }
+      })
+        .then(function (data) {
+          if (!data.is_error) {
+            delete caseTypes.values[caseType.id];
+            $scope.$digest();
+          }
+        });
+    };
+    $scope.revertCaseType = function (caseType) {
+      caseType.definition = 'null';
+      caseType.is_forked = '0';
+      crmApi('CaseType', 'create', caseType, true)
+        .then(function (data) {
+          if (data.is_error) {
+            caseType.is_forked = '1'; // restore
+            $scope.$digest();
+          }
+        });
+    };
   });
 
 })(angular, CRM.$, CRM._);
\ No newline at end of file