<commit_before>define(['plugins/router', 'services/appsecurity', 'services/errorhandler', 'services/entitymanagerprovider', 'model/modelBuilder', 'services/appsecurity'],
    function (router, appsecurity, errorhandler, entitymanagerprovider, modelBuilder, appsecurity) {

    entitymanagerprovider.modelBuilder = modelBuilder.extendMetadata;

    var viewmodel = {

        attached : function() {
            $(document).find("footer").show();
        },

        activate: function () {
            var self = this;

            return entitymanagerprovider
                    .prepare()
                    .then(function() {

                        //configure routing
                        router.makeRelative({ moduleId: 'viewmodels' });

                        // If the route has the authorize flag and the user is not logged in => navigate to login view
                        // If the route has the confirmed flag and the user's email is not confirmed => navigate to login view and display confirmation warning
                        router.guardRoute = function (instance, instruction) {
                            if (sessionStorage["redirectTo"]) {
                                var redirectTo = sessionStorage["redirectTo"]
                                sessionStorage.removeItem("redirectTo");
                                return redirectTo;
                            }

                            if (instruction.config.authorize) {
                                if (typeof (appsecurity.userInfo()) !== 'undefined') {
                                    if (appsecurity.isUserInRole(instruction.config.authorize)) {
                                        if (instruction.config.confirmed) {
                                            if (appsecurity.userInfo().isEmailConfirmed()) {
                                                return true;
                                            } else {
                                                appsecurity.showConfirmationWarning(true);
                                                return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                            }
                                        } else {
                                            return true;
                                        }
                                    } else {
                                        return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                    }
                                } else {
                                    return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                }
                            } else {
                                return true;
                            }
                        };

                        // Config Routes
                        // Routes with authorize flag will be forbidden and will redirect to login page
                        // As this is javascript and is controlled by the user and his browser, the flag is only a UI guidance. You should always check again on
                        // server in order to ensure the resources travelling back on the wire are really allowed

                        return router.map([
                            // Nav urls
                            { route: ['','home/index'],                       moduleId: 'home/index',                        title: 'Home',                        nav: true, hash : "#home/index"    },
                            { route: 'home/articles',                         moduleId: 'home/articles',                     title: 'Articles',                    nav: true, hash : "#home/articles" },
                            { route: 'home/help',                             moduleId: 'home/help',                         title: 'Help',                        nav: true, hash : "#home/help" },
                            { route: 'home/about',                            moduleId: 'home/about',                        title: 'About',                       nav: true, hash : "#home/about" },
                            { route: 'notfound',                              moduleId: 'notfound',                          title: 'Not found',                   nav: false },

                            // Admin panel url
                            { route: 'admin/panel',                           moduleId: 'admin/panel',                       title: 'Admin Panel',                 nav: false, hash : "#admin/panel",  authorize: ["Administrator"] } ,

                            // Account Controller urls
                            { route: 'account/login',                         moduleId: 'account/login',                     title: 'Login',                       nav: false, hash : "#account/login" },
                            { route: 'account/externalloginconfirmation',     moduleId: 'account/externalloginconfirmation', title: 'External login confirmation', nav: false, hash : "#account/externalloginconfirmation" },
                            { route: 'account/externalloginfailure',          moduleId: 'account/externalloginfailure',      title: 'External login failure',      nav: false, hash : "#account/externalloginfailure" },
                            { route: 'account/register',                      moduleId: 'account/register',                  title: 'Register',                    nav: false, hash : "#account/register" },
                            { route: 'account/manage',                        moduleId: 'account/manage',                    title: 'Manage account',              nav: false, hash:  "#account/manage", authorize: ["User", "Administrator"] },
                            { route: 'account/registrationcomplete',          moduleId: 'account/registrationcomplete',      title: 'Registration complete',       nav: false, hash:  "#account/registrationcomplete" },
                            { route: 'account/forgotpassword',                moduleId: 'account/forgotpassword',            title: 'Forgot password',             nav: false, hash:  "#account/forgotpassword" },
                            { route: 'account/resetpassword',                 moduleId: 'account/resetpassword',             title: 'Reset password',              nav: false, hash:  "#account/resetpassword" },

                            // User articles urls
                            { route: 'user/dashboard',                        moduleId: 'user/dashboard',                    title: 'Dashboard',                   nav: false, hash : "#user/dashboard",  authorize: ["User"], confirmed : true  },
                            { route: ':createdby/:categorycode/:articlecode', moduleId: 'user/article',                      title: 'Article',                     nav: false },
                        ])
                        .buildNavigationModel()
                        .mapUnknownRoutes("notfound","notfound")
                        .activate({ pushState : true });
                    })
                    .fail(self.handlevalidationerrors);
        }
    };

    errorhandler.includeIn(viewmodel);

    return viewmodel;
});<commit_msg>services/appsecurity referenced twice<commit_after>define(['plugins/router', 'services/appsecurity', 'services/errorhandler', 'services/entitymanagerprovider', 'model/modelBuilder'],
    function (router, appsecurity, errorhandler, entitymanagerprovider, modelBuilder) {

    entitymanagerprovider.modelBuilder = modelBuilder.extendMetadata;

    var viewmodel = {

        attached : function() {
            $(document).find("footer").show();
        },

        activate: function () {
            var self = this;

            return entitymanagerprovider
                    .prepare()
                    .then(function() {

                        //configure routing
                        router.makeRelative({ moduleId: 'viewmodels' });

                        // If the route has the authorize flag and the user is not logged in => navigate to login view
                        // If the route has the confirmed flag and the user's email is not confirmed => navigate to login view and display confirmation warning
                        router.guardRoute = function (instance, instruction) {
                            if (sessionStorage["redirectTo"]) {
                                var redirectTo = sessionStorage["redirectTo"]
                                sessionStorage.removeItem("redirectTo");
                                return redirectTo;
                            }

                            if (instruction.config.authorize) {
                                if (typeof (appsecurity.userInfo()) !== 'undefined') {
                                    if (appsecurity.isUserInRole(instruction.config.authorize)) {
                                        if (instruction.config.confirmed) {
                                            if (appsecurity.userInfo().isEmailConfirmed()) {
                                                return true;
                                            } else {
                                                appsecurity.showConfirmationWarning(true);
                                                return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                            }
                                        } else {
                                            return true;
                                        }
                                    } else {
                                        return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                    }
                                } else {
                                    return "/account/login?returnUrl=" + encodeURIComponent(instruction.fragment);
                                }
                            } else {
                                return true;
                            }
                        };

                        // Config Routes
                        // Routes with authorize flag will be forbidden and will redirect to login page
                        // As this is javascript and is controlled by the user and his browser, the flag is only a UI guidance. You should always check again on
                        // server in order to ensure the resources travelling back on the wire are really allowed

                        return router.map([
                            // Nav urls
                            { route: ['','home/index'],                       moduleId: 'home/index',                        title: 'Home',                        nav: true, hash : "#home/index"    },
                            { route: 'home/articles',                         moduleId: 'home/articles',                     title: 'Articles',                    nav: true, hash : "#home/articles" },
                            { route: 'home/help',                             moduleId: 'home/help',                         title: 'Help',                        nav: true, hash : "#home/help" },
                            { route: 'home/about',                            moduleId: 'home/about',                        title: 'About',                       nav: true, hash : "#home/about" },
                            { route: 'notfound',                              moduleId: 'notfound',                          title: 'Not found',                   nav: false },

                            // Admin panel url
                            { route: 'admin/panel',                           moduleId: 'admin/panel',                       title: 'Admin Panel',                 nav: false, hash : "#admin/panel",  authorize: ["Administrator"] } ,

                            // Account Controller urls
                            { route: 'account/login',                         moduleId: 'account/login',                     title: 'Login',                       nav: false, hash : "#account/login" },
                            { route: 'account/externalloginconfirmation',     moduleId: 'account/externalloginconfirmation', title: 'External login confirmation', nav: false, hash : "#account/externalloginconfirmation" },
                            { route: 'account/externalloginfailure',          moduleId: 'account/externalloginfailure',      title: 'External login failure',      nav: false, hash : "#account/externalloginfailure" },
                            { route: 'account/register',                      moduleId: 'account/register',                  title: 'Register',                    nav: false, hash : "#account/register" },
                            { route: 'account/manage',                        moduleId: 'account/manage',                    title: 'Manage account',              nav: false, hash:  "#account/manage", authorize: ["User", "Administrator"] },
                            { route: 'account/registrationcomplete',          moduleId: 'account/registrationcomplete',      title: 'Registration complete',       nav: false, hash:  "#account/registrationcomplete" },
                            { route: 'account/forgotpassword',                moduleId: 'account/forgotpassword',            title: 'Forgot password',             nav: false, hash:  "#account/forgotpassword" },
                            { route: 'account/resetpassword',                 moduleId: 'account/resetpassword',             title: 'Reset password',              nav: false, hash:  "#account/resetpassword" },

                            // User articles urls
                            { route: 'user/dashboard',                        moduleId: 'user/dashboard',                    title: 'Dashboard',                   nav: false, hash : "#user/dashboard",  authorize: ["User"], confirmed : true  },
                            { route: ':createdby/:categorycode/:articlecode', moduleId: 'user/article',                      title: 'Article',                     nav: false },
                        ])
                        .buildNavigationModel()
                        .mapUnknownRoutes("notfound","notfound")
                        .activate({ pushState : true });
                    })
                    .fail(self.handlevalidationerrors);
        }
    };

    errorhandler.includeIn(viewmodel);

    return viewmodel;
});
<|endoftext|>


<commit_before>var angular = require('angular');

angular.module('KeyCtrl', ['KeySvc', 'AuthSvc']).controller('KeyController', ['$scope', 'KeyService', 'AuthService', function ($scope, KeyService, AuthService) {
    // Transforms an array of period-separated properties ex. ["file.upload", "user.view", "user.ban"]
    // to json ex. { "file": "upload", "user": ["view", "ban"] }
    function splitScope(scope) {
        var res = {};
        for (var i in scope) {
            if (scope.hasOwnProperty(i)) {
                var perm = scope[i];
                var prefix = perm.substr(0, perm.indexOf('.'));
                var postfix = perm.substr(perm.indexOf('.') + 1);
                if (!res[prefix]) res[prefix] = [];
                res[prefix].push({name: postfix});
            }
        }
        return res;
    }

    // Called on init, retrieves the user's scope from the server.
    $scope.parseScope = function () {
        AuthService.whoami(function (res) {
            $scope.scopeObj = splitScope(res.scope);
            $scope.currKeyScope = [];
        })
    };

    // Triggered when a checkbox for a permission changes.
    // Updates the currKeyScope object with the addition or removal.
    $scope.updateCurrKeyPerm = function(prefix, perm) {
        var index = $scope.scopeObj[prefix].indexOf(perm);
        if ($scope.scopeObj[prefix][index].isChecked) {
            $scope.currKeyScope.push(prefix + '.' + perm.name);
        } else {
            index = $scope.currKeyScope.indexOf(prefix + '.' + perm.name);
            $scope.currKeyScope.splice(index, 1);
        }
    };

    $scope.getKeys = function () {
        KeyService.getAllKeys(function (keys) {
            $scope.keys = keys;
        });
    };

    $scope.deleteKey = function (key) {
        KeyService.deleteKey(key.key, function () {
            var index = $scope.keys.indexOf(key);
            $scope.keys.splice(index, 1);
            $scope.hideKeyInfo();
            $scope.currKey = {};
        });
    };

    $scope.createKey = function () {
        if ($scope.currKeyScope.length === 0 || !$scope.currKeyIdentifier)
            return;

        KeyService.createKey($scope.currKeyIdentifier, $scope.currKeyScope,
            function (res) {
            if (res.key) {
                $scope.hideNewKey();
                $scope.getKeys();
            }
        });
    };

    // Hide/show new key modal dialog
    $scope.hideNewKey = function () {
        $scope.nModalShow = false;
    };
    $scope.showNewKey = function () {
        $scope.nModalShow = true;
    };

    // Hide/show key info modal dialog
    $scope.hideKeyInfo = function () {
        $scope.kModalShow = false;
    };
    $scope.showKeyInfo = function (key) {
        $scope.kModalShow = true;
        $scope.currKey = key;
        $scope.currKey.scopeObj = splitScope($scope.currKey.scope);
    };
}]);<commit_msg>Update KeyController to use new service and create uploader templates<commit_after>var angular = require('angular');

angular.module('KeyCtrl', ['KeySvc', 'AuthSvc']).controller('KeyController', ['$scope', 'KeyService', 'AuthService', function($scope, KeyService, AuthService) {
    // Transforms an array of period-separated properties ex. ["file.upload", "user.view", "user.ban"]
    // to json ex. {"file": "upload", "user": ["view", "ban"]}
    function scopeToObj(scope) {
        const res = {};
        for(const prop in scope) {
            if (scope.hasOwnProperty(prop)) {
                const perm = scope[prop];
                const prefix = perm.substr(0, perm.indexOf('.'));
                const postfix = perm.substr(perm.indexOf('.') + 1);
                if (!res[prefix]) res[prefix] = [];
                res[prefix].push({name: postfix});
            }
        }
        return res;
    }

    $scope.init = () => {
        AuthService.whoami(res => {
            $scope.scope = scopeToObj(res.scope);
            $scope.displayname = res.displayname;
        });
        $scope.getAllKeys();
        $scope.newScope = [];
    };

    // ------------ Keys ------------ ///
    class Key {
        constructor(identifier, scope, key) {
            this.identifier = identifier;
            this.scope = scopeToObj(scope);
            this.key = key;
        }
    }
    $scope.getAllKeys = () =>
        KeyService.getAllKeys((err, res) =>
            $scope.keys = res.map(key => new Key(key.identifier, key.scope, key.key)));
    $scope.createKey = () =>
        KeyService.createKey($scope.newIdentifier, $scope.newScope, (err, res) => {
            if (err) return;
            $scope.hideNewKey();
            $scope.getAllKeys();
        });
    $scope.deleteKey = key =>
        KeyService.deleteKey(key.key, (err, res) => {
            if (err) return;
            $scope.keys.splice($scope.keys.indexOf(key), 1);
            $scope.hideKeyInfo();
            $scope.currKey = {};
        });

    // Triggered when a checkbox for a permission changes.
    // Updates the currKeyScope object with the addition or removal.
    $scope.updateNewScope = function(prefix, perm) {
        // If the checkbox was checked
        if ($scope.scope[prefix][$scope.scope[prefix].indexOf(perm)].isChecked) {
            $scope.newScope.push(prefix + '.' + perm.name);
        } else {
            // Otherwise it was unchecked, remove it
            $scope.newScope.splice($scope.newScope.indexOf(prefix + '.' + perm.name), 1);
        }
    };

    // Hide/show new key modal dialog
    $scope.hideNewKey = () => $scope.newModalStyle = {};
    $scope.showNewKey = () => $scope.newModalStyle = {display: 'block'};

    // Hide/show key info modal dialog
    $scope.hideKeyInfo = () => $scope.infoModalStyle = {};
    $scope.showKeyInfo = key => {
        $scope.currKey = key;
        $scope.infoModalStyle = {display: 'block'};
    };

    function downloadData(mime, filename, data) {
        const dataStr = 'data:' + mime + ';charset=utf-8,' + encodeURIComponent(data);
        const anchor = document.createElement('a');
        anchor.setAttribute('href', dataStr);
        anchor.setAttribute('download', filename);
        document.body.appendChild(anchor);
        anchor.click();
        anchor.remove();
    }

    $scope.downloadBash = () => {
        const data =
            '#!/bin/bash\n' +
            'curl \\\n' +
            '  -F key=' + $scope.currKey.key + ' \\\n' +
            '  -F "file=@$1" \\\n' +
            '  https://shimapan.rocks/api/upload \\\n' +
            '  | grep -Po \'"\'"url"\'"\\s*:\\s*"\\K([^"]*)\'\n';
        downloadData('text/x-shellscript', 'shimapan.rocks.sh', data);
    };

    $scope.downloadSharex = () => {
        const data = {
            RequestURL: 'https://shimapan.rocks/api/upload',
            FileFormName: 'file',
            Arguments: {
                key: $scope.currKey.key
            },
            URL: '$json:url$'
        };
        downloadData('text/json', 'shimapan.rocks.sxcu', JSON.stringify(data));
    };
}]);<|endoftext|>


<commit_before>'use strict';

angular.module('confRegistrationWebApp')
  .controller('eventDetailsCtrl', function ($rootScope, $scope, $http, $sce, $timeout, $window, $modal, modalMessage, $filter, $location, conference, ConfCache, permissions, permissionConstants, uuid) {
    $rootScope.globalPage = {
      type: 'admin',
      mainClass: 'container event-details',
      bodyClass: '',
      title: conference.name,
      confId: conference.id,
      footer: true
    };
    if (permissions.permissionInt >= permissionConstants.UPDATE) {
      $scope.templateUrl = 'views/eventDetails.html';
    } else {
      $scope.templateUrl = 'views/permissionError.html';
    }

    $scope.tabs = [
      {id: 'eventInfo', name: 'Event Information', view: 'views/eventDetails/eventInformation.html'},
      {id: 'regOptions', name: 'Registration Options', view: 'views/eventDetails/regOptions.html'},
      {id: 'regTypes', name: 'Registration Types', view: 'views/eventDetails/regTypes.html'},
      {id: 'paymentOptions', name: 'Payment Options', view: 'views/eventDetails/paymentOptions.html'},
      {id: 'promotions', name: 'Promotions', view: 'views/eventDetails/promotions.html'},
      {id: 'contactInfo', name: 'Contact Information', view: 'views/eventDetails/contactInfo.html'}
    ];

    $scope.changeTab = function(tab){
      $scope.activeTab = tab;
    };
    $scope.changeTab($scope.tabs[0]);

    $scope.paymentGateways = [
      {id: 'AUTHORIZE_NET', name: 'Authorize.Net'}
    ];

    $scope.conference = angular.copy(conference);

    $scope.$on('$locationChangeStart', function(event, newLocation) {
      if(!angular.equals(conference, $scope.conference)){
        event.preventDefault();
        modalMessage.confirm({
          title: 'Warning: Unsaved Changes',
          question: 'You have some unsaved changes on this page, are you sure you want to leave? Your changes will be lost.',
          yesString: 'Discard changes',
          noString: 'Stay on this page',
          normalSize: true
        }).then(function(){
          conference = angular.copy($scope.conference);
          $location.url($location.url(newLocation).hash());
        });
      }
    });

    $scope.addPromotion = function(){
      $scope.conference.promotions.push({
        id: uuid(),
        applyToAllRegistrants: true,
        registrantTypeIds: _.pluck($scope.conference.registrantTypes, 'id'),
        activationDate: $scope.conference.registrationStartTime,
        deactivationDate: $scope.conference.registrationEndTime
      });
    };

    $scope.promotionRegistrantTypeToggle = function (registrantTypes, id) {
      if (registrantTypes.indexOf(id) === -1) {
        registrantTypes.push(id);
      } else {
        registrantTypes.splice(registrantTypes.indexOf(id), 1);
      }
    };

    $scope.addRegType = function(){
      var modalInstance = $modal.open({
        templateUrl: 'views/modals/addRegistrantType.html',
        controller: function($scope, $modalInstance, registrantTypes){
          $scope.types = registrantTypes.data;

          $scope.selectType = function (type) {
            $modalInstance.close(type);
          };
        },
        resolve: {
          registrantTypes: function () {
            return $http.get('registranttypes', {cache: true});
          }
        }
      });

      modalInstance.result.then(function(type) {
        type.id = uuid();
        $scope.conference.registrantTypes.push(type);
      });

      return modalInstance;
    };

    $scope.deleteRegType = function(id){
      if ($scope.conference.registrantTypes.length > 1) {
        _.remove($scope.conference.registrantTypes, function(type) { return type.id === id; });
      } else {
        $scope.notify = {
          class: 'alert-danger',
          message: $sce.trustAsHtml('You must have at least one registration type per event.')
        };
        $timeout(function() { $scope.notify = {}; }, 3500);
      }
    };

    $scope.addEarlyRegistrationDiscount = function(type){
      type.earlyRegistrationDiscounts.push({id: uuid(), enabled: true});
    };

    $scope.saveEvent = function () {
      //validation check
      var validationErrors = [];

      //Event Name
      if (_.isEmpty($scope.conference.name)) {
        validationErrors.push('Please enter an event name.');
      }

      //Event Dates
      if ($scope.conference.eventStartTime > $scope.conference.eventEndTime) {
        validationErrors.push('Event end date/time must be after event start date/time.');
      }

      //Registration Window
      if ($scope.conference.registrationStartTime > $scope.conference.registrationEndTime) {
        validationErrors.push('Registration end date/time must be after registration start date/time.');
      }

      //Promo codes
      angular.forEach($scope.conference.promotions, function(p, index) {
        if (_.isEmpty(p.code)) {
          validationErrors.push('Please enter a code for promotion ' + (index + 1) + '.');
        }else{
          if(p.code.length < 5 || p.code.length > 20){
            validationErrors.push('Code for promotion ' + (index + 1) + ' must be greater than 5 characters and less than 20.');
          }

          if(/[^a-zA-Z0-9]/.test(p.code)){
            validationErrors.push('Code for promotion ' + (index + 1) + ' must only contain letters and/or numbers.');
          }
        }

        if (!p.amount || Number(p.amount) <= 0) {
          validationErrors.push('Please enter a discount amount greater than 0 for promotion ' + (index + 1) + '.');
        }
      });

      //Registrant Name
      angular.forEach($scope.conference.registrantTypes, function(t) {
        if (_.isEmpty(t.name)) {
          validationErrors.push('Please enter a name for all registration types.');
        }
      });

      //Event Cost
      angular.forEach($scope.conference.registrantTypes, function(t) {
        t.cost = Number(t.cost);
        if ( _.isNaN(t.cost) || t.cost < 0) {
          validationErrors.push('Event cost for \'' + t.name + '\' must be a positive number.');
        }
      });

      //Credit cards
      if (_.isEmpty($scope.conference.paymentGatewayId) && _.some($scope.conference.registrantTypes, 'acceptCreditCards')) {
        validationErrors.push('Please enter a credit card Account ID and Key under the "Payment Options" tab.');
      }

      //Minimum Deposit
      angular.forEach($scope.conference.registrantTypes, function(t) {
        if ($scope.conference.requireLogin && $scope.anyPaymentMethodAccepted(t) && String(t.minimumDeposit).length > 0 && !_.isNull(t.minimumDeposit)) {
          t.minimumDeposit = Number(t.minimumDeposit);
          if (t.minimumDeposit > t.cost) {
            validationErrors.push('The minimum deposit for \'' + t.name + '\' must be less than the cost.');
          }
        } else {
          t.minimumDeposit = null;
        }
      });

      //Early bird discount
      angular.forEach($scope.conference.registrantTypes, function(t) {
        angular.forEach(t.earlyRegistrationDiscounts, function(d, index){
          if (d.enabled) {
            d.amountOfDiscount = Number(d.amountOfDiscount);
            if (d.amountOfDiscount <= 0) {
              validationErrors.push('Early registration discount ' + (index + 1) + ' for \'' + t.name + '\' must be a positive number.');
            }
            if (!d.deadline) {
              validationErrors.push('Early registration discount ' + (index + 1) + ' for \'' + t.name + '\' must include a valid date and time.');
            }
          }
        });
      });

      $window.scrollTo(0, 0);
      if (validationErrors.length > 0) {
        var errorMsg = 'Error! Please fix the following issues:
';
        angular.forEach(validationErrors, function (e) {
          errorMsg = errorMsg + '
' + e + '
';
        });
        errorMsg = errorMsg + '
';
        $scope.notify = {
          class: 'alert-danger',
          message: $sce.trustAsHtml(errorMsg)
        };
      } else {
        $scope.notify = {
          class: 'alert-warning',
          message: $sce.trustAsHtml('Saving...')
        };

        $http(
          {method: 'PUT',
            url: 'conferences/' + conference.id,
            data: $scope.conference
        }).success(function () {
            $scope.notify = {
              class: 'alert-success',
              message: $sce.trustAsHtml('Saved! Your event details have been updated.')
            };

            conference = angular.copy($scope.conference);
            //Clear cache
            ConfCache.empty();
          }).error(function (data) {
            $scope.notify = {
              class: 'alert-danger',
              message: $sce.trustAsHtml('Error ' + (data.errorMessage || data))
            };
          });
      }
    };

    $scope.anyPaymentMethodAccepted = function(type){
      return type.acceptCreditCards || type.acceptChecks || type.acceptTransfers || type.acceptScholarships;
    };

    $scope.previewEmail = function(reg){
      var cost = $filter('currency')(reg.cost, '$');
      var eventStartTime = moment(conference.eventStartTime).format('dddd, MMMM D YYYY, h:mm a');
      var eventEndTime = moment(conference.eventEndTime).format('dddd, MMMM D YYYY, h:mm a');
      modalMessage.info({
        'title': 'Email Preview',
        'message': '
Hello ' + $rootScope.globalGreetingName + '!

You are registered for ' + $scope.conference.name + '.
' +
        '
Start Time: ' + eventStartTime + '
End Time: ' + eventEndTime + '
' +
        '
Total Cost: ' + cost + '
Total Amount Paid: ' + cost + '
Remaining Balance: $0.00
' +
        reg.customConfirmationEmailText,
        'okString': 'Close'
      });
    };

    $scope.disableField = function(field, defaultTypeKey){
      var fields = {
        groupSubRegistrantType: ['SPOUSE', 'CHILD']
      };
      return _.contains(fields[field], defaultTypeKey);
    };
  });
<commit_msg>Abbreviation must be 10 characters or less.<commit_after>'use strict';

angular.module('confRegistrationWebApp')
  .controller('eventDetailsCtrl', function ($rootScope, $scope, $http, $sce, $timeout, $window, $modal, modalMessage, $filter, $location, conference, ConfCache, permissions, permissionConstants, uuid) {
    $rootScope.globalPage = {
      type: 'admin',
      mainClass: 'container event-details',
      bodyClass: '',
      title: conference.name,
      confId: conference.id,
      footer: true
    };
    if (permissions.permissionInt >= permissionConstants.UPDATE) {
      $scope.templateUrl = 'views/eventDetails.html';
    } else {
      $scope.templateUrl = 'views/permissionError.html';
    }

    $scope.tabs = [
      {id: 'eventInfo', name: 'Event Information', view: 'views/eventDetails/eventInformation.html'},
      {id: 'regOptions', name: 'Registration Options', view: 'views/eventDetails/regOptions.html'},
      {id: 'regTypes', name: 'Registration Types', view: 'views/eventDetails/regTypes.html'},
      {id: 'paymentOptions', name: 'Payment Options', view: 'views/eventDetails/paymentOptions.html'},
      {id: 'promotions', name: 'Promotions', view: 'views/eventDetails/promotions.html'},
      {id: 'contactInfo', name: 'Contact Information', view: 'views/eventDetails/contactInfo.html'}
    ];

    $scope.changeTab = function(tab){
      $scope.activeTab = tab;
    };
    $scope.changeTab($scope.tabs[0]);

    $scope.paymentGateways = [
      {id: 'AUTHORIZE_NET', name: 'Authorize.Net'}
    ];

    $scope.conference = angular.copy(conference);

    $scope.$on('$locationChangeStart', function(event, newLocation) {
      if(!angular.equals(conference, $scope.conference)){
        event.preventDefault();
        modalMessage.confirm({
          title: 'Warning: Unsaved Changes',
          question: 'You have some unsaved changes on this page, are you sure you want to leave? Your changes will be lost.',
          yesString: 'Discard changes',
          noString: 'Stay on this page',
          normalSize: true
        }).then(function(){
          conference = angular.copy($scope.conference);
          $location.url($location.url(newLocation).hash());
        });
      }
    });

    $scope.addPromotion = function(){
      $scope.conference.promotions.push({
        id: uuid(),
        applyToAllRegistrants: true,
        registrantTypeIds: _.pluck($scope.conference.registrantTypes, 'id'),
        activationDate: $scope.conference.registrationStartTime,
        deactivationDate: $scope.conference.registrationEndTime
      });
    };

    $scope.promotionRegistrantTypeToggle = function (registrantTypes, id) {
      if (registrantTypes.indexOf(id) === -1) {
        registrantTypes.push(id);
      } else {
        registrantTypes.splice(registrantTypes.indexOf(id), 1);
      }
    };

    $scope.addRegType = function(){
      var modalInstance = $modal.open({
        templateUrl: 'views/modals/addRegistrantType.html',
        controller: function($scope, $modalInstance, registrantTypes){
          $scope.types = registrantTypes.data;

          $scope.selectType = function (type) {
            $modalInstance.close(type);
          };
        },
        resolve: {
          registrantTypes: function () {
            return $http.get('registranttypes', {cache: true});
          }
        }
      });

      modalInstance.result.then(function(type) {
        type.id = uuid();
        $scope.conference.registrantTypes.push(type);
      });

      return modalInstance;
    };

    $scope.deleteRegType = function(id){
      if ($scope.conference.registrantTypes.length > 1) {
        _.remove($scope.conference.registrantTypes, function(type) { return type.id === id; });
      } else {
        $scope.notify = {
          class: 'alert-danger',
          message: $sce.trustAsHtml('You must have at least one registration type per event.')
        };
        $timeout(function() { $scope.notify = {}; }, 3500);
      }
    };

    $scope.addEarlyRegistrationDiscount = function(type){
      type.earlyRegistrationDiscounts.push({id: uuid(), enabled: true});
    };

    $scope.saveEvent = function () {
      //validation check
      var validationErrors = [];

      //Event Name
      if (_.isEmpty($scope.conference.name)) {
        validationErrors.push('Please enter an event name.');
      }

      if($scope.conference.abbreviation.length > 10) {
        validationErrors.push('Abbreviation must not be longer than 10 characters.');
      }

      //Event Dates
      if ($scope.conference.eventStartTime > $scope.conference.eventEndTime) {
        validationErrors.push('Event end date/time must be after event start date/time.');
      }

      //Registration Window
      if ($scope.conference.registrationStartTime > $scope.conference.registrationEndTime) {
        validationErrors.push('Registration end date/time must be after registration start date/time.');
      }

      //Promo codes
      angular.forEach($scope.conference.promotions, function(p, index) {
        if (_.isEmpty(p.code)) {
          validationErrors.push('Please enter a code for promotion ' + (index + 1) + '.');
        }else{
          if(p.code.length < 5 || p.code.length > 20){
            validationErrors.push('Code for promotion ' + (index + 1) + ' must be greater than 5 characters and less than 20.');
          }

          if(/[^a-zA-Z0-9]/.test(p.code)){
            validationErrors.push('Code for promotion ' + (index + 1) + ' must only contain letters and/or numbers.');
          }
        }

        if (!p.amount || Number(p.amount) <= 0) {
          validationErrors.push('Please enter a discount amount greater than 0 for promotion ' + (index + 1) + '.');
        }
      });

      //Registrant Name
      angular.forEach($scope.conference.registrantTypes, function(t) {
        if (_.isEmpty(t.name)) {
          validationErrors.push('Please enter a name for all registration types.');
        }
      });

      //Event Cost
      angular.forEach($scope.conference.registrantTypes, function(t) {
        t.cost = Number(t.cost);
        if ( _.isNaN(t.cost) || t.cost < 0) {
          validationErrors.push('Event cost for \'' + t.name + '\' must be a positive number.');
        }
      });

      //Credit cards
      if (_.isEmpty($scope.conference.paymentGatewayId) && _.some($scope.conference.registrantTypes, 'acceptCreditCards')) {
        validationErrors.push('Please enter a credit card Account ID and Key under the "Payment Options" tab.');
      }

      //Minimum Deposit
      angular.forEach($scope.conference.registrantTypes, function(t) {
        if ($scope.conference.requireLogin && $scope.anyPaymentMethodAccepted(t) && String(t.minimumDeposit).length > 0 && !_.isNull(t.minimumDeposit)) {
          t.minimumDeposit = Number(t.minimumDeposit);
          if (t.minimumDeposit > t.cost) {
            validationErrors.push('The minimum deposit for \'' + t.name + '\' must be less than the cost.');
          }
        } else {
          t.minimumDeposit = null;
        }
      });

      //Early bird discount
      angular.forEach($scope.conference.registrantTypes, function(t) {
        angular.forEach(t.earlyRegistrationDiscounts, function(d, index){
          if (d.enabled) {
            d.amountOfDiscount = Number(d.amountOfDiscount);
            if (d.amountOfDiscount <= 0) {
              validationErrors.push('Early registration discount ' + (index + 1) + ' for \'' + t.name + '\' must be a positive number.');
            }
            if (!d.deadline) {
              validationErrors.push('Early registration discount ' + (index + 1) + ' for \'' + t.name + '\' must include a valid date and time.');
            }
          }
        });
      });

      $window.scrollTo(0, 0);
      if (validationErrors.length > 0) {
        var errorMsg = 'Error! Please fix the following issues:
';
        angular.forEach(validationErrors, function (e) {
          errorMsg = errorMsg + '
' + e + '
';
        });
        errorMsg = errorMsg + '
';
        $scope.notify = {
          class: 'alert-danger',
          message: $sce.trustAsHtml(errorMsg)
        };
      } else {
        $scope.notify = {
          class: 'alert-warning',
          message: $sce.trustAsHtml('Saving...')
        };

        $http(
          {method: 'PUT',
            url: 'conferences/' + conference.id,
            data: $scope.conference
        }).success(function () {
            $scope.notify = {
              class: 'alert-success',
              message: $sce.trustAsHtml('Saved! Your event details have been updated.')
            };

            conference = angular.copy($scope.conference);
            //Clear cache
            ConfCache.empty();
          }).error(function (data) {
            $scope.notify = {
              class: 'alert-danger',
              message: $sce.trustAsHtml('Error ' + (data.errorMessage || data))
            };
          });
      }
    };

    $scope.anyPaymentMethodAccepted = function(type){
      return type.acceptCreditCards || type.acceptChecks || type.acceptTransfers || type.acceptScholarships;
    };

    $scope.previewEmail = function(reg){
      var cost = $filter('currency')(reg.cost, '$');
      var eventStartTime = moment(conference.eventStartTime).format('dddd, MMMM D YYYY, h:mm a');
      var eventEndTime = moment(conference.eventEndTime).format('dddd, MMMM D YYYY, h:mm a');
      modalMessage.info({
        'title': 'Email Preview',
        'message': '
Hello ' + $rootScope.globalGreetingName + '!

You are registered for ' + $scope.conference.name + '.
' +
        '
Start Time: ' + eventStartTime + '
End Time: ' + eventEndTime + '
' +
        '
Total Cost: ' + cost + '
Total Amount Paid: ' + cost + '
Remaining Balance: $0.00
' +
        reg.customConfirmationEmailText,
        'okString': 'Close'
      });
    };

    $scope.disableField = function(field, defaultTypeKey){
      var fields = {
        groupSubRegistrantType: ['SPOUSE', 'CHILD']
      };
      return _.contains(fields[field], defaultTypeKey);
    };
  });
<|endoftext|>


<commit_before>define([
    'backbone',
    'communicator',
    'views/show/contact'
],
function( Backbone, Communicator, ContactShowView ) {
    'use strict';

    return new (Backbone.Marionette.Controller.extend({
        showContact: function(id) {
            var contacts = Communicator.reqres.request('contact:entities');
            var model = contacts.get(id);
            var contactShowView = new ContactShowView({
                model: model
            });

            Communicator.mediator.trigger('app:show', contactShowView);
        }
    }));

});
<commit_msg>Fixed syntax error<commit_after>define([
    'backbone',
    'communicator',
    'views/show/contact'
],
function( Backbone, Communicator, ContactShowView ) {
    'use strict';

    return new (Backbone.Marionette.Controller.extend({
        showContact: function(id) {
            var contacts = Communicator.reqres.request('contact:entities');
            var model = contacts.get(id);
            var contactShowView = new ContactShowView({
                model: model
            });

            Communicator.mediator.trigger('app:show', contactShowView);
        }
    }))();

});
<|endoftext|>


<commit_before>'use strict';
/* global jQuery:false */

angular.module('openhimWebui2App')
  .controller('TransactionsCtrl', function ($scope, $modal, $location, Api, Alerting) {

    /***************************************************/
    /**         Initial page load functions           **/
    /***************************************************/

    // get the channels for the transactions filter dropdown
    $scope.channels = Api.Channels.query(function(){
      $scope.channelsMap = {};
      angular.forEach($scope.channels, function(channel){
        $scope.channelsMap[channel._id] = channel.name;
      });
    },
    function(){
      // server error - could not connect to API to get channels
    });

    $scope.transactionsSelected = [];
    $scope.rerunTransactionsSelected = 0;

    //return results for the first page (20 results)
    $scope.showpage = 0;
    $scope.showlimit = 10;
    $scope.filterStatus = '';
    $scope.filterChannel = '';
    $scope.filterDateStart = '';
    $scope.filterDateEnd = '';

    /***************************************************/
    /**         Initial page load functions           **/
    /***************************************************/

    /*******************************************************************/
    /**         Transactions List and Detail view functions           **/
    /*******************************************************************/

    //setup filter options
    $scope.returnFilterObject = function(){
      var filtersObject = {};
      var startDate, endDate;

      var filterStatus = $scope.filterStatus;
      var filterChannel = $scope.filterChannel;
      var filterDateStart = $scope.filterDateStart;
      var filterDateEnd = $scope.filterDateEnd;

      if(filterStatus){ filtersObject.status = filterStatus; }
      if(filterChannel){ filtersObject.channelID = filterChannel; }
      if(filterDateStart && filterDateEnd){
        startDate = new Date( filterDateStart ).toISOString();
        endDate = new Date( filterDateEnd );
        endDate.setDate(endDate.getDate() + 1);
        endDate = endDate.toISOString();

        filtersObject.startDate = startDate;
        filtersObject.endDate = endDate;
      }
      filtersObject.filterPage = $scope.showpage;
      filtersObject.filterLimit = $scope.showlimit;

      return filtersObject;
    };

    var refreshSuccess = function (transactions){
      // on success
      $scope.transactions = transactions;

      if( transactions.length < $scope.showlimit ){
        jQuery('#loadMoreTransactions').hide();

        if( transactions.length === 0 ){
          Alerting.AlertAddMsg('bottom', 'warning', 'There are no transactions for the current filters');
        }

      }else{
        //Show the load more button
        jQuery('#loadMoreTransactions').show();
      }

      //make sure newly added transactions are checked as well
      $scope.resetCheckedItems();
    };

    var refreshError = function(err){
      // on error - Hide load more button and show error message
      jQuery('#loadMoreTransactions').hide();
      Alerting.AlertAddServerMsg(err.status);
    };

    //Refresh transactions list
    $scope.refreshTransactionsList = function () {
      $scope.transactions = null;
      Alerting.AlertReset();

      //reset the showpage filter to start at 0
      $scope.showpage = 0;

      Api.Transactions.query( $scope.returnFilterObject(), refreshSuccess, refreshError);

    };
    //run the transaction list view for the first time
    $scope.refreshTransactionsList();

    //Refresh transactions list
    $scope.loadMoreTransactions = function () {
      $scope.busyLoadingMore = true;
      Alerting.AlertReset();

      $scope.showpage++;
      Api.Transactions.query( $scope.returnFilterObject(), loadMoreSuccess, loadMoreError);
    };

    var loadMoreSuccess = function (transactions){
      //on success
      $scope.transactions = $scope.transactions.concat(transactions);
      //remove any duplicates objects found in the transactions scope
      $scope.transactions = jQuery.unique($scope.transactions);

      if( transactions.length < $scope.showlimit ){
        jQuery('#loadMoreTransactions').hide();
        Alerting.AlertAddMsg('bottom', 'warning', 'There are no more transactions to retrieve');
      }

      //make sure newly added transactions are checked as well
      $scope.toggleCheckedAll();
      $scope.busyLoadingMore = false;
    };

    var loadMoreError = function(err){
      // on error - Hide load more button and show error message
      jQuery('#loadMoreTransactions').hide();
      Alerting.AlertAddServerMsg(err.status);
    };

    //location provider - load transaction details
    $scope.viewTransactionDetails = function (path, $event) {
      //do transactions details redirection when clicked on TD
      if( $event.target.tagName === 'TD' ){
        $location.path(path);
      }
    };

    //Clear filter data end refresh transactions scope
    $scope.clearFilters = function () {
      $scope.filterStatus = '';
      $scope.filterChannel = '';
      $scope.filterDateStart = '';
      $scope.filterDateEnd = '';

      //run the transaction list view after filters been cleared
      $scope.refreshTransactionsList();
    };

    /*******************************************************************/
    /**         Transactions List and Detail view functions           **/
    /*******************************************************************/

    /****************************************************/
    /**         Transactions ReRun Functions           **/
    /****************************************************/

    $scope.confirmRerunTransactions = function(){
      Alerting.AlertReset();

      var transactionsSelected = $scope.transactionsSelected;
      var rerunTransactionsSelected = $scope.rerunTransactionsSelected;
      $modal.open({
        templateUrl: 'views/transactionsRerunModal.html',
        controller: 'TransactionsRerunModalCtrl',
        scope: $scope,
        resolve: {
          transactionsSelected: function () {
            return transactionsSelected;
          },
          rerunTransactionsSelected: function () {
            return rerunTransactionsSelected;
          }
        }
      });

    };

    $scope.toggleCheckedAll = function () {
      //if checked for all
      $scope.rerunTransactionsSelected = 0;
      if( $scope.checkAll === true ){
        $scope.transactionsSelected = [];
        angular.forEach($scope.transactions, function(transaction){
          $scope.transactionsSelected.push(transaction._id);

          // check if transaction is a rerun
          if (transaction.parentID){
            $scope.rerunTransactionsSelected++;
          }
        });
      }else{
        $scope.resetCheckedItems();
      }
    };

    var getObjectById = function(id, myArray) {

      var object = myArray.filter(function(obj) {
        if(obj._id == id) {
          return obj
        }
      })[0]

      return object;
    }

    $scope.toggleTransactionSelection = function(transactionID) {
      var idx = $scope.transactionsSelected.indexOf(transactionID);

      var transaction = getObjectById(transactionID, $scope.transactions);

      // is currently selected
      if (idx > -1) {
        $scope.transactionsSelected.splice(idx, 1);

        // check if transaction is a rerun
        if (transaction.parentID){
          $scope.rerunTransactionsSelected--;
        }
      }else {
        // is newly selected
        $scope.transactionsSelected.push(transactionID);

        // check if transaction is a rerun
        if (transaction.parentID){
          $scope.rerunTransactionsSelected++;
        }
      }
    };

    $scope.resetCheckedItems = function(){
      $scope.transactionsSelected = [];
      $scope.rerunTransactionsSelected = 0;
      $scope.checkAll = false;
    };

    $scope.$on('transactionRerunSuccess', function() {
      $scope.refreshTransactionsList();
    });

    /****************************************************/
    /**         Transactions ReRun Functions           **/
    /****************************************************/

  });<commit_msg>Fixed JSHint errors<commit_after>'use strict';
/* global jQuery:false */

angular.module('openhimWebui2App')
  .controller('TransactionsCtrl', function ($scope, $modal, $location, Api, Alerting) {

    /***************************************************/
    /**         Initial page load functions           **/
    /***************************************************/

    // get the channels for the transactions filter dropdown
    $scope.channels = Api.Channels.query(function(){
      $scope.channelsMap = {};
      angular.forEach($scope.channels, function(channel){
        $scope.channelsMap[channel._id] = channel.name;
      });
    },
    function(){
      // server error - could not connect to API to get channels
    });

    $scope.transactionsSelected = [];
    $scope.rerunTransactionsSelected = 0;

    //return results for the first page (20 results)
    $scope.showpage = 0;
    $scope.showlimit = 10;
    $scope.filterStatus = '';
    $scope.filterChannel = '';
    $scope.filterDateStart = '';
    $scope.filterDateEnd = '';

    /***************************************************/
    /**         Initial page load functions           **/
    /***************************************************/

    /*******************************************************************/
    /**         Transactions List and Detail view functions           **/
    /*******************************************************************/

    //setup filter options
    $scope.returnFilterObject = function(){
      var filtersObject = {};
      var startDate, endDate;

      var filterStatus = $scope.filterStatus;
      var filterChannel = $scope.filterChannel;
      var filterDateStart = $scope.filterDateStart;
      var filterDateEnd = $scope.filterDateEnd;

      if(filterStatus){ filtersObject.status = filterStatus; }
      if(filterChannel){ filtersObject.channelID = filterChannel; }
      if(filterDateStart && filterDateEnd){
        startDate = new Date( filterDateStart ).toISOString();
        endDate = new Date( filterDateEnd );
        endDate.setDate(endDate.getDate() + 1);
        endDate = endDate.toISOString();

        filtersObject.startDate = startDate;
        filtersObject.endDate = endDate;
      }
      filtersObject.filterPage = $scope.showpage;
      filtersObject.filterLimit = $scope.showlimit;

      return filtersObject;
    };

    var refreshSuccess = function (transactions){
      // on success
      $scope.transactions = transactions;

      if( transactions.length < $scope.showlimit ){
        jQuery('#loadMoreTransactions').hide();

        if( transactions.length === 0 ){
          Alerting.AlertAddMsg('bottom', 'warning', 'There are no transactions for the current filters');
        }

      }else{
        //Show the load more button
        jQuery('#loadMoreTransactions').show();
      }

      //make sure newly added transactions are checked as well
      $scope.resetCheckedItems();
    };

    var refreshError = function(err){
      // on error - Hide load more button and show error message
      jQuery('#loadMoreTransactions').hide();
      Alerting.AlertAddServerMsg(err.status);
    };

    //Refresh transactions list
    $scope.refreshTransactionsList = function () {
      $scope.transactions = null;
      Alerting.AlertReset();

      //reset the showpage filter to start at 0
      $scope.showpage = 0;

      Api.Transactions.query( $scope.returnFilterObject(), refreshSuccess, refreshError);

    };
    //run the transaction list view for the first time
    $scope.refreshTransactionsList();

    //Refresh transactions list
    $scope.loadMoreTransactions = function () {
      $scope.busyLoadingMore = true;
      Alerting.AlertReset();

      $scope.showpage++;
      Api.Transactions.query( $scope.returnFilterObject(), loadMoreSuccess, loadMoreError);
    };

    var loadMoreSuccess = function (transactions){
      //on success
      $scope.transactions = $scope.transactions.concat(transactions);
      //remove any duplicates objects found in the transactions scope
      $scope.transactions = jQuery.unique($scope.transactions);

      if( transactions.length < $scope.showlimit ){
        jQuery('#loadMoreTransactions').hide();
        Alerting.AlertAddMsg('bottom', 'warning', 'There are no more transactions to retrieve');
      }

      //make sure newly added transactions are checked as well
      $scope.toggleCheckedAll();
      $scope.busyLoadingMore = false;
    };

    var loadMoreError = function(err){
      // on error - Hide load more button and show error message
      jQuery('#loadMoreTransactions').hide();
      Alerting.AlertAddServerMsg(err.status);
    };

    //location provider - load transaction details
    $scope.viewTransactionDetails = function (path, $event) {
      //do transactions details redirection when clicked on TD
      if( $event.target.tagName === 'TD' ){
        $location.path(path);
      }
    };

    //Clear filter data end refresh transactions scope
    $scope.clearFilters = function () {
      $scope.filterStatus = '';
      $scope.filterChannel = '';
      $scope.filterDateStart = '';
      $scope.filterDateEnd = '';

      //run the transaction list view after filters been cleared
      $scope.refreshTransactionsList();
    };

    /*******************************************************************/
    /**         Transactions List and Detail view functions           **/
    /*******************************************************************/

    /****************************************************/
    /**         Transactions ReRun Functions           **/
    /****************************************************/

    $scope.confirmRerunTransactions = function(){
      Alerting.AlertReset();

      var transactionsSelected = $scope.transactionsSelected;
      var rerunTransactionsSelected = $scope.rerunTransactionsSelected;
      $modal.open({
        templateUrl: 'views/transactionsRerunModal.html',
        controller: 'TransactionsRerunModalCtrl',
        scope: $scope,
        resolve: {
          transactionsSelected: function () {
            return transactionsSelected;
          },
          rerunTransactionsSelected: function () {
            return rerunTransactionsSelected;
          }
        }
      });

    };

    $scope.toggleCheckedAll = function () {
      //if checked for all
      $scope.rerunTransactionsSelected = 0;
      if( $scope.checkAll === true ){
        $scope.transactionsSelected = [];
        angular.forEach($scope.transactions, function(transaction){
          $scope.transactionsSelected.push(transaction._id);

          // check if transaction is a rerun
          if (transaction.parentID){
            $scope.rerunTransactionsSelected++;
          }
        });
      }else{
        $scope.resetCheckedItems();
      }
    };

    var getObjectById = function(id, myArray) {

      var object = myArray.filter(function(obj) {
        if(obj._id === id) {
          return obj;
        }
      })[0];

      return object;
    };

    $scope.toggleTransactionSelection = function(transactionID) {
      var idx = $scope.transactionsSelected.indexOf(transactionID);

      var transaction = getObjectById(transactionID, $scope.transactions);

      // is currently selected
      if (idx > -1) {
        $scope.transactionsSelected.splice(idx, 1);

        // check if transaction is a rerun
        if (transaction.parentID){
          $scope.rerunTransactionsSelected--;
        }
      }else {
        // is newly selected
        $scope.transactionsSelected.push(transactionID);

        // check if transaction is a rerun
        if (transaction.parentID){
          $scope.rerunTransactionsSelected++;
        }
      }
    };

    $scope.resetCheckedItems = function(){
      $scope.transactionsSelected = [];
      $scope.rerunTransactionsSelected = 0;
      $scope.checkAll = false;
    };

    $scope.$on('transactionRerunSuccess', function() {
      $scope.refreshTransactionsList();
    });

    /****************************************************/
    /**         Transactions ReRun Functions           **/
    /****************************************************/

  });<|endoftext|>


<commit_before>'use strict';

app.directive ('ghRepo', function () {
    return {
        restrict: 'E' ,
        templateUrl: 'views/partials/Repo.html' ,
        link: function (scope, element, attr) {
            if (angular.isUndefined (scope.repo)) element.hide ();
            else element.show ();
        }
    };
});<commit_msg>added some comments<commit_after>'use strict';

/**
 * Repo Directive
 * It handles single repo view
 */
app.directive ('ghRepo', function () {
    return {
        restrict: 'E' ,
        templateUrl: 'views/partials/Repo.html' ,
        link: function (scope, element, attr) {
            // Hide or show repo page
            if (angular.isUndefined (scope.repo)) element.hide ();
            else element.show ();
        }
    };
});<|endoftext|>


<commit_before>/**
 * Wheel, copyright (c) 2020 - present by Arno van der Vegt
 * Distributed under an MIT license: https://arnovandervegt.github.io/wheel/license.txt
**/
const dispatcher          = require('../../../../../lib/dispatcher').dispatcher;
const Emitter             = require('../../../../../lib/Emitter').Emitter;
const path                = require('../../../../../lib/path');
const formEditorConstants = require('../formEditorConstants');
const ComponentBuilder    = require('../ComponentBuilder').ComponentBuilder;
const ComponentList       = require('./ComponentList').ComponentList;
const EventList           = require('./EventList').EventList;
const PropertyList        = require('./PropertyList').PropertyList;
const UndoStack           = require('./UndoStack').UndoStack;

exports.FormEditorState = class extends Emitter {
    constructor(opts) {
        super(opts);
        this._formEditorToolbarState = opts.formEditorToolbarState; // Todo: remove this dependency...
        this._settings               = opts.settings;
        this._loading                = !!opts.data;
        this._clipboard              = null;
        this._path                   = opts.path;
        this._filename               = opts.filename;
        this._containerIdsForForm    = opts.containerIdsForForm;
        this._nextId                 = 0;
        this._formId                 = this.peekId();
        this._componentList          = new ComponentList({
            formEditorState:     this
        });
        this._componentBuilder      = new ComponentBuilder({
            formEditorState:     this,
            componentList:       this._componentList
        });
        this._undoStack             = new UndoStack({
            formEditorState:     this,
            componentBuilder:    this._componentBuilder,
            componentList:       this._componentList,
            containerIdsForForm: this._containerIdsForForm
        });
        this._componentList.setUndoStack(this._undoStack);
        this._dispatch              = [
            dispatcher.on('Properties.Property.Change',   this, this.onChangeProperty),
            dispatcher.on('Properties.Event.Change',      this, this.onChangeEvent),
            dispatcher.on('Properties.Select.Properties', this, this.onSelectProperties),
            dispatcher.on('Properties.SelectComponent',   this, this.onSelectComponent)
        ];
        let initTime = ('initTime' in opts) ? opts.initTime : 50;
        setTimeout(this.initForm.bind(this, opts), initTime);
    }

    remove() {
        while (this._dispatch.length) {
            this._dispatch.pop()();
        }
    }

    initForm(opts) {
        let formName  = path.replaceExtension(opts.filename, '');
        let form      = opts.data ? opts.data[0] : null;
        let component = this._componentBuilder.addFormComponent({
                type:   formEditorConstants.COMPONENT_TYPE_FORM,
                uid:    form ? form.uid    : this._componentList.getNewComponentUid(),
                name:   form ? form.name   : (formName.substr(0, 1).toUpperCase() + formName.substr(1 - formName.length)),
                title:  form ? form.title  : formName,
                width:  form ? form.width  : opts.width,
                height: form ? form.height : opts.height
            });
        component.id = this._formId;
        this._componentList.setComponentById(component, this._formId);
        this
            .emit('AddForm', Object.assign({}, component))
            .updateComponents(component.id)
            .onSelectComponent(component.id)
            .getNextId(); // Skip the form Id!
        if (opts.data) {
            let data   = opts.data;
            let nextId = 0;
            for (let i = 1; i < data.length; i++) {
                let component = data[i];
                component.owner = this._containerIdsForForm.getFormComponentContainerByContainerId(component.parentId);
                if (typeof component.parentId === 'number') {
                    nextId = Math.max(nextId, component.parentId);
                }
                if (typeof component.id === 'number') {
                    nextId = Math.max(nextId, component.id);
                }
                this.addComponent(component);
            }
            this._nextId = Math.max(nextId, this._nextId);
        }
        this._undoStack.setEnabled(true);
        this._loading = false;
        this.emit('Loaded', this);
        dispatcher.dispatch('FormEditor.Select.ToolbarTool', {toolGroup: 0, toolIndex: 0});
    }

    peekId() {
        return this._nextId + 1;
    }

    getNextId() {
        this._nextId++;
        return this._nextId;
    }

    getLoading() {
        return this._loading;
    }

    /**
     * Used to change the path when the file is saved...
    **/
    setPath(path) {
        this._path = path;
    }

    getPath() {
        return this._path;
    }

    getFilename() {
        return this._filename;
    }

    getUndoStackLength() {
        return this._undoStack.getLength();
    }

    getFormComponent() {
        return this._componentList.getComponentById(this._formId);
    }

    setComponentPositionById(id, position) {
        let component = this._componentList.getComponentById(id) || {};
        this._undoStack.undoStackPush({
            action:   formEditorConstants.ACTION_CHANGE_POSITION,
            id:       id,
            position: {x: component.x || 0, y: component.y || 0}
        });
        let formGridSize = this._settings.getFormGridSize();
        if (formGridSize) {
            position.x = Math.round(position.x / formGridSize) * formGridSize;
            position.y = Math.round(position.y / formGridSize) * formGridSize;
        }
        component.x = position.x;
        component.y = position.y;
    }

    getComponentById(id) {
        return this._componentList.getComponentById(id);
    }

    getFormName() {
        return this.getComponentById(this._formId).name;
    }

    getActiveComponentId() {
        return this._componentList.getActiveComponentId();
    }

    getActiveComponentParentId() {
        let activeComponent = this.getActiveComponent();
        if (activeComponent.type === formEditorConstants.COMPONENT_TYPE_PANEL) {
            return activeComponent.containerIds;
        }
        if (activeComponent.type === formEditorConstants.COMPONENT_TYPE_TABS) {
            return activeComponent.containerIds;
        }
        if (!activeComponent ||
            (activeComponent.type === formEditorConstants.COMPONENT_TYPE_FORM) ||
            (activeComponent.parentId === this._formId)) {
            return null;
        }
        return activeComponent.parentId || null;
    }

    getActiveComponent() {
        return this._componentList.getComponentById(this.getActiveComponentId()) || null;
    }

    getActiveComponentType() {
        let activeComponent = this.getActiveComponent();
        return activeComponent ? activeComponent.type : null;
    }

    getCanCopy() {
        let type = this.getActiveComponentType();
        if (type) {
            type = type.toUpperCase();
            if (type in formEditorConstants.PROPERTIES_BY_TYPE) {
                return formEditorConstants.PROPERTIES_BY_TYPE[type].canCopy;
            }
        }
        return false;
    }

    getCanPaste() {
        return !!this._clipboard;
    }

    getHasUndo() {
        return this._undoStack.getLength();
    }

    getData(renumIds) {
        return this._componentList.getData(renumIds);
    }

    getComponentList() {
        return this._componentList;
    }

    propertiesFromComponentToOpts(componentId, propertyList, opts) {
        let component = this.getComponentById(componentId);
        propertyList.getList().forEach((property) => {
            if (property.name && (property.name in component)) {
                opts[property.name] = component[property.name];
            }
        });
        return component;
    }

    undo() {
        this._undoStack.undo();
    }

    addComponent(opts) {
        let component = Object.assign({}, opts);
        component.id  = this.getNextId();
        component.uid = component.uid || this._componentList.getNewComponentUid();
        this._componentList
            .setComponentById(component, component.id)
            .setActiveComponentId(component.id);
        this._componentBuilder.addComponentForType(component, opts.type || this._formEditorToolbarState.getActiveAddComponentType());
        this._undoStack.undoStackPush({action: formEditorConstants.ACTION_ADD_COMPONENT, id: component.id});
        this
            .emit('AddComponent', Object.assign({}, component))
            .updateComponents(component.id);
    }

    deleteActiveComponent() {
        let activeComponentId = this._componentList.getActiveComponentId();
        if (!activeComponentId) {
            return;
        }
        this.deleteComponentById(activeComponentId, true);
    }

    deleteComponentById(id, saveUndo) {
        let componentList = this._componentList;
        let component     = this._componentList.getComponentById(id);
        let children      = componentList.getChildComponents(component);
        let components    = [];
        componentList.deleteComponentById(id);
        children.forEach((child) => {
            componentList.deleteComponentById(child.id);
        });
        if (saveUndo) {
            if (children.length) {
                component.children = children;
                children.forEach((component) => {
                    components.push({name: component.name, id: component.id});
                    componentList.deleteComponentById(component.id);
                });
            }
            this._undoStack.undoStackPush({action: formEditorConstants.ACTION_DELETE_COMPONENT, component: component});
        }
        components.push({id: id, name: component.name});
        this.emit(
            'DeleteComponent',
            {
                components: components, // For source builder to remove defines...
                id:         id,
                name:       component.name,
                formName:   this.getFormName()
            }
        );
        dispatcher.dispatch('Properties.ComponentList', {value: null, items: this._componentList.getItems()});
    }

    copy() {
        if (!this.getCanCopy()) {
            return false;
        }
        let component = this.getActiveComponent();
        if (component) {
            this._clipboard = Object.assign({}, component);
            delete this._clipboard.owner;
            return true;
        }
        return false;
    }

    paste(parentId, owner) {
        let clipboard = this._clipboard;
        if (!clipboard) {
            return;
        }
        clipboard.owner    = owner;
        clipboard.parentId = parentId;
        clipboard.x += 32;
        clipboard.y += 32;
        this.addComponent(clipboard);
    }

    selectComponentById(id) {
        let component = this._componentList.selectComponentById(id);
        component && this.emit('SelectComponent', id);
        return component;
    }

    changeTabs(component, value) {
        this._componentList.changeTabs(component, value);
    }

    onChangeProperty(id, property, value) {
        let component = this._componentList.getComponentById(id);
        if (!component) {
            return;
        }
        let renameEvents = [];
        let oldValue     = component[property];
        let isTabs       = (component.type === formEditorConstants.COMPONENT_TYPE_TABS) && (property === 'tabs');
        if (isTabs) {
            this.changeTabs(component, value);
        }
        if (property === 'name') {
            component[property] = value;
            if (id === this._formId) {
                this._componentList.getList().forEach(
                    function(component) {
                        renameEvents.push.apply(renameEvents, this.updateEventsForComponent(component));
                    },
                    this
                );
            } else {
                renameEvents.push.apply(renameEvents, this.updateEventsForComponent(component));
            }
            this.emit(
                (component.type === 'form') ? 'RenameForm' : 'RenameComponent',
                {
                    components:   this._componentList.getList(),
                    oldName:      component[property],
                    newName:      value,
                    renameEvents: renameEvents
                }
            );
        } else {
            component[property] = value;
        }
        if (!isTabs) {
            this._undoStack.undoStackPush({
                action:       formEditorConstants.ACTION_CHANGE_PROPERTY,
                id:           id,
                property:     property,
                value:        oldValue,
                renameEvents: renameEvents
            });
        }
        if (component.type === 'form') {
            this.emit('ChangeForm');
        }
        dispatcher.dispatch('Properties.ComponentList', {items: this._componentList.getItems()});
    }

    onChangeEvent(id, event, value) {
        let component = this._componentList.getComponentById(id);
        if (!component) {
            console.error('Component not found:', id);
            return;
        }
        let newValue = !component[event];
        if (value) {
            component[event] = value;
        } else {
            delete component[event];
            newValue = false;
        }
        if (newValue) {
            this.emit('ChangeEvent');
        }
    }

    onSelectProperties(propertyList) {
        this.selectComponentById(propertyList.getComponentId());
    }

    onSelectComponent(id) {
        let component = this.selectComponentById(id);
        if (component) {
            let formId        = this._formId;
            let componentList = this._componentList;
            let propertyList  = new PropertyList({
                    component:       component,
                    componentList:   this._componentList,
                    formEditorState: this
                });
            let eventList     = new EventList({
                    component:       component,
                    formEditorState: this
                });
            dispatcher
                .dispatch('Properties.Select.Properties', propertyList, this)
                .dispatch('Properties.Select.Events',     eventList,    this);
        }
        return this;
    }

    updateEventsForComponent(component) {
        let eventList     = new EventList({
                component:       component,
                formEditorState: this
            });
        let events        = eventList.getUpdatedEvents();
        let componentList = this._componentList;
        let renameEvents  = [];
        for (let event in events) {
            if (event in component) {
                renameEvents.push({
                    uid:      component.uid,
                    name:     event,
                    newValue: events[event],
                    oldValue: component[event]
                });
                componentList.getComponentById(component.id)[event] = events[event];
            }
        }
        return renameEvents;
    }

    updateComponents(id) {
        dispatcher.dispatch('Properties.ComponentList', {value: id, items: this._componentList.getItems()});
        return this;
    }
};
<commit_msg>Fixed component name property update.<commit_after>/**
 * Wheel, copyright (c) 2020 - present by Arno van der Vegt
 * Distributed under an MIT license: https://arnovandervegt.github.io/wheel/license.txt
**/
const dispatcher          = require('../../../../../lib/dispatcher').dispatcher;
const Emitter             = require('../../../../../lib/Emitter').Emitter;
const path                = require('../../../../../lib/path');
const formEditorConstants = require('../formEditorConstants');
const ComponentBuilder    = require('../ComponentBuilder').ComponentBuilder;
const ComponentList       = require('./ComponentList').ComponentList;
const EventList           = require('./EventList').EventList;
const PropertyList        = require('./PropertyList').PropertyList;
const UndoStack           = require('./UndoStack').UndoStack;

exports.FormEditorState = class extends Emitter {
    constructor(opts) {
        super(opts);
        this._formEditorToolbarState = opts.formEditorToolbarState; // Todo: remove this dependency...
        this._settings               = opts.settings;
        this._loading                = !!opts.data;
        this._clipboard              = null;
        this._path                   = opts.path;
        this._filename               = opts.filename;
        this._containerIdsForForm    = opts.containerIdsForForm;
        this._nextId                 = 0;
        this._formId                 = this.peekId();
        this._componentList          = new ComponentList({
            formEditorState:     this
        });
        this._componentBuilder      = new ComponentBuilder({
            formEditorState:     this,
            componentList:       this._componentList
        });
        this._undoStack             = new UndoStack({
            formEditorState:     this,
            componentBuilder:    this._componentBuilder,
            componentList:       this._componentList,
            containerIdsForForm: this._containerIdsForForm
        });
        this._componentList.setUndoStack(this._undoStack);
        this._dispatch              = [
            dispatcher.on('Properties.Property.Change',   this, this.onChangeProperty),
            dispatcher.on('Properties.Event.Change',      this, this.onChangeEvent),
            dispatcher.on('Properties.Select.Properties', this, this.onSelectProperties),
            dispatcher.on('Properties.SelectComponent',   this, this.onSelectComponent)
        ];
        let initTime = ('initTime' in opts) ? opts.initTime : 50;
        setTimeout(this.initForm.bind(this, opts), initTime);
    }

    remove() {
        while (this._dispatch.length) {
            this._dispatch.pop()();
        }
    }

    initForm(opts) {
        let formName  = path.replaceExtension(opts.filename, '');
        let form      = opts.data ? opts.data[0] : null;
        let component = this._componentBuilder.addFormComponent({
                type:   formEditorConstants.COMPONENT_TYPE_FORM,
                uid:    form ? form.uid    : this._componentList.getNewComponentUid(),
                name:   form ? form.name   : (formName.substr(0, 1).toUpperCase() + formName.substr(1 - formName.length)),
                title:  form ? form.title  : formName,
                width:  form ? form.width  : opts.width,
                height: form ? form.height : opts.height
            });
        component.id = this._formId;
        this._componentList.setComponentById(component, this._formId);
        this
            .emit('AddForm', Object.assign({}, component))
            .updateComponents(component.id)
            .onSelectComponent(component.id)
            .getNextId(); // Skip the form Id!
        if (opts.data) {
            let data   = opts.data;
            let nextId = 0;
            for (let i = 1; i < data.length; i++) {
                let component = data[i];
                component.owner = this._containerIdsForForm.getFormComponentContainerByContainerId(component.parentId);
                if (typeof component.parentId === 'number') {
                    nextId = Math.max(nextId, component.parentId);
                }
                if (typeof component.id === 'number') {
                    nextId = Math.max(nextId, component.id);
                }
                this.addComponent(component);
            }
            this._nextId = Math.max(nextId, this._nextId);
        }
        this._undoStack.setEnabled(true);
        this._loading = false;
        this.emit('Loaded', this);
        dispatcher.dispatch('FormEditor.Select.ToolbarTool', {toolGroup: 0, toolIndex: 0});
    }

    peekId() {
        return this._nextId + 1;
    }

    getNextId() {
        this._nextId++;
        return this._nextId;
    }

    getLoading() {
        return this._loading;
    }

    /**
     * Used to change the path when the file is saved...
    **/
    setPath(path) {
        this._path = path;
    }

    getPath() {
        return this._path;
    }

    getFilename() {
        return this._filename;
    }

    getUndoStackLength() {
        return this._undoStack.getLength();
    }

    getFormComponent() {
        return this._componentList.getComponentById(this._formId);
    }

    setComponentPositionById(id, position) {
        let component = this._componentList.getComponentById(id) || {};
        this._undoStack.undoStackPush({
            action:   formEditorConstants.ACTION_CHANGE_POSITION,
            id:       id,
            position: {x: component.x || 0, y: component.y || 0}
        });
        let formGridSize = this._settings.getFormGridSize();
        if (formGridSize) {
            position.x = Math.round(position.x / formGridSize) * formGridSize;
            position.y = Math.round(position.y / formGridSize) * formGridSize;
        }
        component.x = position.x;
        component.y = position.y;
    }

    getComponentById(id) {
        return this._componentList.getComponentById(id);
    }

    getFormName() {
        return this.getComponentById(this._formId).name;
    }

    getActiveComponentId() {
        return this._componentList.getActiveComponentId();
    }

    getActiveComponentParentId() {
        let activeComponent = this.getActiveComponent();
        if (activeComponent.type === formEditorConstants.COMPONENT_TYPE_PANEL) {
            return activeComponent.containerIds;
        }
        if (activeComponent.type === formEditorConstants.COMPONENT_TYPE_TABS) {
            return activeComponent.containerIds;
        }
        if (!activeComponent ||
            (activeComponent.type === formEditorConstants.COMPONENT_TYPE_FORM) ||
            (activeComponent.parentId === this._formId)) {
            return null;
        }
        return activeComponent.parentId || null;
    }

    getActiveComponent() {
        return this._componentList.getComponentById(this.getActiveComponentId()) || null;
    }

    getActiveComponentType() {
        let activeComponent = this.getActiveComponent();
        return activeComponent ? activeComponent.type : null;
    }

    getCanCopy() {
        let type = this.getActiveComponentType();
        if (type) {
            type = type.toUpperCase();
            if (type in formEditorConstants.PROPERTIES_BY_TYPE) {
                return formEditorConstants.PROPERTIES_BY_TYPE[type].canCopy;
            }
        }
        return false;
    }

    getCanPaste() {
        return !!this._clipboard;
    }

    getHasUndo() {
        return this._undoStack.getLength();
    }

    getData(renumIds) {
        return this._componentList.getData(renumIds);
    }

    getComponentList() {
        return this._componentList;
    }

    propertiesFromComponentToOpts(componentId, propertyList, opts) {
        let component = this.getComponentById(componentId);
        propertyList.getList().forEach((property) => {
            if (property.name && (property.name in component)) {
                opts[property.name] = component[property.name];
            }
        });
        return component;
    }

    undo() {
        this._undoStack.undo();
    }

    addComponent(opts) {
        let component = Object.assign({}, opts);
        component.id  = this.getNextId();
        component.uid = component.uid || this._componentList.getNewComponentUid();
        this._componentList
            .setComponentById(component, component.id)
            .setActiveComponentId(component.id);
        this._componentBuilder.addComponentForType(component, opts.type || this._formEditorToolbarState.getActiveAddComponentType());
        this._undoStack.undoStackPush({action: formEditorConstants.ACTION_ADD_COMPONENT, id: component.id});
        this
            .emit('AddComponent', Object.assign({}, component))
            .updateComponents(component.id);
    }

    deleteActiveComponent() {
        let activeComponentId = this._componentList.getActiveComponentId();
        if (!activeComponentId) {
            return;
        }
        this.deleteComponentById(activeComponentId, true);
    }

    deleteComponentById(id, saveUndo) {
        let componentList = this._componentList;
        let component     = this._componentList.getComponentById(id);
        let children      = componentList.getChildComponents(component);
        let components    = [];
        componentList.deleteComponentById(id);
        children.forEach((child) => {
            componentList.deleteComponentById(child.id);
        });
        if (saveUndo) {
            if (children.length) {
                component.children = children;
                children.forEach((component) => {
                    components.push({name: component.name, id: component.id});
                    componentList.deleteComponentById(component.id);
                });
            }
            this._undoStack.undoStackPush({action: formEditorConstants.ACTION_DELETE_COMPONENT, component: component});
        }
        components.push({id: id, name: component.name});
        this.emit(
            'DeleteComponent',
            {
                components: components, // For source builder to remove defines...
                id:         id,
                name:       component.name,
                formName:   this.getFormName()
            }
        );
        dispatcher.dispatch('Properties.ComponentList', {value: null, items: this._componentList.getItems()});
    }

    copy() {
        if (!this.getCanCopy()) {
            return false;
        }
        let component = this.getActiveComponent();
        if (component) {
            this._clipboard = Object.assign({}, component);
            delete this._clipboard.owner;
            return true;
        }
        return false;
    }

    paste(parentId, owner) {
        let clipboard = this._clipboard;
        if (!clipboard) {
            return;
        }
        clipboard.owner    = owner;
        clipboard.parentId = parentId;
        clipboard.x += 32;
        clipboard.y += 32;
        this.addComponent(clipboard);
    }

    selectComponentById(id) {
        let component = this._componentList.selectComponentById(id);
        component && this.emit('SelectComponent', id);
        return component;
    }

    changeTabs(component, value) {
        this._componentList.changeTabs(component, value);
    }

    onChangeProperty(id, property, value) {
        let component = this._componentList.getComponentById(id);
        if (!component) {
            return;
        }
        let renameEvents = [];
        let oldValue     = component[property];
        let isTabs       = (component.type === formEditorConstants.COMPONENT_TYPE_TABS) && (property === 'tabs');
        if (isTabs) {
            this.changeTabs(component, value);
        }
        if (property === 'name') {
            let oldName = component[property];
            component[property] = value;
            if (id === this._formId) {
                this._componentList.getList().forEach(
                    function(component) {
                        renameEvents.push.apply(renameEvents, this.updateEventsForComponent(component));
                    },
                    this
                );
            } else {
                renameEvents.push.apply(renameEvents, this.updateEventsForComponent(component));
            }
            this.emit(
                (component.type === 'form') ? 'RenameForm' : 'RenameComponent',
                {
                    components:   this._componentList.getList(),
                    oldName:      oldName,
                    newName:      value,
                    renameEvents: renameEvents
                }
            );
        } else {
            component[property] = value;
        }
        if (!isTabs) {
            this._undoStack.undoStackPush({
                action:       formEditorConstants.ACTION_CHANGE_PROPERTY,
                id:           id,
                property:     property,
                value:        oldValue,
                renameEvents: renameEvents
            });
        }
        if (component.type === 'form') {
            this.emit('ChangeForm');
        }
        dispatcher.dispatch('Properties.ComponentList', {items: this._componentList.getItems()});
    }

    onChangeEvent(id, event, value) {
        let component = this._componentList.getComponentById(id);
        if (!component) {
            console.error('Component not found:', id);
            return;
        }
        let newValue = !component[event];
        if (value) {
            component[event] = value;
        } else {
            delete component[event];
            newValue = false;
        }
        if (newValue) {
            this.emit('ChangeEvent');
        }
    }

    onSelectProperties(propertyList) {
        this.selectComponentById(propertyList.getComponentId());
    }

    onSelectComponent(id) {
        let component = this.selectComponentById(id);
        if (component) {
            let formId        = this._formId;
            let componentList = this._componentList;
            let propertyList  = new PropertyList({
                    component:       component,
                    componentList:   this._componentList,
                    formEditorState: this
                });
            let eventList     = new EventList({
                    component:       component,
                    formEditorState: this
                });
            dispatcher
                .dispatch('Properties.Select.Properties', propertyList, this)
                .dispatch('Properties.Select.Events',     eventList,    this);
        }
        return this;
    }

    updateEventsForComponent(component) {
        let eventList     = new EventList({
                component:       component,
                formEditorState: this
            });
        let events        = eventList.getUpdatedEvents();
        let componentList = this._componentList;
        let renameEvents  = [];
        for (let event in events) {
            if (event in component) {
                renameEvents.push({
                    uid:      component.uid,
                    name:     event,
                    newValue: events[event],
                    oldValue: component[event]
                });
                componentList.getComponentById(component.id)[event] = events[event];
            }
        }
        return renameEvents;
    }

    updateComponents(id) {
        dispatcher.dispatch('Properties.ComponentList', {value: id, items: this._componentList.getItems()});
        return this;
    }
};
<|endoftext|>