<commit_before>define(['jstools/tools', 'jquery', './logger', 'signals'], function(tools, $, Logger, Signal) {
    'use strict';

    return Logger.extend(function(base) {

        // if args starts by an evt (contains timestamp and type)
        // returns an array containing timestamp and type and the remaining of the arguments
        // else returns the original arguments
        function _normalizePointerEvtArgs(args) {
            var n = args.length;
            if (n < 1) return args;
            var evt = args[0];
            var timestamp = tools.isSet(evt.timestamp) ? evt.timestamp : evt.timeStamp,
                type = tools.isSet(evt.type) ? tools.eventInfo(evt).type : null;
            if (timestamp && type) {
                var newArgs = [timestamp, type];
                for (var i = 1; i < n; i++) newArgs.push(args[i]);
                return newArgs;
            }
            return args;
        }

        // wrap a function so that pointer events are automatically normalized
        function _pEvtDecorator(f, context) {
            return function() {
                var fcontext = context === void(0) ? this : context;
                var args = _normalizePointerEvtArgs(arguments);
                return f.apply(fcontext, args);
            };
        }

        return {

            init: function(trialProcessors, eventProcessors, settings) {
                base.init.call(this, trialProcessors, settings);
                settings = settings || {};

                if (typeof processor_s == 'function') {
                    this.eventProcessors = [eventProcessors];
                } else if (eventProcessors) {
                    this.eventProcessors = eventProcessors.slice(0);
                } else {
                    this.eventProcessors = [];
                }

                // this can be used to store values that are going to be repeted on all events
                this.constants = {};

                this._evtIndex = {}; // _evtIndex[evtIndex][evtTime] = evt
                this._events = [];

                var that = this;
                this._pointerHandlers = {
                    'touchstart touchend touchmove touchcancel mousesup mousedown mousemove': function(evt) {
                        that.setPointerEvent(evt);
                    },
                };
                this._logPointerEvents = false;
                if(settings.logPointerEvents) this.startLoggingPointerEvents();
                this.eventProcessorParams = settings.eventProcessorParams;

                this.onEvent = new Signal();
            },

            createEvent: function(evtTime, evtType) {
                return this._createEvent(evtTime, evtType);
            },

            forEachEvent: function(f) {
                this._events.every(function(evt, i) {
                    if (f(evt, i) === false) return false;
                    else return true;
                });
            },

            eventCount: function() {
                return this._events.length;
            },

            lastEvent: function() {
                return this._events[this._events.length - 1];
            },

            _pushNewEvent: function(evt) {
                var prevI = this._events.length - 1,
                    prev = this._events[prevI],
                    timestamp = evt.get('timestamp');
                // look for the position of the event in the list
                // (usually, it should always be the last)
                while (prev.get('timestamp') > timestamp) {
                    prevI--;
                    prev = this._events[prevI];
                }
                this._events.splice(prevI + 1, 0, evt);
            },

            // evtTime & evtType can be replace by an event
            _createEvent: _pEvtDecorator(function(evtTime, evtType, noSignal) {
                var evt = new Logger(this.eventProcessors, {
                        processorParams: $.extend({
                            trialLogger: this
                        }, this._eventProcessorParams)
                    }),
                    types = this._evtIndex[evtType] || {};
                this._evtIndex[evtType] = types;
                if (types[evtTime]) throw 'Event already exists: ' + evtType + ' (' + evtTime + ')';
                evt.set('timestamp', evtTime);
                evt.set('type', evtType);
                evt.protectedValues.push('timestamp');
                evt.protectedValues.push('type');
                evt.set(this.constants);
                types[evtTime] = evt;
                this._events.push(evt);
                evt._pointerRegistered = false;
                if (!noSignal) this.onEvent.dispatch(evt);
                return evt;
            }),

            // evtTime & evtType can be replace by an event
            getEvent: _pEvtDecorator(function(evtTime, evtType, createUnfound) {
                var types = this._evtIndex[evtType],
                    evt;
                if (types) evt = types[evtTime];
                if (!evt && createUnfound) evt = this.createEvent(evtTime, evtType);
                return evt;
            }),

            eventExists: function() {
                return Boolean(this.getEvent.apply(this, arguments));
            },

            // evtTime & evtType can be replace by an event
            setEvent: _pEvtDecorator(function(evtTime, evtType, measureNameOrMeasuresObj, measure) {
                var evtLog = this.getEvent(evtTime, evtType);
                if (!evtLog) {
                    evtLog = this._createEvent(evtTime, evtType, true);
                    evtLog.set(measureNameOrMeasuresObj, measure);
                    this.onEvent.dispatch(evtLog);
                } else {
                    evtLog.set(measureNameOrMeasuresObj, measure);
                }
                return evtLog;
            }),

            export: function(continueLogging) {
                // this._events should remain sorted
                var sortedEvents = this._events;
                var eventExports = [];
                var n = sortedEvents.length;
                var i;
                for (i = 0; i < n; i++) {
                    // event processors are applied before trial processors
                    base._applyProcessors.call(sortedEvents[i]);
                }
                var trialExport = base.export.call(this);
                for (i = 0; i < n; i++) {
                    // however the event logs are exported after the trial processors
                    // because they may act on events
                    var event = sortedEvents[i];
                    eventExports.push($.extend(true, {}, event._log));
                }
                if(!continueLogging) this.stopLoggingPointerEvents();
                return {
                    trial: trialExport,
                    events: eventExports
                };
            },

            /*
             * Automatically logs all pointer events.
             * *WARNINGS*, explicitely stop logging when not required anymore! The
             * logger won't be garbage collected while the handlers are still attached.
             * Export by default automatically stop the logging.
             */
            startLoggingPointerEvents: function(targetDiv) {
                // remove the old handlers if needed
                if (this._pointersDiv && this._pointersDiv[0] !== targetDiv) {
                    this.stopLoggingPointerEvents();
                    // add the new one if needed
                    this._pointersDiv = $(targetDiv);
                    this._pointersDiv.on(this._pointerHandlers);
                }
            },

            stopLoggingPointerEvents: function(){
                if(this._pointersDiv) {
                    this._pointersDiv.off(this._pointerHandlers);
                    this._pointersDiv = null;
                }
            },

            get logPointerEvents() {
                return Boolean(this._pointersDiv);
            },

            setPointerEvent: function(event, log) {
                // retrieve the original event (jquery event case)
                event = event.originalEvent || event;
                // get the event log associated to this event
                var eventLog = this.getEvent(event);
                // if there is no eventLog, we will trigger the signal at the end
                // of this set command
                var dispatch = !eventLog;
                // create (if needed) the event log with no signal option
                eventLog = eventLog || this._createEvent(event, true);
                // if we did not already registered the pointer, we register them
                if (!eventLog._pointerRegistered) {
                    // get the pointer log and register it
                    eventLog.set(this._getPointerLog(event));
                    // flag the event log
                    eventLog._pointerRegistered = true;
                }
                // set user log *after* the pointer log (so it can be overwritten)
                eventLog.set(log);
                // dispatch the event if we created the event log here
                if(dispatch) this.onEvent.dispatch(eventLog);
                return eventLog;
            },

            _getPointerLog: function(event, target) {
                target = target || {};
                target.device = tools.eventInfo(event).device;
                target.originalType = event.type;
                if(target.device == 'touch') return this._getTouchLog(event, target);
                else                         return this._getMouseLog(event, target);
            },

            _getTouchLog: function(event, target) {
                var touches     = (event.originalEvent || event).touches,
                    n           = touches ? touches.length : 0,
                    pointersLog = target.pointers || {},
                    i, touch;
                target.pointers = pointersLog;
                pointersLog.count = n;
                for (i = 0; i < n; i++) {
                    touch = touches[i];
                    pointersLog[i] = {
                        identifier: touch.identifier,
                        x: touch.pageX,
                        y: touch.pageY
                    };
                }
                if (n > 0) {
                    pointersLog.mean = {
                        x: event.pageX,
                        y: event.pageY
                    };
                }
                return target;
            },

            _getMouseLog: function(event, target) {
                target.mean = {
                        x: event.pageX,
                        y: event.pageY
                };
                target.pointer = {
                    // avoid putting the same object
                    // so change in one of them does not impact
                    // the other
                    '0': {
                        x: event.pageX,
                        y: event.pageY
                    }
                };
                return target;
            }

        };
    });

});
<commit_msg>Correction of a major bug making pointer events not being logged at all...<commit_after>define(['jstools/tools', 'jquery', './logger', 'signals'], function(tools, $, Logger, Signal) {
    'use strict';

    return Logger.extend(function(base) {

        // if args starts by an evt (contains timestamp and type)
        // returns an array containing timestamp and type and the remaining of the arguments
        // else returns the original arguments
        function _normalizePointerEvtArgs(args) {
            var n = args.length;
            if (n < 1) return args;
            var evt = args[0];
            var timestamp = tools.isSet(evt.timestamp) ? evt.timestamp : evt.timeStamp,
                type = tools.isSet(evt.type) ? tools.eventInfo(evt).type : null;
            if (timestamp && type) {
                var newArgs = [timestamp, type];
                for (var i = 1; i < n; i++) newArgs.push(args[i]);
                return newArgs;
            }
            return args;
        }

        // wrap a function so that pointer events are automatically normalized
        function _pEvtDecorator(f, context) {
            return function() {
                var fcontext = context === void(0) ? this : context;
                var args = _normalizePointerEvtArgs(arguments);
                return f.apply(fcontext, args);
            };
        }

        return {

            init: function(trialProcessors, eventProcessors, settings) {
                base.init.call(this, trialProcessors, settings);
                settings = settings || {};

                if (typeof processor_s == 'function') {
                    this.eventProcessors = [eventProcessors];
                } else if (eventProcessors) {
                    this.eventProcessors = eventProcessors.slice(0);
                } else {
                    this.eventProcessors = [];
                }

                // this can be used to store values that are going to be repeted on all events
                this.constants = {};

                this._evtIndex = {}; // _evtIndex[evtIndex][evtTime] = evt
                this._events = [];

                var that = this;
                this._pointerHandlers = {
                    'touchstart touchend touchmove touchcancel mousesup mousedown mousemove': function(evt) {
                        that.setPointerEvent(evt);
                    },
                };
                this._logPointerEvents = false;
                if(settings.logPointerEvents) this.startLoggingPointerEvents();
                this.eventProcessorParams = settings.eventProcessorParams;

                this.onEvent = new Signal();
            },

            createEvent: function(evtTime, evtType) {
                return this._createEvent(evtTime, evtType);
            },

            forEachEvent: function(f) {
                this._events.every(function(evt, i) {
                    if (f(evt, i) === false) return false;
                    else return true;
                });
            },

            eventCount: function() {
                return this._events.length;
            },

            lastEvent: function() {
                return this._events[this._events.length - 1];
            },

            _pushNewEvent: function(evt) {
                var prevI = this._events.length - 1,
                    prev = this._events[prevI],
                    timestamp = evt.get('timestamp');
                // look for the position of the event in the list
                // (usually, it should always be the last)
                while (prev.get('timestamp') > timestamp) {
                    prevI--;
                    prev = this._events[prevI];
                }
                this._events.splice(prevI + 1, 0, evt);
            },

            // evtTime & evtType can be replace by an event
            _createEvent: _pEvtDecorator(function(evtTime, evtType, noSignal) {
                var evt = new Logger(this.eventProcessors, {
                        processorParams: $.extend({
                            trialLogger: this
                        }, this._eventProcessorParams)
                    }),
                    types = this._evtIndex[evtType] || {};
                this._evtIndex[evtType] = types;
                if (types[evtTime]) throw 'Event already exists: ' + evtType + ' (' + evtTime + ')';
                evt.set('timestamp', evtTime);
                evt.set('type', evtType);
                evt.protectedValues.push('timestamp');
                evt.protectedValues.push('type');
                evt.set(this.constants);
                types[evtTime] = evt;
                this._events.push(evt);
                evt._pointerRegistered = false;
                if (!noSignal) this.onEvent.dispatch(evt);
                return evt;
            }),

            // evtTime & evtType can be replace by an event
            getEvent: _pEvtDecorator(function(evtTime, evtType, createUnfound) {
                var types = this._evtIndex[evtType],
                    evt;
                if (types) evt = types[evtTime];
                if (!evt && createUnfound) evt = this.createEvent(evtTime, evtType);
                return evt;
            }),

            eventExists: function() {
                return Boolean(this.getEvent.apply(this, arguments));
            },

            // evtTime & evtType can be replace by an event
            setEvent: _pEvtDecorator(function(evtTime, evtType, measureNameOrMeasuresObj, measure) {
                var evtLog = this.getEvent(evtTime, evtType);
                if (!evtLog) {
                    evtLog = this._createEvent(evtTime, evtType, true);
                    evtLog.set(measureNameOrMeasuresObj, measure);
                    this.onEvent.dispatch(evtLog);
                } else {
                    evtLog.set(measureNameOrMeasuresObj, measure);
                }
                return evtLog;
            }),

            export: function(continueLogging) {
                // this._events should remain sorted
                var sortedEvents = this._events;
                var eventExports = [];
                var n = sortedEvents.length;
                var i;
                for (i = 0; i < n; i++) {
                    // event processors are applied before trial processors
                    base._applyProcessors.call(sortedEvents[i]);
                }
                var trialExport = base.export.call(this);
                for (i = 0; i < n; i++) {
                    // however the event logs are exported after the trial processors
                    // because they may act on events
                    var event = sortedEvents[i];
                    eventExports.push($.extend(true, {}, event._log));
                }
                if(!continueLogging) this.stopLoggingPointerEvents();
                return {
                    trial: trialExport,
                    events: eventExports
                };
            },

            /*
             * Automatically logs all pointer events.
             * *WARNINGS*, explicitely stop logging when not required anymore! The
             * logger won't be garbage collected while the handlers are still attached.
             * Export by default automatically stop the logging.
             */
            startLoggingPointerEvents: function(targetDiv) {
                targetDiv = targetDiv || document;
                // remove the old handlers if needed
                if (this._pointersDiv && this._pointersDiv[0] !== targetDiv) {
                    this.stopLoggingPointerEvents();
                }
                // add the new one if needed
                this._pointersDiv = $(targetDiv);
                this._pointersDiv.on(this._pointerHandlers);
            },

            stopLoggingPointerEvents: function(){
                if(this._pointersDiv) {
                    this._pointersDiv.off(this._pointerHandlers);
                    this._pointersDiv = null;
                }
            },

            get logPointerEvents() {
                return Boolean(this._pointersDiv);
            },

            setPointerEvent: function(event, log) {
                // retrieve the original event (jquery event case)
                event = event.originalEvent || event;
                // get the event log associated to this event
                var eventLog = this.getEvent(event);
                // if there is no eventLog, we will trigger the signal at the end
                // of this set command
                var dispatch = !eventLog;
                // create (if needed) the event log with no signal option
                eventLog = eventLog || this._createEvent(event, true);
                // if we did not already registered the pointer, we register them
                if (!eventLog._pointerRegistered) {
                    // get the pointer log and register it
                    eventLog.set(this._getPointerLog(event));
                    // flag the event log
                    eventLog._pointerRegistered = true;
                }
                // set user log *after* the pointer log (so it can be overwritten)
                eventLog.set(log);
                // dispatch the event if we created the event log here
                if(dispatch) this.onEvent.dispatch(eventLog);
                return eventLog;
            },

            _getPointerLog: function(event, target) {
                target = target || {};
                target.device = tools.eventInfo(event).device;
                target.originalType = event.type;
                if(target.device == 'touch') return this._getTouchLog(event, target);
                else                         return this._getMouseLog(event, target);
            },

            _getTouchLog: function(event, target) {
                var touches     = (event.originalEvent || event).touches,
                    n           = touches ? touches.length : 0,
                    pointersLog = target.pointers || {},
                    i, touch;
                target.pointers = pointersLog;
                pointersLog.count = n;
                for (i = 0; i < n; i++) {
                    touch = touches[i];
                    pointersLog[i] = {
                        identifier: touch.identifier,
                        x: touch.pageX,
                        y: touch.pageY
                    };
                }
                if (n > 0) {
                    pointersLog.mean = {
                        x: event.pageX,
                        y: event.pageY
                    };
                }
                return target;
            },

            _getMouseLog: function(event, target) {
                target.mean = {
                        x: event.pageX,
                        y: event.pageY
                };
                target.pointer = {
                    // avoid putting the same object
                    // so change in one of them does not impact
                    // the other
                    '0': {
                        x: event.pageX,
                        y: event.pageY
                    }
                };
                return target;
            }

        };
    });

});
<|endoftext|>


<commit_before>(function (extender, extended) {

    function isFunction(obj) {
        return typeof obj === "function";
    }

    function isBoolean(obj) {
        var undef, type = typeof obj;
        return obj !== undef && type === "boolean" || type === "Boolean";
    }

    function isUndefined(obj) {
        var undef;
        return obj !== null && obj === undef;
    }

    function isDefined(obj) {
        return !isUndefined(obj);
    }

    function isUndefinedOrNull(obj) {
        return isUndefined(obj) || isNull(obj);
    }

    function isNull(obj) {
        var undef;
        return obj !== undef && obj === null;
    }

    function isArguments(object) {
        return !isUndefinedOrNull(object) && Object.prototype.toString.call(object) === '[object Arguments]';
    }

    function isInstance(obj, clazz) {
        if (typeof clazz === "function") {
            return obj instanceof clazz;
        } else {
            return false;
        }
    }

    function isInstanceOf(obj, clazz) {
        return comb.array.some(argsToArray(arguments, 1), function (c) {
            return isInstance(obj, c);
        });
    }

    function isRegExp(obj) {
        return !isUndefinedOrNull(obj) && (obj instanceof RegExp);
    }

    function isArray(obj) {
        return Object.prototype.toString.call(obj) === "[object Array]";
    }

    function isDate(obj) {
        return (!isUndefinedOrNull(obj) && typeof obj === "object" && obj instanceof Date);
    }

    function isString(obj) {
        return !isUndefinedOrNull(obj) && (typeof obj === "string" || obj instanceof String);
    }

    function isNumber(obj) {
        return !isUndefinedOrNull(obj) && (typeof obj === "number" || obj instanceof Number);
    }

    var isMethods = {
        isFunction: isFunction,
        isNumber: isNumber,
        isString: isString,
        isDate: isDate,
        isArray: isArray,
        isBoolean: isBoolean,
        isUndefined: isUndefined,
        isDefined: isDefined,
        isUndefinedOrNull: isUndefinedOrNull,
        isNull: isNull,
        isArguments: isArguments,
        isInstanceOf: isInstanceOf,
        isRegExp: isRegExp
    };

    extended.register(extender.define(isMethods).expose(isMethods));
}).call(this, this.extender, this.extended);
<commit_msg>Fixed browser example<commit_after>(function (extender, extended) {

    function isFunction(obj) {
        return typeof obj === "function";
    }

    function isBoolean(obj) {
        var undef, type = typeof obj;
        return obj !== undef && type === "boolean" || type === "Boolean";
    }

    function isUndefined(obj) {
        var undef;
        return obj !== null && obj === undef;
    }

    function isDefined(obj) {
        return !isUndefined(obj);
    }

    function isUndefinedOrNull(obj) {
        return isUndefined(obj) || isNull(obj);
    }

    function isNull(obj) {
        var undef;
        return obj !== undef && obj === null;
    }

    function isArguments(object) {
        return !isUndefinedOrNull(object) && Object.prototype.toString.call(object) === '[object Arguments]';
    }

    function isInstance(obj, clazz) {
        if (typeof clazz === "function") {
            return obj instanceof clazz;
        } else {
            return false;
        }
    }

    function isRegExp(obj) {
        return !isUndefinedOrNull(obj) && (obj instanceof RegExp);
    }

    function isArray(obj) {
        return Object.prototype.toString.call(obj) === "[object Array]";
    }

    function isDate(obj) {
        return (!isUndefinedOrNull(obj) && typeof obj === "object" && obj instanceof Date);
    }

    function isString(obj) {
        return !isUndefinedOrNull(obj) && (typeof obj === "string" || obj instanceof String);
    }

    function isNumber(obj) {
        return !isUndefinedOrNull(obj) && (typeof obj === "number" || obj instanceof Number);
    }

    var isMethods = {
        isFunction: isFunction,
        isNumber: isNumber,
        isString: isString,
        isDate: isDate,
        isArray: isArray,
        isBoolean: isBoolean,
        isUndefined: isUndefined,
        isDefined: isDefined,
        isUndefinedOrNull: isUndefinedOrNull,
        isNull: isNull,
        isArguments: isArguments,
        isInstanceOf: isInstance,
        isRegExp: isRegExp
    };

    extended.register(extender.define(isMethods).expose(isMethods));
}).call(this, this.extender, this.extended);
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.listview_settings['User'] = {
	add_fields: ["enabled", "user_type", "user_image"],
	filters: [["enabled","=",1]],
	prepare_data: function(data) {
		data["user_for_avatar"] = data["name"];
	},
	get_indicator: function(doc) {
		if(doc.enabled) {
			return [__("Active"), "green", "enabled,=,1"];
		} else {
			return [__("Disabled"), "grey", "enabled,=,0"];
		}
	}
};

frappe.help.youtube_id["User"] = "fnBoRhBrwR4";
<commit_msg>fix broken YouTube link for user help<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.listview_settings['User'] = {
	add_fields: ["enabled", "user_type", "user_image"],
	filters: [["enabled","=",1]],
	prepare_data: function(data) {
		data["user_for_avatar"] = data["name"];
	},
	get_indicator: function(doc) {
		if(doc.enabled) {
			return [__("Active"), "green", "enabled,=,1"];
		} else {
			return [__("Disabled"), "grey", "enabled,=,0"];
		}
	}
};

frappe.help.youtube_id["User"] = "8Slw1hsTmUI";
<|endoftext|>


<commit_before><commit_msg>Upgrade editor to v0.20.0<commit_after><|endoftext|>


<commit_before>"use strict";
var GITHUB_DOMAIN = "https://github.com";
function parse(event) {
    var repo = event.repo.name;
    switch (event.type) {
        case 'CreateEvent':
            switch (event.payload.ref_type) {
                case 'repository':
                    return {
                        text: "created repo {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
                case 'tag':
                    return {
                        text: "created tag {{ref_type}} at {{repository}}",
                        data: {
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo + "/releases/tag/" + event.payload.ref
                    };
                case 'branch':
                    return {
                        text: "created branch {{ref_type}} at {{repository}}",
                        data: {
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo + "/tree/" + event.payload.ref
                    };
            }
            break;
        case 'MemberEvent':
            switch (event.payload.action) {
                case 'added':
                    return {
                        text: "added {{member}} to {{repository}}",
                        data: {
                            member: event.payload.member,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + event.payload.member.login
                    };
            }
            break;
        case 'PushEvent':
            var branch = event.payload.ref.substr(event.payload.ref.lastIndexOf('/') + 1);
            return {
                text: "pushed to {{branch}} at {{repository}}",
                data: {
                    branch: branch,
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo + "/compare/" + event.payload.before + "..." + event.payload.head
            };
            break;
        case 'ForkApplyEvent':
            return {
                text: "merged to {{repository}}",
                data: {
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo.name + "/compare/" + event.payload.before + "..." + event.payload.head
            };
            break;
        case 'ForkEvent':
            return {
                text: "forked {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.forkee.html_url
            };
            break;
        case 'WatchEvent':
            switch (event.payload.action) {
                case 'started':
                    return {
                        text: "started watching {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
                    break;
                case 'stopped':
                    return {
                        text: "stopped watching {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
            }
            break;
        case 'FollowEvent':
            return {
                text: "followed {{login}}",
                data: {
                    login: event.payload.target.login,
                    name: event.payload.target.name
                },
                html_url: GITHUB_DOMAIN + "/" + event.payload.target.login
            };
            break;
        case 'IssuesEvent':
        case 'PullRequestEvent':
            var payloadObject = (event.payload.pull_request || event.payload.issue);
            switch (event.payload.action) {
                case 'opened':
                case 'reopened':
                    return {
                        text: "opened issue on {{repository}}#{{number}}",
                        data: {
                            repository: repo,
                            number: payloadObject.number
                        },
                        html_url: payloadObject.html_url
                    };
                case 'closed':
                    return {
                        text: "closed issue on {{repository}}#{{number}}",
                        data: {
                            repository: repo,
                            number: payloadObject.number
                        },
                        html_url: payloadObject.html_url
                    };
            }
            break;
        case 'GistEvent':
            switch (event.payload.action) {
                case 'create':
                    return {
                        text: "created {{name}}",
                        data: {
                            name: event.payload.name
                        },
                        html_url: event.payload.gist.html_url
                    };
                case 'update':
                    return {
                        text: "updated {{name}}",
                        data: {
                            name: event.payload.name
                        },
                        html_url: event.payload.gist.html_url
                    };
                case 'fork':
                    return {
                        text: "forked {{name}}",
                        data: {
                            name: event.payload.name
                        },
                        html_url: event.payload.gist.html_url
                    };
            }
            break;
        case 'WikiEvent':
        case 'GollumEvent':
            if (event.payload.pages.some(function (page) {
                return page.action === "created";
            })) {// created
                return {
                    text: "created a wiki page on {{repository}}",
                    data: {
                        repository: repo
                    },
                    html_url: event.payload.pages[0].html_url

                };
            } else { // edited
                return {
                    text: "edited a wiki page on {{repository}}",
                    data: {
                        repository: repo
                    },
                    // https://github.com/Constellation/escodegen/wiki/_compare/8071c6feb719b3c9e1742620aab9c1bbfda80e70...a567b1a221885a9ae5c576561e18ce68909624b6
                    html_url: GITHUB_DOMAIN + "/" + repo
                        + "/wiki/_compare/" + event.payload.pages[0].sha + "..." + event.payload.pages[event.payload.pages.length-1].sha
                };
            }
            break;
        case 'CommitCommentEvent':
            return {
                text: "commented on {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.comment.html_url
            };
        case 'PullRequestReviewCommentEvent':
            return {
                text: "commented on {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.comment.html_url
            };
        case 'IssueCommentEvent':
            return {
                text: "commented on {{repository}}#{{number}}",
                data: {
                    repository: repo,
                    number: (event.payload.pull_request || event.payload.issue).number
                },
                html_url: event.payload.comment.html_url
            };

        case 'DeleteEvent':
            switch (event.payload.ref_type) {
                case 'branch':
                    return {
                        text: "deleted branch {{ref}} at {{repository}}",
                        data: {
                            ref: event.payload.ref,
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
            }
            break;
        case 'PublicEvent':
            return {
                text: "open sourced {{repository}}",
                data: {
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo
            };
        case 'DownloadEvent':
            return {
                text: "created download {{name}}",
                data: {
                    name: event.payload.download.name
                },
                html_url: event.payload.download.html_url
            };
    }
    console.warn('Event:' + event.type, event);
    // Dummy Object
    return {
        text: "Dummy!! " + event.type,
        data: {}
    }
}

function compile(event) {
    var object = parse(event);
    var userName = event.actor.login;
    var keys = Object.keys(object.data);
    var result = object.text;
    keys.forEach(function (key) {
        result = result.replace("{{" + key + "}}", object.data[key]);
    });
    return userName + " " + result;
}
module.exports.parse = parse;
module.exports.compile = compile;
<commit_msg>fix(parse): fix gist text<commit_after>"use strict";
var GITHUB_DOMAIN = "https://github.com";
function parse(event) {
    var repo = event.repo.name;
    switch (event.type) {
        case 'CreateEvent':
            switch (event.payload.ref_type) {
                case 'repository':
                    return {
                        text: "created repo {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
                case 'tag':
                    return {
                        text: "created tag {{ref_type}} at {{repository}}",
                        data: {
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo + "/releases/tag/" + event.payload.ref
                    };
                case 'branch':
                    return {
                        text: "created branch {{ref_type}} at {{repository}}",
                        data: {
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo + "/tree/" + event.payload.ref
                    };
            }
            break;
        case 'MemberEvent':
            switch (event.payload.action) {
                case 'added':
                    return {
                        text: "added {{member}} to {{repository}}",
                        data: {
                            member: event.payload.member,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + event.payload.member.login
                    };
            }
            break;
        case 'PushEvent':
            var branch = event.payload.ref.substr(event.payload.ref.lastIndexOf('/') + 1);
            return {
                text: "pushed to {{branch}} at {{repository}}",
                data: {
                    branch: branch,
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo + "/compare/" + event.payload.before + "..." + event.payload.head
            };
            break;
        case 'ForkApplyEvent':
            return {
                text: "merged to {{repository}}",
                data: {
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo.name + "/compare/" + event.payload.before + "..." + event.payload.head
            };
            break;
        case 'ForkEvent':
            return {
                text: "forked {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.forkee.html_url
            };
            break;
        case 'WatchEvent':
            switch (event.payload.action) {
                case 'started':
                    return {
                        text: "started watching {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
                    break;
                case 'stopped':
                    return {
                        text: "stopped watching {{repository}}",
                        data: {
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
            }
            break;
        case 'FollowEvent':
            return {
                text: "followed {{login}}",
                data: {
                    login: event.payload.target.login,
                    name: event.payload.target.name
                },
                html_url: GITHUB_DOMAIN + "/" + event.payload.target.login
            };
            break;
        case 'IssuesEvent':
        case 'PullRequestEvent':
            var payloadObject = (event.payload.pull_request || event.payload.issue);
            switch (event.payload.action) {
                case 'opened':
                case 'reopened':
                    return {
                        text: "opened issue on {{repository}}#{{number}}",
                        data: {
                            repository: repo,
                            number: payloadObject.number
                        },
                        html_url: payloadObject.html_url
                    };
                case 'closed':
                    return {
                        text: "closed issue on {{repository}}#{{number}}",
                        data: {
                            repository: repo,
                            number: payloadObject.number
                        },
                        html_url: payloadObject.html_url
                    };
            }
            break;
        case 'GistEvent':
            switch (event.payload.action) {
                case 'create':
                    return {
                        text: "created gist:{{id}}",
                        data: {
                            id: event.payload.gist.id
                        },
                        html_url: event.payload.gist.html_url
                    };
                case 'update':
                    return {
                        text: "updated gist:{{id}}",
                        data: {
                            id: event.payload.gist.id
                        },
                        html_url: event.payload.gist.html_url
                    };
                case 'fork':
                    return {
                        text: "forked gist:{{id}}",
                        data: {
                            id: event.payload.gist.id
                        },
                        html_url: event.payload.gist.html_url
                    };
            }
            break;
        case 'WikiEvent':
        case 'GollumEvent':
            if (event.payload.pages.some(function (page) {
                return page.action === "created";
            })) {// created
                return {
                    text: "created a wiki page on {{repository}}",
                    data: {
                        repository: repo
                    },
                    html_url: event.payload.pages[0].html_url

                };
            } else { // edited
                return {
                    text: "edited a wiki page on {{repository}}",
                    data: {
                        repository: repo
                    },
                    // https://github.com/Constellation/escodegen/wiki/_compare/8071c6feb719b3c9e1742620aab9c1bbfda80e70...a567b1a221885a9ae5c576561e18ce68909624b6
                    html_url: GITHUB_DOMAIN + "/" + repo
                        + "/wiki/_compare/" + event.payload.pages[0].sha + "..." + event.payload.pages[event.payload.pages.length - 1].sha
                };
            }
            break;
        case 'CommitCommentEvent':
            return {
                text: "commented on {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.comment.html_url
            };
        case 'PullRequestReviewCommentEvent':
            return {
                text: "commented on {{repository}}",
                data: {
                    repository: repo
                },
                html_url: event.payload.comment.html_url
            };
        case 'IssueCommentEvent':
            return {
                text: "commented on {{repository}}#{{number}}",
                data: {
                    repository: repo,
                    number: (event.payload.pull_request || event.payload.issue).number
                },
                html_url: event.payload.comment.html_url
            };

        case 'DeleteEvent':
            switch (event.payload.ref_type) {
                case 'branch':
                    return {
                        text: "deleted branch {{ref}} at {{repository}}",
                        data: {
                            ref: event.payload.ref,
                            ref_type: event.payload.ref_type,
                            repository: repo
                        },
                        html_url: GITHUB_DOMAIN + "/" + repo
                    };
            }
            break;
        case 'PublicEvent':
            return {
                text: "open sourced {{repository}}",
                data: {
                    repository: repo
                },
                html_url: GITHUB_DOMAIN + "/" + repo
            };
        case 'DownloadEvent':
            return {
                text: "created download {{name}}",
                data: {
                    name: event.payload.download.name
                },
                html_url: event.payload.download.html_url
            };
    }
    console.warn('Event:' + event.type, event);
    // Dummy Object
    return {
        text: "Dummy!! " + event.type,
        data: {}
    }
}

function compile(event) {
    var object = parse(event);
    var userName = event.actor.login;
    var keys = Object.keys(object.data);
    var result = object.text;
    keys.forEach(function (key) {
        result = result.replace("{{" + key + "}}", object.data[key]);
    });
    return userName + " " + result;
}
module.exports.parse = parse;
module.exports.compile = compile;
<|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames';

const statusColorMap = {
  null: 'text-grey-light',
  error: 'text-red-light',
  queued: 'text-orange-light',
  running: 'text-blue-light',
  success: 'text-green-light',
  interrupted: 'text-grey-light'
};

const statusTextMap = {
  null: 'This task has never been scheduled',
  error: 'Last execution of this task failed',
  queued: 'This task is currently queued',
  running: 'This task is running',
  success: 'Last execution of this task succeeded',
  interrupted: 'Interrupted during last execution'
};

export default function({ status, message, inline, size }) {
  if (status === undefined) return null;
  const svgClassNames = classNames({
    'w-6': size !== 'small',
    'h-6': size !== 'small',
    'w-4': size === 'small',
    'h-4': size === 'small',
    'fill-current': true,
    [statusColorMap[status]]: true
  });

  return (
    <div
      className={classNames({ inline })}
      title={message || statusTextMap[status] || `Unknown status: ${status}`}
    >
      <svg className={svgClassNames} viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="40" stroke="black" strokeWidth="3" />
      </svg>
    </div>
  );
}
<commit_msg>better status message with reason<commit_after>import React from 'react';
import classNames from 'classnames';

const statusColorMap = {
  null: 'text-grey-light',
  error: 'text-red-light',
  queued: 'text-orange-light',
  running: 'text-blue-light',
  success: 'text-green-light',
  interrupted: 'text-grey-light'
};

const statusTextMap = {
  null: 'This task has never been scheduled',
  error: 'Last execution of this task failed',
  queued: 'This task is currently queued',
  running: 'This task is running',
  success: 'Last execution of this task succeeded',
  interrupted: 'Interrupted during last execution'
};

export default function({ status, message, inline, size }) {
  if (status === undefined) return null;
  const svgClassNames = classNames({
    'w-6': size !== 'small',
    'h-6': size !== 'small',
    'w-4': size === 'small',
    'h-4': size === 'small',
    'fill-current': true,
    [statusColorMap[status]]: true
  });

  return (
    <div
      className={classNames({ inline })}
      title={
        message
          ? `${statusTextMap[status]}: ${message}`
          : statusTextMap[status] || `Unknown status: ${status}`
      }
    >
      <svg className={svgClassNames} viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="40" stroke="black" strokeWidth="3" />
      </svg>
    </div>
  );
}
<|endoftext|>


<commit_before>import React, { Component } from "react";
import ReactDOM from "react-dom";

export default class ResultItem extends Component {
  componentDidUpdate() {
    if (this.props.selected) {
      ReactDOM.findDOMNode(this).scrollIntoView(false);
    }
  }
  clickEvent(event) {
    this.props.onClick(this.props.result);
  }
  render() {
    let result = this.props.result;
    return (

            {result.name}

            {result.author}

    );
  }
}
<commit_msg>Inline method call<commit_after>import React, { Component } from "react";
import ReactDOM from "react-dom";

export default class ResultItem extends Component {
  componentDidUpdate() {
    if (this.props.selected) {
      ReactDOM.findDOMNode(this).scrollIntoView(false);
    }
  }
  render() {
    const { result, onClick, selected } = this.props;
    return (

 onClick(result)} className={selected ? 'selected' : ''}>

            {result.name}

            {result.author}

    );
  }
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2015 mifort.org
 *
 * 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.
 */

'use strict';

angular.module('mifortTimelog.timelog', ['ngRoute'])

    .config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/timelog', {
            templateUrl: 'timelog/timelogView.html',
            controller: 'timelogController'
        });
    }])

    .controller('timelogController', ['$scope', '$filter', 'timelogService', 'timesheetService', 'preferences', 'loginService', '$timeout',
        function($scope, $filter, timelogService, timesheetService, preferences, loginService, $timeout) {
        var user = preferences.get('user');
        $scope.projects = [];
        $scope.isCollapsed = false;
        $scope.timelogKeys = timelogService.getTimelogKeys();
        $scope.userName = user.displayName;

        loginService.getUser().success(function (user) {
            if(user){
                $scope.assignments = user.assignments;

                $scope.assignments.forEach(function(assignment, index) {
                    if(!index || index && assignment.projectId != $scope.assignments[index-1].projectId){
                        timelogService.getProject(assignment.projectId).success(function(project) {
                            if(project && project.active) {
                                project.currentPeriodIndex = 0;
                                $scope.projects.push(project);
                            }
                        }).then(function() {

                            if(index == $scope.assignments.length - 1){
                                $scope.init();
                            }
                        });
                    }
                });
            }
        });

        $scope.init = function() {
            $scope.projects.forEach(function(project) {
                var today = moment();

                project.currentPeriodIndex = 0;

                project.periods.forEach(function(period, periodIndex) {
                    if(today >= moment(new Date(period.start)) && today <= moment(new Date(period.end))){
                        project.currentPeriodIndex = periodIndex;
                    }
                });

                initPeriod(project, project.currentPeriodIndex);
            });
        };

        function initPeriod(project, periodIndex){
            var startDate = project.periods[periodIndex].start,
                endDate = project.periods[periodIndex].end;

            project.periods[periodIndex].timelog = [];
            project.periods[periodIndex].userTimelogs = [];

            timelogService.getTimelog(user._id, project._id, startDate, endDate).success(function(dataTimelog) {
                project.periods[periodIndex].userTimelogs.push.apply(project.periods[periodIndex].userTimelogs, dataTimelog.timelog);
            }).then(function() {
                var projectIndex = _.findIndex($scope.projects, {_id: project._id});

                generateDaysTemplates(project, periodIndex);
                applyProjectDefaultValues(project, periodIndex);
                applyUserTimelogs(project, periodIndex);
                initWatchers(projectIndex, periodIndex);
            });
        }

        function applyUserTimelogs(project, periodIndex){
            var period = project.periods[periodIndex];

            project.periods[periodIndex].userTimelogs.forEach(function(day, index) {
                var timelogDayIndex = _.findIndex(period.timelog, {date: moment(new Date(day.date)).format("MM/DD/YYYY")});

                //if current iterated log is not the first for this date to push
                if(project.periods[periodIndex].timelog[index - 1] && project.periods[periodIndex].timelog[index - 1].date == day.date) {
                    if(!period.timelog[timelogDayIndex]._id){
                        day.isFirstDayRecord = true;
                        period.timelog[timelogDayIndex] = day;
                    }
                    else{
                        day.isFirstDayRecord = false;
                        period.timelog.splice(timelogDayIndex + 1, 0, day);
                    }
                }
                else {
                    day.isFirstDayRecord = true;
                    if(!_.findWhere(period.timelog, {date: day.date}).comment){
                        //_.findWhere(period.timelog, {date: day.date}).comment = period.timelog[timelogDayIndex].comment;
                        _.findWhere(period.timelog, {date: day.date}).comment = day.comment;
                    }
                    angular.extend(period.timelog[timelogDayIndex], day);
                }
            });
        }

        function applyProjectDefaultValues(project, periodIndex){
            if(project.defaultValues) {
                project.defaultValues.forEach(function(day) {
                    var dayExisted = _.findWhere(project.periods[periodIndex].timelog, {date: moment(new Date(day.date)).format("MM/DD/YYYY")});
                    if(dayExisted) {
                        angular.extend(dayExisted, day);

                        if(!dayExisted.comment){
                            dayExisted.comment = day.comment;
                        }
                    }
                });
            }
        }

        function generateDaysTemplates(project, periodIndex){
            var startDate = moment(new Date(project.periods[periodIndex].start)),
                endDate = moment(new Date(project.periods[periodIndex].end)),
                daysToGenerate = endDate.diff(startDate, 'days');

            for (var i = 0; i < daysToGenerate + 1; i++) {
                var dayToPush;

                //TODO: to template
                project.template.workload = user.workload;
                project.template.userId = user._id;
                project.template.projectId = project._id;
                project.template.projectName = project.name;

                dayToPush = _.clone(project.template);
                dayToPush.date = angular.copy(startDate).add(i, 'days').format("MM/DD/YYYY");
                dayToPush.isFirstDayRecord = true;
                dayToPush.userName = $scope.userName;

                project.periods[periodIndex].timelog.push(dayToPush);
            }
        }

        function initWatchers(projectIndex, periodIndex){
            var timer = null;

            $scope.$watch('projects[' + projectIndex + '].periods[' + periodIndex +'].timelog', function(newValue, oldValue) {
                if(newValue != oldValue && newValue.length >= oldValue.length) {
                    if(timer){
                        $timeout.cancel(timer);
                    }

                    newValue.map(function(timelogDay) {
                        delete timelogDay.color;

                        return timelogDay;
                    });

                    timer = $timeout(function() {
                        timelogService.updateTimelog(user._id, newValue).success(function(data) {
                            var periodTimelog = $scope.projects[projectIndex].periods[periodIndex].timelog,
                                noIdLog = _.find(periodTimelog, function(log) {
                                    return !log._id;
                                });

                            //if(noIdLog){
                            //    angular.extend(periodTimelog, data.timelog);
                            //}

                            angular.extend(periodTimelog, data.timelog);
                        });
                    }, 500)
                }
            }, true);
        }

        $scope.addRow = function(log, project, periodIndex) {
            var newRow = angular.copy(project.template),
                dayPeriodIndex = _.findIndex(project.periods[periodIndex].timelog, {date: log.date});

            newRow.date = log.date;
            newRow.userName = log.userName;
            newRow.isFirstDayRecord = false;

            project.periods[periodIndex].timelog.splice(dayPeriodIndex + 1, 0, newRow);
        };

        $scope.removeRow = function(log, project, periodIndex) {
            if(log._id) {
                var dayPeriodIndex = _.findIndex(project.periods[periodIndex].timelog, {_id: log._id});
                timelogService.removeTimelog(log);

                project.periods[periodIndex].timelog.splice(dayPeriodIndex, 1);
            }
        };

        $scope.isWeekend = function(date) {
            return new Date(date).getDay() == 6 || new Date(date).getDay() == 0;
        };

        $scope.showPreviousPeriod = function(project) {
            if(project.currentPeriodIndex){
                project.currentPeriodIndex--;

                if(!project.periods[project.currentPeriodIndex].timelog){
                    initPeriod(project, project.currentPeriodIndex);
                }
            }
        };

        $scope.showNextPeriod = function(project) {
            if(project.currentPeriodIndex < project.periods.length - 1){
                project.currentPeriodIndex++;

                if(!project.periods[project.currentPeriodIndex].timelog){
                    initPeriod(project, project.currentPeriodIndex);
                }
            }
        };
    }]);<commit_msg>Update log only on NO id<commit_after>/*!
 * Copyright 2015 mifort.org
 *
 * 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.
 */

'use strict';

angular.module('mifortTimelog.timelog', ['ngRoute'])

    .config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/timelog', {
            templateUrl: 'timelog/timelogView.html',
            controller: 'timelogController'
        });
    }])

    .controller('timelogController', ['$scope', '$filter', 'timelogService', 'timesheetService', 'preferences', 'loginService', '$timeout',
        function($scope, $filter, timelogService, timesheetService, preferences, loginService, $timeout) {
        var user = preferences.get('user');
        $scope.projects = [];
        $scope.isCollapsed = false;
        $scope.timelogKeys = timelogService.getTimelogKeys();
        $scope.userName = user.displayName;

        loginService.getUser().success(function (user) {
            if(user){
                $scope.assignments = user.assignments;

                $scope.assignments.forEach(function(assignment, index) {
                    if(!index || index && assignment.projectId != $scope.assignments[index-1].projectId){
                        timelogService.getProject(assignment.projectId).success(function(project) {
                            if(project && project.active) {
                                project.currentPeriodIndex = 0;
                                $scope.projects.push(project);
                            }
                        }).then(function() {

                            if(index == $scope.assignments.length - 1){
                                $scope.init();
                            }
                        });
                    }
                });
            }
        });

        $scope.init = function() {
            $scope.projects.forEach(function(project) {
                var today = moment();

                project.currentPeriodIndex = 0;

                project.periods.forEach(function(period, periodIndex) {
                    if(today >= moment(new Date(period.start)) && today <= moment(new Date(period.end))){
                        project.currentPeriodIndex = periodIndex;
                    }
                });

                initPeriod(project, project.currentPeriodIndex);
            });
        };

        function initPeriod(project, periodIndex){
            var startDate = project.periods[periodIndex].start,
                endDate = project.periods[periodIndex].end;

            project.periods[periodIndex].timelog = [];
            project.periods[periodIndex].userTimelogs = [];

            timelogService.getTimelog(user._id, project._id, startDate, endDate).success(function(dataTimelog) {
                project.periods[periodIndex].userTimelogs.push.apply(project.periods[periodIndex].userTimelogs, dataTimelog.timelog);
            }).then(function() {
                var projectIndex = _.findIndex($scope.projects, {_id: project._id});

                generateDaysTemplates(project, periodIndex);
                applyProjectDefaultValues(project, periodIndex);
                applyUserTimelogs(project, periodIndex);
                initWatchers(projectIndex, periodIndex);
            });
        }

        function applyUserTimelogs(project, periodIndex){
            var period = project.periods[periodIndex];

            project.periods[periodIndex].userTimelogs.forEach(function(day, index) {
                var timelogDayIndex = _.findIndex(period.timelog, {date: moment(new Date(day.date)).format("MM/DD/YYYY")});

                //if current iterated log is not the first for this date to push
                if(project.periods[periodIndex].timelog[index - 1] && project.periods[periodIndex].timelog[index - 1].date == day.date) {
                    if(!period.timelog[timelogDayIndex]._id){
                        day.isFirstDayRecord = true;
                        period.timelog[timelogDayIndex] = day;
                    }
                    else{
                        day.isFirstDayRecord = false;
                        period.timelog.splice(timelogDayIndex + 1, 0, day);
                    }
                }
                else {
                    day.isFirstDayRecord = true;
                    if(!_.findWhere(period.timelog, {date: day.date}).comment){
                        //_.findWhere(period.timelog, {date: day.date}).comment = period.timelog[timelogDayIndex].comment;
                        _.findWhere(period.timelog, {date: day.date}).comment = day.comment;
                    }
                    angular.extend(period.timelog[timelogDayIndex], day);
                }
            });
        }

        function applyProjectDefaultValues(project, periodIndex){
            if(project.defaultValues) {
                project.defaultValues.forEach(function(day) {
                    var dayExisted = _.findWhere(project.periods[periodIndex].timelog, {date: moment(new Date(day.date)).format("MM/DD/YYYY")});
                    if(dayExisted) {
                        angular.extend(dayExisted, day);

                        if(!dayExisted.comment){
                            dayExisted.comment = day.comment;
                        }
                    }
                });
            }
        }

        function generateDaysTemplates(project, periodIndex){
            var startDate = moment(new Date(project.periods[periodIndex].start)),
                endDate = moment(new Date(project.periods[periodIndex].end)),
                daysToGenerate = endDate.diff(startDate, 'days');

            for (var i = 0; i < daysToGenerate + 1; i++) {
                var dayToPush;

                //TODO: to template
                project.template.workload = user.workload;
                project.template.userId = user._id;
                project.template.projectId = project._id;
                project.template.projectName = project.name;

                dayToPush = _.clone(project.template);
                dayToPush.date = angular.copy(startDate).add(i, 'days').format("MM/DD/YYYY");
                dayToPush.isFirstDayRecord = true;
                dayToPush.userName = $scope.userName;

                project.periods[periodIndex].timelog.push(dayToPush);
            }
        }

        function initWatchers(projectIndex, periodIndex){
            var timer = null;

            $scope.$watch('projects[' + projectIndex + '].periods[' + periodIndex +'].timelog', function(newValue, oldValue) {
                if(newValue != oldValue && newValue.length >= oldValue.length) {
                    if(timer){
                        $timeout.cancel(timer);
                    }

                    newValue.map(function(timelogDay) {
                        delete timelogDay.color;

                        return timelogDay;
                    });

                    timer = $timeout(function() {
                        timelogService.updateTimelog(user._id, newValue).success(function(data) {
                            var periodTimelog = $scope.projects[projectIndex].periods[periodIndex].timelog,
                                noIdLog = _.find(periodTimelog, function(log) {
                                    return !log._id;
                                });

                            if(noIdLog){
                                angular.extend(periodTimelog, data.timelog);
                            }

                            //angular.extend(periodTimelog, data.timelog);
                        });
                    }, 500)
                }
            }, true);
        }

        $scope.addRow = function(log, project, periodIndex) {
            var newRow = angular.copy(project.template),
                dayPeriodIndex = _.findIndex(project.periods[periodIndex].timelog, {date: log.date});

            newRow.date = log.date;
            newRow.userName = log.userName;
            newRow.isFirstDayRecord = false;

            project.periods[periodIndex].timelog.splice(dayPeriodIndex + 1, 0, newRow);
        };

        $scope.removeRow = function(log, project, periodIndex) {
            if(log._id) {
                var dayPeriodIndex = _.findIndex(project.periods[periodIndex].timelog, {_id: log._id});
                timelogService.removeTimelog(log);

                project.periods[periodIndex].timelog.splice(dayPeriodIndex, 1);
            }
        };

        $scope.isWeekend = function(date) {
            return new Date(date).getDay() == 6 || new Date(date).getDay() == 0;
        };

        $scope.showPreviousPeriod = function(project) {
            if(project.currentPeriodIndex){
                project.currentPeriodIndex--;

                if(!project.periods[project.currentPeriodIndex].timelog){
                    initPeriod(project, project.currentPeriodIndex);
                }
            }
        };

        $scope.showNextPeriod = function(project) {
            if(project.currentPeriodIndex < project.periods.length - 1){
                project.currentPeriodIndex++;

                if(!project.periods[project.currentPeriodIndex].timelog){
                    initPeriod(project, project.currentPeriodIndex);
                }
            }
        };
    }]);<|endoftext|>