<commit_before>define([
  'angular',
  'camunda-bpm-sdk',
  './cam-tasklist-filter-form-criteria',
  'text!./cam-tasklist-filter-form.html'
], function(
  angular,
  camSDK,
  criteria,
  template
) {
  'use strict';

  var each = angular.forEach;
  var copy = angular.copy;

  var expressionsExp = /^[\s]*(\#|\$)\{/;
  function fixExpressions(arr) {
    each(arr, function(obj, i) {
      console.info('key is', obj.key, 'value is expression', expressionsExp.test(obj.value));
      if (expressionsExp.test(obj.value) && obj.key.indexOf('Expression') === -1) {
        arr[i].key = 'task'+ obj.key[0].toUpperCase() + obj.key.slice(1) +'Expression';
        console.info('fixed key', arr[i].key);
      }
    });
    return arr;
  }


  function cleanJson(obj) {
    each(Object.keys(obj), function(key) {
      if (key === 'error' || key[0] === '$') {
        delete obj[key];
      }
      else if (angular.isObject(obj[key]) || angular.isArray(obj[key])) {
        obj[key] = cleanJson(obj[key]);
      }
    });
    return obj;
  }


  function unique(a) {
    return a.reduce(function(p, c) {
      if (p.indexOf(c) < 0) p.push(c);
      return p;
    }, []);
  }


  function makeObj(arr) {
    var obj = {};

    each(arr, function(item) {
      obj[item.key] = item.value;
    });

    return obj;
  }


  function makeArr(obj) {
    var arr = [];

    each(obj, function(value, key) {
      arr.push({
        key: key,
        value: value
      });
    });

    return arr;
  }



  function cleanArray(arr) {
    return unique(arr).map(function(a) { return (''+ a).trim(); });
  }



  function removeArrayItem(arr, delta) {
    var newArr = [];
    for (var key in arr) {
      if (key != delta) {
        newArr.push(arr[key]);
      }
    }
    return newArr;
  }


  var filterCreateModalCtrl = [
    '$location',
    '$scope',
    '$translate',
    'Notifications',
    'camAPI',
  function(
    $location,
    $scope,
    $translate,
    Notifications,
    camAPI
  ) {



    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Setup                                                                                        │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */
    var Filter = camAPI.resource('filter');
    var Authorization = camAPI.resource('authorization');



    $scope.$invalid = false;
    $scope.$valid = true;

    $scope.criteria = criteria;

    var state = $location.search();
    var opened = state.focus || 'general';
    $scope.accordion = {
      general:        opened === 'general',
      authorization:  opened === 'authorizations',
      query:          opened === 'query',
      variables:      opened === 'variables'
    };


    // dealing with hints that way,
    // allows to hide them if a translation is left empty (not undefined!)
    $scope.hints = {};
    $translate([
      'FILTER_FORM_BASICS_HINT',
      'FILTER_FORM_CRITERIA_HINT',
      'FILTER_FORM_AUTHORIZATIONS_HINT',
      'FILTER_FORM_VARIABLES_HINT'
    ])
    .then(function(result) {
      $scope.hints.general =        result.FILTER_FORM_BASICS_HINT;
      $scope.hints.criteria =       result.FILTER_FORM_CRITERIA_HINT;
      $scope.hints.authorizations = result.FILTER_FORM_AUTHORIZATIONS_HINT;
      $scope.hints.variables =      result.FILTER_FORM_VARIABLES_HINT;
    });


    $scope.filter =                       copy($scope.$parent.filter || {});
    $scope.filter.query =                 $scope.filter.query || [];
    $scope.filter.authorizations =        $scope.filter.authorizations || [];
    $scope.filter.properties =            $scope.filter.properties || {};
    $scope.filter.properties.variables =  $scope.filter.properties.variables || [];


    $scope.filter.properties.priority =   $scope.filter.properties.priority || 10;
    $scope.filter.properties.color =      $scope.filter.properties.color || '#EEEEEE';





    function isValid() {
      $scope.$valid = !$scope._variableErrors.length &&
                      !$scope._queryErrors.length &&
                      !$scope._authorizationErrors.length;

      $scope.$invalid = !$scope.$valid;

      return $scope.$valid;
    }


    $scope._generalErrors = [];

    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Ctriteria                                                                                    │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */

    var emptyCriterion = {
      key: '',
      operator: '',
      value: ''
    };

    $scope._query = makeArr($scope.filter.query);

    $scope.addCriterion = function() {
      $scope._query.push(copy(emptyCriterion));
    };

    $scope.removeCriterion = function(delta) {
      $scope._query = removeArrayItem($scope._query, delta);
    };

    $scope.simpleCriterionName = function(name) {
      if (!name) { return name; }
      var simple = name.replace(/^task/, '').replace('Expression', '');
      simple = simple[0].toLowerCase() + simple.slice(1);
      return simple;
    };

    // $scope.criterionSupportExpressions = function(key) {
    //   var check = $scope.simpleCriterionName(key);
    //   for (var c in criteria) {
    //     for (var i in criteria[c].options) {
    //       if (check === criteria[c].options[i].name) {
    //         return criteria[c].options[i].expressionSupport;
    //       }
    //     }
    //   }
    // };

    $scope.validateCriterion = function(criterion, delta) {
      criterion.error = null;

      if (!criterion.key && criterion.value) {
        criterion.error = {field: 'key', message: 'REQUIRED_FIELD'};
      }
      else if (criterion.key && !criterion.value) {
        criterion.error = {field: 'value', message: 'REQUIRED_FIELD'};
      }

      isValid();
      return criterion.error;
    };

    $scope._queryErrors = [];
    $scope.validateCriteria = function() {
      $scope._queryErrors = [];

      each($scope._query, function(queryParam, delta) {
        var error = $scope.validateCriterion(queryParam, delta);
        if (error) {
          $scope._queryErrors.push(error);
        }
      });

      return $scope._queryErrors.length ? $scope._queryErrors : false;
    };





    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Authorizations                                                                               │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */

    var permissionsMap = ['READ', 'UPDATE', 'DELETE'];

    var emptyAuthorization = {
      type:                 1,
      identityType:         'user',
      identity:             '',
      permissions:          'ALL',
      availablePermissions: permissionsMap
    };

    var _authorizationsToDelete = [];

    $scope._authorizations = $scope.filter.authorizations;

    function availablePermissions(authorizationPermissions) {
      var available = [];
      if (authorizationPermissions.length === 1 && authorizationPermissions[0] === 'ALL') {
        available = copy(permissionsMap);
      }
      else {
        each(permissionsMap, function(permission) {
          var has = authorizationPermissions.indexOf(permission);

          if (has === -1) {
            available.push(permission);
          }
        });

        if (available.length < 2) {
          available = ['ALL'];
        }
      }

      return available;
    }

    each($scope._authorizations, function(authorization) {
      if (authorization.permissions.indexOf('ALL') > -1) {
        authorization.permissions = ['ALL'];
      }

      var hasNone = authorization.permissions.indexOf('NONE');
      if (hasNone > -1) {
        authorization.permissions.splice(hasNone, 1);
      }
      authorization.permissions = authorization.permissions.join(', ');
      authorization.availablePermissions = availablePermissions(authorization.permissions);
      authorization.identity = authorization.userId || authorization.groupId;
      authorization.identityType = authorization.userId ? 'user' : 'group';
      authorization.type = parseInt(authorization.type, 10);
      authorization._originalType = authorization.type;
    });

    $scope.addAuthorization = function() {
      $scope._authorizations.push(copy(emptyAuthorization));
    };

    $scope.removeAuthorization = function(delta) {
      if ($scope._authorizations[delta].id) {
        $scope._authorizations[delta].toDelete = true;
      }
      else {
        $scope._authorizations = removeArrayItem($scope._authorizations, delta);
      }
    };

    $scope.identityTypeSwitch = function(authorization, delta) {
      authorization.identityType = authorization.identityType === 'user' ? 'group' : 'user';
    };

    $scope.addPermission = function(authorization, permission) {
      if (permission === 'ALL') {
        authorization.permissions = 'ALL';
      }
      else if (authorization.permissions === 'ALL' || !authorization.permissions) {
        authorization.permissions = permission;
      }
      else {
        var arr = authorization.permissions.split(',');
        arr.push(permission);
        arr = cleanArray(arr);
        authorization.permissions = arr.join(', ');
      }

      authorization.availablePermissions = availablePermissions(authorization.permissions);
    };

    $scope.validateAuthorization = function(authorization, delta) {
      authorization.error = null;

      // ALLOW, DENY
      if (authorization.type !== '0') {
        if (!authorization.identity) {
          authorization.error = {field: 'identity', message: 'REQUIRED_FIELD'};
        }
      }
      // GLOBAL
      // else {

      // }

      isValid();
      return authorization.error;
    };

    $scope._authorizationErrors = [];
    $scope.validateAuthorizations = function() {
      $scope._authorizationErrors = [];

      each($scope._authorizations, function(authorization, delta) {
        var error = $scope.validateAuthorization(authorization, delta);
        if (error) {
          $scope._authorizationErrors.push(error);<commit_msg>fix(filter auth): correct the permission choices<commit_after>define([
  'angular',
  'camunda-bpm-sdk',
  './cam-tasklist-filter-form-criteria',
  'text!./cam-tasklist-filter-form.html'
], function(
  angular,
  camSDK,
  criteria,
  template
) {
  'use strict';

  var each = angular.forEach;
  var copy = angular.copy;

  var expressionsExp = /^[\s]*(\#|\$)\{/;
  function fixExpressions(arr) {
    each(arr, function(obj, i) {
      if (expressionsExp.test(obj.value) && obj.key.indexOf('Expression') === -1) {
        arr[i].key = 'task'+ obj.key[0].toUpperCase() + obj.key.slice(1) +'Expression';
      }
    });
    return arr;
  }


  function cleanJson(obj) {
    each(Object.keys(obj), function(key) {
      if (key === 'error' || key[0] === '$') {
        delete obj[key];
      }
      else if (angular.isObject(obj[key]) || angular.isArray(obj[key])) {
        obj[key] = cleanJson(obj[key]);
      }
    });
    return obj;
  }


  function unique(a) {
    return a.reduce(function(p, c) {
      if (p.indexOf(c) < 0) p.push(c);
      return p;
    }, []);
  }


  function makeObj(arr) {
    var obj = {};

    each(arr, function(item) {
      obj[item.key] = item.value;
    });

    return obj;
  }


  function makeArr(obj) {
    var arr = [];

    each(obj, function(value, key) {
      arr.push({
        key: key,
        value: value
      });
    });

    return arr;
  }



  function cleanArray(arr) {
    return unique(arr).map(function(a) { return (''+ a).trim(); });
  }



  function removeArrayItem(arr, delta) {
    var newArr = [];
    for (var key in arr) {
      if (key != delta) {
        newArr.push(arr[key]);
      }
    }
    return newArr;
  }


  var filterCreateModalCtrl = [
    '$location',
    '$scope',
    '$translate',
    'Notifications',
    'camAPI',
  function(
    $location,
    $scope,
    $translate,
    Notifications,
    camAPI
  ) {



    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Setup                                                                                        │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */
    var Filter = camAPI.resource('filter');
    var Authorization = camAPI.resource('authorization');



    $scope.$invalid = false;
    $scope.$valid = true;

    $scope.criteria = criteria;

    var state = $location.search();
    var opened = state.focus || 'general';
    $scope.accordion = {
      general:        opened === 'general',
      authorization:  opened === 'authorizations',
      query:          opened === 'query',
      variables:      opened === 'variables'
    };


    // dealing with hints that way,
    // allows to hide them if a translation is left empty (not undefined!)
    $scope.hints = {};
    $translate([
      'FILTER_FORM_BASICS_HINT',
      'FILTER_FORM_CRITERIA_HINT',
      'FILTER_FORM_AUTHORIZATIONS_HINT',
      'FILTER_FORM_VARIABLES_HINT'
    ])
    .then(function(result) {
      $scope.hints.general =        result.FILTER_FORM_BASICS_HINT;
      $scope.hints.criteria =       result.FILTER_FORM_CRITERIA_HINT;
      $scope.hints.authorizations = result.FILTER_FORM_AUTHORIZATIONS_HINT;
      $scope.hints.variables =      result.FILTER_FORM_VARIABLES_HINT;
    });


    $scope.filter =                       copy($scope.$parent.filter || {});
    $scope.filter.query =                 $scope.filter.query || [];
    $scope.filter.authorizations =        $scope.filter.authorizations || [];
    $scope.filter.properties =            $scope.filter.properties || {};
    $scope.filter.properties.variables =  $scope.filter.properties.variables || [];


    $scope.filter.properties.priority =   $scope.filter.properties.priority || 10;
    $scope.filter.properties.color =      $scope.filter.properties.color || '#EEEEEE';





    function isValid() {
      $scope.$valid = !$scope._variableErrors.length &&
                      !$scope._queryErrors.length &&
                      !$scope._authorizationErrors.length;

      $scope.$invalid = !$scope.$valid;

      return $scope.$valid;
    }


    $scope._generalErrors = [];

    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Ctriteria                                                                                    │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */

    var emptyCriterion = {
      key: '',
      operator: '',
      value: ''
    };

    $scope._query = makeArr($scope.filter.query);

    $scope.addCriterion = function() {
      $scope._query.push(copy(emptyCriterion));
    };

    $scope.removeCriterion = function(delta) {
      $scope._query = removeArrayItem($scope._query, delta);
    };

    $scope.simpleCriterionName = function(name) {
      if (!name) { return name; }
      var simple = name.replace(/^task/, '').replace('Expression', '');
      simple = simple[0].toLowerCase() + simple.slice(1);
      return simple;
    };

    // $scope.criterionSupportExpressions = function(key) {
    //   var check = $scope.simpleCriterionName(key);
    //   for (var c in criteria) {
    //     for (var i in criteria[c].options) {
    //       if (check === criteria[c].options[i].name) {
    //         return criteria[c].options[i].expressionSupport;
    //       }
    //     }
    //   }
    // };

    $scope.validateCriterion = function(criterion, delta) {
      criterion.error = null;

      if (!criterion.key && criterion.value) {
        criterion.error = {field: 'key', message: 'REQUIRED_FIELD'};
      }
      else if (criterion.key && !criterion.value) {
        criterion.error = {field: 'value', message: 'REQUIRED_FIELD'};
      }

      isValid();
      return criterion.error;
    };

    $scope._queryErrors = [];
    $scope.validateCriteria = function() {
      $scope._queryErrors = [];

      each($scope._query, function(queryParam, delta) {
        var error = $scope.validateCriterion(queryParam, delta);
        if (error) {
          $scope._queryErrors.push(error);
        }
      });

      return $scope._queryErrors.length ? $scope._queryErrors : false;
    };





    /*
    ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
    │ Authorizations                                                                               │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘
    */

    var permissionsMap = ['ALL', 'READ', 'UPDATE', 'DELETE'];

    var emptyAuthorization = {
      type:                 1,
      identityType:         'user',
      identity:             '',
      permissions:          'ALL',
      availablePermissions: permissionsMap
    };

    var _authorizationsToDelete = [];

    $scope._authorizations = $scope.filter.authorizations;

    function availablePermissions(authorizationPermissions) {
      var available = copy(permissionsMap);

      each(authorizationPermissions, function(perm) {
        var i = available.indexOf(perm);
        if (i > -1) {
          available.splice(i, 1);
        }
      });

      if (available.length < 3) {
        available = ['ALL'];
      }

      return available;
    }

    each($scope._authorizations, function(authorization) {
      authorization.availablePermissions = availablePermissions(authorization.permissions);

      authorization.permissions = authorization.permissions.join(/[\s]*,[\s]*/);
      authorization.identity = authorization.userId || authorization.groupId;
      authorization.identityType = authorization.userId ? 'user' : 'group';
      authorization.type = parseInt(authorization.type, 10);
      authorization._originalType = authorization.type;
    });

    $scope.addAuthorization = function() {
      $scope._authorizations.push(copy(emptyAuthorization));
    };

    $scope.removeAuthorization = function(delta) {
      if ($scope._authorizations[delta].id) {
        $scope._authorizations[delta].toDelete = true;
      }
      else {
        $scope._authorizations = removeArrayItem($scope._authorizations, delta);
      }
    };

    $scope.identityTypeSwitch = function(authorization, delta) {
      authorization.identityType = authorization.identityType === 'user' ? 'group' : 'user';
    };

    $scope.addPermission = function(authorization, permission) {
      if (permission === 'ALL') {
        authorization.permissions = 'ALL';
      }
      else if (authorization.permissions === 'ALL' || !authorization.permissions) {
        authorization.permissions = permission;
      }
      else {
        var arr = authorization.permissions.split(/[\s]*,[\s]*/);
        arr.push(permission);
        arr = cleanArray(arr);
        authorization.permissions = arr.join(', ');
      }

      authorization.availablePermissions = availablePermissions(authorization.permissions.split(/[\s]*,[\s]*/));
    };

    $scope.validateAuthorization = function(authorization, delta) {
      authorization.error = null;

      // ALLOW, DENY
      if (authorization.type !== '0') {
        if (!authorization.identity) {
          authorization.error = {field: 'identity', message: 'REQUIRED_FIELD'};
        }
      }
      // GLOBAL
      // else {

      // }

      isValid();
      return authorization.error;
    };

    $scope._authorizationErrors = [];
    $scope.validateAuthorizations = function() {
      $scope._authorizationErrors = [];

      each($scope._authorizations, function(authorization, delta) {
        var error = $scope.validateAuthorization(authorization, delta);
        if (error) {
          $scope._authorizationErrors.push(error);
{'fraction_non_alphanumeric': 0.19340187662208025, 'fraction_numerical': 0.0017967658215212617, 'mean_word_length': 2.3624769256586675, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6716919', 'n_tokens_mistral': 6199, 'n_tokens_neox': 5646, 'n_words': 968}