<commit_before>(function (angular, page, notifications) {
  /**
   * Controller to download the analysis.
   * @constructor
   */
  function FileDownloadController() {
    var vm = this;

    vm.getZipFile = function (id) {
      var iFrameId = 'hiddenDownloader';
      var hiddenIFrame = document.getElementById(iFrameId);
      if (hiddenIFrame === null) {
        hiddenIFrame = document.createElement('iframe');
        hiddenIFrame.id = iFrameId;
        hiddenIFrame.style.display = 'none';
        document.body.appendChild(hiddenIFrame);
      }
      hiddenIFrame.src = page.URLS.download + id + '?dandelionAssetFilterState=false';
    };
  }

  /**
   * Service for Analysis
   * @param $http
   * @param $interval
   * @returns {AnalysisService}
   * @constructor
   */
  function AnalysisService($http) {
    var svc = this;

    /**
     * Call the server to get the status for the current analysis.
     * 'page.URLS.status' is on the `_base.html` page for the analysis.
     * @returns {*}
     * @private
     */
    function _getState() {
      return $http.get(page.URLS.status).then(function (data) {
        return data.data;
      });
    }

    /**
     * Get the results from a SISTR analysis to preview in the browser.
     */
    svc.getSistrResults = function() {
      return $http.get(page.URLS.sistr).then(function(result) {
        return result.data;
      });
    }

    /**
     * Exported function to call the server for information about the current analysis.
     * @param fn Callback function with how to handle the results.
     */
    svc.getAnalysisState = function (fn) {
      _getState().then(function (data) {
        fn(data);
      });
    };

    /**
     * Call the server to update the shared status of the current analysis.
     */
    svc.updateProjectShare = function(project, shared) {
      var data = {project: project, shared: shared};
      return $http.post(page.URLS.share, data).then(function(response) {
        return response.data;
      });
    };

    /**
     * Call the server to get the shared status of project
     */
    svc.getSharedProjects = function() {
      return $http.get(page.URLS.share).then(function(response) {
        return response.data;
      });
    };

    return svc;
  }

  function ProjectShareController(AnalysisService, notifications) {
    var vm = this;

    vm.projects = {};

    function initialize() {
      AnalysisService.getSharedProjects().then(function(response){
        vm.projects = response;
        console.log(vm.projects);
      });
    }

    vm.updateShared = function(project) {
      AnalysisService.updateProjectShare(project.project.identifier, project.shared).then(function(response) {
        notifications.show({msg: response.message});
      });
    };

    initialize();
  }

  /**
   * Controls the state for the current analysis.
   * @param AnalysisService
   * @constructor
   */
  function StateController(AnalysisService) {
    var vm = this;
    vm.percentage = 0;

    /**
     * Initializes the sate of the analysis.
     */
    function initialize() {
      return AnalysisService.getAnalysisState(function (data) {
        vm.state = data.state;
        vm.stateLang = data.stateLang;
        vm.percentage = Math.round(parseFloat(data.percentComplete));
        vm.stateClass = _createClass(vm.state);
      });
    }

    /**
     * Dynamically creates the border color for the top of the sidebar depending on the state of the analysis.
     * @param state
     * @returns {string}
     * @private
     */
    function _createClass(state) {
      return 'analysis__alert--' + state.toLowerCase();
    }

    initialize();
  }

  function PreviewController() {
    var vm = this;
    vm.newick = page.NEWICK;
  }

  function SistrController(analysisService) {
    var vm = this;

    analysisService.getSistrResults().then(function(result) {
      if (result['parse_results_error']) {
        vm.parse_results_error = true;
      } else {
        var sample_information = {};
        sample_information['name'] = result['sample_name'];
        sample_information['qc_status'] = result['qc_status'];
        sample_information['qc_messages'] = result['qc_messages'].split("|");
        sample_information['qc_pass'] = (result['qc_status'] == 'PASS');

        var serotype_predictions_order = ['Serovar (overall)', 'Serovar (antigen)', 'Serovar (cgMLST)', 'Serogroup', 'H1', 'H2', 'O antigen'];
        var serotype_predictions = {};
        serotype_predictions['Serovar (overall)'] = result['serovar'];
        serotype_predictions['Serovar (antigen)'] = result['serovar_antigen'];
        serotype_predictions['Serovar (cgMLST)'] = result['serovar_cgmlst'];
        serotype_predictions['Serogroup'] = result['serogroup'];
        serotype_predictions['H1'] = result['h1'];
        serotype_predictions['H2'] = result['h2'];
        serotype_predictions['O antigen'] = result['o_antigen'];

        var cgMLST_predictions = {};
        var cgMLST_predictions_order = ['cgMLST subspecies', 'cgMLST matching alleles', 'cgMLST genome match', 'cgMLST ST'];
        cgMLST_predictions['cgMLST subspecies'] = result['cgmlst_subspecies'];
        cgMLST_predictions['cgMLST matching alleles'] = result['cgmlst_matching_alleles']+'/330';
        cgMLST_predictions['cgMLST genome match'] = result['cgmlst_genome_match'];
        cgMLST_predictions['cgMLST ST'] = result['cgmlst_ST'];

        var mash_predictions = {};
        var mash_predictions_order = ['Mash subspecies', 'Mash serovar', 'Mash genome match', 'Mash match distance'];
        mash_predictions['Mash subspecies'] = result['mash_subspecies'];
        mash_predictions['Mash serovar'] = result['mash_serovar'];
        mash_predictions['Mash genome match'] = result['mash_genome'];
        mash_predictions['Mash match distance'] = result['mash_distance'];

        vm.sample_information = sample_information;
        vm.serotype_predictions = serotype_predictions;
        vm.serotype_predictions_order = serotype_predictions_order;
        vm.cgMLST_predictions_order = cgMLST_predictions_order;
        vm.cgMLST_predictions = cgMLST_predictions;
        vm.mash_predictions_order = mash_predictions_order;
        vm.mash_predictions = mash_predictions;
        vm.parse_results_error = result['parse_results_error'];
      }
    });
  }

  angular.module('irida.analysis', ['ui.router', 'subnav', 'phylocanvas'])
    .config(['$stateProvider', function ($stateProvider) {
      $stateProvider
        .state("preview", {
          url        : "/preview",
          templateUrl: "preview.html"
        })
        .state("sistr", {
          url: "/sistr",
          templateUrl: "sistr.html",
          controllerAs: "sistrCtrl",
          controller: ["AnalysisService", SistrController]
        })
        .state("inputs", {
          url        : "/inputs",
          templateUrl: "inputs.html"
        })
        .state("provenance", {
          url        : "/provenance",
          templateUrl: "provenance.html"
        })
        .state("share", {
          url        : "/share",
          templateUrl: "share.html"
        })
      ;
    }])
    .service('AnalysisService', ['$http', AnalysisService])
    .controller('FileDownloadController', [FileDownloadController])
    .controller('StateController', ['AnalysisService', StateController])
    .controller('PreviewController', [PreviewController])
    .controller('ProjectShareController', ['AnalysisService', 'notifications', ProjectShareController])
  ;
})(window.angular, window.PAGE, window.notifications);
<commit_msg>Re-arranged names of sistr results<commit_after>(function (angular, page, notifications) {
  /**
   * Controller to download the analysis.
   * @constructor
   */
  function FileDownloadController() {
    var vm = this;

    vm.getZipFile = function (id) {
      var iFrameId = 'hiddenDownloader';
      var hiddenIFrame = document.getElementById(iFrameId);
      if (hiddenIFrame === null) {
        hiddenIFrame = document.createElement('iframe');
        hiddenIFrame.id = iFrameId;
        hiddenIFrame.style.display = 'none';
        document.body.appendChild(hiddenIFrame);
      }
      hiddenIFrame.src = page.URLS.download + id + '?dandelionAssetFilterState=false';
    };
  }

  /**
   * Service for Analysis
   * @param $http
   * @param $interval
   * @returns {AnalysisService}
   * @constructor
   */
  function AnalysisService($http) {
    var svc = this;

    /**
     * Call the server to get the status for the current analysis.
     * 'page.URLS.status' is on the `_base.html` page for the analysis.
     * @returns {*}
     * @private
     */
    function _getState() {
      return $http.get(page.URLS.status).then(function (data) {
        return data.data;
      });
    }

    /**
     * Get the results from a SISTR analysis to preview in the browser.
     */
    svc.getSistrResults = function() {
      return $http.get(page.URLS.sistr).then(function(result) {
        return result.data;
      });
    }

    /**
     * Exported function to call the server for information about the current analysis.
     * @param fn Callback function with how to handle the results.
     */
    svc.getAnalysisState = function (fn) {
      _getState().then(function (data) {
        fn(data);
      });
    };

    /**
     * Call the server to update the shared status of the current analysis.
     */
    svc.updateProjectShare = function(project, shared) {
      var data = {project: project, shared: shared};
      return $http.post(page.URLS.share, data).then(function(response) {
        return response.data;
      });
    };

    /**
     * Call the server to get the shared status of project
     */
    svc.getSharedProjects = function() {
      return $http.get(page.URLS.share).then(function(response) {
        return response.data;
      });
    };

    return svc;
  }

  function ProjectShareController(AnalysisService, notifications) {
    var vm = this;

    vm.projects = {};

    function initialize() {
      AnalysisService.getSharedProjects().then(function(response){
        vm.projects = response;
        console.log(vm.projects);
      });
    }

    vm.updateShared = function(project) {
      AnalysisService.updateProjectShare(project.project.identifier, project.shared).then(function(response) {
        notifications.show({msg: response.message});
      });
    };

    initialize();
  }

  /**
   * Controls the state for the current analysis.
   * @param AnalysisService
   * @constructor
   */
  function StateController(AnalysisService) {
    var vm = this;
    vm.percentage = 0;

    /**
     * Initializes the sate of the analysis.
     */
    function initialize() {
      return AnalysisService.getAnalysisState(function (data) {
        vm.state = data.state;
        vm.stateLang = data.stateLang;
        vm.percentage = Math.round(parseFloat(data.percentComplete));
        vm.stateClass = _createClass(vm.state);
      });
    }

    /**
     * Dynamically creates the border color for the top of the sidebar depending on the state of the analysis.
     * @param state
     * @returns {string}
     * @private
     */
    function _createClass(state) {
      return 'analysis__alert--' + state.toLowerCase();
    }

    initialize();
  }

  function PreviewController() {
    var vm = this;
    vm.newick = page.NEWICK;
  }

  function SistrController(analysisService) {
    var vm = this;

    analysisService.getSistrResults().then(function(result) {
      if (result['parse_results_error']) {
        vm.parse_results_error = true;
      } else {
        var sample_information = {};
        sample_information['name'] = result['sample_name'];
        sample_information['qc_status'] = result['qc_status'];
        sample_information['qc_messages'] = result['qc_messages'].split("|");
        sample_information['qc_pass'] = (result['qc_status'] == 'PASS');

        var serotype_predictions_order = ['Serovar (overall)', 'Serovar (antigen)', 'Serovar (cgMLST)', 'Serogroup', 'H1', 'H2', 'O antigen'];
        var serotype_predictions = {};
        serotype_predictions['Serovar (overall)'] = result['serovar'];
        serotype_predictions['Serovar (antigen)'] = result['serovar_antigen'];
        serotype_predictions['Serovar (cgMLST)'] = result['serovar_cgmlst'];
        serotype_predictions['Serogroup'] = result['serogroup'];
        serotype_predictions['H1'] = result['h1'];
        serotype_predictions['H2'] = result['h2'];
        serotype_predictions['O antigen'] = result['o_antigen'];

        var cgMLST_predictions = {};
        var cgMLST_predictions_order = ['Subspecies', 'Matching genome name', 'Alleles matching genome', 'Percent matching', 'cgMLST Sequence Type'];
        cgMLST_predictions['Subspecies'] = result['cgmlst_subspecies'];
        cgMLST_predictions['Matching genome name'] = result['cgmlst_genome_match'];
        cgMLST_predictions['Alleles matching genome'] = result['cgmlst_matching_alleles']+'/330';
        cgMLST_predictions['Percent matching'] = parseFloat((1 - result['cgmlst_distance'])*100).toFixed(2);
        cgMLST_predictions['cgMLST Sequence Type'] = result['cgmlst_ST'];

        var mash_predictions = {};
        var mash_predictions_order = ['Subspecies', 'Serovar', 'Matching genome', 'Percent matching'];
        mash_predictions['Subspecies'] = result['mash_subspecies'];
        mash_predictions['Serovar'] = result['mash_serovar'];
        mash_predictions['Matching genome'] = result['mash_genome'];
        mash_predictions['Percent matching'] = parseFloat((1 - result['mash_distance'])*100).toFixed(2);

        vm.sample_information = sample_information;
        vm.serotype_predictions = serotype_predictions;
        vm.serotype_predictions_order = serotype_predictions_order;
        vm.cgMLST_predictions_order = cgMLST_predictions_order;
        vm.cgMLST_predictions = cgMLST_predictions;
        vm.mash_predictions_order = mash_predictions_order;
        vm.mash_predictions = mash_predictions;
        vm.parse_results_error = result['parse_results_error'];
      }
    });
  }

  angular.module('irida.analysis', ['ui.router', 'subnav', 'phylocanvas'])
    .config(['$stateProvider', function ($stateProvider) {
      $stateProvider
        .state("preview", {
          url        : "/preview",
          templateUrl: "preview.html"
        })
        .state("sistr", {
          url: "/sistr",
          templateUrl: "sistr.html",
          controllerAs: "sistrCtrl",
          controller: ["AnalysisService", SistrController]
        })
        .state("inputs", {
          url        : "/inputs",
          templateUrl: "inputs.html"
        })
        .state("provenance", {
          url        : "/provenance",
          templateUrl: "provenance.html"
        })
        .state("share", {
          url        : "/share",
          templateUrl: "share.html"
        })
      ;
    }])
    .service('AnalysisService', ['$http', AnalysisService])
    .controller('FileDownloadController', [FileDownloadController])
    .controller('StateController', ['AnalysisService', StateController])
    .controller('PreviewController', [PreviewController])
    .controller('ProjectShareController', ['AnalysisService', 'notifications', ProjectShareController])
  ;
})(window.angular, window.PAGE, window.notifications);
<|endoftext|>


<commit_before>var async = require("async");
const template = require("./template");

exports.notifyContacts = function (gh, pr, status, mailer, emailConfig, store, log, cb) {
    log.info("Attempting to notify error on " + pr.fullName);
    var staff = gh.getRepoContacts(pr.fullName, function(err, emails) {
        var actualEmails;
        if (err || !emails) {
            log.error(err);
            actualEmails = emailConfig.fallback;
        }
        else {
            actualEmails = emails.filter(function(e) { return e !== null;});
            if (!actualEmails || !actualEmails.length) {
                log.error("Could not retrieve email addresses from repo contacts for " + pr.fullName);
                actualEmails = emailConfig.fallback;
            }
        }
        mailer.sendMail({
            from: emailConfig.from,
            to: actualEmails.join(","),
            subject: "IPR check failed for PR #" + pr.num+ " on " + pr.fullName,
            text: status.payload.description + "\n\n See " + status.payload.target_url
        }, function(err) {
            if (err) {
                log.error(err);
                return cb();
            }
            // send mail to unaffiliated users
            async.each(pr.unaffiliatedUsers, function(u, userCB) {
                store.getUser(u, function(err, user) {
                    if (err) return userCB(err);
                    if (user.emails.length) {
                        const mailData = {
                            displayName: user.displayName ? user.displayName : user.login,
                            prnum: pr.num,
                            repo: pr.fullName,
                            contacts: actualEmails.join(",")
                        }
                        mailer.sendMail({
                            from: emailConfig.from,
                            to: user.emails[0].value,
                            cc: [...actualEmails, ...emailConfig.cc].join(",")
                            subject: "Information needed for your PR #" + pr.num+ " on " + pr.fullName,
                            text: template('affiliation-mail.txt', mailData)
                        }, userCB);
                    } else {
                        // TODO: comment on pull request directly?
                        return userCB();
                    }
                })
            }, function(err) {
                if (err)  log.error(err);
                return cb();
            });
        });
    });
};
<commit_msg>Fix typo<commit_after>var async = require("async");
const template = require("./template");

exports.notifyContacts = function (gh, pr, status, mailer, emailConfig, store, log, cb) {
    log.info("Attempting to notify error on " + pr.fullName);
    var staff = gh.getRepoContacts(pr.fullName, function(err, emails) {
        var actualEmails;
        if (err || !emails) {
            log.error(err);
            actualEmails = emailConfig.fallback;
        }
        else {
            actualEmails = emails.filter(function(e) { return e !== null;});
            if (!actualEmails || !actualEmails.length) {
                log.error("Could not retrieve email addresses from repo contacts for " + pr.fullName);
                actualEmails = emailConfig.fallback;
            }
        }
        mailer.sendMail({
            from: emailConfig.from,
            to: actualEmails.join(","),
            subject: "IPR check failed for PR #" + pr.num+ " on " + pr.fullName,
            text: status.payload.description + "\n\n See " + status.payload.target_url
        }, function(err) {
            if (err) {
                log.error(err);
                return cb();
            }
            // send mail to unaffiliated users
            async.each(pr.unaffiliatedUsers, function(u, userCB) {
                store.getUser(u, function(err, user) {
                    if (err) return userCB(err);
                    if (user.emails.length) {
                        const mailData = {
                            displayName: user.displayName ? user.displayName : user.login,
                            prnum: pr.num,
                            repo: pr.fullName,
                            contacts: actualEmails.join(",")
                        }
                        mailer.sendMail({
                            from: emailConfig.from,
                            to: user.emails[0].value,
                            cc: [...actualEmails, ...emailConfig.cc].join(","),
                            subject: "Information needed for your PR #" + pr.num+ " on " + pr.fullName,
                            text: template('affiliation-mail.txt', mailData)
                        }, userCB);
                    } else {
                        // TODO: comment on pull request directly?
                        return userCB();
                    }
                })
            }, function(err) {
                if (err)  log.error(err);
                return cb();
            });
        });
    });
};
<|endoftext|>


<commit_before>/*
          ___           ___       ____                                 ___
         |   |         |   |     |    |                               |   |
         |   |      ___|   |____ |    |                               |   |
         |   |     |____    ____||    |                               |   |   ____     __  __ (_)
     ____|   |  _____  |   |     |    |         _____    ______   ____|   | /      \  |  |/ /  __  ______
    /  ___   | /  _  \ |   |     |    |______  /  _  \  /  _ | | /  ___   ||   (_) |  |  / /  |  |/  ___|
   |  (___)  ||  (_)  ||   |     |           ||  (_)  ||  (_)| ||  (___)  ||   –––/__ |  |    |  |\__   \
    \________| \_____/ |___|     |___________| \_____/  \____|_| \________| \________||__|(_) |  | ___\  \
                                                                                _   /  /|______/
                                                                                / /__/  /
                                                                                /______ /
    Version: 1.0.0
    Author: Daniel Torres
    Repo: https://github.com/Danny908/dotLoader.js
    Issues: https://github.com/Danny908/dotLoader.js/issues
*/
(function( $ ) {
    $.fn.dot = function(options, action){
        var _settings = $.extend({
            dotNum: 5,
            dotColor: 'white',
            dotOpacity: 1,
            dotSize: 10,
            backColor: 'black',
            backOpacity: 0.6,
            speed: 300,
            style: 'circle',
            animation: 'fade',
        }, options);

        var _dot = '';
        var _template;
        var _style;

        for(var a = 0; a < _settings.dotNum; a++) {
            _dot += `<div class='dot'></div>`;
        }

        _template =
        `

                ${_dot}

        `;
        _style = (_settings.style === 'circle' ? '50%' : '0%');

        $(this).append(_template);

        $('.loader-container').css({
            'background': _settings.backColor,
            'opacity':          _settings.backOpacity
        });

        $('.dot').css({
            'width':                    `${_settings.dotSize}px`,
            'height':                   `${_settings.dotSize}px`,
            'background':               _settings.dotColor,
            'opacity':                  _settings.dotOpacity,
            'border-radius':            _style
        });

        setInterval(function(){
            var selector = $('.loader').children().eq(counter);
            switch(_settings.animation){
                case 'none':
                    break;
                case 'fade':
                    selector.fadeOut(300).fadeIn(300);
                    break;
                case 'jump':
                    selector.animate({marginBottom: `${_settings.dotSize*1.5}px`}, 300).animate({marginBottom: '0px'}, 300);
                    break;
                case 'zoom':
                    selector.animate({width: `${_settings.dotSize*1.5}px`,height: `${_settings.dotSize*1.5}px`}, 300);
                    selector.animate({width: `${_settings.dotSize}px`,height: `${_settings.dotSize}px`}, 300);
                    break;
                case 'rotate':
                    $('.dot').css({'transform': `rotate(${counter * 45}deg`});
                    break;
            }
            counter = (counter === _settings.dotNum-1 ? 0 : counter+= 1);
        }, _settings.speed, counter = 0);

        if(action === 'close')
            $('.loader-container').remove();
    };
}( jQuery ));<commit_msg>Added loaded event<commit_after>/*
          ___           ___   ____                                 ___
         |   |         |   | |    |                               |   |
         |   |      ___|   |_|__  |                               |   |
         |   |     |____    ____| |                               |   |   ____     __  __ (_)
     ____|   |  _____  |   | |    |         _____    ______   ____|   | /      \  |  |/ /  __  ______
    /  ___   | /  _  \ |   | |    |_____   /  _  \  /  _ | | /  ___   ||   (_) |  |  / /  |  |/  ___|
   |  (___)  ||  (_)  ||   | |           ||  (_)  ||  (_)| ||  (___)  ||   –––/__ |  |    |  |\__   \
    \________| \_____/ |___| |___________| \_____/  \____|_| \________| \________||__|(_) |  | ___\  \
                                                                                _   /  /|______/
    Version: 1.0.0                                                                  / /__/  /
    Author: Daniel Torres                                                          /______ /
    Repo: https://github.com/Danny908/dotLoader.js
    Issues: https://github.com/Danny908/dotLoader.js/issues
*/
(function( $ ) {
    $.fn.dot = function(options, action){
        var _settings = $.extend({
            dotNum: 5,
            dotColor: 'white',
            dotOpacity: 1,
            dotSize: 10,
            backColor: 'black',
            backOpacity: 0.6,
            speed: 300,
            style: 'circle',
            animation: 'fade',
        }, options);

        var _dot = '';
        var _template;
        var _style;

        for(var a = 0; a < _settings.dotNum; a++) {
            _dot += `<div class='dot'></div>`;
        }

        _template =
        `

                ${_dot}

        `;
        _style = (_settings.style === 'circle' ? '50%' : '0%');

        $(this).append(_template);

        $('.loader-container').css({
            'background': _settings.backColor,
            'opacity':          _settings.backOpacity
        });

        $('.dot').css({
            'width':                    `${_settings.dotSize}px`,
            'height':                   `${_settings.dotSize}px`,
            'background':               _settings.dotColor,
            'opacity':                  _settings.dotOpacity,
            'border-radius':            _style
        });

        setInterval(function(){
            var selector = $('.loader').children().eq(counter);
            switch(_settings.animation){
                case 'none':
                    break;
                case 'fade':
                    selector.fadeOut(300).fadeIn(300);
                    break;
                case 'jump':
                    selector.animate({marginBottom: `${_settings.dotSize*1.5}px`}, 300).animate({marginBottom: '0px'}, 300);
                    break;
                case 'zoom':
                    selector.animate({width: `${_settings.dotSize*1.5}px`,height: `${_settings.dotSize*1.5}px`}, 300);
                    selector.animate({width: `${_settings.dotSize}px`,height: `${_settings.dotSize}px`}, 300);
                    break;
                case 'rotate':
                    $('.dot').css({'transform': `rotate(${counter * 45}deg`});
                    break;
            }
            counter = (counter === _settings.dotNum-1 ? 0 : counter+= 1);
        }, _settings.speed, counter = 0);

        $(this).on('loaded', function(){
            $('.loader-container').remove();
        });
    };
}( jQuery ));<|endoftext|>


<commit_before>module.exports = function  (req, res, next) {

    return {

        getModelIndex: function getModelIndex () {

            var records = [],
                filters = {},
                totalRecords = 0,
                pageSize = linz.get('page size'),
                pageIndex = req.body.page || 1;

            // set the model on linz
            req.linz.model = req.linz.get('models')[req.params.model];

            async.series([

                // grab the grid object and append it to the model, i.e. req.linz.model.grid.columns
                function (cb) {

                    req.linz.model.getGrid(function (err, grid) {

                        if (!err) {
                            req.linz.model.grid = grid;
                        }

                        // reset the pageSize value
                        pageSize = req.body.pageSize || req.linz.model.grid.paging.size;

                        cb(err);

                    });

                },

                // render the filters
                function (cb) {

                    async.each(Object.keys(req.linz.model.grid.filters), function (fieldName, filtersDone) {

                        if (req.linz.model.grid.filters[fieldName].formControls) {
                            return filtersDone(null);
                        }

                        // call the filter renderer and update the content with the result
                        req.linz.model.grid.filters[fieldName].filter.renderer(fieldName, function (err, result) {

                            if (!err) {
                                req.linz.model.grid.filters[fieldName].formControls = result;
                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // render the active filters
                function (cb) {

                    req.linz.model.grid.activeFilters = {};

                    // check if there are any filters in the form post
                    if (!req.body.selectedFilters) {
                        return cb(null);
                    }

                    async.each(req.body.selectedFilters.split(','), function (fieldName, filtersDone) {

                        // call the filter binder to render active filter form controls with form value added
                        req.linz.model.grid.filters[fieldName].filter.bind(fieldName, req.body, function (err, result) {

                            if (!err) {
                                req.linz.model.grid.activeFilters[fieldName] = {
                                    label: req.linz.model.grid.filters[fieldName].label,
                                    controls: result
                                }
                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // get the filters
                function (cb) {

                    // check if there are any filters in the form post
                    if (!req.body.selectedFilters) {
                        return cb(null);
                    }

                    async.each(req.body.selectedFilters.split(','), function (fieldName, filtersDone) {

                        // call the filter renderer and update the content with the result
                        req.linz.model.grid.filters[fieldName].filter.filter(fieldName, req.body, function (err, result) {

                            if (!err) {

                                filters = req.linz.model.addSearchFilter(filters, result);

                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // count the docs
                function (cb) {

                    // consolidate filters into query
                    if (Object.keys(filters).length) {
                        filters = req.linz.model.setFiltersAsQuery(filters);
                    }

                    req.linz.model.count(filters, function (err, docs) {

                        if (!err) {
                            totalRecords = docs;
                        }

                        return cb(null);

                    });

                },

                // find the docs
                function (cb) {

                    var query = req.linz.model.find(filters);

                    // sort by the chosen sort field, or use the first sortBy option as the default
                    if (!req.body.sort && req.linz.model.grid.sortBy.length) {

                        query.sort(req.linz.model.grid.sortBy[0].field);

                    } else if (req.body.sort) {

                        query.sort(req.body.sort);

                    }

                    if (req.linz.model.grid.paging.active === true) {
                        // add in paging skip and limit
                        query.skip(pageIndex*pageSize-pageSize).limit(pageSize);
                    }

                    query.exec(function (err, docs) {

                        if (!err && docs.length === 0) {

                            return cb(new Error('No records found'));

                        }

                        if (!err) {

                            mongooseRecords = docs;
                            // convert mongoose documents to plain javascript objects
                            mongooseRecords.forEach(function (record) {
                                records.push(record.toObject({ virtuals: true}));
                            });

                        }

                        cb(err);

                    });

                },

                // check if each doc can be edited
                function (cb) {

                    // skip this if canEdit is not define for model
                    if (!mongooseRecords[0].canEdit) {
                        return cb(null);
                    }

                    async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                        mongooseRecords[index].canEdit(function (err, result, message) {

                            if (err) {
                                return recordDone(err);
                            }

                            records[index].edit = { disabled: !result, message: message };

                            return recordDone(null);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // check if each doc can be deleted
                function (cb) {

                    // skip this if canEdit is not define for model
                    if (!mongooseRecords[0].canDelete) {
                        return cb(null);
                    }

                    async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                        mongooseRecords[index].canDelete(function (err, result, message) {

                            if (err) {
                                return recordDone(err);
                            }

                            records[index].delete = { disabled: !result, message: message };

                            return recordDone(null);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // create the values for the datagrids for each doc
                function (cb) {

                    // loop through each record
                    async.each(Object.keys(records), function (index, recordDone) {

                        // loop through each column
                        async.each(Object.keys(req.linz.model.grid.columns), function (column, columnDone) {

                            var args = [];

                            // value is not applicable for virtual column
                            if (!req.linz.model.grid.columns[column].virtual) {
                                args.push(records[index][column]);
                            }

                            args.push(records[index]);
                            args.push(column);
                            args.push(req.linz.model);
                            args.push(function (err, value) {

                                if (!err) {
                                    records[index][column] = value;
                                }

                                return columnDone(err);

                            });

                            // call the cell renderer and update the content with the result
                            req.linz.model.grid.columns[column].renderer.apply(this,args);

                        }, function (err) {

                            recordDone(err);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // check if we need to process each record again record actions
                function (cb) {

                    if (!req.linz.model.grid.recordActions.length) {
                        return cb(null);
                    }

                    async.each(req.linz.model.grid.recordActions, function (action, actionDone) {

                        if (!action.disabled) {
                            return actionDone(null);
                        }

                        if (typeof action.disabled !== 'function') {
                            throw new Error('Invalid type for record.action.disabled. It must be a function');
                        }

                        async.each(records, function (record, recordDone) {

                            action.disabled(record, function (err, isDisabled, message) {

                                record.recordActions = record.recordActions || {};

                                record.recordActions[action.label] = {
                                    disabled: isDisabled,
                                    message: message
                                };

                                return recordDone(null);

                            });

                        }, function (err) {

                            return actionDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });
                }

            ], function (err, result) {

                // map the update records to linz
                req.linz.records = {
                    records: records,
                    page: pageIndex,
                    total: totalRecords,
                    pages: Math.ceil(totalRecords/pageSize),
                    pageSize: pageSize
                };

                req.linz.model.formData = req.body;

                // add session control data
                req.session[req.params.model] = req.session[req.params.model] || {};
                req.session[req.params.model].grid = req.linz.model.grid;
                req.session[req.params.model].records = req.linz.records;
                req.session[req.params.model].formData = req.linz.model.formData;

                if (err && err.message === 'No records found') {
                    err = null;
                }

                // next middleware
                next(err);

            });

        } // end getModelIndex()

    }

}
<commit_msg>Fixed an issue with a missing require.<commit_after>var async = require('async');

module.exports = function  (req, res, next) {

    return {

        getModelIndex: function getModelIndex () {

            var records = [],
                filters = {},
                totalRecords = 0,
                pageSize = linz.get('page size'),
                pageIndex = req.body.page || 1;

            // set the model on linz
            req.linz.model = req.linz.get('models')[req.params.model];

            async.series([

                // grab the grid object and append it to the model, i.e. req.linz.model.grid.columns
                function (cb) {

                    req.linz.model.getGrid(function (err, grid) {

                        if (!err) {
                            req.linz.model.grid = grid;
                        }

                        // reset the pageSize value
                        pageSize = req.body.pageSize || req.linz.model.grid.paging.size;

                        cb(err);

                    });

                },

                // render the filters
                function (cb) {

                    async.each(Object.keys(req.linz.model.grid.filters), function (fieldName, filtersDone) {

                        if (req.linz.model.grid.filters[fieldName].formControls) {
                            return filtersDone(null);
                        }

                        // call the filter renderer and update the content with the result
                        req.linz.model.grid.filters[fieldName].filter.renderer(fieldName, function (err, result) {

                            if (!err) {
                                req.linz.model.grid.filters[fieldName].formControls = result;
                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // render the active filters
                function (cb) {

                    req.linz.model.grid.activeFilters = {};

                    // check if there are any filters in the form post
                    if (!req.body.selectedFilters) {
                        return cb(null);
                    }

                    async.each(req.body.selectedFilters.split(','), function (fieldName, filtersDone) {

                        // call the filter binder to render active filter form controls with form value added
                        req.linz.model.grid.filters[fieldName].filter.bind(fieldName, req.body, function (err, result) {

                            if (!err) {
                                req.linz.model.grid.activeFilters[fieldName] = {
                                    label: req.linz.model.grid.filters[fieldName].label,
                                    controls: result
                                }
                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // get the filters
                function (cb) {

                    // check if there are any filters in the form post
                    if (!req.body.selectedFilters) {
                        return cb(null);
                    }

                    async.each(req.body.selectedFilters.split(','), function (fieldName, filtersDone) {

                        // call the filter renderer and update the content with the result
                        req.linz.model.grid.filters[fieldName].filter.filter(fieldName, req.body, function (err, result) {

                            if (!err) {

                                filters = req.linz.model.addSearchFilter(filters, result);

                            }

                            return filtersDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });

                },

                // count the docs
                function (cb) {

                    // consolidate filters into query
                    if (Object.keys(filters).length) {
                        filters = req.linz.model.setFiltersAsQuery(filters);
                    }

                    req.linz.model.count(filters, function (err, docs) {

                        if (!err) {
                            totalRecords = docs;
                        }

                        return cb(null);

                    });

                },

                // find the docs
                function (cb) {

                    var query = req.linz.model.find(filters);

                    // sort by the chosen sort field, or use the first sortBy option as the default
                    if (!req.body.sort && req.linz.model.grid.sortBy.length) {

                        query.sort(req.linz.model.grid.sortBy[0].field);

                    } else if (req.body.sort) {

                        query.sort(req.body.sort);

                    }

                    if (req.linz.model.grid.paging.active === true) {
                        // add in paging skip and limit
                        query.skip(pageIndex*pageSize-pageSize).limit(pageSize);
                    }

                    query.exec(function (err, docs) {

                        if (!err && docs.length === 0) {

                            return cb(new Error('No records found'));

                        }

                        if (!err) {

                            mongooseRecords = docs;
                            // convert mongoose documents to plain javascript objects
                            mongooseRecords.forEach(function (record) {
                                records.push(record.toObject({ virtuals: true}));
                            });

                        }

                        cb(err);

                    });

                },

                // check if each doc can be edited
                function (cb) {

                    // skip this if canEdit is not define for model
                    if (!mongooseRecords[0].canEdit) {
                        return cb(null);
                    }

                    async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                        mongooseRecords[index].canEdit(function (err, result, message) {

                            if (err) {
                                return recordDone(err);
                            }

                            records[index].edit = { disabled: !result, message: message };

                            return recordDone(null);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // check if each doc can be deleted
                function (cb) {

                    // skip this if canEdit is not define for model
                    if (!mongooseRecords[0].canDelete) {
                        return cb(null);
                    }

                    async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                        mongooseRecords[index].canDelete(function (err, result, message) {

                            if (err) {
                                return recordDone(err);
                            }

                            records[index].delete = { disabled: !result, message: message };

                            return recordDone(null);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // create the values for the datagrids for each doc
                function (cb) {

                    // loop through each record
                    async.each(Object.keys(records), function (index, recordDone) {

                        // loop through each column
                        async.each(Object.keys(req.linz.model.grid.columns), function (column, columnDone) {

                            var args = [];

                            // value is not applicable for virtual column
                            if (!req.linz.model.grid.columns[column].virtual) {
                                args.push(records[index][column]);
                            }

                            args.push(records[index]);
                            args.push(column);
                            args.push(req.linz.model);
                            args.push(function (err, value) {

                                if (!err) {
                                    records[index][column] = value;
                                }

                                return columnDone(err);

                            });

                            // call the cell renderer and update the content with the result
                            req.linz.model.grid.columns[column].renderer.apply(this,args);

                        }, function (err) {

                            recordDone(err);

                        });

                    }, function (err) {

                        cb(err);

                    });

                },

                // check if we need to process each record again record actions
                function (cb) {

                    if (!req.linz.model.grid.recordActions.length) {
                        return cb(null);
                    }

                    async.each(req.linz.model.grid.recordActions, function (action, actionDone) {

                        if (!action.disabled) {
                            return actionDone(null);
                        }

                        if (typeof action.disabled !== 'function') {
                            throw new Error('Invalid type for record.action.disabled. It must be a function');
                        }

                        async.each(records, function (record, recordDone) {

                            action.disabled(record, function (err, isDisabled, message) {

                                record.recordActions = record.recordActions || {};

                                record.recordActions[action.label] = {
                                    disabled: isDisabled,
                                    message: message
                                };

                                return recordDone(null);

                            });

                        }, function (err) {

                            return actionDone(err);

                        });

                    }, function (err) {

                        return cb(err);

                    });
                }

            ], function (err, result) {

                // map the update records to linz
                req.linz.records = {
                    records: records,
                    page: pageIndex,
                    total: totalRecords,
                    pages: Math.ceil(totalRecords/pageSize),
                    pageSize: pageSize
                };

                req.linz.model.formData = req.body;

                // add session control data
                req.session[req.params.model] = req.session[req.params.model] || {};
                req.session[req.params.model].grid = req.linz.model.grid;
                req.session[req.params.model].records = req.linz.records;
                req.session[req.params.model].formData = req.linz.model.formData;

                if (err && err.message === 'No records found') {
                    err = null;
                }

                // next middleware
                next(err);

            });

        } // end getModelIndex()

    }

}
<|endoftext|>


<commit_before>var linz = require('../'),
    async = require('async'),
    formtoolsAPI = require('../lib/api/formtools'),
    clone = require('clone'),
    dedupe = require('dedupe');

module.exports = function  (req, res, next) {

    const isDevelopment = process.env.NODE_ENV === 'development';
    let body = req.body;

    // set up session control
    var session = req.session[req.params.model] = req.session[req.params.model] || {};
        session.list = session.list || {};
        session.list.formData = session.list.formData || {};

    // Store the previous version of the selectedFilters
    session.list.previous = { formData: session.list.formData || {} };

    // Use the incoming form post for filter, paging, and sorting information.
    if (Object.keys(body).length) {
        session.list.formData = body;
    }

    /**
     * This method should be executed when a query error is returned.
     * It will abort the current query and return the results of the previous query instead.
     * @return {Void}
     */
    function handleQueryError (err) {

        // Reset the last known working state.
        session.list.formData = session.list.previous.formData;

        // If we're in development mode, return the error
        // so that the developers are aware of it and can fix it.
        if (isDevelopment) {
            return next(err);
        }

        // Notify the user that an error has occured.
        req.linz.notifications.push(linz.api.views.notification({
            text: 'An error has occured with one of the filters you added. It has been removed.',
            type: 'error'
        }));

        // Rerun the query at the last known working state.
        // eslint-disable-next-line no-use-before-define
        getModelIndex();

    }

    /**
     * Use this method to completely render the index.
     * @return {Void}
     */
    function getModelIndex () {

        var records = [],
            filters = {},
            refColData = {},
            totalRecords = 0,
            pageSize = linz.get('page size'),
            pageIndex = session.list.formData.page || 1,
            query,
            mongooseRecords;

        // cloned a copy of list settings and append it to the request model
        req.linz.model.list = clone(req.linz.model.linz.formtools.list);

        // reset the pageSize value
        pageSize = session.list.formData.pageSize || req.linz.model.list.paging.size;

        // holder for the sortingBy value
        req.linz.model.list.sortingBy = {};

        async.series([

            // check if there are toolbar items required
            function (cb) {

                formtoolsAPI.list.renderToolbarItems(req, res, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.toolbarItems = result;

                    return cb(null);

                });

            },

            // render the filters
            function (cb) {

                // check if we need to render the filters
                if (!Object.keys(req.linz.model.list.filters).length) {
                    return cb(null);
                }

                formtoolsAPI.list.renderFilters(req.user, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.filters = result;

                    return cb(null);
                });

            },

            // render the active filters
            function (cb) {

                req.linz.model.list.activeFilters = {};

                // check if there are any filters in the form post
                if (!session.list.formData.selectedFilters) {
                    return cb(null);
                }

                formtoolsAPI.list.getActiveFilters(req.user, session.list.formData.selectedFilters.split(','), session.list.formData, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.activeFilters = result;

                    return cb(null);
                });

            },

            // get the filters
            function (cb) {

                // check if there are any filters in the form post
                if (!session.list.formData.selectedFilters) {
                    return cb(null);
                }

                formtoolsAPI.list.renderSearchFilters(req.user, session.list.formData.selectedFilters.split(','), session.list.formData, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    filters = result;

                    return cb(null);

                });

            },

            // create the query
            function (cb) {

                req.linz.model.getQuery(req, filters, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    query = result;

                    return cb(null);

                });

            },

            // get page total
            function (cb) {

                req.linz.model.getCount(req, filters, function (err, countQuery) {

                    if (err) {
                        return cb(err);
                    }

                    countQuery.exec(function (countQueryErr, count) {

                        // A query error has occured, let's short circuit this entire process
                        // and start again from the last known working state.
                        if (countQueryErr) {
                            return handleQueryError(countQueryErr);
                        }

                        if (!countQueryErr && count === 0) {
                            return cb(new Error('No records found'));
                        }

                        if (!countQueryErr) {
                            totalRecords = count;
                        }

                        return cb(countQueryErr);

                    });

                });

            },

            // minimise the fields we're selecting
            function (cb) {

                let fields = Object.keys(req.linz.model.list.fields);

                // Add the default fields we'll look for in the title virtual.
                if (req.linz.model.schema.tree.label) {
                    fields.push('label');
                }

                if (req.linz.model.schema.tree.name) {
                    fields.push('name');
                }

                const select = fields.join(' ');

                query.select(select);

                // If they've provided the `listQuery` static, use it to allow customisation of the fields we'll retrieve.
                if (!req.linz.model.listQuery) {
                    return cb();
                }

                req.linz.model.listQuery(query, cb);

            },

            // find the docs
            function (cb) {

                if (!session.list.formData.sort && req.linz.model.list.sortBy.length) {

                    req.linz.model.list.sortingBy = req.linz.model.list.sortBy[0];

                    // set default form sort
                    session.list.formData.sort = req.linz.model.list.sortingBy.field;

                } else {

                    req.linz.model.list.sortBy.forEach(function (sort) {
                        if (sort.field === session.list.formData.sort || '-' + sort.field === session.list.formData.sort) {
                            req.linz.model.list.sortingBy = sort;
                        }
                    });

                }

                query.sort(session.list.formData.sort);

                if (req.linz.model.list.paging.active === true) {
                    // add in paging skip and limit
                    query.skip(pageIndex*pageSize-pageSize).limit(pageSize);
                }

                query.exec(function (err, docs) {

                    // A query error has occured, let's short circuit this entire process
                    // and start again from the last known working state.
                    if (err) {
                        return handleQueryError(err);
                    }

                    if (!err && docs.length === 0) {

                        return cb(new Error('No records found'));

                    }

                    if (!err) {

                        mongooseRecords = docs;
                        // convert mongoose documents to plain javascript objects
                        mongooseRecords.forEach(function (record) {
                            records.push(record.toObject({ virtuals: true}));
                        });

                    }

                    cb(err);

                });

            },

            // check if each doc can be edited
            function (cb) {

                // skip this if canEdit is not define for model
                if (!mongooseRecords[0].canEdit) {
                    return cb(null);
                }

                async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                    mongooseRecords[index].canEdit(function (err, result, message) {

                        if (err) {
                            return recordDone(err);
                        }

                        records[index].edit = { disabled: !result, message: message };

                        return recordDone(null);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            // check if each doc can be deleted
            function (cb) {

                // skip this if canEdit is not define for model
                if (!mongooseRecords[0].canDelete) {
                    return cb(null);
                }

                async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                    mongooseRecords[index].canDelete(function (err, result, message) {

                        if (err) {
                            return recordDone(err);
                        }

                        records[index].delete = { disabled: !result, message: message };

                        return recordDone(null);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            function (cb) {

                // Determine if there are any fields with refs
                for (let field in req.linz.model.list.fields) {

                    // Support multiple types ref fields.

                    if (req.linz.model.schema.tree[field] && req.linz.model.schema.tree[field].ref) {

                        // Get the records.
                        // Start by filtering records which have valid ObjectIds (support multiple types of reference fields).
                        // Then deduplicate them using a custom hashing function.
                        refColData[field] = {
                            records: dedupe(records.filter(record => !(!record[field]) && linz.api.model.getObjectIdFromRefField(record[field]) instanceof linz.mongoose.Types.ObjectId), record => linz.api.model.getObjectIdFromRefField(record[field]).toString())
                        };

                        // Now get the values.
                        refColData[field].values = refColData[field].records.map(record => linz.api.model.getObjectIdFromRefField(record[field]));

                    }

                }

                // Now we have the objectIds, asynchronously loop through them
                // and retrieve the actual values from the database.
                async.each(Object.keys(refColData), function (field, fieldDone) {

                    let args = [
                        refColData[field].values,
                        refColData[field].records,
                        field,
                        req.linz.model,
                        function (err, value) {

                            refColData[field].rendered = value;

                            return fieldDone(err);

                        }
                    ];

                    // Call the cell renderer and update the content with the result.
                    // val, record, fieldname, model, callback
                    linz.formtools.cellRenderers.reference.apply(null, args);

                }, function (err) {

                    if (err) {
                        return cb(err);
                    }

                    return cb();

                });

            },

            // create the values for the datalists for each doc
            function (cb) {

                // loop through each record
                async.each(Object.keys(records), function (index, recordDone) {

                    // store the rendered content into a separate property
                    records[index]['rendered'] = {};

                    // loop through each field
                    async.each(Object.keys(req.linz.model.list.fields), function (field, fieldDone) {

                        // Skip this field if we have a falsy value
                        if (!req.linz.model.list.fields[field]) {
                            return fieldDone();
                        }

                        // If we have a reference field, data has been pre-rendered.
                        // Let's grab it from there.
                        if (req.linz.model.schema.tree[field] && req.linz.model.schema.tree[field].ref) {

                            // The default value, but could be replaced below if the conditions are right.
                            records[index]['rendered'][field] = records[index][field];

                            // Do we have a rendered result for this field in this particular record?
                            // Support multiple types ref fields.
                            if (refColData[field].rendered && records[index][field] && refColData[field].rendered[linz.api.model.getObjectIdFromRefField(records[index][field]).toString()]) {

                                records[index]['rendered'][field] = refColData[field].rendered[linz.api.model.getObjectIdFromRefField(records[index][field]).toString()];

                            }

                            // We're all done here.
                            return fieldDone();

                        }

                        // This will only execute if we don't have a ref field.

                        let args = [];

                        // value is not applicable for virtual field
                        if (!req.linz.model.list.fields[field].virtual) {
                            args.push(records[index][field]);
                        }

                        args.push(mongooseRecords[index]);
                        args.push(field);
                        args.push(req.linz.model);
                        args.push(function (err, value) {

                            if (!err) {
                                records[index]['rendered'][field] = value;
                            }

                            return fieldDone(err);

                        });

                        // call the cell renderer and update the content with the result
                        // val, record, fieldname, model, callback
                        req.linz.model.list.fields[field].renderer.apply(this, args);

                    }, function (err) {

                        recordDone(err);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            // check if we need to process each record again record actions
            function (cb) {

                if (!req.linz.model.list.recordActions.length) {
                    return cb(null);
                }

                async.each(req.linz.model.list.recordActions, function (action, actionDone) {

                    if (!action.disabled) {
                        return actionDone(null);
                    }

                    if (typeof action.disabled !== 'function') {
                        throw new Error('Invalid type for record.action.disabled. It must be a function');
                    }

                    async.each(Object.keys(records), function (index, recordDone) {

                        action.disabled(mongooseRecords[index], function (err, isDisabled, message) {

                            records[index].recordActions = records[index].recordActions || {};

                            records[index].recordActions[action.label] = {
                                disabled: isDisabled,
                                message: message
                            };

                            return recordDone(null);

                        });

                    }, function (err) {

                        return actionDone(err);

                    });

                }, function (err) {

                    return cb(err);

                });
            }

        ], function (err, result) {

            // map the update records to linz
            req.linz.records = {
                records: records,
                page: pageIndex,
                total: totalRecords,
                pages: Math.ceil(totalRecords/pageSize),
                pageSize: pageSize
            };

            req.linz.model.formData = session.list.formData;

            if (err && err.message === 'No records found') {
                err = null;
            }

            // next middleware
            next(err);

        });

    }; // end getModelIndex()

    return { getModelIndex };

}
<commit_msg>Fixed an issue with the model list query on later versions of MongoDB.<commit_after>var linz = require('../'),
    async = require('async'),
    formtoolsAPI = require('../lib/api/formtools'),
    clone = require('clone'),
    dedupe = require('dedupe');

module.exports = function  (req, res, next) {

    const isDevelopment = process.env.NODE_ENV === 'development';
    let body = req.body;

    // set up session control
    var session = req.session[req.params.model] = req.session[req.params.model] || {};
        session.list = session.list || {};
        session.list.formData = session.list.formData || {};

    // Store the previous version of the selectedFilters
    session.list.previous = { formData: session.list.formData || {} };

    // Use the incoming form post for filter, paging, and sorting information.
    if (Object.keys(body).length) {
        session.list.formData = body;
    }

    /**
     * This method should be executed when a query error is returned.
     * It will abort the current query and return the results of the previous query instead.
     * @return {Void}
     */
    function handleQueryError (err) {

        // Reset the last known working state.
        session.list.formData = session.list.previous.formData;

        // If we're in development mode, return the error
        // so that the developers are aware of it and can fix it.
        if (isDevelopment) {
            return next(err);
        }

        // Notify the user that an error has occured.
        req.linz.notifications.push(linz.api.views.notification({
            text: 'An error has occured with one of the filters you added. It has been removed.',
            type: 'error'
        }));

        // Rerun the query at the last known working state.
        // eslint-disable-next-line no-use-before-define
        getModelIndex();

    }

    /**
     * Use this method to completely render the index.
     * @return {Void}
     */
    function getModelIndex () {

        var records = [],
            filters = {},
            refColData = {},
            totalRecords = 0,
            pageSize = Number(linz.get('page size')),
            pageIndex = Number(session.list.formData.page || 1),
            query,
            mongooseRecords;

        // cloned a copy of list settings and append it to the request model
        req.linz.model.list = clone(req.linz.model.linz.formtools.list);

        // reset the pageSize value
        pageSize = Number(session.list.formData.pageSize || req.linz.model.list.paging.size);

        // holder for the sortingBy value
        req.linz.model.list.sortingBy = {};

        async.series([

            // check if there are toolbar items required
            function (cb) {

                formtoolsAPI.list.renderToolbarItems(req, res, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.toolbarItems = result;

                    return cb(null);

                });

            },

            // render the filters
            function (cb) {

                // check if we need to render the filters
                if (!Object.keys(req.linz.model.list.filters).length) {
                    return cb(null);
                }

                formtoolsAPI.list.renderFilters(req.user, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.filters = result;

                    return cb(null);
                });

            },

            // render the active filters
            function (cb) {

                req.linz.model.list.activeFilters = {};

                // check if there are any filters in the form post
                if (!session.list.formData.selectedFilters) {
                    return cb(null);
                }

                formtoolsAPI.list.getActiveFilters(req.user, session.list.formData.selectedFilters.split(','), session.list.formData, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    req.linz.model.list.activeFilters = result;

                    return cb(null);
                });

            },

            // get the filters
            function (cb) {

                // check if there are any filters in the form post
                if (!session.list.formData.selectedFilters) {
                    return cb(null);
                }

                formtoolsAPI.list.renderSearchFilters(req.user, session.list.formData.selectedFilters.split(','), session.list.formData, req.params.model, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    filters = result;

                    return cb(null);

                });

            },

            // create the query
            function (cb) {

                req.linz.model.getQuery(req, filters, function (err, result) {

                    if (err) {
                        return cb(err);
                    }

                    query = result;

                    return cb(null);

                });

            },

            // get page total
            function (cb) {

                req.linz.model.getCount(req, filters, function (err, countQuery) {

                    if (err) {
                        return cb(err);
                    }

                    countQuery.exec(function (countQueryErr, count) {

                        // A query error has occured, let's short circuit this entire process
                        // and start again from the last known working state.
                        if (countQueryErr) {
                            return handleQueryError(countQueryErr);
                        }

                        if (!countQueryErr && count === 0) {
                            return cb(new Error('No records found'));
                        }

                        if (!countQueryErr) {
                            totalRecords = count;
                        }

                        return cb(countQueryErr);

                    });

                });

            },

            // minimise the fields we're selecting
            function (cb) {

                let fields = Object.keys(req.linz.model.list.fields);

                // Add the default fields we'll look for in the title virtual.
                if (req.linz.model.schema.tree.label) {
                    fields.push('label');
                }

                if (req.linz.model.schema.tree.name) {
                    fields.push('name');
                }

                const select = fields.join(' ');

                query.select(select);

                // If they've provided the `listQuery` static, use it to allow customisation of the fields we'll retrieve.
                if (!req.linz.model.listQuery) {
                    return cb();
                }

                req.linz.model.listQuery(query, cb);

            },

            // find the docs
            function (cb) {

                if (!session.list.formData.sort && req.linz.model.list.sortBy.length) {

                    req.linz.model.list.sortingBy = req.linz.model.list.sortBy[0];

                    // set default form sort
                    session.list.formData.sort = req.linz.model.list.sortingBy.field;

                } else {

                    req.linz.model.list.sortBy.forEach(function (sort) {
                        if (sort.field === session.list.formData.sort || '-' + sort.field === session.list.formData.sort) {
                            req.linz.model.list.sortingBy = sort;
                        }
                    });

                }

                query.sort(session.list.formData.sort);

                if (req.linz.model.list.paging.active === true) {
                    // add in paging skip and limit
                    query.skip(pageIndex*pageSize-pageSize).limit(pageSize);
                }

                query.exec(function (err, docs) {

                    // A query error has occured, let's short circuit this entire process
                    // and start again from the last known working state.
                    if (err) {
                        return handleQueryError(err);
                    }

                    if (!err && docs.length === 0) {

                        return cb(new Error('No records found'));

                    }

                    if (!err) {

                        mongooseRecords = docs;
                        // convert mongoose documents to plain javascript objects
                        mongooseRecords.forEach(function (record) {
                            records.push(record.toObject({ virtuals: true}));
                        });

                    }

                    cb(err);

                });

            },

            // check if each doc can be edited
            function (cb) {

                // skip this if canEdit is not define for model
                if (!mongooseRecords[0].canEdit) {
                    return cb(null);
                }

                async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                    mongooseRecords[index].canEdit(function (err, result, message) {

                        if (err) {
                            return recordDone(err);
                        }

                        records[index].edit = { disabled: !result, message: message };

                        return recordDone(null);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            // check if each doc can be deleted
            function (cb) {

                // skip this if canEdit is not define for model
                if (!mongooseRecords[0].canDelete) {
                    return cb(null);
                }

                async.each(Object.keys(mongooseRecords), function (index, recordDone) {

                    mongooseRecords[index].canDelete(function (err, result, message) {

                        if (err) {
                            return recordDone(err);
                        }

                        records[index].delete = { disabled: !result, message: message };

                        return recordDone(null);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            function (cb) {

                // Determine if there are any fields with refs
                for (let field in req.linz.model.list.fields) {

                    // Support multiple types ref fields.

                    if (req.linz.model.schema.tree[field] && req.linz.model.schema.tree[field].ref) {

                        // Get the records.
                        // Start by filtering records which have valid ObjectIds (support multiple types of reference fields).
                        // Then deduplicate them using a custom hashing function.
                        refColData[field] = {
                            records: dedupe(records.filter(record => !(!record[field]) && linz.api.model.getObjectIdFromRefField(record[field]) instanceof linz.mongoose.Types.ObjectId), record => linz.api.model.getObjectIdFromRefField(record[field]).toString())
                        };

                        // Now get the values.
                        refColData[field].values = refColData[field].records.map(record => linz.api.model.getObjectIdFromRefField(record[field]));

                    }

                }

                // Now we have the objectIds, asynchronously loop through them
                // and retrieve the actual values from the database.
                async.each(Object.keys(refColData), function (field, fieldDone) {

                    let args = [
                        refColData[field].values,
                        refColData[field].records,
                        field,
                        req.linz.model,
                        function (err, value) {

                            refColData[field].rendered = value;

                            return fieldDone(err);

                        }
                    ];

                    // Call the cell renderer and update the content with the result.
                    // val, record, fieldname, model, callback
                    linz.formtools.cellRenderers.reference.apply(null, args);

                }, function (err) {

                    if (err) {
                        return cb(err);
                    }

                    return cb();

                });

            },

            // create the values for the datalists for each doc
            function (cb) {

                // loop through each record
                async.each(Object.keys(records), function (index, recordDone) {

                    // store the rendered content into a separate property
                    records[index]['rendered'] = {};

                    // loop through each field
                    async.each(Object.keys(req.linz.model.list.fields), function (field, fieldDone) {

                        // Skip this field if we have a falsy value
                        if (!req.linz.model.list.fields[field]) {
                            return fieldDone();
                        }

                        // If we have a reference field, data has been pre-rendered.
                        // Let's grab it from there.
                        if (req.linz.model.schema.tree[field] && req.linz.model.schema.tree[field].ref) {

                            // The default value, but could be replaced below if the conditions are right.
                            records[index]['rendered'][field] = records[index][field];

                            // Do we have a rendered result for this field in this particular record?
                            // Support multiple types ref fields.
                            if (refColData[field].rendered && records[index][field] && refColData[field].rendered[linz.api.model.getObjectIdFromRefField(records[index][field]).toString()]) {

                                records[index]['rendered'][field] = refColData[field].rendered[linz.api.model.getObjectIdFromRefField(records[index][field]).toString()];

                            }

                            // We're all done here.
                            return fieldDone();

                        }

                        // This will only execute if we don't have a ref field.

                        let args = [];

                        // value is not applicable for virtual field
                        if (!req.linz.model.list.fields[field].virtual) {
                            args.push(records[index][field]);
                        }

                        args.push(mongooseRecords[index]);
                        args.push(field);
                        args.push(req.linz.model);
                        args.push(function (err, value) {

                            if (!err) {
                                records[index]['rendered'][field] = value;
                            }

                            return fieldDone(err);

                        });

                        // call the cell renderer and update the content with the result
                        // val, record, fieldname, model, callback
                        req.linz.model.list.fields[field].renderer.apply(this, args);

                    }, function (err) {

                        recordDone(err);

                    });

                }, function (err) {

                    cb(err);

                });

            },

            // check if we need to process each record again record actions
            function (cb) {

                if (!req.linz.model.list.recordActions.length) {
                    return cb(null);
                }

                async.each(req.linz.model.list.recordActions, function (action, actionDone) {

                    if (!action.disabled) {
                        return actionDone(null);
                    }

                    if (typeof action.disabled !== 'function') {
                        throw new Error('Invalid type for record.action.disabled. It must be a function');
                    }

                    async.each(Object.keys(records), function (index, recordDone) {

                        action.disabled(mongooseRecords[index], function (err, isDisabled, message) {

                            records[index].recordActions = records[index].recordActions || {};

                            records[index].recordActions[action.label] = {
                                disabled: isDisabled,
                                message: message
                            };

                            return recordDone(null);

                        });

                    }, function (err) {

                        return actionDone(err);

                    });

                }, function (err) {

                    return cb(err);

                });
            }

        ], function (err, result) {

            // map the update records to linz
            req.linz.records = {
                records: records,
                page: pageIndex,
                total: totalRecords,
                pages: Math.ceil(totalRecords/pageSize),
                pageSize: pageSize
            };

            req.linz.model.formData = session.list.formData;

            if (err && err.message === 'No records found') {
                err = null;
            }

            // next middleware
            next(err);

        });

    }; // end getModelIndex()

    return { getModelIndex };

}
<|endoftext|>


<commit_before>import _ from 'lodash';
import React from 'react';
import RaisedButton from 'material-ui/lib/raised-button';
import { connect } from 'react-redux';
import { getNetwork } from '../data/neuralNetworkActions';
import Dialog from 'material-ui/lib/dialog';
import {
  Table,
  TableBody,
  TableHeader,
  TableHeaderColumn,
  TableRow,
  TableRowColumn
} from 'material-ui/lib/Table';

class NetworkChooser extends React.Component {
  constructor(nextProps) {
    super(nextProps);
    this.state = {
      isOpen: false,
      selectedRowIndex: null
    };
    this._openModal = this._openModal.bind(this);
    this._closeModal = this._closeModal.bind(this);
    this._renderContent = this._renderContent.bind(this);
    this._onRowSelection = this._onRowSelection.bind(this);
    this._selectNetwork = this._selectNetwork.bind(this);
  }
  _openModal() {
    this.setState({ isOpen: true });
  }
  _closeModal() {
    this.setState({ isOpen: false });
  }
  _onRowSelection(vals) {
    this.setState({ selectedRowIndex: vals[0] });
  }
  _selectNetwork(index) {
    const path = this.props.networkSummaries[index].path;
    this.props.dispatch(getNetwork(path));
    this.setState({ isOpen: false });
  }
  _renderContent() {
    if (!this.props.networkSummaries) {
      return false;
    }
    const rows = this.props.networkSummaries.map((summary, index) => {

      const weight = summary.improvedWeightInit
        ? 'Gaussian(0,1) * 1/sqrt(n)'
        : 'Gaussian(0,1)';

      return (
        <TableRow key={summary.path} selected={this.state.selectedRowIndex === index}>
          <TableRowColumn>{summary.accuracy}</TableRowColumn>
          <TableRowColumn>{summary.hiddenNodes}</TableRowColumn>
          <TableRowColumn>{summary.eta}</TableRowColumn>
          <TableRowColumn>{summary.activation}</TableRowColumn>
          <TableRowColumn>{summary.cost}</TableRowColumn>
          <TableRowColumn style={{width: '140px'}}>{weight}</TableRowColumn>
        </TableRow>
      );
    });
    return (

        <TableHeader>
          <TableRow>
            <TableHeaderColumn>Accuracy</TableHeaderColumn>
            <TableHeaderColumn>Hidden Layers</TableHeaderColumn>
            <TableHeaderColumn>Learning Rate</TableHeaderColumn>
            <TableHeaderColumn>Activation</TableHeaderColumn>
            <TableHeaderColumn>Cost</TableHeaderColumn>
            <TableHeaderColumn style={{width: '140px'}}>Weight Init</TableHeaderColumn>
          </TableRow>
        </TableHeader>
        <TableBody deselectOnClickaway={false}>
          {rows}
        </TableBody>

    );
  }
  render() {
    const actions = [
      <RaisedButton
        label="Cancel"
        primary
        onClick={this._closeModal}
      />
    ];

    if (_.isNumber(this.state.selectedRowIndex)) {
      actions.push(
        <RaisedButton
          style={{ marginLeft: '10px' }}
          label="Select Network"
          secondary
          onClick={_.partial(this._selectNetwork, this.state.selectedRowIndex)}
        />
      );
    }

    return (

        <RaisedButton
          secondary
          label="Choose Network Design"
          onClick={this._openModal}
        />
        <Dialog
          title="Choose a model to visualize"
          actions={actions}
          modal={false}
          contentStyle={{width: '80%', maxWidth: 'none'}}
          titleStyle={{fontFamily: 'Raleway'}}
          open={this.state.isOpen}
        >
        {this._renderContent()}
        </Dialog>

    );
  }
}

function mapStateToProps(state) {
  return {
    networkSummaries: state.neuralNetwork.networkSummaries
  };
}

export default connect(mapStateToProps)(NetworkChooser);
<commit_msg>fixed typo in import<commit_after>import _ from 'lodash';
import React from 'react';
import RaisedButton from 'material-ui/lib/raised-button';
import { connect } from 'react-redux';
import { getNetwork } from '../data/neuralNetworkActions';
import Dialog from 'material-ui/lib/dialog';
import {
  Table,
  TableBody,
  TableHeader,
  TableHeaderColumn,
  TableRow,
  TableRowColumn
} from 'material-ui/lib/table';

class NetworkChooser extends React.Component {
  constructor(nextProps) {
    super(nextProps);
    this.state = {
      isOpen: false,
      selectedRowIndex: null
    };
    this._openModal = this._openModal.bind(this);
    this._closeModal = this._closeModal.bind(this);
    this._renderContent = this._renderContent.bind(this);
    this._onRowSelection = this._onRowSelection.bind(this);
    this._selectNetwork = this._selectNetwork.bind(this);
  }
  _openModal() {
    this.setState({ isOpen: true });
  }
  _closeModal() {
    this.setState({ isOpen: false });
  }
  _onRowSelection(vals) {
    this.setState({ selectedRowIndex: vals[0] });
  }
  _selectNetwork(index) {
    const path = this.props.networkSummaries[index].path;
    this.props.dispatch(getNetwork(path));
    this.setState({ isOpen: false });
  }
  _renderContent() {
    if (!this.props.networkSummaries) {
      return false;
    }
    const rows = this.props.networkSummaries.map((summary, index) => {

      const weight = summary.improvedWeightInit
        ? 'Gaussian(0,1) * 1/sqrt(n)'
        : 'Gaussian(0,1)';

      return (
        <TableRow key={summary.path} selected={this.state.selectedRowIndex === index}>
          <TableRowColumn>{summary.accuracy}</TableRowColumn>
          <TableRowColumn>{summary.hiddenNodes}</TableRowColumn>
          <TableRowColumn>{summary.eta}</TableRowColumn>
          <TableRowColumn>{summary.activation}</TableRowColumn>
          <TableRowColumn>{summary.cost}</TableRowColumn>
          <TableRowColumn style={{width: '140px'}}>{weight}</TableRowColumn>
        </TableRow>
      );
    });
    return (

        <TableHeader>
          <TableRow>
            <TableHeaderColumn>Accuracy</TableHeaderColumn>
            <TableHeaderColumn>Hidden Layers</TableHeaderColumn>
            <TableHeaderColumn>Learning Rate</TableHeaderColumn>
            <TableHeaderColumn>Activation</TableHeaderColumn>
            <TableHeaderColumn>Cost</TableHeaderColumn>
            <TableHeaderColumn style={{width: '140px'}}>Weight Init</TableHeaderColumn>
          </TableRow>
        </TableHeader>
        <TableBody deselectOnClickaway={false}>
          {rows}
        </TableBody>

    );
  }
  render() {
    const actions = [
      <RaisedButton
        label="Cancel"
        primary
        onClick={this._closeModal}
      />
    ];

    if (_.isNumber(this.state.selectedRowIndex)) {
      actions.push(
        <RaisedButton
          style={{ marginLeft: '10px' }}
          label="Select Network"
          secondary
          onClick={_.partial(this._selectNetwork, this.state.selectedRowIndex)}
        />
      );
    }

    return (

        <RaisedButton
          secondary
          label="Choose Network Design"
          onClick={this._openModal}
        />
        <Dialog
          title="Choose a model to visualize"
          actions={actions}
          modal={false}
          contentStyle={{width: '80%', maxWidth: 'none'}}
          titleStyle={{fontFamily: 'Raleway'}}
          open={this.state.isOpen}
        >
        {this._renderContent()}
        </Dialog>

    );
  }
}

function mapStateToProps(state) {
  return {
    networkSummaries: state.neuralNetwork.networkSummaries
  };
}

export default connect(mapStateToProps)(NetworkChooser);
<|endoftext|>