<commit_before>/* global config, reloadPaths */

(function(W) {
	'use strict';

	var chalk = require('chalk'),
		fs = require('fs-extra'),
		notifier = require('node-notifier'),
		path = require('path');

	W.fn.extend({
		/**
		 * Build root or relative path
		 *
		 * @param {string} loc
		 * @param {string} file
		 * @returns {string} path
		 */
		buildPath: function(loc, file) {
			return file.substring(0, 2) === './' ?
				file :
				path.join(loc, file);
		},

		/**
		 * Append minified extension
		 *
		 * @param {string} dest
		 * @param {string} src
		 * @param {string} ext
		 * @returns {string} path
		 */
		getMinExtension: function(dest, src, ext) {
			var dir = src.substring(0, src.lastIndexOf('/')),
				filename = src.substring(src.lastIndexOf('/'), src.length)
					.substring(0, filename.lastIndexOf('.'));

			return dest + '/' + dir + filename + ext;
		},

		/**
		 * Validate source file
		 *
		 * @param {string} root
		 * @param {object} config
		 * @param {string} file
		 */
		validate: function(root, config, file) {
			var ext = path.extname(file);

			if (['temp', '/vendor'].indexOf(file) < 0) {
				if (ext === '.js') {
					var validate = config.script.validate,
						src = fs.readFileSync(file, {
							encoding: 'utf-8'
						});

					if (validate.jshint) {
						this.validateJshint(
							path.join(root, validate.jshint),
							file,
							src
						);
					}

					if (validate.jscs) {
						this.validateJscs(
							path.join(root, validate.jscs),
							file,
							src
						);
					}
				}
			}
		},

		/**
		 * Validate JavaScript source file using JSHint
		 *
		 * @param {object} rules
		 * @param {string} file
		 * @param {string} src
		 */
		validateJshint: function(rules, file, src) {
			var jshint = require('jshint').JSHINT,
				config = fs.readJsonSync(rules);

			if (! jshint(src, config)) {
				var out = jshint.data(),
					errors = out.errors,
					total = errors.length;

				console.log(
					chalk.bgRed('JSHint error' +
						((total > 1) ? 's' : '') + ' in ' + file + '.')
				);

				errors.forEach(function(error) {
					if (error) {
						W.logError(
							error.line + ':' + error.character,
							error.reason,
							error.evidence
						);
					}
				});

				console.log('\n');

				this.notify({
					title: 'JSHint Validation Error',
					message: 'Check console for error details'
				}, 'error', false);
			}
		},

		/**
		 * Validate JavaScript source file using JSCS
		 *
		 * @param {object} rules
		 * @param {string} file
		 * @param {string} src
		 */
		validateJscs: function(rules, file, src) {
			var JSCS = require('jscs'),
				jscsConfig = fs.readJsonSync(rules),
				checker = new JSCS();

			checker.registerDefaultRules();
			checker.configure(jscsConfig);

			var errors = checker.checkString(src),
				errorList = errors.getErrorList(),
				total = errorList.length;

			if (total > 0) {
				console.log(
					chalk.bgRed('JSCS error' +
						((total > 1) ? 's' : '') + ' in ' + file + '.')
				);

				errorList.forEach(function(error) {
					if (error) {
						W.logError(
							error.line + ':' + error.column,
							error.rule,
							error.message
						);
					}
				});

				console.log('\n');

				this.notify({
					title: 'JSCS Validation Error',
					message: 'Check console for error details'
				}, 'error', false);
			}
		},

		/**
		 * Log an error to the console
		 *
		 * @param {number} position
		 * @param {string} message
		 * @param {string} [details]
		 */
		logError: function(position, message, details) {
			console.log(
				chalk.bgBlack.bold('[' + position + '] ') +
				message + ' ' + (details || '')
			);
		},

		/**
		 * Notify through a naitvely available notification option
		 *
		 * @param {object} options
		 * @param {string} [type=notice]
		 * @param {boolean} [log=true]
		 */
		notify: function(options, type, log) {
			options.icon = 'build/img/' + (type || 'notice') + '.png';
			options.group = 1;

			if (type == 'error') {
				options.group = 2;
				options.sound = true;
				options.wait = true;
			}

			if (log !== false) {
				console.log(options.message);
			}

			notifier.notify(options);
		},

		/**
		 * Push full server watch path
		 *
		 * @param {string} url
		 */
		serverWatch: function(url) {
			if (url.substring(0, 4) !== 'http') {
				reloadPaths.push(
					path.join(config.paths.root, url)
				);
			}
		}
	});
})(Wee);<commit_msg>Fix bug with compiling lib files causing lastIndexOf error<commit_after>/* global config, reloadPaths */

(function(W) {
	'use strict';

	var chalk = require('chalk'),
		fs = require('fs-extra'),
		notifier = require('node-notifier'),
		path = require('path');

	W.fn.extend({
		/**
		 * Build root or relative path
		 *
		 * @param {string} loc
		 * @param {string} file
		 * @returns {string} path
		 */
		buildPath: function(loc, file) {
			return file.substring(0, 2) === './' ?
				file :
				path.join(loc, file);
		},

		/**
		 * Append minified extension
		 *
		 * @param {string} dest
		 * @param {string} src
		 * @param {string} ext
		 * @returns {string} path
		 */
		getMinExtension: function(dest, src, ext) {
			var dir = src.substring(0, src.lastIndexOf('/')),
				filename = src.substring(src.lastIndexOf('/'), src.length);
			filename = filename.substring(0, filename.lastIndexOf('.'));

			return dest + '/' + dir + filename + ext;
		},

		/**
		 * Validate source file
		 *
		 * @param {string} root
		 * @param {object} config
		 * @param {string} file
		 */
		validate: function(root, config, file) {
			var ext = path.extname(file);

			if (['temp', '/vendor'].indexOf(file) < 0) {
				if (ext === '.js') {
					var validate = config.script.validate,
						src = fs.readFileSync(file, {
							encoding: 'utf-8'
						});

					if (validate.jshint) {
						this.validateJshint(
							path.join(root, validate.jshint),
							file,
							src
						);
					}

					if (validate.jscs) {
						this.validateJscs(
							path.join(root, validate.jscs),
							file,
							src
						);
					}
				}
			}
		},

		/**
		 * Validate JavaScript source file using JSHint
		 *
		 * @param {object} rules
		 * @param {string} file
		 * @param {string} src
		 */
		validateJshint: function(rules, file, src) {
			var jshint = require('jshint').JSHINT,
				config = fs.readJsonSync(rules);

			if (! jshint(src, config)) {
				var out = jshint.data(),
					errors = out.errors,
					total = errors.length;

				console.log(
					chalk.bgRed('JSHint error' +
						((total > 1) ? 's' : '') + ' in ' + file + '.')
				);

				errors.forEach(function(error) {
					if (error) {
						W.logError(
							error.line + ':' + error.character,
							error.reason,
							error.evidence
						);
					}
				});

				console.log('\n');

				this.notify({
					title: 'JSHint Validation Error',
					message: 'Check console for error details'
				}, 'error', false);
			}
		},

		/**
		 * Validate JavaScript source file using JSCS
		 *
		 * @param {object} rules
		 * @param {string} file
		 * @param {string} src
		 */
		validateJscs: function(rules, file, src) {
			var JSCS = require('jscs'),
				jscsConfig = fs.readJsonSync(rules),
				checker = new JSCS();

			checker.registerDefaultRules();
			checker.configure(jscsConfig);

			var errors = checker.checkString(src),
				errorList = errors.getErrorList(),
				total = errorList.length;

			if (total > 0) {
				console.log(
					chalk.bgRed('JSCS error' +
						((total > 1) ? 's' : '') + ' in ' + file + '.')
				);

				errorList.forEach(function(error) {
					if (error) {
						W.logError(
							error.line + ':' + error.column,
							error.rule,
							error.message
						);
					}
				});

				console.log('\n');

				this.notify({
					title: 'JSCS Validation Error',
					message: 'Check console for error details'
				}, 'error', false);
			}
		},

		/**
		 * Log an error to the console
		 *
		 * @param {number} position
		 * @param {string} message
		 * @param {string} [details]
		 */
		logError: function(position, message, details) {
			console.log(
				chalk.bgBlack.bold('[' + position + '] ') +
				message + ' ' + (details || '')
			);
		},

		/**
		 * Notify through a naitvely available notification option
		 *
		 * @param {object} options
		 * @param {string} [type=notice]
		 * @param {boolean} [log=true]
		 */
		notify: function(options, type, log) {
			options.icon = 'build/img/' + (type || 'notice') + '.png';
			options.group = 1;

			if (type == 'error') {
				options.group = 2;
				options.sound = true;
				options.wait = true;
			}

			if (log !== false) {
				console.log(options.message);
			}

			notifier.notify(options);
		},

		/**
		 * Push full server watch path
		 *
		 * @param {string} url
		 */
		serverWatch: function(url) {
			if (url.substring(0, 4) !== 'http') {
				reloadPaths.push(
					path.join(config.paths.root, url)
				);
			}
		}
	});
})(Wee);<|endoftext|>


<commit_before>'use strict'

var ObjectId = require("mongodb").ObjectId;

require("mongodb-toolkit");

var DLModels = require('dl-models');
var map = DLModels.map;
var Instruction = DLModels.master.Instruction;
var BaseManager = require('module-toolkit').BaseManager;
var i18n = require('dl-i18n');

module.exports = class InstructionManager extends BaseManager {

    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Instruction);
    }

    _getQuery(paging) {
        var _default = {
                _deleted: false
            },
            pagingFilter = paging.filter || {},
            keywordFilter = {},
            query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var materialFilter = {
                "material": {
                    "$regex": regex
                }
            };
            var constructionFilter = {
                "construction": {
                    "$regex": regex
                }
            };
            var processTypeFilter = {
                "processType": {
                    "$regex": regex
                }
            };
            keywordFilter["$or"] = [materialFilter, constructionFilter, proccessTypeFilter];
        }
        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _validate(instruction) {
        var errors = {};
        var valid = instruction;
        // 1. begin: Declare promises.
        var getInstructionPromise = this.collection.singleOrDefault({
            _id: {
                '$ne'   : new ObjectId(valid._id)
            },
            material    :valid.material,
            construction:valid.construction,
            processType :valid.processType
        });

        // 2. begin: Validation.
        return Promise.all([getInstructionPromise])
            .then(results => {
                var _instruction = results[0];

                if (_instruction) {
                    errors["material"] = i18n.__("Instruction.material.isExists:%s is exists", i18n.__("Instruction.material._:Material"));
                    errors["construction"] = i18n.__("Instruction.construction.isExists:%s is exists", i18n.__("Instruction.construction._:Construction"));
                    errors["processType"] = i18n.__("Instruction.processType.isExists:%s is exists", i18n.__("Instruction.processType._:ProcessType"));
                }
                else {
                    if (!valid.material || valid.material == "")
                        errors["material"] = i18n.__("Instruction.material.isRequired:%s is required", i18n.__("Instruction.material._:Material")); //"Material Tidak Boleh Kosong";

                    if (!valid.construction || valid.construction == "")
                        errors["construction"] = i18n.__("Instruction.construction.isRequired:%s is required", i18n.__("Instruction.construction._:Construction")); //"construction Tidak Boleh Kosong";

                    if (!valid.processType || valid.processType == "")
                        errors["processType"] = i18n.__("Instruction.processType.isRequired:%s is required", i18n.__("Instruction.processType._:ProcessType")); //"processType Tidak Boleh Kosong";

                    if (!valid.steps || valid.steps.length<=0)
                        errors["steps"] = i18n.__("Instruction.steps.isRequired:%s is required", i18n.__("Instruction.steps._:Steps")); //"steps Tidak Boleh Kosong";
                }
                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require("module-toolkit").ValidationError;
                    return Promise.reject(new ValidationError("data does not pass validation", errors));
                }

                valid = new Instruction(valid);
                valid.stamp(this.user.username, "manager");
                return Promise.resolve(valid);
            });
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${map.master.collection.Instruction}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        };

        var nameIndex = {
            name: `ix_${map.master.collection.Instruction}_material_construction_processType`,
            key: {
                material: 1,
                construction: 1,
                processType: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, nameIndex]);
    }
}

<commit_msg>fixing instruction filter<commit_after>'use strict'

var ObjectId = require("mongodb").ObjectId;

require("mongodb-toolkit");

var DLModels = require('dl-models');
var map = DLModels.map;
var Instruction = DLModels.master.Instruction;
var BaseManager = require('module-toolkit').BaseManager;
var i18n = require('dl-i18n');

module.exports = class InstructionManager extends BaseManager {

    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Instruction);
    }

    _getQuery(paging) {
        var _default = {
                _deleted: false
            },
            pagingFilter = paging.filter || {},
            keywordFilter = {},
            query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var materialFilter = {
                "material": {
                    "$regex": regex
                }
            };
            var constructionFilter = {
                "construction": {
                    "$regex": regex
                }
            };
            var processTypeFilter = {
                "processType": {
                    "$regex": regex
                }
            };
            keywordFilter["$or"] = [materialFilter, constructionFilter, processTypeFilter];
        }
        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _validate(instruction) {
        var errors = {};
        var valid = instruction;
        // 1. begin: Declare promises.
        var getInstructionPromise = this.collection.singleOrDefault({
            _id: {
                '$ne'   : new ObjectId(valid._id)
            },
            material    :valid.material,
            construction:valid.construction,
            processType :valid.processType
        });

        // 2. begin: Validation.
        return Promise.all([getInstructionPromise])
            .then(results => {
                var _instruction = results[0];

                if (_instruction) {
                    errors["material"] = i18n.__("Instruction.material.isExists:%s is exists", i18n.__("Instruction.material._:Material"));
                    errors["construction"] = i18n.__("Instruction.construction.isExists:%s is exists", i18n.__("Instruction.construction._:Construction"));
                    errors["processType"] = i18n.__("Instruction.processType.isExists:%s is exists", i18n.__("Instruction.processType._:ProcessType"));
                }
                else {
                    if (!valid.material || valid.material == "")
                        errors["material"] = i18n.__("Instruction.material.isRequired:%s is required", i18n.__("Instruction.material._:Material")); //"Material Tidak Boleh Kosong";

                    if (!valid.construction || valid.construction == "")
                        errors["construction"] = i18n.__("Instruction.construction.isRequired:%s is required", i18n.__("Instruction.construction._:Construction")); //"construction Tidak Boleh Kosong";

                    if (!valid.processType || valid.processType == "")
                        errors["processType"] = i18n.__("Instruction.processType.isRequired:%s is required", i18n.__("Instruction.processType._:ProcessType")); //"processType Tidak Boleh Kosong";

                    if (!valid.steps || valid.steps.length<=0)
                        errors["steps"] = i18n.__("Instruction.steps.isRequired:%s is required", i18n.__("Instruction.steps._:Steps")); //"steps Tidak Boleh Kosong";
                }
                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require("module-toolkit").ValidationError;
                    return Promise.reject(new ValidationError("data does not pass validation", errors));
                }

                valid = new Instruction(valid);
                valid.stamp(this.user.username, "manager");
                return Promise.resolve(valid);
            });
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${map.master.collection.Instruction}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        };

        var nameIndex = {
            name: `ix_${map.master.collection.Instruction}_material_construction_processType`,
            key: {
                material: 1,
                construction: 1,
                processType: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, nameIndex]);
    }
}

<|endoftext|>


<commit_before>/* Copyright 2007 by Oliver Steele.  All rights reserved. */

/*
 * Timing
 */

Function.prototype.delay = function(ms) {
    setTimeout(this, ms || 10);
}

Function.prototype.defer = Function.prototype.delay;

Function.delay = Function.defer = function(fn, ms) {
    return fn.delay(ms);
}

/*
 * Throttling
 */

Function.prototype.throttled = function(ms, options) {
    ms = ms || 10;
    options = options || {};
    var fn = this,
        lastTime = null;
    return function() {
        var self = this,
            args = [].slice.call(arguments, 0);
        run();
        function run() {
            var wait = ms - (new Date() - lastTime);
            // false for wait==NaN
            if (wait > 0)
                return run.defer(wait);
            lastTime = new Date();
            if (options.backoff)
                ms *= 2;
            fn.apply(self, args);
            if (options.fromEnd)
                lastTime = new Date();
        }
    }
}

Function.throttled = function(fn, ms, options) {
    return fn.throttled(ms, options);
}

Function.maxtimes = function(count, fn) {
    return function() {
        if (--count < 0)
            return;
        fn.apply(this, arguments);
    }
}
<commit_msg>variable-rate backoff; add after callback to maxtimes<commit_after>/* Copyright 2007 by Oliver Steele.  All rights reserved. */

/*
 * Timing
 */

Function.prototype.delay = function(ms) {
    setTimeout(this, ms || 10);
}

Function.prototype.defer = Function.prototype.delay;

Function.delay = Function.defer = function(fn, ms) {
    return fn.delay(ms);
}

/*
 * Throttling
 */

Function.prototype.throttled = function(interval, options) {
    interval = interval || 10;
    options = options || {};
    var fn = this,
        lastTime = null,
        backoffRatio = options.backoff == true ? 2 : options.backoff;
    return function() {
        var self = this,
            args = [].slice.call(arguments, 0);
        run.defer();
        function run() {
            var now = new Date,
                wait = interval - (now - lastTime);
            // false for wait==NaN
            if (wait > 0)
                return run.defer(wait);
            if (backoffRatio)
                interval = Math.ceil(interval * backoffRatio);
            lastTime = now;
            fn.apply(self, args);
            if (options.fromEnd)
                lastTime = new Date();
        }
    }
}

Function.throttled = function(fn, interval, options) {
    return fn.throttled(interval, options);
}

Function.maxtimes = function(count, fn, after) {
    return function() {
        if (--count < 0) {
            fn = after;
            after = undefined;
        }
        return fn && fn.apply(this, arguments);
    }
}
<|endoftext|>


<commit_before>// View model for the courses page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("CourseTitle2");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CourseTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);

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

    /*Teacher*/
    gvm.availableTeacher = ko.observableArray([]);
    gvm.currentteacherid = null;
    /*teacher*/

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

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

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

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

        // Attach delete handler to delete button
        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        // Attach edit handler to edit button
        $('#editbtn-' + id).bind('click', function(event, data){
            // Edit the table item
            showEditProjectTypeModal(code, name, desc, id);
            event.stopPropagation();
        });

        //Attach manage handler to manage competences, subcompetences and indicators to manage button
        $('#managebtn-' + id).bind('click', function(event, data) {
            //TODO
        });

        /*$('#studentbtn-' + id).bind('click', function(event, data) {
            showCoupleStudentListModal(id);
            gvm.currentprojectid = id;
            gvm.currentselectedlist = -1;
            event.stopPropagation();
            loadCoupleDropdown();
        });*/
    }

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

    gvm.updateDropdowns = function() {
        $.getJSON('api/teacherrapport/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-teacher span:first").text(item.teacher);
                    gvm.currentteacherid = item.id;
                    gvm.updateTeacher(item.id);
                    LoadTablePage(item.currentteacherid, 1);
                });
            } else {
                gvm.updateTeacher();
            }
        });
    }

    gvm.updateTeacher = function(id) {
    $.getJSON('/api/getteacherrapport/' + id, function(data) {
        gvm.availableTeacher.removeAll();
        $.each(data, function(i, item) {
            console.log(item);
            gvm.availableTeacher.push(item);
            /* Add listener to listitem */
            $("#teacherbtn-" + item.id).click(function(){
                $(".btn-teacher span:first").text($(this).text());
                gvm.currentteacherid = item.id;
                gvm.saveLastSelectedDropdowns();
                loadTablePage(item.id, 1);
            });
        });
    });
    }
    }
/*
 * Delete item from table given the id.
 */
function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });
}

/*
 * Add a new projecttype
 */
function addNewProjecttypeForm(serialData, callback) {
    $.ajax({
            url: "/api/courserapport",
            type: "POST",
            data: serialData,
            success: function(data) {
                viewModel.addTableData(data['id'], data['code'], data['name'], data['description']);
                callback(true);
            },
            error: function(data) {
                callback(false);
            }
        });
}

/*
 * Add a new projecttype
 */
function addNewProjecttypeRaw(code, name, description, callback) {
    addNewProjecttypeForm("code=" + encodeURIComponent(code) + "&name=" + encodeURIComponent(name) + "&description=" + encodeURIComponent(description), callback);
}

/*
 * Update the projecttype
 * @param {type} id
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} callback
 * @returns {undefined}
 */
function updateProjecttypeForm(id, serialData, callback) {
    $.ajax({
        url: "/api/courseupdate/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            //viewModel.addTableData(data['id'], data['code'], data['name'], data['description']);
            loadTablePage(1); //TODO now it is refreshing table after updating but it redirects to pagenr 1     WERKT NIET
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

/**
 * update project type
 * @param {type} id
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} callback
 * @returns {undefined}
 */
function updateProjecttypeRaw(id, code, name, description, callback) {
    updateProjecttypeForm(id, "code=" + encodeURIComponent(code) + "&name=" + encodeURIComponent(name) + "&description=" + encodeURIComponent(description), callback);
}

/*
 * Load page of the table
 */
function loadTablePage(pagenr)
{
    $.getJSON('/api/coursesrapport/page/' + pagenr, function(data){

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

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

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

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

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

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

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

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

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

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

}

/**
 * Show a new projecttype modal.
 * @returns {undefined}
 */
function showNewProjectTypeModal()
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewCourse"));
    setGeneralModalBody('<form id="newprojectform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('CodeTableTitle') + '" " name="code"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" name="name"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('DescTableTitle') + '" name="description"> \

 \

' +
                '<button class="btn btn-wide btn-default btn-teacher dropdown-toggle" type="button" id="availableTeacher" data-toggle="dropdown" aria-expanded="true" placeholder="' + i18n.__('TeacherTableTitle') + '">' +
                    'Teacher' + '' +
                '</button>' +
                '
' +
                    '

' +
                '
' +
            '
' +
            '</form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
        console.log($('#newprojectform').serialize());
       addNewProjecttypeForm($('#newprojectform').serialize(), function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

/**
 * Show the edit projecttype modal.
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} tid
 * @returns {undefined}
 */
function showEditProjectTypeModal(code, name, description, tid)
{
  resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditProjectTitle2"));
    setGeneralModalBody('<form id="updateprojectform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('CodeTableTitle') + '" " name="code" value="' + code + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" name="name" value="' + name + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('DescTableTitle') + '" name="description" value="' + description + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateProjecttypeForm(tid, $('#updateprojectform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function showCoupleStudentListModal(projectid) {
    viewModel.currentselectedlist = -1;
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("CoupleStudentList"));
    setGeneralModalBody(
        '
' +
            '<button class="btn btn-default dropdown-toggle" type="button" id="dropdownStudLists" data-toggle="dropdown" aria-expanded="true">' +
                'Dropdown' +
                '' +
            '</button>' +
            '
' +
            '
' +
        '
');

    addGeneralModalButton(i18n.__("SaveBtn"), function() {
        updateListForm(viewModel.currentselectedlist, $('#coupleform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })
    showGeneralModal();
}
function loadCoupleDropdown() {
    $.getJSON('/api/studentlists/' + viewModel.userId, function(data) {
        $.each(data, function(i, item) {
            $("#ddlLists").append('
' + item.name + '
')
            $("#dropdownitem-" + item.id).click(function(){
                $(this).parent().parent().parent().removeClass("open");
                $(this).parent().parent().parent().find(".btn").html($(this).text() + '');
                viewModel.currentselectedlist = item.id;
            });
        });
    });
    $("#dropdownStudLists").click(function() {
        $(this).parent().toggleClass("open");
    });
}

function updateListForm(id, serialData, callback) {
    $.ajax({
        url: "/api/project/" + viewModel.currentprojectid + "/studentlist/" + id,
        type: "POST",
        data: serialData,
        success: function(data) {
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function initPage() {
    // Add button handlers
    $('#addProjectTypeBtn').click(function(){
        showNewProjectTypeModal();
    });

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

    loadTablePage(1);
}
<commit_msg>save/get project score<commit_after>// View model for the courses page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("CourseTitle2");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CourseTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);

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

    /*Teacher*/
    gvm.availableTeacher = ko.observableArray([]);
    gvm.currentteacherid = null;
    /*teacher*/

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

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

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

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

        // Attach delete handler to delete button
        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        // Attach edit handler to edit button
        $('#editbtn-' + id).bind('click', function(event, data){
            // Edit the table item
            showEditProjectTypeModal(code, name, desc, id);
            event.stopPropagation();
        });

        //Attach manage handler to manage competences, subcompetences and indicators to manage button
        $('#managebtn-' + id).bind('click', function(event, data) {
            //TODO
        });

        /*$('#studentbtn-' + id).bind('click', function(event, data) {
            showCoupleStudentListModal(id);
            gvm.currentprojectid = id;
            gvm.currentselectedlist = -1;
            event.stopPropagation();
            loadCoupleDropdown();
        });*/
    }

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

    gvm.updateDropdowns = function() {
        $.getJSON('api/teacherrapport/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-teacher span:first").text(item.teacher);
                    gvm.currentteacherid = item.id;
                    gvm.updateTeacher(item.id);
                    LoadTablePage(item.currentteacherid, 1);
                });
            } else {
                gvm.updateTeacher();
            }
        });
    }

    gvm.updateTeacher = function(id) {
    $.getJSON('/api/getteacherrapport/' + id, function(data) {
        gvm.availableTeacher.removeAll();
        $.each(data, function(i, item) {
            console.log(item);
            gvm.availableTeacher.push(item);
            /* Add listener to listitem */
            $("#teacherbtn-" + item.id).click(function(){
                $(".btn-teacher span:first").text($(this).text());
                gvm.currentteacherid = item.id;
                gvm.saveLastSelectedDropdowns();
                loadTablePage(item.id, 1);
            });
        });
    });
    }
    }
/*
 * Delete item from table given the id.
 */
function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });
}

/*
 * Add a new projecttype
 */
function addNewProjecttypeForm(serialData, callback) {
    $.ajax({
            url: "/api/courserapport",
            type: "POST",
            data: serialData,
            success: function(data) {
                viewModel.addTableData(data['id'], data['code'], data['name'], data['description']);
                callback(true);
            },
            error: function(data) {
                callback(false);
            }
        });
}

/*
 * Add a new projecttype
 */
function addNewProjecttypeRaw(code, name, description, callback) {
    addNewProjecttypeForm("code=" + encodeURIComponent(code) + "&name=" + encodeURIComponent(name) + "&description=" + encodeURIComponent(description), callback);
}

/*
 * Update the projecttype
 * @param {type} id
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} callback
 * @returns {undefined}
 */
function updateProjecttypeForm(id, serialData, callback) {
    $.ajax({
        url: "/api/courseupdate/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            //viewModel.addTableData(data['id'], data['code'], data['name'], data['description']);
            loadTablePage(1); //TODO now it is refreshing table after updating but it redirects to pagenr 1     WERKT NIET
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

/**
 * update project type
 * @param {type} id
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} callback
 * @returns {undefined}
 */
function updateProjecttypeRaw(id, code, name, description, callback) {
    updateProjecttypeForm(id, "code=" + encodeURIComponent(code) + "&name=" + encodeURIComponent(name) + "&description=" + encodeURIComponent(description), callback);
}

/*
 * Load page of the table
 */
function loadTablePage(pagenr)
{
    $.getJSON('/api/coursesrapport/page/' + pagenr, function(data){

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

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

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

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

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

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

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

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

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

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

}

/**
 * Show a new projecttype modal.
 * @returns {undefined}
 */
function showNewProjectTypeModal()
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewCourse"));
    setGeneralModalBody('<form id="newprojectform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('CodeTableTitle') + '" " name="code"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" name="name"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('DescTableTitle') + '" name="description"> \

 \

' +
                '<button class="btn btn-wide btn-default btn-teacher dropdown-toggle" type="button" id="availableTeacher" data-toggle="dropdown" aria-expanded="true" placeholder="' + i18n.__('TeacherTableTitle') + '">' +
                    'Teacher' + '' +
                '</button>' +
                '
' +
                    '

' +
                '
' +
            '
' +
            '</form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
        console.log($('#newprojectform').serialize());
       addNewProjecttypeForm($('#newprojectform').serialize(), function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

/**
 * Show the edit projecttype modal.
 * @param {type} code
 * @param {type} name
 * @param {type} description
 * @param {type} tid
 * @returns {undefined}
 */
function showEditProjectTypeModal(code, name, description, tid)
{
  resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditProjectTitle2"));
    setGeneralModalBody('<form id="updateprojectform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('CodeTableTitle') + '" " name="code" value="' + code + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" name="name" value="' + name + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('DescTableTitle') + '" name="description" value="' + description + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateProjecttypeForm(tid, $('#updateprojectform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function showCoupleStudentListModal(projectid) {
    viewModel.currentselectedlist = -1;
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("CoupleStudentList"));
    setGeneralModalBody(
        '
' +
            '<button class="btn btn-default dropdown-toggle" type="button" id="dropdownStudLists" data-toggle="dropdown" aria-expanded="true">' +
                'Dropdown' +
                '' +
            '</button>' +
            '
' +
            '
' +
        '
');

    addGeneralModalButton(i18n.__("SaveBtn"), function() {
        updateListForm(viewModel.currentselectedlist, $('#coupleform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })
    showGeneralModal();
}
function loadCoupleDropdown() {
    $.getJSON('/api/studentlists/' + viewModel.userId, function(data) {
        $.each(data, function(i, item) {
            $("#ddlLists").append('
' + item.name + '
')
            $("#dropdownitem-" + item.id).click(function(){
                $(this).parent().parent().parent().removeClass("open");
                $(this).parent().parent().parent().find(".btn").html($(this).text() + '');
                viewModel.currentselectedlist = item.id;
            });
        });
    });
    $("#dropdownStudLists").click(function() {
        $(this).parent().toggleClass("open");
    });
}

function updateListForm(id, serialData, callback) {
    $.ajax({
        url: "/api/project/" + viewModel.currentprojectid + "/studentlist/" + id,
        type: "POST",
        data: serialData,
        success: function(data) {
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function initPage() {
    // Add button handlers
    $('#addProjectTypeBtn').click(function(){
        showNewProjectTypeModal();
    });

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

    loadTablePage(1);
}
<|endoftext|>


<commit_before>StandaloneDashboard(function (tdb) {
	tdb.setTabbedDashboardTitle("Tabbed Dashboard");

	var db1 = new Dashboard('db1');
	db1.setDashboardTitle('Dashboard 1');
	var kpi1 = new KPIComponent();
    kpi1.setDimensions(3,2);
    kpi1.setCaption('KPI normal test');
    kpi1.setValue(244);
    db1.addComponent(kpi1);

	var db2 = new Dashboard('db2');
	db2.setDashboardTitle('Dashboard 2');
	var chart = new ChartComponent('someid');
	chart.setDimensions (4, 4);
	chart.setCaption("Expenses incurred on Food Consumption by Year");
	chart.setLabels (["2009", "2010", "2011"])
	chart.addSeries ("beverages", "Beverages", [1355, 1916, 1150]);
	chart.addSeries ("packaged_foods", "Packaged Foods", [1513, 976, 1321]);
	db2.addComponent (chart);

	var db3 = new Dashboard('db3');
	db3.setDashboardTitle('Dashboard 3');
	var chart = new ChartComponent();
	chart.setDimensions (4, 4);
	chart.setCaption("2011 Sales");
	chart.setLabels (["Beverages", "Vegetables"])
	chart.addSeries ("sales", "Sales", [1343, 7741]);
	chart.addSeries ("quantity", "Quantity", [76, 119]);
	db3.addComponent (chart);

	var db4 = new Dashboard('db4');
	db4.setDashboardTitle('Dashboard 4');
	var table = new TableComponent ('test');
	table.setCaption ("Regional Sales");
	table.setDimensions(4, 4);
	table.addColumn ('zone', "Zone");
	table.addColumn ('name', "Store Name");
	table.addColumn ('sale', "Sales amount");
	var data = [
		{zone: "North", name: "Northern Stores", sale: 4000},
		{zone: "South", name: "Southern Stores", sale: 4500},
	];
	table.addMultipleRows (data);
	db4.addComponent(table);

	tdb.addDashboardTab(db1);
	tdb.addDashboardTab(db2);
	tdb.addDashboardTab(db3);
	tdb.addDashboardTab(db4);

}, {tabbed: true});
<commit_msg>updated tabbed dashboard example<commit_after>StandaloneDashboard(function (tdb) {
	tdb.setTabbedDashboardTitle("Tabbed Dashboard");

	var db1 = new Dashboard('db1');
	db1.setDashboardTitle('Dashboard 1');
	var kpi1 = new KPIComponent();
    kpi1.setDimensions(3,2);
    kpi1.setCaption('KPI normal test');
    kpi1.setValue(244);
    db1.addComponent(kpi1);

	var db2 = new Dashboard('db2');
	db2.setDashboardTitle('Dashboard 2');
	var chart = new ChartComponent('someid');
	chart.setDimensions (4, 4);
	chart.setCaption("Expenses incurred on Food Consumption by Year");
	chart.setLabels (["2009", "2010", "2011"])
	chart.addSeries ("beverages", "Beverages", [1355, 1916, 1150]);
	chart.addSeries ("packaged_foods", "Packaged Foods", [1513, 976, 1321]);
	db2.addComponent (chart);

	var db3 = new Dashboard('db3');
	db3.setDashboardTitle('Dashboard 3');
	var chart = new ChartComponent();
	chart.setDimensions (4, 4);
	chart.setCaption("2011 Sales");
	chart.setLabels (["Beverages", "Vegetables"])
	chart.addSeries ("sales", "Sales", [1343, 7741]);
	chart.addSeries ("quantity", "Quantity", [76, 119]);
	db3.addComponent (chart);

	var db4 = new Dashboard('db4');
	db4.setDashboardTitle('Dashboard 4');
	var table = new TableComponent ('test');
	table.setCaption ("Regional Sales");
	table.setDimensions(4, 4);
	table.addColumn ('zone', "Zone");
	table.addColumn ('name', "Store Name");
	table.addColumn ('sale', "Sales amount");
	var data = [
		{zone: "North", name: "Northern Stores", sale: 4000},
		{zone: "South", name: "Southern Stores", sale: 4500},
	];
	table.addMultipleRows (data);
	db4.addComponent(table);

	tdb.addDashboardTab(db1);
	tdb.addDashboardTab(db2);
	tdb.addDashboardTab(db3);
	tdb.addDashboardTab(db4, {'active':true});

}, {tabbed: true});
<|endoftext|>


<commit_before>/**
 * Created by utking on 10/19/16.
 * Uses features: Array.isArray
 */

(function () {
    var lib = {};

    lib.filterHaving = function (items, fields) {
        var _fieldsArray = [];
        var result = [];
        if (Array.isArray(fields)) {
            for (var f in fields) {
                _fieldsArray.push(fields[f]);
            }
        } else {
            for (var f in fields) {
                _fieldsArray.push(f);
            }
        }
        if (Array.isArray(items)) {
            var _hit;
            result = items.filter(function (i) {
                _hit = false;
                _fieldsArray.forEach(function (f) {
                    if (!_hit && i[f]) {
                        _hit = true;
                    }
                });
                return _hit;
            });
        }
        return result;
    };

    return lib;

})();<commit_msg>feat: Added new features<commit_after>/**
 * Created by utking on 10/19/16.
 * Uses features: Array.isArray, filter, forEach
 */

(function () {

    /**
     * Convert the argument into a plain array of simple strings
     * @param fields
     * @returns {Array}
     * @private
     */
    var _clearFields = function (fields) {
        var _fieldsArray = [];
        var f;
        if (!!fields) {
            if (fields.charAt) {
                // a simple string
                _fieldsArray.push(fields);
            } else if (Array.isArray(fields)) {
                // an array
                for (f in fields) {
                    if (fields.hasOwnProperty(f)) {
                        _fieldsArray.push(fields[f]);
                    }
                }
            } else {
                // other type (object, function, number, etc)
                for (f in fields) {
                    if (fields.hasOwnProperty(f)) {
                        _fieldsArray.push(f);
                    }
                }
            }
        }
        return _fieldsArray;
    };

    /**
     * Return only items having particular properties
     * @param items - array of objects
     * @param fields - array/object defining properties to filter by
     * @returns {Array}
     * @private
     */
    var _filterHaving = function (items, fields) {
        var result = [];
        var _fieldsArray = _clearFields(fields);
        if (Array.isArray(items)) {
            var _hit;
            result = items.filter(function (i) {
                _hit = false;
                _fieldsArray.forEach(function (f) {
                    if (!_hit && i[f]) {
                        _hit = true;
                    }
                });
                return _hit;
            });
        }
        return result;
    };

    /**
     * Return an array that contains only the specified properties
     * @param items - array of objects
     * @param fields - desired properties
     * @returns {Array}
     * @private
     */
    var _extract = function (items, fields) {
        var _fieldsArray = _clearFields(fields);
        return _filterHaving(items, _fieldsArray)
            .map(function (i) {
                var item = {};
                _fieldsArray.forEach(function (f) {
                    item[f] = i[f];
                });
                return item;
            });
    };

    /**
     * Return a plain array collected by the field property
     * @param items - array of objects
     * @param field - simple string
     * @returns {Array}
     * @private
     */
    var _plain = function (items, field) {
        var _result = [];
        if (field.charAt && Array.isArray(items)) {
            items.forEach(function (i) {
                _result.push(i[field]);
            });
        }
        return _result;
    };

    /**
     * Add property/properties specified in the fields argument
     * @param items - array of objects
     * @param fields - an object
     * @returns {Array}
     * @private
     */
    var _addProperty = function (items, fields) {
        return items.map(function (i) {
            for (var f in fields) {
                if (fields.hasOwnProperty(f)) {
                    i[f] = fields[f];
                }
            }
            return i;
        });
    };

    /**
     * Public interface
     */
    return {
        filterHaving: _filterHaving,
        extract: _extract,
        plain: _plain,
        addProperty: _addProperty
    };

})();<|endoftext|>


<commit_before>'use strict';

const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const ManifestPlugin = require('webpack-manifest-plugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');

// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
const publicPath = '/';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);

// List of all component names for generating the corresponding html pages.
const components = ['button'];

// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
module.exports = {
  // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
  // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.
  devtool: 'cheap-module-source-map',
  // These are the "entry points" to our application.
  // This means they will be the "root" imports that are included in JS bundle.
  // The first two entry points enable "hot" CSS and auto-refreshes for JS.
  entry: [
    // We ship a few polyfills by default:
    require.resolve('./polyfills'),
    // Include an alternative client for WebpackDevServer. A client's job is to
    // connect to WebpackDevServer by a socket and get notified about changes.
    // When you save a file, the client will either apply hot updates (in case
    // of CSS changes), or refresh the page (in case of JS changes). When you
    // make a syntax error, this client will display a syntax error overlay.
    // Note: instead of the default WebpackDevServer client, we use a custom one
    // to bring better experience for Create React App users. You can replace
    // the line below with these two lines if you prefer the stock client:
    // require.resolve('webpack-dev-server/client') + '?/',
    // require.resolve('webpack/hot/dev-server'),
    require.resolve('react-dev-utils/webpackHotDevClient'),
    // Finally, this is your app's code:
    paths.appIndexJs,
    // We include the app code last so that if there is a runtime error during
    // initialization, it doesn't blow up the WebpackDevServer client, and
    // changing JS code would still trigger a refresh.
  ],
  output: {
    // Add /* filename */ comments to generated require()s in the output.
    pathinfo: true,
    // This does not produce a real file. It's just the virtual path that is
    // served by WebpackDevServer in development. This is the JS bundle
    // containing code from all our entry points, and the Webpack runtime.
    filename: 'static/js/bundle.js',
    // There are also additional JS chunk files if you use code splitting.
    chunkFilename: 'static/js/[name].chunk.js',
    // This is the URL that app is served from. We use "/" in development.
    publicPath: publicPath,
    // Point sourcemap entries to original disk location (format as URL on Windows)
    devtoolModuleFilenameTemplate: info =>
      path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
  },
  resolve: {
    // This allows you to set a fallback for where Webpack should look for modules.
    // We placed these paths second because we want `node_modules` to "win"
    // if there are any conflicts. This matches Node resolution mechanism.
    // https://github.com/facebookincubator/create-react-app/issues/253
    modules: ['node_modules', paths.appNodeModules].concat(
      // It is guaranteed to exist because we tweak it in `env.js`
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
    ),
    // These are the reasonable defaults supported by the Node ecosystem.
    // We also include JSX as a common component filename extension to support
    // some tools, although we do not recommend using it, see:
    // https://github.com/facebookincubator/create-react-app/issues/290
    // `web` extension prefixes have been added for better support
    // for React Native Web.
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {

      // Support React Native Web
      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
      'react-native': 'react-native-web',
    },
    plugins: [
      // Prevents users from importing files from outside of src/ (or node_modules/).
      // This often causes confusion because we only process files within src/ with babel.
      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
      // please link the files into your node_modules/ and let module-resolution kick in.
      // Make sure your source files are compiled, as they will not be processed in any way.
      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
    ],
  },
  module: {
    strictExportPresence: true,
    rules: [
      // TODO: Disable require.ensure as it's not a standard language feature.
      // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
      // { parser: { requireEnsure: false } },

      // First, run the linter.
      // It's important to do this before Babel processes the JS.
      {
        test: /\.(js|jsx|mjs)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: eslintFormatter,
              eslintPath: require.resolve('eslint'),

            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        include: paths.appSrc,
      },
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works like "file" loader except that it embeds assets
          // smaller than specified limit in bytes as data URLs to avoid requests.
          // A missing `test` is equivalent to a match.
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
          // Process JS with Babel.
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {

              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
            },
          },
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader turns CSS into JS modules that inject <style> tags.
          // In production, we use a plugin to extract that CSS to a file, but
          // in development "style" loader enables hot editing of CSS.
          {
            test: /\.scss$/,
            use: ExtractTextPlugin.extract([
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                },
              },
              {
                loader: require.resolve('postcss-loader'),
                options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      browsers: [
                        '>1%',
                        'last 4 versions',
                        'Firefox ESR',
                        'not ie < 9', // React doesn't support IE8 anyway
                      ],
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
              {
                loader: 'sass-loader',
                options: {
                  includePaths: ['./node_modules']
                }
              },
            ]),
          },
          // "file" loader makes sure those assets get served by WebpackDevServer.
          // When you `import` an asset, you get its (virtual) filename.
          // In production, they would get copied to the `build` folder.
          // This loader doesn't use a "test" so it will catch all modules
          // that fall through the other loaders.
          {
            // Exclude `js` files to keep "css" loader working as it injects
            // its runtime that would otherwise processed through "file" loader.
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            loader: require.resolve('file-loader'),
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
        ],
      },
      // ** STOP ** Are you adding a new loader?
      // Make sure to add the new loader(s) before the "file" loader.
    ],
  },
  plugins: [
    // Makes some environment variables available in index.html.
    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    // In development, this will be an empty string.
    new InterpolateHtmlPlugin(env.raw),
    // Generates an `index.html` file with the <script> injected.
    new ExtractTextPlugin('[name].[contenthash:8].css'),
    new ManifestPlugin({
      fileName: './src/asset-manifest.json',
      writeToFileEmit: true
    }),
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
    }),
  ].concat(components.map(componentName => {
    // Generates an html page for each component with the <script> injected.
    return new HtmlWebpackPlugin({
      filename: `${componentName}.html`,
      inject: true,
      template: paths.appHtml
    })
  })).concat([
    // Add module names to factory functions so they appear in browser profiler.
    new webpack.NamedModulesPlugin(),
    // Makes some environment variables available to the JS code, for example:
    // if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
    new webpack.DefinePlugin(env.stringified),
    // This is necessary to emit hot updates (currently CSS only):
    new webpack.HotModuleReplacementPlugin(),
    // Watcher doesn't work well if you mistype casing in a path so we use
    // a plugin that prints an error when you attempt to do this.
    // See https://github.com/facebookincubator/create-react-app/issues/240
    new CaseSensitivePathsPlugin(),
    // If you require a missing module and then `npm install` it, you still have
    // to restart the development server for Webpack to discover it. This plugin
    // makes the discovery automatic so you don't have to restart.
    // See https://github.com/facebookincubator/create-react-app/issues/186
    new WatchMissingNodeModulesPlugin(paths.appNodeModules),
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ]),
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty',
  },
  // Turn off performance hints during development because we don't do any
  // splitting or minification in interest of speed. These warnings become
  // cumbersome.
  performance: {
    hints: false,
  },
};
<commit_msg>WIP: switch to single quotes<commit_after>'use strict';

const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');

// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
const publicPath = '/';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);

// List of all component names for generating the corresponding html pages.
const components = ['button'];

// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
module.exports = {
  // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
  // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.
  devtool: 'cheap-module-source-map',
  // These are the "entry points" to our application.
  // This means they will be the "root" imports that are included in JS bundle.
  // The first two entry points enable "hot" CSS and auto-refreshes for JS.
  entry: [
    // We ship a few polyfills by default:
    require.resolve('./polyfills'),
    // Include an alternative client for WebpackDevServer. A client's job is to
    // connect to WebpackDevServer by a socket and get notified about changes.
    // When you save a file, the client will either apply hot updates (in case
    // of CSS changes), or refresh the page (in case of JS changes). When you
    // make a syntax error, this client will display a syntax error overlay.
    // Note: instead of the default WebpackDevServer client, we use a custom one
    // to bring better experience for Create React App users. You can replace
    // the line below with these two lines if you prefer the stock client:
    // require.resolve('webpack-dev-server/client') + '?/',
    // require.resolve('webpack/hot/dev-server'),
    require.resolve('react-dev-utils/webpackHotDevClient'),
    // Finally, this is your app's code:
    paths.appIndexJs,
    // We include the app code last so that if there is a runtime error during
    // initialization, it doesn't blow up the WebpackDevServer client, and
    // changing JS code would still trigger a refresh.
  ],
  output: {
    // Add /* filename */ comments to generated require()s in the output.
    pathinfo: true,
    // This does not produce a real file. It's just the virtual path that is
    // served by WebpackDevServer in development. This is the JS bundle
    // containing code from all our entry points, and the Webpack runtime.
    filename: 'static/js/bundle.js',
    // There are also additional JS chunk files if you use code splitting.
    chunkFilename: 'static/js/[name].chunk.js',
    // This is the URL that app is served from. We use "/" in development.
    publicPath: publicPath,
    // Point sourcemap entries to original disk location (format as URL on Windows)
    devtoolModuleFilenameTemplate: info =>
      path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
  },
  resolve: {
    // This allows you to set a fallback for where Webpack should look for modules.
    // We placed these paths second because we want `node_modules` to "win"
    // if there are any conflicts. This matches Node resolution mechanism.
    // https://github.com/facebookincubator/create-react-app/issues/253
    modules: ['node_modules', paths.appNodeModules].concat(
      // It is guaranteed to exist because we tweak it in `env.js`
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
    ),
    // These are the reasonable defaults supported by the Node ecosystem.
    // We also include JSX as a common component filename extension to support
    // some tools, although we do not recommend using it, see:
    // https://github.com/facebookincubator/create-react-app/issues/290
    // `web` extension prefixes have been added for better support
    // for React Native Web.
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {

      // Support React Native Web
      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
      'react-native': 'react-native-web',
    },
    plugins: [
      // Prevents users from importing files from outside of src/ (or node_modules/).
      // This often causes confusion because we only process files within src/ with babel.
      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
      // please link the files into your node_modules/ and let module-resolution kick in.
      // Make sure your source files are compiled, as they will not be processed in any way.
      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
    ],
  },
  module: {
    strictExportPresence: true,
    rules: [
      // TODO: Disable require.ensure as it's not a standard language feature.
      // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
      // { parser: { requireEnsure: false } },

      // First, run the linter.
      // It's important to do this before Babel processes the JS.
      {
        test: /\.(js|jsx|mjs)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: eslintFormatter,
              eslintPath: require.resolve('eslint'),

            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        include: paths.appSrc,
      },
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works like "file" loader except that it embeds assets
          // smaller than specified limit in bytes as data URLs to avoid requests.
          // A missing `test` is equivalent to a match.
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
          // Process JS with Babel.
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {

              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
            },
          },
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader turns CSS into JS modules that inject <style> tags.
          // In production, we use a plugin to extract that CSS to a file, but
          // in development "style" loader enables hot editing of CSS.
          {
            test: /\.scss$/,
            use: ExtractTextPlugin.extract([
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                },
              },
              {
                loader: require.resolve('postcss-loader'),
                options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      browsers: [
                        '>1%',
                        'last 4 versions',
                        'Firefox ESR',
                        'not ie < 9', // React doesn't support IE8 anyway
                      ],
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
              {
                loader: 'sass-loader',
                options: {
                  includePaths: ['./node_modules']
                }
              },
            ]),
          },
          // "file" loader makes sure those assets get served by WebpackDevServer.
          // When you `import` an asset, you get its (virtual) filename.
          // In production, they would get copied to the `build` folder.
          // This loader doesn't use a "test" so it will catch all modules
          // that fall through the other loaders.
          {
            // Exclude `js` files to keep "css" loader working as it injects
            // its runtime that would otherwise processed through "file" loader.
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            loader: require.resolve('file-loader'),
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
        ],
      },
      // ** STOP ** Are you adding a new loader?
      // Make sure to add the new loader(s) before the "file" loader.
    ],
  },
  plugins: [
    // Makes some environment variables available in index.html.
    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    // In development, this will be an empty string.
    new InterpolateHtmlPlugin(env.raw),
    // Generates an `index.html` file with the <script> injected.
    new ExtractTextPlugin('[name].[contenthash:8].css'),
    new ManifestPlugin({
      fileName: './src/asset-manifest.json',
      writeToFileEmit: true
    }),
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
    }),
  ].concat(components.map(componentName => {
    // Generates an html page for each component with the <script> injected.
    return new HtmlWebpackPlugin({
      filename: `${componentName}.html`,
      inject: true,
      template: paths.appHtml
    })
  })).concat([
    // Add module names to factory functions so they appear in browser profiler.
    new webpack.NamedModulesPlugin(),
    // Makes some environment variables available to the JS code, for example:
    // if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
    new webpack.DefinePlugin(env.stringified),
    // This is necessary to emit hot updates (currently CSS only):
    new webpack.HotModuleReplacementPlugin(),
    // Watcher doesn't work well if you mistype casing in a path so we use
    // a plugin that prints an error when you attempt to do this.
    // See https://github.com/facebookincubator/create-react-app/issues/240
    new CaseSensitivePathsPlugin(),
    // If you require a missing module and then `npm install` it, you still have
    // to restart the development server for Webpack to discover it. This plugin
    // makes the discovery automatic so you don't have to restart.
    // See https://github.com/facebookincubator/create-react-app/issues/186
    new WatchMissingNodeModulesPlugin(paths.appNodeModules),
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ]),
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty',
  },
  // Turn off performance hints during development because we don't do any
  // splitting or minification in interest of speed. These warnings become
  // cumbersome.
  performance: {
    hints: false,
  },
};
<|endoftext|>


<commit_before>/**
 *
 * @license
 * Copyright (C) 2016 Joseph Roque
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author Joseph Roque
 * @file ShuttleCampusDetails.js
 * @providesModule ShuttleCampusDetails
 * @description Displays details about the departure times of the shuttle from a single campus.
 *
 * @flow
 */
'use strict';

// React imports
import React from 'react';
import {
  StyleSheet,
  View,
} from 'react-native';

// Type imports
import type {
  LatLong,
  ShuttleCampus,
  University,
} from '../../types';

// Type definition for component props.
type Props = {
  campusColor: string,
  campusName: string,
};

// Type definition for component state.
type State = {
  campus: ?ShuttleCampus,
  region: ?LatLong,
};

// Imports
const Configuration = require('Configuration');
const LanguageUtils = require('LanguageUtils');
const MapView = require('react-native-maps');
const Preferences = require('Preferences');

class ShuttleCampusDetails extends React.Component {

  /**
   * Properties which the parent component should make available to this component.
   */
  static propTypes = {
    campusColor: React.PropTypes.string.isRequired,
    campusName: React.PropTypes.string.isRequired,
  };

  /**
   * Define type for the component state.
   */
  state: State;

  /**
   * Pass props and declares initial state.
   *
   * @param {Props} props properties passed from container to this component.
   */
  constructor(props: Props) {
    super(props);

    this.state = {
      campus: null,
      region: null,
    };

    // Explicitly binding 'this' to all methods that need it
    (this:any)._getCampusMap = this._getCampusMap.bind(this);
    (this:any)._loadCampusInfo = this._loadCampusInfo.bind(this);
  }

  /**
   * If the campus info has not been loaded yet, then load it.
   */
  componentDidMount(): void {
    if (this.state.campus == null) {
      this._loadCampusInfo();
    }
  }

  /**
   * Renders a map with a list of markers to denote bus stops near the campus.
   *
   * @param {Object} Translations translations in the current language of certain text.
   * @returns {ReactElement<any>} a map view with a marker
   */
  _getCampusMap(Translations: Object): ReactElement<any> {
    let initialRegion: LatLong;
    let marker: ?ReactElement<any>;

    if (this.state.campus == null) {
      const university: ?University = Configuration.getUniversity();
      if (university != null) {
        initialRegion = {
          latitude: university.lat,
          longitude: university.long,
          latitudeDelta: 0.01,
          longitudeDelta: 0.01,
        };
      }
    } else {
      const lat = this.state.campus.lat;
      const long = this.state.campus.lat;
      initialRegion = {
        latitude: lat,
        longitude: long,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      };

      marker = (
        <MapView.Marker
            coordinate={initialRegion}
            description={LanguageUtils.getTranslatedName(Preferences.getSelectedLanguage(), this.state.campus)}
            title={Translations.shuttle_stop} />
      );
    }

    return (
      <MapView
          region={initialRegion}
          style={_styles.map}>
        {marker}
      </MapView>
    );
  }

  /**
   * Retrieves data about the campus provided as this.props.campusName.
   */
  _loadCampusInfo(): void {
    const campuses: Array<ShuttleCampus> = require('../../../assets/json/shuttle.json');
    if (this.props.campusName in campuses) {
      this.setState({
        campus: campuses[this.props.campusName],
      });
    }
  }

  /**
   * Renders a map and details about the shuttle drop off times at the campus specified by {this.props.campusName}.
   *
   * @returns {ReactElement<any>} the hierarchy of views to render.
   */
  render(): ReactElement<any> {
    // Get current language for translations
    let Translations: Object;
    if (Preferences.getSelectedLanguage() === 'fr') {
      Translations = require('../../../assets/js/Translations.fr.js');
    } else {
      Translations = require('../../../assets/js/Translations.en.js');
    }

    return (
      <View style={[_styles.container, {backgroundColor: this.props.campuscolor}]}>
        <View style={_styles.mapContainer}>
          {this._getCampusMap(Translations)}
        </View>
        <View style={_styles.timeContainer} />
      </View>
    );
  }
}

// Private styles for the component
const _styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  mapContainer: {
    flex: 3,
  },
  timeContainer: {
    flex: 4,
  },
  map: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
});

module.exports = ShuttleCampusDetails;
<commit_msg>Use downloaded config instead of static file in ShuttleCampusDetails.js<commit_after>/**
 *
 * @license
 * Copyright (C) 2016 Joseph Roque
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author Joseph Roque
 * @file ShuttleCampusDetails.js
 * @providesModule ShuttleCampusDetails
 * @description Displays details about the departure times of the shuttle from a single campus.
 *
 * @flow
 */
'use strict';

// React imports
import React from 'react';
import {
  StyleSheet,
  View,
} from 'react-native';

// Type imports
import type {
  LatLong,
  ShuttleCampus,
  University,
} from '../../types';

// Type definition for component props.
type Props = {
  campusColor: string,
  campusName: string,
};

// Type definition for component state.
type State = {
  campus: ?ShuttleCampus,
  region: ?LatLong,
};

// Imports
const Configuration = require('Configuration');
const LanguageUtils = require('LanguageUtils');
const MapView = require('react-native-maps');
const Preferences = require('Preferences');

class ShuttleCampusDetails extends React.Component {

  /**
   * Properties which the parent component should make available to this component.
   */
  static propTypes = {
    campusColor: React.PropTypes.string.isRequired,
    campusName: React.PropTypes.string.isRequired,
  };

  /**
   * Define type for the component state.
   */
  state: State;

  /**
   * Pass props and declares initial state.
   *
   * @param {Props} props properties passed from container to this component.
   */
  constructor(props: Props) {
    super(props);

    this.state = {
      campus: null,
      region: null,
    };

    // Explicitly binding 'this' to all methods that need it
    (this:any)._getCampusMap = this._getCampusMap.bind(this);
    (this:any)._loadCampusInfo = this._loadCampusInfo.bind(this);
  }

  /**
   * If the campus info has not been loaded yet, then load it.
   */
  componentDidMount(): void {
    if (this.state.campus == null) {
      Configuration.init()
          .then(this._loadCampusInfo())
          .catch(err => console.error('Configuration could not be initialized for shuttle campus details.', err));
    }
  }

  /**
   * Renders a map with a list of markers to denote bus stops near the campus.
   *
   * @param {Object} Translations translations in the current language of certain text.
   * @returns {ReactElement<any>} a map view with a marker
   */
  _getCampusMap(Translations: Object): ReactElement<any> {
    let initialRegion: LatLong;
    let marker: ?ReactElement<any>;

    if (this.state.campus == null) {
      const university: ?University = Configuration.getUniversity();
      if (university != null) {
        initialRegion = {
          latitude: university.lat,
          longitude: university.long,
          latitudeDelta: 0.01,
          longitudeDelta: 0.01,
        };
      }
    } else {
      const lat = this.state.campus.lat;
      const long = this.state.campus.lat;
      initialRegion = {
        latitude: lat,
        longitude: long,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      };

      marker = (
        <MapView.Marker
            coordinate={initialRegion}
            description={LanguageUtils.getTranslatedName(Preferences.getSelectedLanguage(), this.state.campus)}
            title={Translations.shuttle_stop} />
      );
    }

    return (
      <MapView
          region={initialRegion}
          style={_styles.map}>
        {marker}
      </MapView>
    );
  }

  /**
   * Retrieves data about the campus provided as this.props.campusName.
   */
  _loadCampusInfo(): void {
    Configuration.getConfig('/shuttle.json')
        .then(campuses => {
          if (this.props.campusName in campuses) {
            this.setState({
              campus: campuses[this.props.campusName],
            });
          }
        })
        .catch(err => console.error('Could not get /shuttle.json.', err));
  }

  /**
   * Renders a map and details about the shuttle drop off times at the campus specified by {this.props.campusName}.
   *
   * @returns {ReactElement<any>} the hierarchy of views to render.
   */
  render(): ReactElement<any> {
    // Get current language for translations
    let Translations: Object;
    if (Preferences.getSelectedLanguage() === 'fr') {
      Translations = require('../../../assets/js/Translations.fr.js');
    } else {
      Translations = require('../../../assets/js/Translations.en.js');
    }

    return (
      <View style={[_styles.container, {backgroundColor: this.props.campuscolor}]}>
        <View style={_styles.mapContainer}>
          {this._getCampusMap(Translations)}
        </View>
        <View style={_styles.timeContainer} />
      </View>
    );
  }
}

// Private styles for the component
const _styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  mapContainer: {
    flex: 3,
  },
  timeContainer: {
    flex: 4,
  },
  map: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
});

module.exports = ShuttleCampusDetails;
<|endoftext|>


<commit_before>var _ = require('lodash');
var React = require('react/addons');
var API = require('data/api');
var RegionTitleMenu     = require('component/RegionTitleMenu.jsx');
var IndicatorDropdownMenu = require('component/IndicatorDropdownMenu.jsx');
var CampaignDropdownMenu = require('component/CampaignDropdownMenu.jsx');

const {
	Datascope, LocalDatascope,
	SimpleDataTable, SimpleDataTableColumn,
	ClearQueryLink,
	Paginator,
	SearchBar,
	FilterPanel, FilterDateRange, FilterInputRadio
	} = require('react-datascope');

var parseSchema = require('ufadmin/utils/parseSchema');

var ReviewPage = React.createClass({
	propTypes: {
		title: React.PropTypes.string.isRequired,
		getMetadata: React.PropTypes.func.isRequired,
		getData: React.PropTypes.func.isRequired,
    loading   : React.PropTypes.bool.isRequired,
		fields 		: React.PropTypes.object.isRequired,
		region 		: React.PropTypes.object.isRequired,
	},
	getInitialState: function() {
		return {
			data: null,
			schema: null,
			query: {},
			loading   : false,
		}
	},

	componentWillMount: function() {
		this.props.getMetadata().then(response => this.setState({
			metadata: response,
			schema: parseSchema(response)
		}));
		this.props.getData({master_object_id:this.props.region.id},null,{'cache-control':'no-cache'}).then(response => this.setState({data: response.objects}));
		},

	componentWillUpdate : function (nextProps, nextState) {
		// update this.state.data if there is a metadata change //
			if (nextProps.region != this.props.region) {
				console.log('updating!')
				return;
			console.log('not updating')
			}
		},

	componentWillReceiveProps: function(nextProps) {
		this.props.getData({master_object_id:nextProps.region.id}
			,null,{'cache-control':'no-cache'}).then(
					response => this.setState({data: response.objects})
				);
		this.forceUpdate()
		},
	render() {

		var isLoaded = _.isArray(this.state.data) && this.state.schema && (!this.state.loading);
		if(!isLoaded) return this.renderLoading();

		var {data, schema} = this.state;

		return

        <LocalDatascope data={data} schema={schema} pageSize={25}>
	         <Datascope>
	           {this.props.children}
	         </Datascope>
         </LocalDatascope>

	},
	renderLoading() {
		return
 Review Page Loading...

	},
});

module.exports = ReviewPage;
<commit_msg>remove all references to metadata in source dashboard<commit_after>var _ = require('lodash');
var React = require('react/addons');
var API = require('data/api');
var RegionTitleMenu     = require('component/RegionTitleMenu.jsx');
var IndicatorDropdownMenu = require('component/IndicatorDropdownMenu.jsx');
var CampaignDropdownMenu = require('component/CampaignDropdownMenu.jsx');

const {
	Datascope, LocalDatascope,
	SimpleDataTable, SimpleDataTableColumn,
	ClearQueryLink,
	Paginator,
	SearchBar,
	FilterPanel, FilterDateRange, FilterInputRadio
	} = require('react-datascope');

var parseSchema = require('ufadmin/utils/parseSchema');

var ReviewPage = React.createClass({
	propTypes: {
		title: React.PropTypes.string.isRequired,
		getMetadata: React.PropTypes.func.isRequired,
		getData: React.PropTypes.func.isRequired,
    loading   : React.PropTypes.bool.isRequired,
		fields 		: React.PropTypes.object.isRequired,
		region 		: React.PropTypes.object.isRequired,
	},
	getInitialState: function() {
		return {
			data: null,
			schema: null,
			query: {},
			loading   : false,
		}
	},

	componentWillMount: function() {
		this.props.getMetadata()
		.then(response => this.setState({
				schema: parseSchema(response)
		}));

		this.props.getData({master_object_id:this.props.region.id},null,{'cache-control':'no-cache'})
			.then(response => this.setState({
						data: response.objects
			}));
		},

	componentWillUpdate : function (nextProps, nextState) {
			if (nextProps.region != this.props.region) {
				console.log('updating!')
				return;
			console.log('not updating')
			}
		},

	componentWillReceiveProps: function(nextProps) {
		this.props.getData({master_object_id:nextProps.region.id}
			,null,{'cache-control':'no-cache'}).then(
					response => this.setState({data: response.objects})
				);
		this.forceUpdate()
		},
	render() {

		var isLoaded = _.isArray(this.state.data) && this.state.schema && (!this.state.loading);
		if(!isLoaded) return this.renderLoading();

		var {data, schema} = this.state;

		return

        <LocalDatascope data={data} schema={schema} pageSize={25}>
	         <Datascope>
	           {this.props.children}
	         </Datascope>
         </LocalDatascope>

	},
	renderLoading() {
		return
 Review Page Loading...

	},
});

module.exports = ReviewPage;
<|endoftext|>