<commit_before>module.exports = ediTr;

ediTr.$inject = ['$q', '_', '$timeout', 'ediTrMultiSelection'];
function ediTr($q, _, $timeout, ediTrMultiSelection) {
  var directive = {
    template: require('./edi-tr.html'),
    restrict: 'A',
    scope: {
      colSetup: '<ediTrSetup',
      editable: '<?ediTrEditable',
      saveCallback: '&?ediTrOnSave'
    },
    require: {
      form: '?form',
      model: 'ngModel'
    },
    link: linkTr
  };
  return directive;

  function linkTr(scope, ele, attr, api) {

    var disposeMultiSelectListener = null;
    var _previousModelValue = undefined;
    var ediTableId = ele.closest('edi-table').attr('id') || ele.closest('table').attr('id');
    var displayActions = false;

    scope.showActions = function() {
      if (scope.editable) {
        // A trick to wait for DOM to render, then do our action
        $timeout(/*see LESSONS.md for more info*/)
        .then(function () {
          scope.displayActions = true;
        });
      }
    }

    //ngModel
    api.model.$render =  function viewToTdData() {
      var value = api.model.$viewValue || api.model.$modelValue;

      scope.model = Object.assign({}, value);

      //register in the render so that the model id can be obtained
      //register multi-selector only if the edi-table was given an id
      if(attr.ediTrMultiSelector && disposeMultiSelectListener == null && ediTableId) {
        disposeMultiSelectListener = ediTrMultiSelection.register({
          set model(changeObj) {
            var newModel = Object.assign({}, api.model.$modelValue || api.model.$viewValue, changeObj);
            api.model.$setViewValue(newModel);
          },
          get model() {
            return Object.assign({}, api.model.$modelValue);
          },
          set previousModel(model) {
            _previousModelValue = Object.assign({}, model);
          },
          get previousModel() {
            return Object.assign({}, _previousModelValue);
          }
        },
        rollBackNgModelAndResetEditState,
        function updateEdiTrState(newState) {
          Object.assign(scope._editState, newState);
        },
        scope.model.id, ediTableId);
      }
    };

    if (scope.editable)
    {
      if (_.isPlainObject(scope.editable)) {
        scope._editState = Object.assign(setResetEditState(), { inProgress: scope.editable.inProgress, forceEdit: scope.editable.forceEdit});
      }
      else {
        scope._editState = setResetEditState();
      }

      api.model.$viewChangeListeners.push(function updateModel() {
        scope.model = api.model.$modelValue;
      });
    }

    //callback to obtain changes in the tds
    scope.modelValueChange = function (changeObj) {
      //clones into a new object to overcome the strict equality on $render, with persisting any properties needed by angular
      var data = Object.assign({}, api.model.$modelValue || api.model.$viewValue, changeObj);
      if(EdiTrMultiSelection.hasMultiSelected(ediTableId)) {
        EdiTrMultiSelection.updateProperty(ediTableId, data.id, changeObj);
      }
      api.model.$setViewValue(data);
    }

    // Buttons
    if (api.form) {
      scope.edit = function (evt, selectedItem) {
        evt.stopPropagation();

        if (!scope.editable) return;

        _previousModelValue = api.model.$modelValue;

        if(EdiTrMultiSelection.hasMultiSelected(ediTableId)) {
          EdiTrMultiSelection.prepareForEdit(ediTableId, scope.model.id);
        }

        scope._editState.inProgress = true;
        scope._editState.saving = false;
      };

      scope.save = function (evt, selectedItem) {
        evt.stopPropagation();

        if (!scope.editable) return;

        if (api.form.$pristine || api.form.$invalid) return;

        updateToServer(api.model.$modelValue);
      };

      scope.cancel = function (evt) {
        evt.stopPropagation();

        if (!scope.editable) return;

        if(EdiTrMultiSelection.hasMultiSelected(ediTableId)) {
          EdiTrMultiSelection.rollbackAll(scope.model.id, ediTableId);
        }

        rollBackNgModelAndResetEditState();
      };
    }

    scope.$on('$destroy', function () {
      if (disposeMultiSelectListener != null) { disposeMultiSelectListener(); }
    });

    function updateToServer(value) {
      scope._editState.saving = true;

      //TODO this isn't working yet to set the loading state
      var items = EdiTrMultiSelection.hasMultiSelected(ediTableId) ? EdiTrMultiSelection.getSelectedItems(ediTableId, true) : [value];

      scope.saveCallback({ items: items })
        .then(function () {
          api.form.$setPristine();
          scope._editState.saving = false;
          EdiTrMultiSelection.updateEditState(ediTableId, {saving: false, inProgress: scope._editState.forceEdit});
        }, function () {
          scope._editState.saving = false;
        });
    };

    function rollBackNgModelAndResetEditState() {
      api.model.$setViewValue(_previousModelValue);
      api.form.$setPristine();
      scope._editState = setResetEditState();
    }

    function setResetEditState() {
      return {
        inProgress: false,
        saving: false,
        forceEdit: false,
        multiSelected: false
      };
    }
  }
}<commit_msg>fix wrong letter casing<commit_after>module.exports = ediTr;

ediTr.$inject = ['$q', '_', '$timeout', 'ediTrMultiSelection'];
function ediTr($q, _, $timeout, ediTrMultiSelection) {
  var directive = {
    template: require('./edi-tr.html'),
    restrict: 'A',
    scope: {
      colSetup: '<ediTrSetup',
      editable: '<?ediTrEditable',
      saveCallback: '&?ediTrOnSave'
    },
    require: {
      form: '?form',
      model: 'ngModel'
    },
    link: linkTr
  };
  return directive;

  function linkTr(scope, ele, attr, api) {

    var disposeMultiSelectListener = null;
    var _previousModelValue = undefined;
    var ediTableId = ele.closest('edi-table').attr('id') || ele.closest('table').attr('id');
    var displayActions = false;

    scope.showActions = function() {
      if (scope.editable) {
        // A trick to wait for DOM to render, then do our action
        $timeout(/*see LESSONS.md for more info*/)
        .then(function () {
          scope.displayActions = true;
        });
      }
    }

    //ngModel
    api.model.$render =  function viewToTdData() {
      var value = api.model.$viewValue || api.model.$modelValue;

      scope.model = Object.assign({}, value);

      //register in the render so that the model id can be obtained
      //register multi-selector only if the edi-table was given an id
      if(attr.ediTrMultiSelector && disposeMultiSelectListener == null && ediTableId) {
        disposeMultiSelectListener = ediTrMultiSelection.register({
          set model(changeObj) {
            var newModel = Object.assign({}, api.model.$modelValue || api.model.$viewValue, changeObj);
            api.model.$setViewValue(newModel);
          },
          get model() {
            return Object.assign({}, api.model.$modelValue);
          },
          set previousModel(model) {
            _previousModelValue = Object.assign({}, model);
          },
          get previousModel() {
            return Object.assign({}, _previousModelValue);
          }
        },
        rollBackNgModelAndResetEditState,
        function updateEdiTrState(newState) {
          Object.assign(scope._editState, newState);
        },
        scope.model.id, ediTableId);
      }
    };

    if (scope.editable)
    {
      if (_.isPlainObject(scope.editable)) {
        scope._editState = Object.assign(setResetEditState(), { inProgress: scope.editable.inProgress, forceEdit: scope.editable.forceEdit});
      }
      else {
        scope._editState = setResetEditState();
      }

      api.model.$viewChangeListeners.push(function updateModel() {
        scope.model = api.model.$modelValue;
      });
    }

    //callback to obtain changes in the tds
    scope.modelValueChange = function (changeObj) {
      //clones into a new object to overcome the strict equality on $render, with persisting any properties needed by angular
      var data = Object.assign({}, api.model.$modelValue || api.model.$viewValue, changeObj);
      if(ediTrMultiSelection.hasMultiSelected(ediTableId)) {
        ediTrMultiSelection.updateProperty(ediTableId, data.id, changeObj);
      }
      api.model.$setViewValue(data);
    }

    // Buttons
    if (api.form) {
      scope.edit = function (evt, selectedItem) {
        evt.stopPropagation();

        if (!scope.editable) return;

        _previousModelValue = api.model.$modelValue;

        if(ediTrMultiSelection.hasMultiSelected(ediTableId)) {
          ediTrMultiSelection.prepareForEdit(ediTableId, scope.model.id);
        }

        scope._editState.inProgress = true;
        scope._editState.saving = false;
      };

      scope.save = function (evt, selectedItem) {
        evt.stopPropagation();

        if (!scope.editable) return;

        if (api.form.$pristine || api.form.$invalid) return;

        updateToServer(api.model.$modelValue);
      };

      scope.cancel = function (evt) {
        evt.stopPropagation();

        if (!scope.editable) return;

        if(ediTrMultiSelection.hasMultiSelected(ediTableId)) {
          ediTrMultiSelection.rollbackAll(scope.model.id, ediTableId);
        }

        rollBackNgModelAndResetEditState();
      };
    }

    scope.$on('$destroy', function () {
      if (disposeMultiSelectListener != null) { disposeMultiSelectListener(); }
    });

    function updateToServer(value) {
      scope._editState.saving = true;

      //TODO this isn't working yet to set the loading state
      var items = ediTrMultiSelection.hasMultiSelected(ediTableId) ? ediTrMultiSelection.getSelectedItems(ediTableId, true) : [value];

      scope.saveCallback({ items: items })
        .then(function () {
          api.form.$setPristine();
          scope._editState.saving = false;
          ediTrMultiSelection.updateEditState(ediTableId, {saving: false, inProgress: scope._editState.forceEdit});
        }, function () {
          scope._editState.saving = false;
        });
    };

    function rollBackNgModelAndResetEditState() {
      api.model.$setViewValue(_previousModelValue);
      api.form.$setPristine();
      scope._editState = setResetEditState();
    }

    function setResetEditState() {
      return {
        inProgress: false,
        saving: false,
        forceEdit: false,
        multiSelected: false
      };
    }
  }
}
{'fraction_non_alphanumeric': 0.12224334600760456, 'fraction_numerical': 0.0, 'mean_word_length': 2.5187290969899667, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7246006', 'n_tokens_mistral': 3082, 'n_tokens_neox': 3015, 'n_words': 609}