<commit_before>(function () {
  'use strict';

  angular.module('foundation.iconic', [])
    .provider('Iconic', Iconic)
    .directive('zfIconic', zfIconic)
  ;

  // iconic wrapper
  function Iconic() {
    // default path
    var assetPath = 'assets/img/iconic/';

    /**
     * Sets the path used to locate the iconic SVG files
     * @param {string} path - the base path used to locate the iconic SVG files
     */
    this.setAssetPath = function (path) {
      assetPath = angular.isString(path) ? path : assetPath;
    };

    /**
     * Service implementation
     * @returns {{}}
     */
    this.$get = function () {
      var iconicObject = new IconicJS();

      var service = {
        getAccess: getAccess,
        getAssetPath: getAssetPath
      };

      return service;

      /**
       *
       * @returns {Window.IconicJS}
       */
      function getAccess() {
        return iconicObject;
      }

      /**
       *
       * @returns {string}
       */
      function getAssetPath() {
        return assetPath;
      }
    };
  }

  zfIconic.$inject = ['Iconic', 'FoundationApi', '$compile'];

  function zfIconic(iconic, foundationApi, $compile) {
    var directive = {
      restrict: 'A',
      template: '<img ng-transclude>',
      transclude: true,
      replace: true,
      scope: {
        dynSrc: '=?',
        dynIcon: '=?',
        dynIconAttrs: '=?',
        size: '@?',
        icon: '@',
        iconDir: '@?',
        iconAttrs: '@?'
      },
      compile: compile
    };

    return directive;

    function compile() {
      var contents, origAttrs, lastIconAttrs, assetPath;

      return {
        pre: preLink,
        post: postLink
      };

      function preLink(scope, element, attrs) {
        var iconAttrsObj, iconAttr;

        if (scope.iconDir) {
          // path set via attribute
          assetPath = scope.iconDir;
        } else {
          // default path
          assetPath = iconic.getAssetPath();
        }
        // make sure ends with /
        if (assetPath.charAt(assetPath.length - 1) !== '/') {
          assetPath += '/';
        }

        if (scope.dynSrc) {
          attrs.$set('data-src', scope.dynSrc);
        } else if (scope.dynIcon) {
          attrs.$set('data-src', assetPath + scope.dynIcon + '.svg');
        } else {
          if (scope.icon) {
            attrs.$set('data-src', assetPath + scope.icon + '.svg');
          } else {
            // To support expressions on data-src
            attrs.$set('data-src', attrs.src);
          }
        }

        // check if size already added as class
        if (!element.hasClass('iconic-sm') && !element.hasClass('iconic-md') && !element.hasClass('iconic-lg')) {
          var iconicClass;
          switch (scope.size) {
            case 'small':
              iconicClass = 'iconic-sm';
              break;
            case 'medium':
              iconicClass = 'iconic-md';
              break;
            case 'large':
              iconicClass = 'iconic-lg';
              break;
            default:
              iconicClass = 'iconic-fluid';
          }
          element.addClass(iconicClass);
        }

        // add static icon attributes to iconic element
        if (scope.iconAttrs) {
          iconAttrsObj = angular.fromJson(scope.iconAttrs);
          for (iconAttr in iconAttrsObj) {
            // add data- to attribute name if not already present
            attrs.$set(addDataDash(iconAttr), iconAttrsObj[iconAttr]);
          }
        }

        // save contents and attributes of un-inject html, to use for dynamic re-injection
        contents = element[0].outerHTML;
        origAttrs = element[0].attributes;
      }

      function postLink(scope, element, attrs) {
        var svgElement, ico = iconic.getAccess();

        injectSvg(element[0]);

        foundationApi.subscribe('resize', function () {
          // only run update on current element
          ico.update(element[0]);
        });

        // handle dynamic updating of src
        if (scope.dynSrc) {
          scope.$watch('dynSrc', function (newVal, oldVal) {
            if (newVal && newVal !== oldVal) {
              reinjectSvg(scope.dynSrc, scope.dynIconAttrs);
            }
          });
        }
        // handle dynamic updating of icon
        if (scope.dynIcon) {
          scope.$watch('dynIcon', function (newVal, oldVal) {
            if (newVal && newVal !== oldVal) {
              reinjectSvg(assetPath + scope.dynIcon + '.svg', scope.dynIconAttrs);
            }
          });
        }
        // handle dynamic updating of icon attrs
        scope.$watch('dynIconAttrs', function (newVal, oldVal) {
          if (newVal && newVal !== oldVal) {
            if (scope.dynSrc) {
              reinjectSvg(scope.dynSrc, scope.dynIconAttrs);
            } else {
              reinjectSvg(assetPath + scope.dynIcon + '.svg', scope.dynIconAttrs);
            }
          }
        });

        function reinjectSvg(newSrc, newAttrs) {
          var iconAttr;

          if (svgElement) {
            // set html
            svgElement.empty();
            svgElement.append(angular.element(contents));

            // remove 'data-icon' attribute added by injector as it
            // will cause issues with reinjection when changing icons
            svgElement.removeAttr('data-icon');

            // set new source
            svgElement.attr('data-src', newSrc);

            // add additional icon attributes to iconic element
            if (newAttrs) {
              // remove previously added attributes
              if (lastIconAttrs) {
                for (iconAttr in lastIconAttrs) {
                  svgElement.removeAttr(addDataDash(iconAttr));
                }
              }

              // add newly added attributes
              for (iconAttr in newAttrs) {
                // add data- to attribute name if not already present
                svgElement.attr(addDataDash(iconAttr), newAttrs[iconAttr]);
              }
            }

            // store current attrs
            lastIconAttrs = newAttrs;

            // reinject
            injectSvg(svgElement[0]);
          }
        }

        function injectSvg(element) {
          ico.inject(element, {
            each: function (injectedElem) {
              var i, angElem;

              // wrap raw element
              angElem = angular.element(injectedElem);

              for(i = 0; i < origAttrs.length; i++) {
                // check if attribute should be ignored
                if (origAttrs[i].name !== 'zf-iconic' &&
                    origAttrs[i].name !== 'ng-transclude' &&
                    origAttrs[i].name !== 'icon' &&
                    origAttrs[i].name !== 'src') {
                  // check if attribute already exists on svg
                  if (angular.isUndefined(angElem.attr(origAttrs[i].name))) {
                    // add attribute to svg
                    angElem.attr(origAttrs[i].name, origAttrs[i].value);
                  }
                }
              }

              // compile
              svgElement = $compile(angElem)(angElem.scope());
            }
          });
        }

        function addDataDash(attr) {
          return attr.indexOf('data-') !== 0 ? 'data-' + attr : attr;
        }
      }
    }
  }

})();
<commit_msg>Fix issue with addDataDash not existing<commit_after>(function () {
  'use strict';

  angular.module('foundation.iconic', [])
    .provider('Iconic', Iconic)
    .directive('zfIconic', zfIconic)
  ;

  // iconic wrapper
  function Iconic() {
    // default path
    var assetPath = 'assets/img/iconic/';

    /**
     * Sets the path used to locate the iconic SVG files
     * @param {string} path - the base path used to locate the iconic SVG files
     */
    this.setAssetPath = function (path) {
      assetPath = angular.isString(path) ? path : assetPath;
    };

    /**
     * Service implementation
     * @returns {{}}
     */
    this.$get = function () {
      var iconicObject = new IconicJS();

      var service = {
        getAccess: getAccess,
        getAssetPath: getAssetPath
      };

      return service;

      /**
       *
       * @returns {Window.IconicJS}
       */
      function getAccess() {
        return iconicObject;
      }

      /**
       *
       * @returns {string}
       */
      function getAssetPath() {
        return assetPath;
      }
    };
  }

  zfIconic.$inject = ['Iconic', 'FoundationApi', '$compile'];

  function zfIconic(iconic, foundationApi, $compile) {
    var directive = {
      restrict: 'A',
      template: '<img ng-transclude>',
      transclude: true,
      replace: true,
      scope: {
        dynSrc: '=?',
        dynIcon: '=?',
        dynIconAttrs: '=?',
        size: '@?',
        icon: '@',
        iconDir: '@?',
        iconAttrs: '@?'
      },
      compile: compile
    };

    return directive;

    function compile() {
      var contents, origAttrs, lastIconAttrs, assetPath;

      return {
        pre: preLink,
        post: postLink
      };

      function preLink(scope, element, attrs) {
        var iconAttrsObj, iconAttr;

        if (scope.iconDir) {
          // path set via attribute
          assetPath = scope.iconDir;
        } else {
          // default path
          assetPath = iconic.getAssetPath();
        }
        // make sure ends with /
        if (assetPath.charAt(assetPath.length - 1) !== '/') {
          assetPath += '/';
        }

        if (scope.dynSrc) {
          attrs.$set('data-src', scope.dynSrc);
        } else if (scope.dynIcon) {
          attrs.$set('data-src', assetPath + scope.dynIcon + '.svg');
        } else {
          if (scope.icon) {
            attrs.$set('data-src', assetPath + scope.icon + '.svg');
          } else {
            // To support expressions on data-src
            attrs.$set('data-src', attrs.src);
          }
        }

        // check if size already added as class
        if (!element.hasClass('iconic-sm') && !element.hasClass('iconic-md') && !element.hasClass('iconic-lg')) {
          var iconicClass;
          switch (scope.size) {
            case 'small':
              iconicClass = 'iconic-sm';
              break;
            case 'medium':
              iconicClass = 'iconic-md';
              break;
            case 'large':
              iconicClass = 'iconic-lg';
              break;
            default:
              iconicClass = 'iconic-fluid';
          }
          element.addClass(iconicClass);
        }

        // add static icon attributes to iconic element
        if (scope.iconAttrs) {
          iconAttrsObj = angular.fromJson(scope.iconAttrs);
          for (iconAttr in iconAttrsObj) {
            // add data- to attribute name if not already present
            attrs.$set(addDataDash(iconAttr), iconAttrsObj[iconAttr]);
          }
        }

        // save contents and attributes of un-inject html, to use for dynamic re-injection
        contents = element[0].outerHTML;
        origAttrs = element[0].attributes;
      }

      function postLink(scope, element, attrs) {
        var svgElement, ico = iconic.getAccess();

        injectSvg(element[0]);

        foundationApi.subscribe('resize', function () {
          // only run update on current element
          ico.update(element[0]);
        });

        // handle dynamic updating of src
        if (scope.dynSrc) {
          scope.$watch('dynSrc', function (newVal, oldVal) {
            if (newVal && newVal !== oldVal) {
              reinjectSvg(scope.dynSrc, scope.dynIconAttrs);
            }
          });
        }
        // handle dynamic updating of icon
        if (scope.dynIcon) {
          scope.$watch('dynIcon', function (newVal, oldVal) {
            if (newVal && newVal !== oldVal) {
              reinjectSvg(assetPath + scope.dynIcon + '.svg', scope.dynIconAttrs);
            }
          });
        }
        // handle dynamic updating of icon attrs
        scope.$watch('dynIconAttrs', function (newVal, oldVal) {
          if (newVal && newVal !== oldVal) {
            if (scope.dynSrc) {
              reinjectSvg(scope.dynSrc, scope.dynIconAttrs);
            } else {
              reinjectSvg(assetPath + scope.dynIcon + '.svg', scope.dynIconAttrs);
            }
          }
        });

        function reinjectSvg(newSrc, newAttrs) {
          var iconAttr;

          if (svgElement) {
            // set html
            svgElement.empty();
            svgElement.append(angular.element(contents));

            // remove 'data-icon' attribute added by injector as it
            // will cause issues with reinjection when changing icons
            svgElement.removeAttr('data-icon');

            // set new source
            svgElement.attr('data-src', newSrc);

            // add additional icon attributes to iconic element
            if (newAttrs) {
              // remove previously added attributes
              if (lastIconAttrs) {
                for (iconAttr in lastIconAttrs) {
                  svgElement.removeAttr(addDataDash(iconAttr));
                }
              }

              // add newly added attributes
              for (iconAttr in newAttrs) {
                // add data- to attribute name if not already present
                svgElement.attr(addDataDash(iconAttr), newAttrs[iconAttr]);
              }
            }

            // store current attrs
            lastIconAttrs = newAttrs;

            // reinject
            injectSvg(svgElement[0]);
          }
        }

        function injectSvg(element) {
          ico.inject(element, {
            each: function (injectedElem) {
              var i, angElem;

              // wrap raw element
              angElem = angular.element(injectedElem);

              for(i = 0; i < origAttrs.length; i++) {
                // check if attribute should be ignored
                if (origAttrs[i].name !== 'zf-iconic' &&
                    origAttrs[i].name !== 'ng-transclude' &&
                    origAttrs[i].name !== 'icon' &&
                    origAttrs[i].name !== 'src') {
                  // check if attribute already exists on svg
                  if (angular.isUndefined(angElem.attr(origAttrs[i].name))) {
                    // add attribute to svg
                    angElem.attr(origAttrs[i].name, origAttrs[i].value);
                  }
                }
              }

              // compile
              svgElement = $compile(angElem)(angElem.scope());
            }
          });
        }
      }

      function addDataDash(attr) {
        return attr.indexOf('data-') !== 0 ? 'data-' + attr : attr;
      }
    }
  }

})();
<|endoftext|>


<commit_before>//viewmodel for the assess page
function pageViewModel(gvm) {
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n. __("AssessTitle2");}, gvm);
    gvm.userId = -1;

    // Page specific i18n bindings
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("HomeRapportManual");}, gvm);
    gvm.foundProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FoundProjects");}, gvm);
    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);

    // Pagination i18n bindings
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    // Table i18n bindings
    gvm.codeTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CodeTableTitle");}, gvm);
    gvm.nameTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NameTableTitle");}, gvm);
    gvm.descTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("DescTableTitle");}, gvm);
    gvm.actionTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ActionTableTitle");}, gvm);

    gvm.availableLocations = ko.observableArray([]);
    gvm.availableTrainings = ko.observableArray([]);
    gvm.availableCourses = ko.observableArray([]);

    gvm.currentCourseId = null;
    gvm.currentLocationId = null;
    gvm.currentTrainingid = null;

    gvm.updateDropdowns = function() {
        $.getJSON('api/lastdropdownchoice/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-location span:first").text(item.location);
                    $(".btn-training span:first").text(item.training);
                    $(".btn-course span:first").text(item.course);
                    gvm.currentLocationId = item.locationid;
                    gvm.currentTrainingid = item.trainingid;
                    gvm.currentCourseId = item.courseid;
                    gvm.updateLocations();
                    gvm.updateTrainings(item.locationid);
                    gvm.updateCourses(item.trainingid);
                    loadTablePage(item.courseid, 1);
                });
            } else {
                gvm.updateLocations();
            }
        });
    }

    gvm.saveLastSelectedDropdowns = function() {
        data = {};
        data["location"] = $(".btn-location span:first").text();
        data["locationid"] = gvm.currentLocationId;
        data["training"] = $(".btn-training span:first").text();
        data["trainingid"] = gvm.currentTrainingid;
        data["course"] = $(".btn-course span:first").text();
        data["courseid"] = gvm.currentCourseId;
        data["user"] = gvm.userId;
        console.log(data);
        $.ajax({
            type: "POST",
            url: "/api/savedropdowns",
            data: data,
            success: function() {
                console.log("success");
            }
        })
    }

    gvm.updateLocations = function() {
        $.getJSON('/api/courserapportdrop', function(data) {
            gvm.availableLocations.removeAll();
            $.each(data, function(i, item) {
              //  Put item in list
                gvm.availableLocations.push(item);

                // Add listener to listitem
                $("#locbtn-" + item.id).click(function(){
                    gvm.currentLocationId = item.id;
                    gvm.currentTrainingid = null;
                    gvm.currentCourseId = null;
                    gvm.updateTrainings(item.id);
                    $(".btn-location span:first").text($(this).text());
                    $(".btn-training span:first").text("training");
                    $(".btn-course span:first").text("course");
                });
            });
        });
    };

    /*
     * Update the course data
     */
    gvm.updateTrainings = function(id) {
        $.getJSON('/api/coursesrapport/' + id, function(data) {
            gvm.availableTrainings.removeAll();
            $.each(data, function(i, item) {
                gvm.availableTrainings.push(item);

                console.log(id);

                /* Add listener to listitem */
                $("#trainingbtn-" + item.id).click(function(){
                    gvm.currentTrainingid = item.id;
                    gvm.currentCourseId = null;
                    gvm.updateCourses(item.id);
                    $(".btn-training span:first").text($(this).text());
                    $(".btn-course span:first").text("course");
                });
            });
        });
    }

    /*
     * Update available courses
     */
    gvm.updateCourses = function(id) {
        $.getJSON('/api/courses/' + id, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                gvm.availableCourses.push(item);

                /* Add listener to listitem */
                $("#coursebtn-" + item.id).click(function(){
                    $(".btn-course span:first").text($(this).text());
                    gvm.currentCourseId = item.id;
                    gvm.saveLastSelectedDropdowns();
                    loadTablePage(item.id, 1);
                });
            });
        });
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(id, code, name, desc) {
        // Push data
        var tblOject = {tid: id, tcode: code, tname: name, tdesc: desc};
        gvm.tabledata.push(tblOject);
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function loadTablePage(courseid, pagenr)
{
    $.getJSON('/api/projects/' + courseid + '/page/' + pagenr, function(data){

        /* Clear current table page */
        viewModel.clearTable()

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.code, item.name, item.description);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(courseid, thispagenr);
                });
            }
        });
    });

}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateDropdowns();
    });
}<commit_msg>changing dropdown label names<commit_after>//viewmodel for the assess page
function pageViewModel(gvm) {
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n. __("AssessTitle2");}, gvm);
    gvm.userId = -1;

    // Page specific i18n bindings
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("HomeRapportManual");}, gvm);
    gvm.foundProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FoundProjects");}, gvm);
    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);

    // Pagination i18n bindings
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    // Table i18n bindings
    gvm.codeTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CodeTableTitle");}, gvm);
    gvm.nameTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NameTableTitle");}, gvm);
    gvm.descTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("DescTableTitle");}, gvm);
    gvm.actionTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ActionTableTitle");}, gvm);

    gvm.availableLocations = ko.observableArray([]);
    gvm.availableTrainings = ko.observableArray([]);
    gvm.availableCourses = ko.observableArray([]);

    gvm.currentCourseId = null;
    gvm.currentLocationId = null;
    gvm.currentTrainingid = null;

    gvm.updateDropdowns = function() {
        $.getJSON('api/lastdropdownchoice/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-location span:first").text(item.location);
                    $(".btn-training span:first").text(item.training);
                    $(".btn-course span:first").text(item.course);
                    gvm.currentLocationId = item.locationid;
                    gvm.currentTrainingid = item.trainingid;
                    gvm.currentCourseId = item.courseid;
                    gvm.updateLocations();
                    gvm.updateTrainings(item.locationid);
                    gvm.updateCourses(item.trainingid);
                    loadTablePage(item.courseid, 1);
                });
            } else {
                gvm.updateLocations();
            }
        });
    }

    gvm.saveLastSelectedDropdowns = function() {
        data = {};
        data["location"] = $(".btn-location span:first").text();
        data["locationid"] = gvm.currentLocationId;
        data["training"] = $(".btn-training span:first").text();
        data["trainingid"] = gvm.currentTrainingid;
        data["course"] = $(".btn-course span:first").text();
        data["courseid"] = gvm.currentCourseId;
        data["user"] = gvm.userId;
        console.log(data);
        $.ajax({
            type: "POST",
            url: "/api/savedropdowns",
            data: data,
            success: function() {
                console.log("success");
            }
        })
    }

    gvm.updateLocations = function() {
        $.getJSON('/api/courserapportdrop', function(data) {
            gvm.availableLocations.removeAll();
            $.each(data, function(i, item) {
              //  Put item in list
                gvm.availableLocations.push(item);

                // Add listener to listitem
                $("#locbtn-" + item.id).click(function(){
                    gvm.currentLocationId = item.id;
                    gvm.currentTrainingid = null;
                    gvm.currentCourseId = null;
                    gvm.updateTrainings(item.id);
                    $(".btn-location span:first").text($(this).text());
                    $(".btn-training span:first").text("test");
                    $(".btn-course span:first").text("blah");
                });
            });
        });
    };

    /*
     * Update the course data
     */
    gvm.updateTrainings = function(id) {
        $.getJSON('/api/coursesrapport/' + id, function(data) {
            gvm.availableTrainings.removeAll();
            $.each(data, function(i, item) {
                gvm.availableTrainings.push(item);

                console.log(id);

                /* Add listener to listitem */
                $("#trainingbtn-" + item.id).click(function(){
                    gvm.currentTrainingid = item.id;
                    gvm.currentCourseId = null;
                    gvm.updateCourses(item.id);
                    $(".btn-training span:first").text($(this).text());
                    $(".btn-course span:first").text("course");
                });
            });
        });
    }

    /*
     * Update available courses
     */
    gvm.updateCourses = function(id) {
        $.getJSON('/api/courses/' + id, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                gvm.availableCourses.push(item);

                /* Add listener to listitem */
                $("#coursebtn-" + item.id).click(function(){
                    $(".btn-course span:first").text($(this).text());
                    gvm.currentCourseId = item.id;
                    gvm.saveLastSelectedDropdowns();
                    loadTablePage(item.id, 1);
                });
            });
        });
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(id, code, name, desc) {
        // Push data
        var tblOject = {tid: id, tcode: code, tname: name, tdesc: desc};
        gvm.tabledata.push(tblOject);
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function loadTablePage(courseid, pagenr)
{
    $.getJSON('/api/projects/' + courseid + '/page/' + pagenr, function(data){

        /* Clear current table page */
        viewModel.clearTable()

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.code, item.name, item.description);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(courseid, thispagenr);
                });
            }
        });
    });

}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateDropdowns();
    });
}<|endoftext|>


<commit_before>/**
 * module class
 */
function module(viewmodel, id, name, description, doelstellingen) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        doelstellingen: ko.observableArray(doelstellingen),

        addDoelstelling: function() {
            this.doelstellingen.push(new doelstelling(this));
        },

        removeThis: function() {
            //viewModel.removeModule(this);
            this.module.remove(module);
        },

        removeDoelstelling: function(doelstelling) {
            this.doelstellingen.remove(doelstelling);
        }
    };

}

/**
 * doelstelling class
 */
function doelstelling(parent, id, name, description, crit) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        criterias: ko.observableArray(crit),

        addCriteria: function() {
            this.criterias.push(new criteria(this));
        },

        removeThis: function() {
            parent.removeDoelstelling(this);
        },

        removeCriteria: function(criteria) {
            this.criterias.remove(criteria);
        }
    };
}

/**
 * criteria class
 */
function criteria(parent, id, name, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeCriteria(this);
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.modules = 0;
    gvm.doelstelling = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.modules = ko.observableArray([]);

    gvm.addModule = function() {
        gvm.modules.push(new module(this));
    };

    gvm.removeModule = function(module) {
        gvm.modules.remove(module);
    }

    gvm.updateModule = function(id, name, description) {
        var mod = new module(this, id, name, description);
        gvm.modules.push(mod);
        return mod;
    }

    gvm.clearStructure = function() {
        gvm.modules.destroyAll();
    }
}

function fetchCourseStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/coursestructure/" + courseid, function(data){
        $.each(data, function(i, item){
            var module = viewModel.updateModule(item.id, item.name, item.description);

            $.each(item.doelstellingen, function(i, doel){
               var doelst = new doelstelling(module, doel.id, doel.name, doel.description);
                module.doelstellingen.push(doelst);

               $.each(doel.criterias, function(i, crit){
                  doelst.criterias.push(new criteria(doelst, crit.id, crit.name, crit.description));
               });
            });
        })
    });
}

function initPage() {
    fetchCourseStructure();

    $(".addmoduleBtn").click(function() {
        console.log('clicked on add module');
        viewModel.addModule();
    });

    $(".savePageBtn").click(function(){
        if(validationCheck()) {
            saveCourseStructure();
            console.log("Saved");
        } else {
            window.scrollTo(0,0);
            console.log("Not saved");
        }
    });
}

function saveCourseStructure() {
    $.ajax({
        type: "POST",
        url: "/api/savemodules/" + courseid,
        data: ko.toJSON(viewModel.modules),
        success: function(){
            // TODO make multilangual and with modals
            alert("Saved coursestructure to server");

            fetchCourseStructure();
        }
    });
}

function validationCheck()
{
    var allmodulesValid = true;
    var alldoelstellingenValid = true;
    var allcriteriasValid = true;

    for(var indexmodules =0; indexmodules < viewModel.modules().length; indexmodules++)
    {
        if(!viewModel.modules()[indexmodules].name() && !viewModel.modules()[indexmodules].description())
        {
            if(allmodulesValid)
            {
                $(".validationSummary ul").append("
Code or name in modules is empty
");
                $(".validationSummary").removeClass("hide");
            }
            allmodulesValid = false;
        }
        for(var indexdoelstelling = 0; indexdoelstelling < viewModel.modules()[indexmodules].doelstellingen().length; indexdoelstelling++)
        {
            if(!viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].name() && !viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].description())
            {
                if(alldoelstellingenValid)
                {
                    $(".validationSummary ul").append("
Code or name in doelstellingen is empty
");
                    $(".validationSummary").removeClass("hide");
                }
                alldoelstellingenValid = false;
            }
            for(var indexcriterias = 0; indexcriterias < viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias().length; indexcriterias++)
            {
                if(!viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias()[indexcriterias].name() && !viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias()[indexcriterias].description())
                {
                    if(allcriteriasValid)
                    {
                        $(".validationSummary ul").append("
Description or name in criterias is empty
");
                        $(".validationSummary").removeClass("hide");
                    }
                    allcriteriasValid = false;
                }
            }
        }
    }
    return allmodulesValid && alldoelstellingenValid && allcriteriasValid;
}
<commit_msg>remove module<commit_after>/**
 * module class
 */
function module(viewmodel, id, name, description, doelstellingen) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        doelstellingen: ko.observableArray(doelstellingen),

        addDoelstelling: function() {
            this.doelstellingen.push(new doelstelling(this));
        },

        removeThis: function() {
            viewModel.removeModule(this);
        },

        removeDoelstelling: function(doelstelling) {
            this.doelstellingen.remove(doelstelling);
        }
    };

}

/**
 * doelstelling class
 */
function doelstelling(parent, id, name, description, crit) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        criterias: ko.observableArray(crit),

        addCriteria: function() {
            this.criterias.push(new criteria(this));
        },

        removeThis: function() {
            parent.removeDoelstelling(this);
        },

        removeCriteria: function(criteria) {
            this.criterias.remove(criteria);
        }
    };
}

/**
 * criteria class
 */
function criteria(parent, id, name, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeCriteria(this);
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.modules = 0;
    gvm.doelstelling = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.modules = ko.observableArray([]);

    gvm.addModule = function() {
        gvm.modules.push(new module(this));
    };

    gvm.removeModule = function(module) {
        gvm.modules.remove(module);
    }

    gvm.updateModule = function(id, name, description) {
        var mod = new module(this, id, name, description);
        gvm.modules.push(mod);
        return mod;
    }

    gvm.clearStructure = function() {
        gvm.modules.destroyAll();
    }
}

function fetchCourseStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/coursestructure/" + courseid, function(data){
        $.each(data, function(i, item){
            var module = viewModel.updateModule(item.id, item.name, item.description);

            $.each(item.doelstellingen, function(i, doel){
               var doelst = new doelstelling(module, doel.id, doel.name, doel.description);
                module.doelstellingen.push(doelst);

               $.each(doel.criterias, function(i, crit){
                  doelst.criterias.push(new criteria(doelst, crit.id, crit.name, crit.description));
               });
            });
        })
    });
}

function initPage() {
    fetchCourseStructure();

    $(".addmoduleBtn").click(function() {
        console.log('clicked on add module');
        viewModel.addModule();
    });

    $(".savePageBtn").click(function(){
        if(validationCheck()) {
            saveCourseStructure();
            console.log("Saved");
        } else {
            window.scrollTo(0,0);
            console.log("Not saved");
        }
    });
}

function saveCourseStructure() {
    $.ajax({
        type: "POST",
        url: "/api/savemodules/" + courseid,
        data: ko.toJSON(viewModel.modules),
        success: function(){
            // TODO make multilangual and with modals
            alert("Saved coursestructure to server");

            fetchCourseStructure();
        }
    });
}

function validationCheck()
{
    var allmodulesValid = true;
    var alldoelstellingenValid = true;
    var allcriteriasValid = true;

    for(var indexmodules =0; indexmodules < viewModel.modules().length; indexmodules++)
    {
        if(!viewModel.modules()[indexmodules].name() && !viewModel.modules()[indexmodules].description())
        {
            if(allmodulesValid)
            {
                $(".validationSummary ul").append("
Code or name in modules is empty
");
                $(".validationSummary").removeClass("hide");
            }
            allmodulesValid = false;
        }
        for(var indexdoelstelling = 0; indexdoelstelling < viewModel.modules()[indexmodules].doelstellingen().length; indexdoelstelling++)
        {
            if(!viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].name() && !viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].description())
            {
                if(alldoelstellingenValid)
                {
                    $(".validationSummary ul").append("
Code or name in doelstellingen is empty
");
                    $(".validationSummary").removeClass("hide");
                }
                alldoelstellingenValid = false;
            }
            for(var indexcriterias = 0; indexcriterias < viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias().length; indexcriterias++)
            {
                if(!viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias()[indexcriterias].name() && !viewModel.modules()[indexmodules].doelstellingen()[indexdoelstelling].criterias()[indexcriterias].description())
                {
                    if(allcriteriasValid)
                    {
                        $(".validationSummary ul").append("
Description or name in criterias is empty
");
                        $(".validationSummary").removeClass("hide");
                    }
                    allcriteriasValid = false;
                }
            }
        }
    }
    return allmodulesValid && alldoelstellingenValid && allcriteriasValid;
}
<|endoftext|>


<commit_before>// Copyright 2022, University of Colorado Boulder

/**
 * This script makes a JSON file that combines translations for all locales in a repo. Each locale object has every
 * string key/translated-value pair we have for that locale. This is used when running the unbuilt mode simulation with
 * locales=*
 *
 * @author Liam Mulhall (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 */

// imports
const fs = require( 'fs' );
const path = require( 'path' );

/**
 * @param {string} repo - repo to generate strings for
 */
module.exports = repo => {

  const start = Date.now();

  const rootPath = path.join( __dirname, '..', '..', '..' );

  // OS-independent path to babel repo.
  const babelPath = path.join( rootPath, 'babel' );

  // Create a file name for the conglomerate string file.
  const conglomerateStringFileName = `${repo}_all.json`;

  // Create an empty object for the conglomerate string file that we will add to later.
  const conglomerateStringObject = {};

  // Get an array of files (string files) in the repo subdirectory.
  const babelRepoPath = path.join( babelPath, repo );

  // Regex for extracting locale from file name.
  const localeRegex = /(?<=_)(.*)(?=.json)/;

  const stringFiles = [];
  try {
    const paths = fs.readdirSync( babelRepoPath );
    stringFiles.push( ...paths.map( p => path.join( babelRepoPath, p ) ) );
  }
  catch( e ) {

    // no translations found in babel
  }

  const englishStringPath = path.join( rootPath, repo, `${repo}-strings_en.json` );
  if ( fs.existsSync( englishStringPath ) ) {
    stringFiles.push( englishStringPath );
  }

  // Do not generate a file if no translations were found.
  if ( stringFiles.length > 0 ) {

    // For each string file in the repo subdirectory...
    for ( const stringFile of stringFiles ) {

      // Extract the locale.
      const localeMatches = stringFile.match( localeRegex );
      const locale = localeMatches[ 0 ];

      // Get the contents of the string file.
      const stringFileContents = fs.readFileSync( stringFile, 'utf8' );

      // Parse the string file contents.
      const parsedStringFileContents = JSON.parse( stringFileContents );

      // Add only the values of the string file to the new conglomerate string file, and ignore other fields, such as
      // the history.
      const objectToAddToLocale = {};
      for ( const stringKey of Object.keys( parsedStringFileContents ) ) {
        objectToAddToLocale[ stringKey ] = {
          value: parsedStringFileContents[ stringKey ].value
        };
      }

      // Add the string values to the locale object of the conglomerate string object.
      conglomerateStringObject[ locale ] = objectToAddToLocale;
    }

    // Make sure the output directory exists.  The name starts with an underscore so that it appears alphabetically
    // first and looks different from the repo names.
    const outputDir = path.join( babelPath, '_generated_development_strings' );
    try {
      fs.mkdirSync( outputDir );
    }
    catch( e ) {
      // already exists
    }

    const outputPath = path.join( outputDir, conglomerateStringFileName );
    fs.writeFileSync( outputPath, JSON.stringify( conglomerateStringObject, null, 2 ) );

    const end = Date.now();
    console.log( 'Wrote ' + outputPath + ' in ' + ( end - start ) + 'ms' );
  }
  else {
    console.log( 'no translations found' );
  }
};<commit_msg>Add documentation, see https://github.com/phetsims/chipper/issues/1308<commit_after>// Copyright 2022, University of Colorado Boulder

/**
 * This script makes a JSON file that combines translations for all locales in a repo. Each locale object has every
 * string key/translated-value pair we have for that locale. This is used when running the unbuilt mode simulation with
 * locales=*
 *
 * @author Liam Mulhall (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 */

// imports
const fs = require( 'fs' );
const path = require( 'path' );

/**
 * @param {string} repo - repo to generate strings for
 */
module.exports = repo => {

  const start = Date.now();

  const rootPath = path.join( __dirname, '..', '..', '..' );

  // OS-independent path to babel repo.
  const babelPath = path.join( rootPath, 'babel' );

  // Create a file name for the conglomerate string file.
  const conglomerateStringFileName = `${repo}_all.json`;

  // Create an empty object for the conglomerate string file that we will add to later.
  const conglomerateStringObject = {};

  // Get an array of files (string files) in the repo subdirectory.
  const babelRepoPath = path.join( babelPath, repo );

  // Regex for extracting locale from file name.
  const localeRegex = /(?<=_)(.*)(?=.json)/;

  const stringFiles = [];
  try {
    const paths = fs.readdirSync( babelRepoPath );
    stringFiles.push( ...paths.map( p => path.join( babelRepoPath, p ) ) );
  }
  catch( e ) {

    // no translations found in babel. But we still must continue in order to generate an (albeit empty) string file.
  }

  const englishStringPath = path.join( rootPath, repo, `${repo}-strings_en.json` );
  if ( fs.existsSync( englishStringPath ) ) {
    stringFiles.push( englishStringPath );
  }

  // Do not generate a file if no translations were found.
  if ( stringFiles.length > 0 ) {

    // For each string file in the repo subdirectory...
    for ( const stringFile of stringFiles ) {

      // Extract the locale.
      const localeMatches = stringFile.match( localeRegex );
      const locale = localeMatches[ 0 ];

      // Get the contents of the string file.
      const stringFileContents = fs.readFileSync( stringFile, 'utf8' );

      // Parse the string file contents.
      const parsedStringFileContents = JSON.parse( stringFileContents );

      // Add only the values of the string file to the new conglomerate string file, and ignore other fields, such as
      // the history.
      const objectToAddToLocale = {};
      for ( const stringKey of Object.keys( parsedStringFileContents ) ) {
        objectToAddToLocale[ stringKey ] = {
          value: parsedStringFileContents[ stringKey ].value
        };
      }

      // Add the string values to the locale object of the conglomerate string object.
      conglomerateStringObject[ locale ] = objectToAddToLocale;
    }

    // Make sure the output directory exists.  The name starts with an underscore so that it appears alphabetically
    // first and looks different from the repo names.
    const outputDir = path.join( babelPath, '_generated_development_strings' );
    try {
      fs.mkdirSync( outputDir );
    }
    catch( e ) {
      // already exists
    }

    const outputPath = path.join( outputDir, conglomerateStringFileName );
    fs.writeFileSync( outputPath, JSON.stringify( conglomerateStringObject, null, 2 ) );

    const end = Date.now();
    console.log( 'Wrote ' + outputPath + ' in ' + ( end - start ) + 'ms' );
  }
  else {
    console.log( 'no translations found' );
  }
};<|endoftext|>


<commit_before>
/**

reference population upload from lists.

Isaak Y Tecle
iyt2@cornell.edu
*/

JSAN.use("CXGN.List");
JSAN.use("jquery.blockUI");

jQuery(document).ready( function() {

        var list = new CXGN.List();

    var listMenu = list.listSelect("list_type_training_pops", ['plots', 'trials']);

	if (listMenu.match(/option/) != null) {

            jQuery("#list_type_training_pops_list").append(listMenu);
        } else {

            jQuery("#list_type_training_pops_list").append("<select><option>no lists found</option></select>");
        }

    });

jQuery(document).ready( function() {

        jQuery("<option>", {value: '', selected: true}).prependTo("#list_type_training_pops_list_select");

        jQuery("#list_type_training_pops_list_select").change(function() {
	    alert('select')
                var listId = jQuery(this).find("option:selected").val();
            alert(listId);
                if (listId) {
                    jQuery("#list_type_training_pop_load").click(function() {
                            //alert('get list: ' + listId);
                            loadReferenceGenotypesList(listId);
                        });
                }
            });
    });

function getReferenceGenotypesList(listId) {

    var list = new CXGN.List();
    var genotypesList;

    if (! listId == "") {
        genotypesList = list.getListData(listId);
    }

    var listName = list.listNameById(listId);

    return {'name'      : listName,
            'list'      : genotypesList.elements,
            };
}

function loadReferenceGenotypesList(listId) {

    var genoList       = getReferenceGenotypesList(listId);
    var listName       = genoList.name;
    var list           = genoList.list;
    var modelId        = getModelId(listId);

    var populationType = 'uploaded_reference';

    if ( list.length === 0) {
        alert('The list is empty. Please select a list with content.' );
    }
    else {
        jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
        jQuery.blockUI({message: 'Please wait..'});

        list = JSON.stringify(list);

        jQuery.ajax({
                type: 'POST',
                    dataType: 'json',
                    data: {'model_id': modelId, 'list_name': listName, 'list': list, 'population_type': populationType},
                    url: '/solgs/upload/reference/genotypes/list',

                    success: function(response) {

                    if (response.status == 'success') {

                        var uploadedRefPops = jQuery("#uploaded_reference_pops_table").doesExist();

                        if (uploadedRefPops == false) {

                            uploadedRefPops = getUserUploadedRefPop(listId);
                            jQuery("#uploaded_reference_populations").append(uploadedRefPops).show();

                        }
                        else {

                            var url =   '\'/solgs/population/'+ modelId + '\'';
                            var listIdArg = '\'' + listId +'\'';
                            var listSource = '\'from_db\'';

                            var popIdName   = {model_id : modelId, name: listName,};
                            popIdName       = JSON.stringify(popIdName);
                            var hiddenInput =  '<input type="hidden" value=\'' + popIdName + '\'/>';

                            var addRow = '
'
                                + '' + '<data>'+ hiddenInput + '</data>'
                                + listName + ''
                                + '	'
                                + ''
                                + ''
                                + '[ Build Model ]'+ ''
                                + '
';
                            // alert(addRow);
                            var tdId = '#list_reference_page_' + modelId;
                            var addedRow = jQuery(tdId).doesExist();
                            // alert(addedRow);
                            if (addedRow == false) {
                                jQuery("#uploaded_reference_pops_table tr:last").after(addRow);

                            }
                        }
                        jQuery.unblockUI();

                    } else {

                        alert("fail: Error occured while uploading the list of reference genotypes.");
                        jQuery.unblockUI();
                    }

                },
                    error: function(res) {
                    alert("Error occured while uploading the list of reference genotypes.");
                    jQuery.unblockUI();
                }
            });
    }
}

jQuery.fn.doesExist = function(){
        return jQuery(this).length > 0;
 };

function getUserUploadedRefPop (listId) {

    var genoList       = getReferenceGenotypesList(listId);
    var listName       = genoList.name;
    var list           = genoList.list;
    var modelId        = getModelId(listId);

    var url         =   '\'/solgs/population/'+ modelId + '\'';
    var listIdArg   = '\'' + listId +'\'';
    var listSource  = '\'from_db\'';
    var popIdName   = {id : modelId, name: listName,};
    popIdName       = JSON.stringify(popIdName);
    var hiddenInput =  '<input type="hidden" value=\'' + popIdName + '\'/>';

    var uploadedSelPop ='

'
                                + 'List-based training population	'
                                + 'Models	'
                                +'
'
                                + '
'
                                + ''
                                + '' + '<data>'+ hiddenInput + '</data>'
                                + listName + ''
                                + '	'
                                + ''
                                + ''
                                + '[ Build model ]'+ ''
                                + '

';

    return uploadedSelPop;
}

function loadPopulationPage (url, listId, listSource) {

    // var traitId        = getTraitId();
    var genoList       = getReferenceGenotypesList(listId);
    var listName       = genoList.name;
    var modelId        = getModelId(listId);

    //alert('loadPopulationPage: url ' + url);
    jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
    jQuery.blockUI({message: 'Please wait..'});

    jQuery.ajax({
            type: 'POST',
                url: url,
                dataType: 'json',
                data: {
                       'uploaded_reference': 1,
                       'model_id': modelId,
                       'list_source': listSource,
                       'list_name'  : listName,
                      },

                success: function (response) {

                if (response.status == 'success') {

                    jQuery.unblockUI();

                }
                else {
                    alert('Fail: Error occured calculating GEBVs for the list of selection genotypes.');
                    jQuery.unblockUI();
                }
            },
                error: function(response) {
                alert('error: ' + res.responseText);

            }
        });

}

function getModelId (listId) {

    var modelId = 'uploaded_' + listId;
    return modelId;

}

<commit_msg>work with trials list type training pop..<commit_after>
/**

reference population upload from lists.

Isaak Y Tecle
iyt2@cornell.edu
*/

JSAN.use("CXGN.List");
JSAN.use("jquery.blockUI");

jQuery(document).ready( function() {

        var list = new CXGN.List();

    var listMenu = list.listSelect("list_type_training_pops", ['plots', 'trials']);

	if (listMenu.match(/option/) != null) {
            jQuery("#list_type_training_pops_list").append(listMenu);
        } else {
            jQuery("#list_type_training_pops_list").append("<select><option>no lists found</option></select>");
        }

    });

jQuery(document).ready( function() {

    jQuery("<option>", {value: 'select...', selected: true})
	.prependTo("#list_type_training_pops_list_select");

    jQuery("#list_type_training_pops_list_select")
	.change(function() {

	    var listId = jQuery(this).find("option:selected").val();
            if (listId) {
		var listDetail = getListTypeTrainingPopDetail(listId);
		jQuery("#list_type_training_pop_load").click(function() {

		    if (listDetail.type.match(/plots/)) {
			loadPlotListTypeTrainingPop(listId);
		    } else {
			alert('this is trials type');
			var trialsList = listDetail.list;
			var trialsNames = listDetail.elementsNames;

			loadTrialListTypeTrainingPop(trialsNames);
		    }
            });
        }
    });
});

function getListElementsNames (list) {

    var names = [];
    for (var i = 0; i < list.length; i++) {
	names.push(list[i][1]);
    }

    return names;

}

function getListTypeTrainingPopDetail(listId) {

    var list = new CXGN.List();

    var listData;
    var listType;
    var listName;
    var listElements;
    var listElementsNames;

    if (listId) {
        listData      = list.getListData(listId);
	listType      = list.getListType(listId);
	listName      = list.listNameById(listId);
	listElements  = listData.elements;

	listElementsNames = getListElementsNames(listElements);
    }

    return {'name'          : listName,
            'list'          : listElements,
	    'type'          : listType,
	    'elementsNames' : listElementsNames,
           };
}

function loadTrialListTypeTrainingPop (trialsNames) {
    alert('laod trials ' + trialsNames)
    jQuery.ajax({
        type: 'POST',
        url: '/solgs/get/trial/id/',
        dataType: 'json',
        data: { 'trials_names': trialsNames},
        success: function (res) {
            getCombinedPopsId(res.trials_ids);
        },
        error: function(response) {
            alert('Error occured querying for trials ids');
        }
    });

}

function loadPlotListTypeTrainingPop(listId) {

    var genoList       = getListTypeTrainingPopDetail(listId);
    var listName       = genoList.name;
    var list           = genoList.list;
    var modelId        = getModelId(listId);

    var populationType = 'uploaded_reference';

    if ( list.length === 0) {
        alert('The list is empty. Please select a list with content.' );
    }
    else {
        jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
        jQuery.blockUI({message: 'Please wait..'});

        list = JSON.stringify(list);

        jQuery.ajax({
            type: 'POST',
            dataType: 'json',
            data: {'model_id': modelId, 'list_name': listName, 'list': list, 'population_type': populationType},
            url: '/solgs/load/plots/list/training',
            success: function(response) {

                if (response.status == 'success') {

                    var uploadedRefPops = jQuery("#uploaded_reference_pops_table").doesExist();

                    if (uploadedRefPops == false) {

                        uploadedRefPops = getUserUploadedRefPop(listId);
                        jQuery("#uploaded_reference_populations").append(uploadedRefPops).show();
                    }
                    else {
                        var url =   '\'/solgs/population/'+ modelId + '\'';
                        var listIdArg = '\'' + listId +'\'';
                        var listSource = '\'from_db\'';

                        var popIdName   = {model_id : modelId, name: listName,};
                        popIdName       = JSON.stringify(popIdName);
                        var hiddenInput =  '<input type="hidden" value=\'' + popIdName + '\'/>';

                        var addRow = '
'
                            + '' + '<data>'+ hiddenInput + '</data>'
                            + listName + ''
                            + '	'
                            + ''
                            + ''
                            + '[ Build Model ]'+ ''
                            + '
';
                            // alert(addRow);
                        var tdId = '#list_reference_page_' + modelId;
                        var addedRow = jQuery(tdId).doesExist();
                            // alert(addedRow);
                        if (addedRow == false) {
                            jQuery("#uploaded_reference_pops_table tr:last").after(addRow);
                        }
                    }

		    jQuery.unblockUI();

                    } else {
                        alert("fail: Error occured while uploading the list of reference genotypes.");
                        jQuery.unblockUI();
                    }
            },
            error: function(res) {
                alert("Error occured while uploading the list of reference genotypes.");
                jQuery.unblockUI();
            }
        });
    }
}

jQuery.fn.doesExist = function(){
        return jQuery(this).length > 0;
 };

function getUserUploadedRefPop (listId) {

    var genoList       = getListTypeTrainingPopDetail(listId);
    var listName       = genoList.name;
    var list           = genoList.list;
    var modelId        = getModelId(listId);

    var url         =   '\'/solgs/population/'+ modelId + '\'';
    var listIdArg   = '\'' + listId +'\'';
    var listSource  = '\'from_db\'';
    var popIdName   = {id : modelId, name: listName,};
    popIdName       = JSON.stringify(popIdName);
    var hiddenInput =  '<input type="hidden" value=\'' + popIdName + '\'/>';

    var uploadedSelPop ='

'
                                + 'List-based training population	'
                                + 'Models	'
                                +'
'
                                + '
'
                                + ''
                                + '' + '<data>'+ hiddenInput + '</data>'
                                + listName + ''
                                + '	'
                                + ''
                                + ''
                                + '[ Build model ]'+ ''
                                + '

';

    return uploadedSelPop;
}

function loadPopulationPage (url, listId, listSource) {

    // var traitId        = getTraitId();
    var genoList       = getListTypeTrainingPopDetail(listId);
    var listName       = genoList.name;
    var modelId        = getModelId(listId);

    //alert('loadPopulationPage: url ' + url);
    jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
    jQuery.blockUI({message: 'Please wait..'});

    jQuery.ajax({
            type: 'POST',
                url: url,
                dataType: 'json',
                data: {
                       'uploaded_reference': 1,
                       'model_id': modelId,
                       'list_source': listSource,
                       'list_name'  : listName,
                      },

                success: function (response) {

                if (response.status == 'success') {
                    jQuery.unblockUI();
                }
                else {
                    alert('Fail: Error occured calculating GEBVs for the list of selection genotypes.');
                    jQuery.unblockUI();
                }
            },
                error: function(response) {
                alert('error: ' + res.responseText);

            }
        });

}

function getModelId (listId) {

    var modelId = 'uploaded_' + listId;
    return modelId;

}

<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('app.avengers')
        .run(['routehelper', function(routehelper){
            routehelper.configureRoutes(getRoutes());
        }]);

    function getRoutes() {
        return [
            {
                url: '/avengers',
                config: {
                    templateUrl: 'app/avengers/avengers.html',
                    title: 'avengers',
                    settings: {
                        nav: 2,
                        content: ' Avengers'
                    }
                }
            }
        ];
    }
})();<commit_msg>modular: added leading slash to avengers route<commit_after>(function () {
    'use strict';

    angular
        .module('app.avengers')
        .run(['routehelper', function(routehelper){
            routehelper.configureRoutes(getRoutes());
        }]);

    function getRoutes() {
        return [
            {
                url: '/avengers',
                config: {
                    templateUrl: '/app/avengers/avengers.html',
                    title: 'avengers',
                    settings: {
                        nav: 2,
                        content: ' Avengers'
                    }
                }
            }
        ];
    }
})();<|endoftext|>


<commit_before>import { takeLatest, call, put, select } from 'redux-saga/effects';
import { SubmissionError } from 'redux-form';

import uploadAssetApi from 'api/uploadAssetApi';
import { getActiveDeckId, getActiveSlideId } from 'selectors/app/slide-editor';

import { ADD_CONTENT_ITEM_TO_SLIDE } from 'actions/entities/slides';

import { contentItemTypes } from 'constants/contentItemTypes';

import {
  UPLOAD_ASSET,
} from 'actions/other/assetActions';

export function* doUploadAsset(action) {
  const { resolve, reject } = action.meta;

  try {
    const activeDeckId = yield select(getActiveDeckId);
    const activeSlideId = yield select(getActiveSlideId);

    const { assetType, values: { imageFile, imageType, imageCaption, altText } } = yield action.meta;

    const response = yield call(uploadAssetApi, activeDeckId, imageFile[0]);

    const assetUri = yield response.links.raw;

    yield put({ type: ADD_CONTENT_ITEM_TO_SLIDE,
      meta: { slideId: activeSlideId,
        contentItemType: assetType,
        contentItemTypeProps: { src: assetUri, alt: altText, caption: imageCaption } } });

    yield call(resolve);
  }
  catch (error) {
    let errorMessage;

    switch (error.statusCode) {
      case 422:
        // TODO: Handle the case where the file already exists
        yield (errorMessage = { _error: 'This file already exists.' });
        break;
      default:
        yield (errorMessage = { _error: 'Something went wrong on our end.' });
    }

    yield call(reject, new SubmissionError(errorMessage));
  }
}

function* uploadAssetWatcher() {
  yield takeLatest(UPLOAD_ASSET, doUploadAsset);
}

export default uploadAssetWatcher;
<commit_msg>Removes unneeded prop<commit_after>import { takeLatest, call, put, select } from 'redux-saga/effects';
import { SubmissionError } from 'redux-form';

import uploadAssetApi from 'api/uploadAssetApi';
import { getActiveDeckId, getActiveSlideId } from 'selectors/app/slide-editor';

import { ADD_CONTENT_ITEM_TO_SLIDE } from 'actions/entities/slides';

import { contentItemTypes } from 'constants/contentItemTypes';

import {
  UPLOAD_ASSET,
} from 'actions/other/assetActions';

export function* doUploadAsset(action) {
  const { resolve, reject } = action.meta;

  try {
    const activeDeckId = yield select(getActiveDeckId);
    const activeSlideId = yield select(getActiveSlideId);

    const { assetType, values: { imageFile, imageCaption, altText } } = yield action.meta;

    const response = yield call(uploadAssetApi, activeDeckId, imageFile[0]);

    const assetUri = yield response.links.raw;

    yield put({ type: ADD_CONTENT_ITEM_TO_SLIDE,
      meta: { slideId: activeSlideId,
        contentItemType: assetType,
        contentItemTypeProps: { src: assetUri, alt: altText, caption: imageCaption } } });

    yield call(resolve);
  }
  catch (error) {
    let errorMessage;

    switch (error.statusCode) {
      case 422:
        // TODO: Handle the case where the file already exists
        yield (errorMessage = { _error: 'This file already exists.' });
        break;
      default:
        yield (errorMessage = { _error: 'Something went wrong on our end.' });
    }

    yield call(reject, new SubmissionError(errorMessage));
  }
}

function* uploadAssetWatcher() {
  yield takeLatest(UPLOAD_ASSET, doUploadAsset);
}

export default uploadAssetWatcher;
<|endoftext|>


<commit_before>import { takeLatest, call, put, select } from 'redux-saga/effects';
import { SubmissionError } from 'redux-form';

import uploadAssetApi from 'api/uploadAssetApi';
import { getActiveDeckId, getActiveSlideId } from 'selectors/app/slide-editor';

import { ADD_CONTENT_ITEM_TO_SLIDE } from 'actions/entities/slides';
import { SIGNOUT } from 'actions/signoutActions';

import { contentItemTypes } from 'constants/contentItemTypes';

import {
  UPLOAD_ASSET,
} from 'actions/other/assetActions';

export function* doUploadAsset(action) {
  const { resolve, reject } = action.meta;

  try {
    const activeDeckId = yield select(getActiveDeckId);
    const activeSlideId = yield select(getActiveSlideId);

    const { assetType, values: { imageFile, imageCaption, altText } } = yield action.meta;

    const response = yield call(uploadAssetApi, activeDeckId, imageFile[0]);

    const assetUri = yield response.links.raw;
    const { filename } = yield response.attributes;

    yield put({ type: ADD_CONTENT_ITEM_TO_SLIDE,
      meta: { slideId: activeSlideId,
        contentItemType: assetType,
        contentItemTypeProps: { src: assetUri, alt: altText, filename, caption: imageCaption, dataId: response.id } } });

    yield call(resolve);
  }
  catch (error) {
    let errorMessage;

    switch (error.statusCode) {
      case 401:
        yield put({ type: SIGNOUT });
        break;
      case 422:
        // TODO: Handle the case where the file already exists
        yield (errorMessage = { _error: 'This file already exists.' });
        break;
      default:
        yield (errorMessage = { _error: 'Something wrong on our end.' });
    }

    yield call(reject, new SubmissionError(errorMessage));
  }
}

function* uploadAssetWatcher() {
  yield takeLatest(UPLOAD_ASSET, doUploadAsset);
}

export default uploadAssetWatcher;
<commit_msg>Uses action creator to add images<commit_after>import { takeLatest, call, put, select } from 'redux-saga/effects';
import { SubmissionError } from 'redux-form';

import uploadAssetApi from 'api/uploadAssetApi';
import { getActiveDeckId, getActiveSlideId } from 'selectors/app/slide-editor';

import { addContentItemToSlide } from 'actions/entities/slides';
import { SIGNOUT } from 'actions/signoutActions';

import { contentItemTypes } from 'constants/contentItemTypes';

import {
  UPLOAD_ASSET,
} from 'actions/other/assetActions';

export function* doUploadAsset(action) {
  const { resolve, reject } = action.meta;

  try {
    const activeDeckId = yield select(getActiveDeckId);
    const activeSlideId = yield select(getActiveSlideId);

    const { assetType, values: { imageFile, imageCaption, altText } } = yield action.meta;

    const response = yield call(uploadAssetApi, activeDeckId, imageFile[0]);

    const assetUri = yield response.links.raw;
    const { filename } = yield response.attributes;

    yield put(addContentItemToSlide(
      activeSlideId,
      assetType,
      { src: assetUri, alt: altText, filename, caption: imageCaption, dataId: response.id },
    ));

    yield call(resolve);
  }
  catch (error) {
    let errorMessage;

    switch (error.statusCode) {
      case 401:
        yield put({ type: SIGNOUT });
        break;
      case 422:
        // TODO: Handle the case where the file already exists
        yield (errorMessage = { _error: 'This file already exists.' });
        break;
      default:
        yield (errorMessage = { _error: 'Something wrong on our end.' });
    }

    yield call(reject, new SubmissionError(errorMessage));
  }
}

function* uploadAssetWatcher() {
  yield takeLatest(UPLOAD_ASSET, doUploadAsset);
}

export default uploadAssetWatcher;
<|endoftext|>


<commit_before>import request from 'axios';

const API_URL = 'comments.json';

const CommentsManager = {

  /**
   * Retrieve comments from server using AJAX call.
   *
   * @returns {Promise} - result of ajax call.
   */
  fetchComments() {
    return request({
      method: 'GET',
      url: API_URL,
      responseType: 'json',
    });
  },

  /**
   * Submit new comment to server using AJAX call.
   *
   * @param {Object} comment - Comment body to post.
   * @returns {Promise} - result of ajax call.
   */
  submitComment(comment) {
    return request({
      method: 'POST',
      url: API_URL,
      responseType: 'json',
      headers: {
        'X-CSRF-Token': this.getCSRFToken(),
      },
      data: { comment },
    });
  },

  /**
   * Get CSRF Token from the DOM.
   *
   * @returns {String} - CSRF Token.
   */
  getCSRFToken() {
    const metas = document.getElementsByTagName('meta');
    for (let i = 0; i < metas.length; i++) {
      const meta = metas[i];
      if (meta.getAttribute('name') === 'csrf-token') {
        return meta.getAttribute('content');
      }
    }
    return null;
  },

};

export default CommentsManager;
<commit_msg>Fix linter error<commit_after>import request from 'axios';

const API_URL = 'comments.json';

const CommentsManager = {

  /**
   * Retrieve comments from server using AJAX call.
   *
   * @returns {Promise} - result of ajax call.
   */
  fetchComments() {
    return request({
      method: 'GET',
      url: API_URL,
      responseType: 'json',
    });
  },

  /**
   * Submit new comment to server using AJAX call.
   *
   * @param {Object} comment - Comment body to post.
   * @returns {Promise} - result of ajax call.
   */
  submitComment(comment) {
    return request({
      method: 'POST',
      url: API_URL,
      responseType: 'json',
      headers: {
        'X-CSRF-Token': this.getCSRFToken(),
      },
      data: { comment },
    });
  },

  /**
   * Get CSRF Token from the DOM.
   *
   * @returns {String} - CSRF Token.
   */
  getCSRFToken() {
    const metas = document.getElementsByTagName('meta');
    for (let i = 0; i < metas.length; i++) {
      const meta = metas[i];
      if (meta.getAttribute('name') === 'csrf-token') {
        return meta.getAttribute('content');
      }
    }

    return null;
  },

};

export default CommentsManager;
<|endoftext|>


<commit_before>import React from 'react'
import { Link } from 'react-router'
import RestService from '../RestService'
import LanguageStats from './LanguageStats'
import RPCButton from '../RPCButton'
import SFConfigIndex from '../SFConfig/Index'
import _ from 'lodash'
import update from 'react-addons-update'
import Switch from '../Switch'
import SFReleaseFilter from './Filter'

export default class SFReleaseList extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      data: [],
      current: null,
      connectionError: false,
      loading: false,
      filter: {
        // empty: false
      }
    }
  }

  componentWillMount() {
    this.loadData()
  }

  async loadData() {
    try {
      this.setState({loading: true})

      let data = await RestService.load('release')
      // console.log(data)

      this.setState({data: data, connectionError: false, loading: false})
    } catch (promise) {
//      console.log('error', promise)
      this.setState({connectionError: true, loading: false})
    }
  }

  // toggleFilter() {
  //   this.setState(update(this.state, {filter: {$set: {empty: !this.state.filter.empty}}}))
  // }

  filter(item) {
    if (this.state.filter.empty) {
      return _.isEmpty(item.subtitles)
    }

    if (this.state.filter.lang_vi) {
      return !item.subtitles["vi"] || item.subtitles["vi"].length == 0
    }

    return true
  }

  updateFilter(filter) {
    console.log('filter', filter);
    this.setState({filter: filter})
  }

  render() {

    return (

Movies

            <button type="button" className="btn btn-box-tool" data-widget="collapse">
            </button>

            <RPCButton query="release/scan-all" name="Scan All" />

          <SFReleaseFilter onChange={this.updateFilter.bind(this)}/>

          {this.state.data.filter(this.filter.bind(this)).map((item, k) => {
            let stateClass = ""
            if (_.isEmpty(item.subtitles)) {
              stateClass = " bg-warning"
            }
            return (

                    {item.name}

                  <LanguageStats data={item.subtitles} />

                  <RPCButton query="release/download" params={{src: item.src}} name="Download" />

            )
          })}

    )
  }
}
<commit_msg>support en, vi filter<commit_after>import React from 'react'
import { Link } from 'react-router'
import RestService from '../RestService'
import LanguageStats from './LanguageStats'
import RPCButton from '../RPCButton'
import SFConfigIndex from '../SFConfig/Index'
import _ from 'lodash'
import update from 'react-addons-update'
import Switch from '../Switch'
import SFReleaseFilter from './Filter'

export default class SFReleaseList extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      data: [],
      current: null,
      connectionError: false,
      loading: false,
      filter: {
        // empty: false
      }
    }
  }

  componentWillMount() {
    this.loadData()
  }

  async loadData() {
    try {
      this.setState({loading: true})

      let data = await RestService.load('release')
      // console.log(data)

      this.setState({data: data, connectionError: false, loading: false})
    } catch (promise) {
//      console.log('error', promise)
      this.setState({connectionError: true, loading: false})
    }
  }

  // toggleFilter() {
  //   this.setState(update(this.state, {filter: {$set: {empty: !this.state.filter.empty}}}))
  // }

  filter(item) {
    if (this.state.filter.empty) {
      return _.isEmpty(item.subtitles)
    }

    for (let lang of ["en", "vi"]) {
      let fieldName = `lang_${lang}`
      if (this.state.filter[fieldName]) {
        return !item.subtitles[lang] || item.subtitles[lang].length == 0
      }
    }

    return true
  }

  updateFilter(filter) {
    console.log('filter', filter);
    this.setState({filter: filter})
  }

  render() {

    return (

Movies

            <button type="button" className="btn btn-box-tool" data-widget="collapse">
            </button>

            <RPCButton query="release/scan-all" name="Scan All" />

          <SFReleaseFilter onChange={this.updateFilter.bind(this)}/>

          {this.state.data.filter(this.filter.bind(this)).map((item, k) => {
            let stateClass = ""
            if (_.isEmpty(item.subtitles)) {
              stateClass = " bg-warning"
            }
            return (

                    {item.name}

                  <LanguageStats data={item.subtitles} />

                  <RPCButton query="release/download" params={{src: item.src}} name="Download" />

            )
          })}

    )
  }
}
<|endoftext|>


<commit_before>import React from 'react'
import {connect} from 'react-redux'
import PropTypes from 'prop-types'
import {Router, Route, Switch} from 'react-router-dom'
import PrivateRoute from './PrivateRoute'
import Hook from 'util/hook'
import config from 'gen/config'
import {createBrowserHistory} from 'history'
const {ADMIN_BASE_URL} = config
import LogoutContainer from 'client/containers/LogoutContainer'
import Async from 'client/components/Async'
import {
    CAPABILITY_ACCESS_ADMIN_PAGE
} from 'util/capabilities'

const LoginContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/LoginContainer')}/>
const SignUpContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/SignUpContainer')}/>
const UserProfileContainer = (props) => <Async {...props}
                                               load={import(/* webpackChunkName: "admin" */ '../../containers/UserProfileContainer')}/>
const SystemContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/SystemContainer')}/>
const DbDumpContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/DbDumpContainer')}/>
const FilesContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/FilesContainer')}/>
const TypesContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/TypesContainer')}/>
const HomeContainer = (props) => <Async {...props}
                                        load={import(/* webpackChunkName: "admin" */ '../../containers/HomeContainer')}/>
const ErrorPage = (props) => <Async {...props}
                                    load={import(/* webpackChunkName: "admin" */ '../../components/layout/ErrorPage')}/>

const UnauthorizedPage = (props) => (
    <ErrorPage code="401" title="Unauthorized" background="#f4a742"/>
)

class Routes extends React.Component {

    adminBaseUrlPlain = ADMIN_BASE_URL.slice(1)
    history = createBrowserHistory()

    routes = [
        {exact: true, private: true, path: ADMIN_BASE_URL + '/', component: HomeContainer},
        {path: ADMIN_BASE_URL + '/login', component: LoginContainer},
        {path: ADMIN_BASE_URL + '/logout', component: LogoutContainer},
        {path: ADMIN_BASE_URL + '/signup', component: SignUpContainer},
        {private: true, path: ADMIN_BASE_URL + '/profile', component: UserProfileContainer},
        {exact: true, private: true, path: ADMIN_BASE_URL + '/types/:type*', component: TypesContainer},
        {private: true, path: ADMIN_BASE_URL + '/system', component: SystemContainer},
        {private: true, path: ADMIN_BASE_URL + '/backup', component: DbDumpContainer},
        {private: true, path: ADMIN_BASE_URL + '/files', component: FilesContainer}
    ]

    constructor(props) {
        super(props)
        Hook.call('Routes', {routes: this.routes, container: this})

        // override push and replace methode to prepend language code if needed
        this.history._replace = this.history.replace
        this.history._push = this.history.push
        this.history.push = (path, state) => {
            let newPath

            if( path.constructor === Object)
                path = path.pathname
            if (path.split('#')[0]!==_app_.contextPath && path.indexOf(_app_.contextPath + '/') < 0) {
                newPath = _app_.contextPath + path
            } else {
                newPath = path
            }
            this.history._last = this.history.location.pathname

            this.history._push(newPath, state)
        }
        this.history.replace = (o, state) => {
            if (o.pathname !== _app_.contextPath && o.pathname.indexOf(_app_.contextPath + '/') < 0) {
                o.pathname = _app_.contextPath + o.pathname
            }
            this.history._replace(o, state)
        }
    }

    render() {
        const {user: {isAuthenticated, userData}} = this.props
        const capabilities = (userData && userData.role && userData.role.capabilities) || []

        return <Router history={this.history}>
            <Switch>
                {this.routes.map((o, i) => {
                    if (!isAuthenticated || !o.path.startsWith(ADMIN_BASE_URL) || o.path.startsWith(ADMIN_BASE_URL + '/login') || o.path.startsWith(ADMIN_BASE_URL + '/types') || o.path.startsWith(ADMIN_BASE_URL + '/logout') || capabilities.indexOf(CAPABILITY_ACCESS_ADMIN_PAGE) >= 0) {
                        if (o.private) {
                            return <PrivateRoute key={i} path={_app_.contextPath + o.path}
                                                 isAuthenticated={isAuthenticated}
                                                 exact={o.exact}
                                                 component={o.component}/>
                        } else {
                            return <Route key={i} path={_app_.contextPath + o.path} exact={o.exact}
                                          component={o.component}
                                          render={o.render}/>
                        }
                    } else {
                        return <Route key={i} path={_app_.contextPath + o.path} exact={o.exact}
                                      component={UnauthorizedPage}/>
                    }
                })}
                <Route component={ErrorPage}/>
            </Switch>
        </Router>
    }
}

Routes.propTypes = {
    user: PropTypes.object.isRequired
}

/**
 * Map the state to props.
 */
const mapStateToProps = (store) => {
    return {
        user: store.user
    }
}

/**
 * Connect the component to
 * the Redux store.
 */
export default connect(
    mapStateToProps
)(Routes)
<commit_msg>Small improvements<commit_after>import React from 'react'
import {connect} from 'react-redux'
import PropTypes from 'prop-types'
import {Router, Route, Switch} from 'react-router-dom'
import PrivateRoute from './PrivateRoute'
import Hook from 'util/hook'
import config from 'gen/config'
import {createBrowserHistory} from 'history'
const {ADMIN_BASE_URL} = config
import LogoutContainer from 'client/containers/LogoutContainer'
import Async from 'client/components/Async'
import {
    CAPABILITY_ACCESS_ADMIN_PAGE
} from 'util/capabilities'

const LoginContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/LoginContainer')}/>
const SignUpContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/SignUpContainer')}/>
const UserProfileContainer = (props) => <Async {...props}
                                               load={import(/* webpackChunkName: "admin" */ '../../containers/UserProfileContainer')}/>
const SystemContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/SystemContainer')}/>
const DbDumpContainer = (props) => <Async {...props}
                                          load={import(/* webpackChunkName: "admin" */ '../../containers/DbDumpContainer')}/>
const FilesContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/FilesContainer')}/>
const TypesContainer = (props) => <Async {...props}
                                         load={import(/* webpackChunkName: "admin" */ '../../containers/TypesContainer')}/>
const HomeContainer = (props) => <Async {...props}
                                        load={import(/* webpackChunkName: "admin" */ '../../containers/HomeContainer')}/>
const ErrorPage = (props) => <Async {...props}
                                    load={import(/* webpackChunkName: "admin" */ '../../components/layout/ErrorPage')}/>

const UnauthorizedPage = (props) => (
    <ErrorPage code="401" title="Unauthorized" background="#f4a742"/>
)

class Routes extends React.Component {

    adminBaseUrlPlain = ADMIN_BASE_URL.slice(1)
    history = createBrowserHistory()

    routes = [
        {exact: true, private: true, path: ADMIN_BASE_URL + '/', component: HomeContainer},
        {path: ADMIN_BASE_URL + '/login', component: LoginContainer},
        {path: ADMIN_BASE_URL + '/logout', component: LogoutContainer},
        {path: ADMIN_BASE_URL + '/signup', component: SignUpContainer},
        {private: true, path: ADMIN_BASE_URL + '/profile', component: UserProfileContainer},
        {exact: true, private: true, path: ADMIN_BASE_URL + '/types/:type*', component: TypesContainer},
        {private: true, path: ADMIN_BASE_URL + '/system', component: SystemContainer},
        {private: true, path: ADMIN_BASE_URL + '/backup', component: DbDumpContainer},
        {private: true, path: ADMIN_BASE_URL + '/files', component: FilesContainer}
    ]

    constructor(props) {
        super(props)
        Hook.call('Routes', {routes: this.routes, container: this})

        // override push and replace methode to prepend language code if needed
        this.history._replace = this.history.replace
        this.history._push = this.history.push
        this.history.push = (path, state) => {
            let newPath

            if( path.constructor === Object)
                path = path.pathname
            if (path.split('#')[0]!==_app_.contextPath && path.indexOf(_app_.contextPath + '/') !== 0) {
                newPath = _app_.contextPath + path
            } else {
                newPath = path
            }
            this.history._last = this.history.location.pathname
            this.history._push(newPath, state)
        }
        this.history.replace = (o, state) => {
            if (o.pathname !== _app_.contextPath && o.pathname.indexOf(_app_.contextPath + '/') < 0) {
                o.pathname = _app_.contextPath + o.pathname
            }
            this.history._replace(o, state)
        }
    }

    render() {
        const {user: {isAuthenticated, userData}} = this.props
        const capabilities = (userData && userData.role && userData.role.capabilities) || []
        return <Router history={this.history}>
            <Switch>
                {this.routes.map((o, i) => {
                    if (!isAuthenticated || !o.path.startsWith(ADMIN_BASE_URL) || o.path.startsWith(ADMIN_BASE_URL + '/login') || o.path.startsWith(ADMIN_BASE_URL + '/types') || o.path.startsWith(ADMIN_BASE_URL + '/logout') || capabilities.indexOf(CAPABILITY_ACCESS_ADMIN_PAGE) >= 0) {
                        if (o.private) {
                            return <PrivateRoute key={i} path={_app_.contextPath + o.path}
                                                 isAuthenticated={isAuthenticated}
                                                 exact={o.exact}
                                                 component={o.component}/>
                        } else {
                            return <Route key={i} path={_app_.contextPath + o.path} exact={o.exact}
                                          component={o.component}
                                          render={o.render}/>
                        }
                    } else {
                        return <Route key={i} path={_app_.contextPath + o.path} exact={o.exact}
                                      component={UnauthorizedPage}/>
                    }
                })}
                <Route component={ErrorPage}/>
            </Switch>
        </Router>
    }
}

Routes.propTypes = {
    user: PropTypes.object.isRequired
}

/**
 * Map the state to props.
 */
const mapStateToProps = (store) => {
    return {
        user: store.user
    }
}

/**
 * Connect the component to
 * the Redux store.
 */
export default connect(
    mapStateToProps
)(Routes)
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import withRouter from 'found/lib/withRouter'
import { routerShape } from 'found/lib/PropTypes'
import { graphql } from 'react-relay'
import { fragment } from 'relay-compose'
import { compose, flattenProp, setPropTypes, withHandlers } from 'recompose'
import { SubmissionError } from 'redux-form'

import Wrapper from './Wrapper'
import Bold from './Bold'
import Hint from './Hint'
import FormWrapper from './FormWrapper'
import Form from './Form'
import Button, { FacebookLoginButton } from '../../components/Button'

import LoginMutation from '../../mutation/LoginMutation'
import { ERRORS } from '../../../common/config'

const UserLoginPage = ({
  onFacebookLoginSuccess,
  onFacebookLoginFailure,
  login,
}) => (
  <Wrapper>

Logins

    <Hint>
      You can use <Bold>reader@test.com</Bold>, <Bold>publisher@test.com</Bold>,
      <Bold> publisher2@test.com</Bold> with password <Bold>qwerty</Bold>.
    </Hint>

    <FormWrapper>

      <FacebookLoginButton
        label="Login with facebook"
        onLoginSuccess={onFacebookLoginSuccess}
        onLoginFailure={onFacebookLoginFailure}
        fullWidth
        secondary
      />

      <Form onSubmit={login} />

      <Button
        label="Register"
        to="/register"
        fullWidth
        primary
      />
    </FormWrapper>
  </Wrapper>
)

UserLoginPage.propTypes = {
  onFacebookLoginSuccess: PropTypes.func.isRequired,
  onFacebookLoginFailure: PropTypes.func.isRequired,
  login: PropTypes.func.isRequired,
}

const loginHandlers = {
  login: ({ router }) => ({ email, password, facebookToken }) =>
    LoginMutation.commit({ email, password, facebookToken })
      .then((result, errors) => {
        if (!errors) {
          router.replace('/')
          return
        }

        console.error('login failed', errors[0])
        throw new SubmissionError(errors[0])
      }),
}

const facebookHandlers = {
  onFacebookLoginSuccess: ({ login }) => (result) => {
    const { email } = result.profile
    const { accessToken } = result.token

    login({ email, facebookToken: accessToken })
  },
  onFacebookLoginFailure: (error) => {
    console.log('facebook failure', error)
  },
}

const propTypes = {
  router: routerShape.isRequired,
  isLoggedIn: PropTypes.bool.isRequired,
}

const enhance = compose(
  withRouter,
  fragment(graphql`
    fragment UserLogin on Query {
      permission {
        isLoggedIn
        canPublish
      }
    }
  `),
  setPropTypes(propTypes),
  withHandlers(loginHandlers),
  withHandlers(facebookHandlers),
  flattenProp('data'),
  flattenProp('permission'),
)

export default enhance(UserLoginPage)
<commit_msg>Show submit errors in login form<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import withRouter from 'found/lib/withRouter'
import { compose, withHandlers, withProps } from 'recompose'
import { SubmissionError, reduxForm } from 'redux-form'

import Wrapper from './Wrapper'
import Bold from './Bold'
import Hint from './Hint'
import FormWrapper from './FormWrapper'
import TextField from '../../components/Input/TextField'
import Button, { FacebookLoginButton } from '../../components/Button'

import LoginMutation from '../../mutation/LoginMutation'
import { ERRORS } from '../../../common/config'
import mapSubmitErrorsToFormErrors from './mapSubmitErrorsToFormErrors'

const acceptedErrors = [
  { id: ERRORS.WrongEmailOrPassword, field: 'email', message: 'Wrong email or password' },
  { id: ERRORS.WrongEmailOrPassword, field: 'password', message: 'Wrong email or password' },
]

const UserLoginPage = ({
  onFacebookLoginSuccess,
  onFacebookLoginFailure,
  handleSubmit,
}) => (
  <Wrapper>

Logins

    <Hint>
      You can use <Bold>reader@test.com</Bold>, <Bold>publisher@test.com</Bold>,
      <Bold> publisher2@test.com</Bold> with password <Bold>qwerty</Bold>.
    </Hint>

    <FormWrapper>

      <FacebookLoginButton
        label="Login with facebook"
        onLoginSuccess={onFacebookLoginSuccess}
        onLoginFailure={onFacebookLoginFailure}
        fullWidth
        secondary
      />

      <form onSubmit={handleSubmit}>
        <TextField
          name="email"
          label="E-Mail"
          validations="email"
          fullWidth
          required
        />

        <TextField
          type="password"
          name="password"
          label="Passwort"
          fullWidth
          required
        />

        <Button
          type="submit"
          label="Login"
          fullWidth
          secondary
        />
      </form>

      <Button
        label="Register"
        to="/register"
        fullWidth
        primary
      />
    </FormWrapper>
  </Wrapper>
)

UserLoginPage.propTypes = {
  onFacebookLoginSuccess: PropTypes.func.isRequired,
  onFacebookLoginFailure: PropTypes.func.isRequired,
  handleSubmit: PropTypes.func.isRequired,
}

const loginHandlers = {
  login: ({ router }) => ({ email, password, facebookToken }) =>
    LoginMutation.commit({ email, password, facebookToken })
      .then(() => router.replace('/'))
      .catch((error) => {
        console.error('login failed', error)
        const formErrors = mapSubmitErrorsToFormErrors(error, acceptedErrors)
        throw new SubmissionError(formErrors)
      }),
}

const facebookHandlers = {
  onFacebookLoginSuccess: ({ login }) => (result) => {
    const { email } = result.profile
    const { accessToken } = result.token

    login({ email, facebookToken: accessToken })
  },
  onFacebookLoginFailure: (error) => {
    console.log('facebook failure', error)
  },
}

const enhance = compose(
  withRouter,
  withHandlers(loginHandlers),
  withHandlers(facebookHandlers),
  withProps(({ login }) => ({ onSubmit: login })),
  reduxForm({ form: 'login' }),
)

export default enhance(UserLoginPage)
<|endoftext|>