<commit_before>
import React from 'react';
import { CacheRequester, Loading } from './ajax';

var dropCookie = true;  // false disables the Cookie, allowing you to style the banner
var cookieDurationClose = 3;
var cookieDurationVote = 60;
var cookieName = 'anketaKolacik2018Leto'; // Name of our cookie
var cookieValue = 'on'; // Value of cookie
var cookieHideDate = Date.parse('3 July 2018'); // Starting this day the cookie won't be visible

export class AnketaPopup extends React.Component {
  constructor(props) {
    super(props);
    var today = new Date();
    var showPopup = checkCookie(cookieName) != cookieValue && cookieHideDate > today;
    this.state = { showPopup };
  }

  onClosePopup = (action) => {
    if(action == 0) {
      createCookie(cookieName, cookieValue, cookieDurationVote); // Create vote cookie
    } else {
      createCookie(cookieName, cookieValue, cookieDurationClose); // Create close cookie
    }
    this.setState({showPopup: false})
  }

  render() {
    if (!this.state.showPopup) return null;

    var cache = new CacheRequester();
    var studia = cache.get('get_studia');
    if (!studia) return
<Loading requests={cache.missing} />
;
    if (!studia.some(s => s.organizacna_jednotka == 'FMFI')) return null;

    return

Daj semestru ešte chvíľu

                     {this.onClosePopup(0)}} href="https://anketa.fmph.uniba.sk/?anketaPopup" target="_blank" rel="noopener noreferrer" >Hlasuj v ankete
                     {this.onClosePopup(1)}} href="javascript:void(0);">Neskôr

;
  }
}

function createCookie(name, value, days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    if(dropCookie) {
        document.cookie = name+"="+value+expires+"; path=/";
    }
}

function checkCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name,"",-1);
}
<commit_msg>anketa-popup: Updates for Winter 2018 (#130)<commit_after>
import React from 'react';
import { CacheRequester, Loading } from './ajax';

var dropCookie = true;  // false disables the Cookie, allowing you to style the banner
var cookieDurationClose = 3;
var cookieDurationVote = 60;
var cookieName = 'anketaKolacik2018Zima'; // Name of our cookie
var cookieValue = 'on'; // Value of cookie
var cookieHideDate = Date.parse('19 February 2019'); // Starting this day the cookie won't be visible

export class AnketaPopup extends React.Component {
  constructor(props) {
    super(props);
    var today = new Date();
    var showPopup = checkCookie(cookieName) != cookieValue && cookieHideDate > today;
    this.state = { showPopup };
  }

  onClosePopup = (action) => {
    if(action == 0) {
      createCookie(cookieName, cookieValue, cookieDurationVote); // Create vote cookie
    } else {
      createCookie(cookieName, cookieValue, cookieDurationClose); // Create close cookie
    }
    this.setState({showPopup: false})
  }

  render() {
    if (!this.state.showPopup) return null;

    var cache = new CacheRequester();
    var studia = cache.get('get_studia');
    if (!studia) return
<Loading requests={cache.missing} />
;
    if (!studia.some(s => s.organizacna_jednotka == 'FMFI')) return null;

    return

Daj semestru ešte chvíľu

                     {this.onClosePopup(0)}} href="https://anketa.fmph.uniba.sk/?anketaPopup" target="_blank" rel="noopener noreferrer" >Hlasuj v ankete
                     {this.onClosePopup(1)}} href="javascript:void(0);">Neskôr

;
  }
}

function createCookie(name, value, days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    if(dropCookie) {
        document.cookie = name+"="+value+expires+"; path=/";
    }
}

function checkCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name,"",-1);
}
<|endoftext|>


<commit_before>export default class CityNameGenerator {
  constructor ({cityNames}) {
    this.cityNames = cityNames
  }

  generateName () {
    var first = this.getRandomId()
    var second = this.getRandomId()

    if (second === first) {
      second++
      if (second === this.cityNames.length) {
        second = 0
      }
    }

    var name = this.getStart(first) + this.getEnd(second, first)

    return name
  }

  getStart (id) {
    var no = this.cityNames[id]

    if (no.full !== undefined) {
      return no.name.slice(0, no.full)
    }

    return no.name.slice(0, no.point)
  }

  getEnd (id, first) {
    var no = this.cityNames[id]

    if (this.cityNames[first].full !== undefined) {
      return no.name
    }

    return no.name.slice(no.point)
  }

  getRandomId () {
    var r = Math.random()
    return Math.floor(r * (this.cityNames.length))
  }
}
<commit_msg>jsdocs kaupungin nimigeneraattorille<commit_after>/**
 * Generates a random name for the city
 */

export default class CityNameGenerator {

  /**
   * Creates the generator
   *
   * @param {Object[]} param.cityNames - list of names that the generator uses
   */
  constructor ({cityNames}) {
    this.cityNames = cityNames
  }

  /**
  * Generates the name from two randomly chosen names from the list
  *
  * @returns {String} - newly generated name
  */
  generateName () {
    var first = this.getRandomId()
    var second = this.getRandomId()

    if (second === first) {
      second++
      if (second === this.cityNames.length) {
        second = 0
      }
    }

    var name = this.getStart(first) + this.getEnd(second, first)

    return name
  }

  /**
   * Generates a start for the new name
   *
   * @param {int} param.id - id of the word to be used
   * @returns {String} - start for the new name
   */
  getStart (id) {
    var no = this.cityNames[id]

    if (no.full !== undefined) {
      return no.name.slice(0, no.full)
    }

    return no.name.slice(0, no.point)
  }

  /**
   * Generater an end for the new name
   *
   * @param {int} id - id of the word to be used
   * @param {int} first - id of the name used in the first part
   * @returns {String} - end for the new name
   */
  getEnd (id, first) {
    var no = this.cityNames[id]

    if (this.cityNames[first].full !== undefined) {
      return no.name
    }

    return no.name.slice(no.point)
  }

  /**
   * Ramndomly chooses an id to be used
   *
   * @returns {int} - randomly chosen id
   */
  getRandomId () {
    var r = Math.random()
    return Math.floor(r * (this.cityNames.length))
  }
}
<|endoftext|>


<commit_before>export default list

import Entry from '../entry'
import PouchDB from 'pouchdb'
import {getOutputs} from './output'
import moment from 'moment'
import _ from 'lodash'
import chalk from 'chalk'
import format from '../time'
import conf from '../config'

let db = new PouchDB(conf.db)

function list (yargs) {
  let argv = yargs
  .usage('tick list')
  .help('h')
  .alias('h', 'help')
  .argv

  db.query(mapDate, {
    include_docs: true,
    descending: true
  }).then(writeEntries)

}

function mapDate (doc) {
  emit(doc.fromArr)
}

function writeEntries (results) {
  let prevDate = null
  let dat = _.chain(results.rows)
  .map(row => { return Entry.fromJSON(row.doc) })
  .groupBy(e => { return moment(e.from).startOf('day').format('YYYY-MM-DD') })
  .map((group, d) => {
    return {
      ticks: group,
      date: moment(d, 'YYYY-MM-DD').toDate(),
      minutes: _.reduce(group, (sum, e) => { return sum + e.duration.minutes }, 0)
    }
  })
  .each(group => {
    const date = moment(group.date).format('ddd, MMM DD, YYYY')
    const time = format(group.minutes)
    console.log(`${chalk.yellow(date)} ${chalk.green(time)}`)
    group.ticks.forEach(t => { console.log(getOutputs(t).simple) })
  })
  .value()
}
<commit_msg>Clean up usage for tick list<commit_after>export default list

import Entry from '../entry'
import PouchDB from 'pouchdb'
import {getOutputs} from './output'
import moment from 'moment'
import _ from 'lodash'
import chalk from 'chalk'
import format from '../time'
import conf from '../config'

let db = new PouchDB(conf.db)

function list (yargs) {
  let argv = yargs
  .usage('Usage: tick list [options]')
  .help('h')
  .alias('h', 'help')
  .argv

  db.query(mapDate, {
    include_docs: true,
    descending: true
  }).then(writeEntries)

}

function mapDate (doc) {
  emit(doc.fromArr)
}

function writeEntries (results) {
  let prevDate = null
  let dat = _.chain(results.rows)
  .map(row => { return Entry.fromJSON(row.doc) })
  .groupBy(e => { return moment(e.from).startOf('day').format('YYYY-MM-DD') })
  .map((group, d) => {
    return {
      ticks: group,
      date: moment(d, 'YYYY-MM-DD').toDate(),
      minutes: _.reduce(group, (sum, e) => { return sum + e.duration.minutes }, 0)
    }
  })
  .each(group => {
    const date = moment(group.date).format('ddd, MMM DD, YYYY')
    const time = format(group.minutes)
    console.log(`${chalk.yellow(date)} ${chalk.green(time)}`)
    group.ticks.forEach(t => { console.log(getOutputs(t).simple) })
  })
  .value()
}
<|endoftext|>


<commit_before>angular.module('cat-buddy', [
  'ngRoute'
])
.config(function($routeProvider) {
  $routeProvider
    .when('/search/cats', {
      templateUrl: 'app/search/cat/searchCats.html',
      controller: ''
    })
    .when('/saved/cats', {
      templateUrl: 'app/saved/cat/savedCats.html',
      controller: ''
    })
    .otherwise({
      redirectTo: '/search/cats'
    });
});<commit_msg>Add dependencies and controllers for cat-buddy app<commit_after>angular.module('cat-buddy', [
  'ngRoute',
  'cat-buddy.services',
  'cat-buddy.search-cats',
  'cat-buddy.saved-cats'
])
.config(function($routeProvider) {
  $routeProvider
    .when('/search/cats', {
      templateUrl: 'app/search/cat/searchCats.html',
      controller: 'SearchCatsController'
    })
    .when('/saved/cats', {
      templateUrl: 'app/saved/cat/savedCats.html',
      controller: 'SavedCatsController'
    })
    .otherwise({
      redirectTo: '/search/cats'
    });
});<|endoftext|>


<commit_before>'use strict';
/**
 * @ngdoc overview
 * @name loopbackApp
 * @description
 * # loopbackApp
 *
 * Main module of the application.
 */
angular.module('loopbackApp', [
    'angular-loading-bar',
    'angular.filter',
    'angularBootstrapNavTree',
    'angularFileUpload',
    // 'btford.markdown',
    'oitozero.ngSweetAlert',
    'config',
    'formly',
    'lbServices',
    'monospaced.elastic',
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ngMap',
    'ngVis',
    'ui.bootstrap',
    'ui.codemirror',
    'ui.gravatar',
    'ui.grid',
    'ui.router',
    'toasty',
    'autofields',
    'gettext',
    'angular-underscore/filters',
    'schemaForm',
    'ui.select',
    "angular-advanced-searchbox",
    'com.module.core',
    'com.module.files',
    'com.module.protocols',
    'com.module.healthcenters',
    'com.module.products',
    'com.module.settings',
    'com.module.users',
    'permission'
  ]);
  // .run(function($rootScope, $cookies, gettextCatalog) {

  //   $rootScope.locales = {

  //     'de': {
  //       lang: 'de',
  //       country: 'DE',
  //       name: gettextCatalog.getString('German')
  //     },
  //     'en': {
  //       lang: 'en',
  //       country: 'US',
  //       name: gettextCatalog.getString('English')
  //     },
  //     'es_MX': {
  //       lang: 'es_MX',
  //       country: 'MX',
  //       name: gettextCatalog.getString('Spanish')
  //     },
  //     'fr': {
  //       lang: 'fr',
  //       country: 'FR',
  //       name: gettextCatalog.getString('Français')
  //     },
  //     'nl': {
  //       lang: 'nl',
  //       country: 'NL',
  //       name: gettextCatalog.getString('Dutch')
  //     },
  //     'pt-BR': {
  //       lang: 'pt_BR',
  //       country: 'BR',
  //       name: gettextCatalog.getString('Portuguese Brazil')
  //     },
  //     'ru_RU': {
  //       lang: 'ru_RU',
  //       country: 'RU',
  //       name: gettextCatalog.getString('Russian')
  //     }
  //   }

  //   var lang = $cookies.lang || navigator.language || navigator.userLanguage;

  //   $rootScope.locale = $rootScope.locales[lang];

  //   if ($rootScope.locale === undefined) {
  //     $rootScope.locale = $rootScope.locales[lang];
  //     if ($rootScope.locale === undefined) {
  //       $rootScope.locale = $rootScope.locales['en'];
  //     }
  //   }

  //   gettextCatalog.setCurrentLanguage($rootScope.locale.lang);

  // });
<commit_msg>fix crash<commit_after>'use strict';
/**
 * @ngdoc overview
 * @name loopbackApp
 * @description
 * # loopbackApp
 *
 * Main module of the application.
 */
angular.module('loopbackApp', [
    'angular-loading-bar',
    'angular.filter',
    'angularBootstrapNavTree',
    'angularFileUpload',
    // 'btford.markdown',
    'oitozero.ngSweetAlert',
    'config',
    'formly',
    'lbServices',
    'monospaced.elastic',
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ngMap',
    'ngVis',
    'ui.bootstrap',
    'ui.codemirror',
    'ui.gravatar',
    'ui.grid',
    'ui.router',
    'toasty',
    'autofields',
    'gettext',
    'angular-underscore/filters',
    'schemaForm',
    'ui.select',
    "angular-advanced-searchbox",
    'com.module.core',
    'com.module.files',
    'com.module.protocols',
    'com.module.healthcenters',
    'com.module.settings',
    'com.module.users',
    'permission'
  ]);
  // .run(function($rootScope, $cookies, gettextCatalog) {

  //   $rootScope.locales = {

  //     'de': {
  //       lang: 'de',
  //       country: 'DE',
  //       name: gettextCatalog.getString('German')
  //     },
  //     'en': {
  //       lang: 'en',
  //       country: 'US',
  //       name: gettextCatalog.getString('English')
  //     },
  //     'es_MX': {
  //       lang: 'es_MX',
  //       country: 'MX',
  //       name: gettextCatalog.getString('Spanish')
  //     },
  //     'fr': {
  //       lang: 'fr',
  //       country: 'FR',
  //       name: gettextCatalog.getString('Français')
  //     },
  //     'nl': {
  //       lang: 'nl',
  //       country: 'NL',
  //       name: gettextCatalog.getString('Dutch')
  //     },
  //     'pt-BR': {
  //       lang: 'pt_BR',
  //       country: 'BR',
  //       name: gettextCatalog.getString('Portuguese Brazil')
  //     },
  //     'ru_RU': {
  //       lang: 'ru_RU',
  //       country: 'RU',
  //       name: gettextCatalog.getString('Russian')
  //     }
  //   }

  //   var lang = $cookies.lang || navigator.language || navigator.userLanguage;

  //   $rootScope.locale = $rootScope.locales[lang];

  //   if ($rootScope.locale === undefined) {
  //     $rootScope.locale = $rootScope.locales[lang];
  //     if ($rootScope.locale === undefined) {
  //       $rootScope.locale = $rootScope.locales['en'];
  //     }
  //   }

  //   gettextCatalog.setCurrentLanguage($rootScope.locale.lang);

  // });
<|endoftext|>


<commit_before>$(function() {
    var app = {
        init: function() {
            this.user = {};
            $('.menu-crud').addClass('hidden');
            $('.menu-user').addClass('hidden');
            $('.menu-loading').removeClass('hidden');
            $('.menu-user').addClass('hidden');
            $('.btn-login').addClass('hidden');
            $('.search-input').addClass('hidden');
            $('.btn-login').attr('href', '/api/login?url=/');
            $('.btn-logout').attr('href','/api/logout?url=/');
            this.router = new Router();
            this.setEventListeners();
            this.getUser();
            Backbone.history.start({pushState: true});
        },
        setEventListeners: function() {
            var self = this;
            $('.menu-crud .item a').click(function(ev) {
                var $el = $(ev.target).closest('.item');
                $('.menu-crud .item').removeClass('active');
                $el.addClass("active");
                if ($el.hasClass('menu-list')) {
                    $('.search-input').addClass('hidden');
                    self.router.navigate('list', {trigger: true});
                }
                if ($el.hasClass('menu-create')) {
                    $('.search-input').addClass('hidden');
                    self.router.navigate('new', {trigger: true});
                }
                if ($el.hasClass('menu-search')) {
                    $('.search-input').removeClass('hidden');
                    $('.app-content').html('');
                    self.router.navigate('search?=', {trigger: true});
                }
            });
            $('.form-search').unbind('submit').submit(function(ev) {
                self.router.navigate('search?=' + $('.search-input').val(), {trigger: true});
                return false;
            });
        },
        getUser: function() {
            var self = this;
            $.ajax({
                method: 'GET',
                url: '/api/users/me',
                success: function(me) {
                    console.log(me);
                    self.user = me;
                    self.showLogout();
                },
                error: function(err) {
                    console.log('you have not authenticated');
                    self.showLogin();
                }
            });
        },
        showLogin: function() {
           $('.menu-loading').addClass('hidden');
           $('.menu-user').addClass('hidden');
           $('.btn-login').removeClass('hidden');
        },
        showLogout: function() {
           $('.menu-crud').removeClass('hidden');
           $('.user-email').text(this.user.email);
           $('.menu-loading').addClass('hidden');
           $('.btn-login').addClass('hidden');
           $('.menu-user').removeClass('hidden');
           $('.menu-list').addClass("active");
           this.router.navigate('list', {trigger: true});
        },
        showList: function() {
            var $listTemplate = getTemplate('tpl-thesis-list');
            $('.app-content').html($listTemplate);
        },
        search: function(query, callback) {
            $.get('/api/search/?q=' + query, {
                returned_fields: JSON.stringify(['Title', 'Year'])
            }, function(list) {
                callback(list);
            });
        },
        getThesisByID: function(id, callback) {
            var object = {};
            $.get('/api/thesis/' + id, function(item) {
                callback(item);
            });
        },
        showThesis: function(thesis) {
            var self = this;
            var $viewTemplate = getTemplate('tpl-thesis-detail', thesis);
            $('.app-content').html($viewTemplate);
        },
        showForm: function(object) {
            var self = this;
            if (!object) {
                object = {};
            }
            var $formTemplate = getTemplate('tpl-thesis-form', object);
            $('.app-content').html($formTemplate);
            $('form').unbind('submit').submit(function(ev) {
                var thesisObject = {};
                var inputs = $('form').serializeArray();
                for (var i = 0; i < inputs.length; i++) {
                    thesisObject[inputs[i].name] = inputs[i].value;
                }
                self.save(thesisObject);
                return false;
            });
            $('.btn-cancel').click(function() {
                self.router.navigate('list', {trigger: true});
                return false;
            });
            self.setEventListeners();
        },
        loadAllThesis: function() {
            var self = this;
            setTimeout(function() {
                $.get('/api/thesis', function(res) {
                    self.displayLoadedList(res);
                });
            }, 200);
        },
        displayLoadedList: function(list) {
            var self = this;
            if (list.length === 0) {
                $('.app-content').html("There is no thesis file at the moment.");
            } else {
                _.each(list, function(item) {
                    var $thesisItem = $(getTemplate('tpl-thesis-list-item', item));
                    var id = item.Id
                    if (item.Key) {
                        id = item.Key;
                    }
                    $thesisItem.find('.btn-edit').click(function() {
                        self.router.navigate('edit-' + id, {trigger: true});
                    });
                    $thesisItem.find('.btn-view').click(function() {
                        self.router.navigate('thesis-' + id, {trigger: true});
                    });
                    $thesisItem.find('.btn-delete').click(function() {
                        self.router.navigate('delete-' + id, {trigger: true});
                    });
                    $('.thesis-list').append($thesisItem);
                });
            }
        },
        save: function(object) {
            var self = this;

            var thesisObject = {};
            var inputs = $('form').serializeArray();
            for (var i = 0; i < inputs.length; i++)
            {
                thesisObject[inputs[i].name] = inputs[i].value;
            }
            if (thesisObject.Title.length != 0 && thesisObject.Description.length != 0)
            {
                $.post('api/thesis', object, function(res) {
                self.router.navigate('list', {trigger: true});
                $('.menu-list').addClass("active");
                $('.menu-create').removeClass("active");
                $('.col-md-7').html('A thesis was created/modified.'+$('.col-md-7').html());
                });
                return false;
            }
            else
            {
                $('#new-thesis-form').html($('#new-thesis-form').html()+ 'Please fill up the required fields(*).');
            }
        },
        deleteThesis: function(id){
            var self = this;
            $.ajax({
                type: 'DELETE',
                url: '/api/thesis/' + id,
                success: function() {
                    self.router.navigate('list', {trigger: true});
                }
            });
        },
        searchThesis: function(keyword){
            var self = this;
            var regexStatement = new RegExp(".*(" + keyword + ").*", "i");
            $.get('/api/thesis', function(obj){
               var sorted_list = $.grep(obj, function(thesis, index){
                    return regexStatement.test(thesis.Title);
               });
               if(sorted_list.length == 0){
                    $('.app-content').html('Your search does not have any match.');
               }
               else{
                    var $listTemplate = getTemplate('tpl-thesis-list');
                    $('.app-content').html($listTemplate);
                    _.each(sorted_list, function(item) {
                        var $thesisItem = $(getTemplate('tpl-thesis-list-item', item));
                        $('.thesis-list').append($thesisItem);
                        var id = item.Id
                        if (item.Key) {
                            id = item.Key;
                        }
                        $thesisItem.find('.btn-edit').click(function() {
                            self.router.navigate('edit-' + id, {trigger: true});
                        });
                        $thesisItem.find('.btn-view').click(function() {
                            self.router.navigate('thesis-' + id, {trigger: true});
                        });
                        $thesisItem.find('.btn-delete').click(function() {
                            self.router.navigate('delete-' + id, {trigger: true});
                        });
                    });
               }
               $('.search-input').val('');
            });
        }
    };
    function getTemplate(template_id, context) {
        var template, $template, markup;
        template = $('#' + template_id);
        $template = Handlebars.compile(template.html());
        markup = $template(context);
        return markup;
    }
    var Router = Backbone.Router.extend({
        routes: {
            '': 'onHome',
            'search?=:query': 'onSearch',
            'thesis-:id': 'onView',
            'new': 'onCreate',
            'edit-:id': 'onEdit',
            'list': 'onList',
            'delete-:id': 'onDelete'
       },
       onSearch: function(query) {
            app.searchThesis(query);
       },
       onView: function(id) {
           console.log('thesis id', id);
            app.getThesisByID(id, function(item) {
                app.showThesis(item);
                FB.XFBML.parse();
            });
       },
       onCreate: function() {
            app.showForm();
       },
       onEdit: function(id) {
            app.getThesisByID(id, function(item) {
                app.showForm(item);
            });
       },
       onList: function() {
            app.showList();
            app.loadAllThesis();
       },
       onDelete: function(id) {
            app.deleteThesis(id);
       },

    });
    app.init();
});
<commit_msg>change message<commit_after>$(function() {
    var app = {
        init: function() {
            this.user = {};
            $('.menu-crud').addClass('hidden');
            $('.menu-user').addClass('hidden');
            $('.menu-loading').removeClass('hidden');
            $('.menu-user').addClass('hidden');
            $('.btn-login').addClass('hidden');
            $('.search-input').addClass('hidden');
            $('.btn-login').attr('href', '/api/login?url=/');
            $('.btn-logout').attr('href','/api/logout?url=/');
            this.router = new Router();
            this.setEventListeners();
            this.getUser();
            Backbone.history.start({pushState: true});
        },
        setEventListeners: function() {
            var self = this;
            $('.menu-crud .item a').click(function(ev) {
                var $el = $(ev.target).closest('.item');
                $('.menu-crud .item').removeClass('active');
                $el.addClass("active");
                if ($el.hasClass('menu-list')) {
                    $('.search-input').addClass('hidden');
                    self.router.navigate('list', {trigger: true});
                }
                if ($el.hasClass('menu-create')) {
                    $('.search-input').addClass('hidden');
                    self.router.navigate('new', {trigger: true});
                }
                if ($el.hasClass('menu-search')) {
                    $('.search-input').removeClass('hidden');
                    $('.app-content').html('');
                    self.router.navigate('search?=', {trigger: true});
                }
            });
            $('.form-search').unbind('submit').submit(function(ev) {
                self.router.navigate('search?=' + $('.search-input').val(), {trigger: true});
                return false;
            });
        },
        getUser: function() {
            var self = this;
            $.ajax({
                method: 'GET',
                url: '/api/users/me',
                success: function(me) {
                    console.log(me);
                    self.user = me;
                    self.showLogout();
                },
                error: function(err) {
                    console.log('you have not authenticated');
                    self.showLogin();
                }
            });
        },
        showLogin: function() {
           $('.menu-loading').addClass('hidden');
           $('.menu-user').addClass('hidden');
           $('.btn-login').removeClass('hidden');
        },
        showLogout: function() {
           $('.menu-crud').removeClass('hidden');
           $('.user-email').text(this.user.email);
           $('.menu-loading').addClass('hidden');
           $('.btn-login').addClass('hidden');
           $('.menu-user').removeClass('hidden');
           $('.menu-list').addClass("active");
           this.router.navigate('list', {trigger: true});
        },
        showList: function() {
            var $listTemplate = getTemplate('tpl-thesis-list');
            $('.app-content').html($listTemplate);
        },
        search: function(query, callback) {
            $.get('/api/search/?q=' + query, {
                returned_fields: JSON.stringify(['Title', 'Year'])
            }, function(list) {
                callback(list);
            });
        },
        getThesisByID: function(id, callback) {
            var object = {};
            $.get('/api/thesis/' + id, function(item) {
                callback(item);
            });
        },
        showThesis: function(thesis) {
            var self = this;
            var $viewTemplate = getTemplate('tpl-thesis-detail', thesis);
            $('.app-content').html($viewTemplate);
        },
        showForm: function(object) {
            var self = this;
            if (!object) {
                object = {};
            }
            var $formTemplate = getTemplate('tpl-thesis-form', object);
            $('.app-content').html($formTemplate);
            $('form').unbind('submit').submit(function(ev) {
                var thesisObject = {};
                var inputs = $('form').serializeArray();
                for (var i = 0; i < inputs.length; i++) {
                    thesisObject[inputs[i].name] = inputs[i].value;
                }
                self.save(thesisObject);
                return false;
            });
            $('.btn-cancel').click(function() {
                self.router.navigate('list', {trigger: true});
                return false;
            });
            self.setEventListeners();
        },
        loadAllThesis: function() {
            var self = this;
            setTimeout(function() {
                $.get('/api/thesis', function(res) {
                    self.displayLoadedList(res);
                });
            }, 200);
        },
        displayLoadedList: function(list) {
            var self = this;
            if (list.length === 0) {
                $('.app-content').html("There are no thesis files at the moment.");
            } else {
                _.each(list, function(item) {
                    var $thesisItem = $(getTemplate('tpl-thesis-list-item', item));
                    var id = item.Id
                    if (item.Key) {
                        id = item.Key;
                    }
                    $thesisItem.find('.btn-edit').click(function() {
                        self.router.navigate('edit-' + id, {trigger: true});
                    });
                    $thesisItem.find('.btn-view').click(function() {
                        self.router.navigate('thesis-' + id, {trigger: true});
                    });
                    $thesisItem.find('.btn-delete').click(function() {
                        self.router.navigate('delete-' + id, {trigger: true});
                    });
                    $('.thesis-list').append($thesisItem);
                });
            }
        },
        save: function(object) {
            var self = this;

            var thesisObject = {};
            var inputs = $('form').serializeArray();
            for (var i = 0; i < inputs.length; i++)
            {
                thesisObject[inputs[i].name] = inputs[i].value;
            }
            if (thesisObject.Title.length != 0 && thesisObject.Description.length != 0)
            {
                $.post('api/thesis', object, function(res) {
                self.router.navigate('list', {trigger: true});
                $('.menu-list').addClass("active");
                $('.menu-create').removeClass("active");
                $('.col-md-7').html('A thesis was created/modified.'+$('.col-md-7').html());
                });
                return false;
            }
            else
            {
                $('#new-thesis-form').html($('#new-thesis-form').html()+ 'Please fill up the required fields(*).');
            }
        },
        deleteThesis: function(id){
            var self = this;
            $.ajax({
                type: 'DELETE',
                url: '/api/thesis/' + id,
                success: function() {
                    self.router.navigate('list', {trigger: true});
                }
            });
        },
        searchThesis: function(keyword){
            var self = this;
            var regexStatement = new RegExp(".*(" + keyword + ").*", "i");
            $.get('/api/thesis', function(obj){
               var sorted_list = $.grep(obj, function(thesis, index){
                    return regexStatement.test(thesis.Title);
               });
               if(sorted_list.length == 0){
                    $('.app-content').html('Your search does not have any match.');
               }
               else{
                    var $listTemplate = getTemplate('tpl-thesis-list');
                    $('.app-content').html($listTemplate);
                    _.each(sorted_list, function(item) {
                        var $thesisItem = $(getTemplate('tpl-thesis-list-item', item));
                        $('.thesis-list').append($thesisItem);
                        var id = item.Id
                        if (item.Key) {
                            id = item.Key;
                        }
                        $thesisItem.find('.btn-edit').click(function() {
                            self.router.navigate('edit-' + id, {trigger: true});
                        });
                        $thesisItem.find('.btn-view').click(function() {
                            self.router.navigate('thesis-' + id, {trigger: true});
                        });
                        $thesisItem.find('.btn-delete').click(function() {
                            self.router.navigate('delete-' + id, {trigger: true});
                        });
                    });
               }
               $('.search-input').val('');
            });
        }
    };
    function getTemplate(template_id, context) {
        var template, $template, markup;
        template = $('#' + template_id);
        $template = Handlebars.compile(template.html());
        markup = $template(context);
        return markup;
    }
    var Router = Backbone.Router.extend({
        routes: {
            '': 'onHome',
            'search?=:query': 'onSearch',
            'thesis-:id': 'onView',
            'new': 'onCreate',
            'edit-:id': 'onEdit',
            'list': 'onList',
            'delete-:id': 'onDelete'
       },
       onSearch: function(query) {
            app.searchThesis(query);
       },
       onView: function(id) {
           console.log('thesis id', id);
            app.getThesisByID(id, function(item) {
                app.showThesis(item);
                FB.XFBML.parse();
            });
       },
       onCreate: function() {
            app.showForm();
       },
       onEdit: function(id) {
            app.getThesisByID(id, function(item) {
                app.showForm(item);
            });
       },
       onList: function() {
            app.showList();
            app.loadAllThesis();
       },
       onDelete: function(id) {
            app.deleteThesis(id);
       },

    });
    app.init();
});
<|endoftext|>


<commit_before>/*
 * Background controller. Wallpapers, proper fitting and video backgrounds
 */

const main = require('./main'),
	{Backbone, common, etc, options, stackBlur, state} = main;

const BackgroundView = Backbone.View.extend({
	tagName: 'style',
	colourMap: {
		glass: {
			normal: 'rgba(40, 42, 46, 0.5)',
			editing: 'rgba(145, 145, 145, 0.5)'
		},
		ocean: {
			normal: 'rgba(28, 29, 34, 0.781)',
			editing: 'rgba(44, 57, 71, 0.88)'
		}
	},
	initialize() {
		document.head.append(this.el);
		document.body.append(etc.parseDOM('

'));
		this.render();

		main.reply('background:store', this.store, this);
		this.listenTo(options, {
			'change:userBG': this.render,
			'change:illyaBGToggle': this.render,
			'change:illyaMuteToggle': this.render,
			'change:theme': this.render
		});
	},
	// Store image as dataURL in localStorage
	store(target) {
		// This could take a while, so loading animation
		main.request('loading:show');
		let reader = new FileReader();
		reader.readAsDataURL(target.files[0]);
		reader.onload = event => {
			let img = new Image();
			img.onload = () => {
				// Convert to JPEG
				let canvas = document.createElement("canvas");
				canvas.width = img.width;
				canvas.height = img.height;
				canvas
					.getContext('2d')
					.drawImage(img, 0, 0, img.width, img.height);
				localStorage.background = canvas.toDataURL('image/jpeg', 0.95);

				// Generate a blurred version of the background to use for
				// posts, modals, etc.
				stackBlur.canvas(canvas, 0, 0, img.width, img.height, 10);
				localStorage.blurred = canvas.toDataURL('image/jpeg', 0.95);

				main.request('loading:hide');

				// Apply new background
				if (options.get('userBG'))
					this.render();
			};
			img.src = event.target.result;
		};
	},
	render() {
		const {el} = this;
		el.innerHTML = '';
		if (options.get('illyaBGToggle') && state.hotConfig.get('ILLYA_DANCE'))
			this.renderIllya();
		else if (options.get('userBG'))
			this.renderBackground();
	},
	renderBackground() {
		const bg = localStorage.background;
		if (!bg)
			return;
		let html = common.parseHTML
			`#user_bg {
				background: url(${bg}) no-repeat fixed center;
				background-size: cover;
			}`;

		// Add blurred background image to elements, if theme is glass or ocean
		const theme = options.get('theme');
		if (theme === 'glass' || theme === 'ocean') {
			const {blurred} = localStorage;
			if (blurred)
				html += ' ' + this.renderGlass(theme, blurred);
		}
		this.el.innerHTML = html;
	},
	renderGlass(theme, blurred) {
		const {normal, editing} = this.colourMap[theme];
		return common.parseHTML
			`.glass {
				background:
					linear-gradient(${normal}, ${normal}),
					url(${blurred}) center fixed no-repeat;
				background-size: cover;
			}
			glass.editing, .editing .background {
				background:
					linear-gradient(${editing}, ${editing}),
					url(${blurred}) center fixed no-repeat;
				background-size: cover;
			}
			.background {
				padding: 10px;
				margin: 2px;
			}`;
	},
	renderIllya() {
		const urlBase = main.config.MEDIA_URL + 'illya.';
		this.el.innerHTML = common.parseHTML
			`<video autoplay loop ${options.get('illyaMuteToggle') && 'muted'}>
				<source src="${urlBase + 'webm'}" type="video/webm">
				<source src="${urlBase + 'mp4'}" type="video/mp4">
			</video>`;
	}
});

main.defer(() => module.exports = new BackgroundView());
<commit_msg>Fix glass theme editing post BG<commit_after>/*
 * Background controller. Wallpapers, proper fitting and video backgrounds
 */

const main = require('./main'),
	{Backbone, common, etc, options, stackBlur, state} = main;

const BackgroundView = Backbone.View.extend({
	tagName: 'style',
	colourMap: {
		glass: {
			normal: 'rgba(40, 42, 46, 0.5)',
			editing: 'rgba(145, 145, 145, 0.5)'
		},
		ocean: {
			normal: 'rgba(28, 29, 34, 0.781)',
			editing: 'rgba(44, 57, 71, 0.88)'
		}
	},
	initialize() {
		document.head.append(this.el);
		document.body.append(etc.parseDOM('

'));
		this.render();

		main.reply('background:store', this.store, this);
		this.listenTo(options, {
			'change:userBG': this.render,
			'change:illyaBGToggle': this.render,
			'change:illyaMuteToggle': this.render,
			'change:theme': this.render
		});
	},
	// Store image as dataURL in localStorage
	store(target) {
		// This could take a while, so loading animation
		main.request('loading:show');
		let reader = new FileReader();
		reader.readAsDataURL(target.files[0]);
		reader.onload = event => {
			let img = new Image();
			img.onload = () => {
				// Convert to JPEG
				let canvas = document.createElement("canvas");
				canvas.width = img.width;
				canvas.height = img.height;
				canvas
					.getContext('2d')
					.drawImage(img, 0, 0, img.width, img.height);
				localStorage.background = canvas.toDataURL('image/jpeg', 0.95);

				// Generate a blurred version of the background to use for
				// posts, modals, etc.
				stackBlur.canvas(canvas, 0, 0, img.width, img.height, 10);
				localStorage.blurred = canvas.toDataURL('image/jpeg', 0.95);

				main.request('loading:hide');

				// Apply new background
				if (options.get('userBG'))
					this.render();
			};
			img.src = event.target.result;
		};
	},
	render() {
		const {el} = this;
		el.innerHTML = '';
		if (options.get('illyaBGToggle') && state.hotConfig.get('ILLYA_DANCE'))
			this.renderIllya();
		else if (options.get('userBG'))
			this.renderBackground();
	},
	renderBackground() {
		const bg = localStorage.background;
		if (!bg)
			return;
		let html = common.parseHTML
			`#user_bg {
				background: url(${bg}) no-repeat fixed center;
				background-size: cover;
			}`;

		// Add blurred background image to elements, if theme is glass or ocean
		const theme = options.get('theme');
		if (theme === 'glass' || theme === 'ocean') {
			const {blurred} = localStorage;
			if (blurred)
				html += ' ' + this.renderGlass(theme, blurred);
		}
		this.el.innerHTML = html;
	},
	renderGlass(theme, blurred) {
		const {normal, editing} = this.colourMap[theme];
		return common.parseHTML
			`.glass {
				background:
					linear-gradient(${normal}, ${normal}),
					url(${blurred}) center fixed no-repeat;
				background-size: cover;
			}
			.glass.editing, .editing .background {
				background:
					linear-gradient(${editing}, ${editing}),
					url(${blurred}) center fixed no-repeat;
				background-size: cover;
			}
			.background {
				padding: 10px;
				margin: 2px;
			}`;
	},
	renderIllya() {
		const urlBase = main.config.MEDIA_URL + 'illya.';
		this.el.innerHTML = common.parseHTML
			`<video autoplay loop ${options.get('illyaMuteToggle') && 'muted'}>
				<source src="${urlBase + 'webm'}" type="video/webm">
				<source src="${urlBase + 'mp4'}" type="video/mp4">
			</video>`;
	}
});

main.defer(() => module.exports = new BackgroundView());
<|endoftext|>


<commit_before>/*
 *     (C) Copyright 2012 Universidad Politécnica de Madrid
 *     (C) Copyright 2012 Center for Open Middleware
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*global Draggable, Wirecloud */

(function () {

    "use strict";
    /*************************************************************************
     * Constructor
     *************************************************************************/
    /*
     * ArrowCreator.
     */
    var ArrowCreator = function ArrowCreator(canvas, data, onStart, onDrag, onFinish, canBeDragged) {
        var x, y;
        var theArrow;
        var dragboardCover;
        var draggable = this;
        var drag, currentSource, currentTarget;
        var layer = canvas.getHTMLElement().parentNode; // TODO Trampa
        canBeDragged = canBeDragged ? canBeDragged : Draggable._canBeDragged;
        this.layer = layer;
        /*************************************************************************
         * Public methods
         *************************************************************************/

        /**
         * stardrag, first step to draw a dragable arrow
         */
        this.startdrag = function startdrag(e, initAnchor) {
            var tmpPos, xStart, yStart;
            // Only process left mouse button events
            if (e.button !== 0) {
                return;
            }

            this.initAnchor = initAnchor;

            if (initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                initAnchor.context.iObject.wiringEditor.emphasize(initAnchor.initAnchor);
            } else {
                initAnchor.context.iObject.wiringEditor.emphasize(initAnchor);
            }

            document.oncontextmenu = Draggable._cancel; // disable context menu
            document.onmousedown = Draggable._cancel; // disable text selection in Firefox
            document.onselectstart = Draggable._cancel; // disable text selection in IE
            // enddrag when mouseup in no-anchor
            document.addEventListener('mouseup', this.enddrag, false);

            xStart = parseInt(e.clientX, 10);
            yStart = parseInt(e.clientY, 10);

            tmpPos = initAnchor.getCoordinates(layer);
            // arrow pointer
            theArrow = canvas.drawArrow(tmpPos, tmpPos, "arrow");
            this.theArrow = theArrow;
            theArrow.emphasize();
            // we can draw invert arrows from the end to the start
            if (initAnchor instanceof Wirecloud.ui.WiringEditor.TargetAnchor) {
                this.invert = true;
                currentSource = null;
                currentTarget = initAnchor;
                theArrow.setEnd(tmpPos, initAnchor);
            } else if (initAnchor instanceof Wirecloud.ui.WiringEditor.SourceAnchor) {
                this.invert = false;
                currentSource = initAnchor;
                currentTarget = null;
                theArrow.setStart(tmpPos, initAnchor);
            } else if (initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                if (initAnchor.initAnchor instanceof Wirecloud.ui.WiringEditor.TargetAnchor) {
                    this.invert = true;
                    currentSource = null;
                    currentTarget = initAnchor;
                    theArrow.setEnd(tmpPos, initAnchor.initAnchor);
                    theArrow.endMulti = initAnchor.id;
                } else if (initAnchor.initAnchor instanceof Wirecloud.ui.WiringEditor.SourceAnchor) {
                    this.invert = false;
                    currentSource = initAnchor;
                    currentTarget = null;
                    theArrow.startMulti = initAnchor.id;
                    theArrow.setStart(tmpPos, initAnchor.initAnchor);
                }
            }
            document.addEventListener("mousemove", this.drag, false);
            onStart(draggable, data);
            return false;
        };

        /**
         * drag, second step to draw a dragable arrow.
         */
        this.drag = function drag(e) {

            e = e || window.event; // needed for IE
            var hasChanged;
            var x = parseInt(e.clientX, 10);
            var y = parseInt(e.clientY, 10);
            var relatCoord, relatX;
            if (!this.invert) {
                theArrow.setEnd(getRelativeScreenPosition(x, y, layer));
            } else {
                theArrow.setStart(getRelativeScreenPosition(x, y, layer));
            }
            theArrow.redraw();
            onDrag(e, draggable, data, x, y);
        }.bind(this);

        /**
         * enddrag, last step to draw a dragable arrow.
         */
        this.enddrag = function enddrag(e, fAnchor) {
            // Only process left mouse button events
            if (e.button !== 0) {
                return;
            }
            if (fAnchor !== this.initAnchor) {
                if (fAnchor != null) {
                    if (fAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                        if (!this.invert) {
                            currentTarget = fAnchor.initAnchor;
                            theArrow.setEnd(fAnchor.getCoordinates(layer), fAnchor.initAnchor);
                            theArrow.endMulti = fAnchor.id;
                        } else {
                            currentSource = fAnchor.initAnchor;
                            theArrow.setStart(fAnchor.getCoordinates(layer), fAnchor.initAnchor);
                            theArrow.startMulti = fAnchor.id;
                        }
                    } else {
                        if (!this.invert) {
                            currentTarget = fAnchor;
                            theArrow.setEnd(fAnchor.getCoordinates(layer), fAnchor);
                        } else {
                            currentSource = fAnchor;
                            theArrow.setStart(fAnchor.getCoordinates(layer), fAnchor);
                        }
                    }
                    theArrow.deemphasize();
                    if (isVal(currentSource, currentTarget)) {
                        theArrow.calculateHighlight();
                        theArrow.calculateEmphasize();
                        theArrow.redraw();
                        // add the arrow to the arrow list of both anchors
                        this.initAnchor.addArrow(theArrow);
                        if (this.initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                            this.initAnchor.initAnchor.addArrow(theArrow);
                        } else if (fAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                            fAnchor.initAnchor.addArrow(theArrow);
                        }
                        fAnchor.addArrow(theArrow);
                    } else {
                        theArrow.destroy();
                    }
                // mouseup out of an anchor
                } else {
                    theArrow.destroy();
                }
            } else {
                theArrow.destroy();
            }

            if (this.initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                this.initAnchor.context.iObject.wiringEditor.deemphasize(this.initAnchor.initAnchor);
            } else {
                this.initAnchor.context.iObject.wiringEditor.deemphasize(this.initAnchor);
            }

            document.removeEventListener("mouseup", this.enddrag, false);
            document.removeEventListener("mousemove", this.drag, false);
            onFinish(draggable, data);
            document.onmousedown = null; // reenable context menu
            document.onselectstart = null; // reenable text selection in IE
            document.oncontextmenu = null; // reenable text selection
            currentTarget = null;
            currentSource = null;
            this.initAnchor = null;
            this.invert = null;
            return theArrow;
        }.bind(this);
    };

    /*************************************************************************
     * Private methods
     *************************************************************************/

    /**
     * isVal return if the relation between currentTarget and currentSource is
     * a valid connection or not.
     */
    var isVal = function isVal(currentSource, currentTarget) {
        var arrows, i, source, target;

        source = currentSource;
        target = currentTarget;

        if (source instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
            source = currentSource.initAnchor;
        }
        if (target instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
            target = currentTarget.initAnchor;
        }
        if (source === target) {
            return false;
        }

        if (!(source instanceof Wirecloud.ui.WiringEditor.SourceAnchor) || !(target instanceof Wirecloud.ui.WiringEditor.TargetAnchor)) {
            return false;
        }

        if (target.context.iObject === source.context.iObject) {
            return false;
        }

        arrows = source.getArrows();
        for (i = 0; i < arrows.length; i++) {
            if (arrows[i].endAnchor === target) {
                return false;
            }
        }

        return true;
    };

    /**
     * get Relative Screen Position, about from (x,y) to another element
     */
    var getRelativeScreenPosition = function getRelativeScreenPosition(x, y, element) {
        var bounding_box = element.getBoundingClientRect();
        return {
            posX: x - bounding_box.left + element.scrollLeft,
            posY: y - bounding_box.top + element.scrollTop
        };
    };

    /*************************************************************************
     * Make ArrowCreator public
     *************************************************************************/
    Wirecloud.ui.WiringEditor.ArrowCreator = ArrowCreator;
})();
<commit_msg>bug fixed. Not correctly disabled the context menu and selecting in ArrowCreator startdragg method<commit_after>/*
 *     (C) Copyright 2012 Universidad Politécnica de Madrid
 *     (C) Copyright 2012 Center for Open Middleware
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*global Draggable, Wirecloud */

(function () {

    "use strict";

    var _cancel = function () {
        return false;
    };

    /*************************************************************************
     * Constructor
     *************************************************************************/
    /*
     * ArrowCreator.
     */
    var ArrowCreator = function ArrowCreator(canvas, data, onStart, onDrag, onFinish, canBeDragged) {
        var x, y;
        var theArrow;
        var dragboardCover;
        var draggable = this;
        var drag, currentSource, currentTarget;
        var layer = canvas.getHTMLElement().parentNode; // TODO Trampa
        canBeDragged = canBeDragged ? canBeDragged : Draggable._canBeDragged;
        this.layer = layer;
        /*************************************************************************
         * Public methods
         *************************************************************************/

        /**
         * stardrag, first step to draw a dragable arrow
         */
        this.startdrag = function startdrag(e, initAnchor) {
            var tmpPos, xStart, yStart;
            // Only process left mouse button events
            if (e.button !== 0) {
                return;
            }

            this.initAnchor = initAnchor;

            if (initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                initAnchor.context.iObject.wiringEditor.emphasize(initAnchor.initAnchor);
            } else {
                initAnchor.context.iObject.wiringEditor.emphasize(initAnchor);
            }

            document.oncontextmenu = _cancel; // disable context menu
            document.onmousedown = _cancel; // disable text selection in Firefox
            document.onselectstart = _cancel; // disable text selection in IE
            // enddrag when mouseup in no-anchor
            document.addEventListener('mouseup', this.enddrag, false);

            xStart = parseInt(e.clientX, 10);
            yStart = parseInt(e.clientY, 10);

            tmpPos = initAnchor.getCoordinates(layer);
            // arrow pointer
            theArrow = canvas.drawArrow(tmpPos, tmpPos, "arrow");
            this.theArrow = theArrow;
            theArrow.emphasize();
            // we can draw invert arrows from the end to the start
            if (initAnchor instanceof Wirecloud.ui.WiringEditor.TargetAnchor) {
                this.invert = true;
                currentSource = null;
                currentTarget = initAnchor;
                theArrow.setEnd(tmpPos, initAnchor);
            } else if (initAnchor instanceof Wirecloud.ui.WiringEditor.SourceAnchor) {
                this.invert = false;
                currentSource = initAnchor;
                currentTarget = null;
                theArrow.setStart(tmpPos, initAnchor);
            } else if (initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                if (initAnchor.initAnchor instanceof Wirecloud.ui.WiringEditor.TargetAnchor) {
                    this.invert = true;
                    currentSource = null;
                    currentTarget = initAnchor;
                    theArrow.setEnd(tmpPos, initAnchor.initAnchor);
                    theArrow.endMulti = initAnchor.id;
                } else if (initAnchor.initAnchor instanceof Wirecloud.ui.WiringEditor.SourceAnchor) {
                    this.invert = false;
                    currentSource = initAnchor;
                    currentTarget = null;
                    theArrow.startMulti = initAnchor.id;
                    theArrow.setStart(tmpPos, initAnchor.initAnchor);
                }
            }
            document.addEventListener("mousemove", this.drag, false);
            onStart(draggable, data);
            return false;
        };

        /**
         * drag, second step to draw a dragable arrow.
         */
        this.drag = function drag(e) {

            e = e || window.event; // needed for IE
            var hasChanged;
            var x = parseInt(e.clientX, 10);
            var y = parseInt(e.clientY, 10);
            var relatCoord, relatX;
            if (!this.invert) {
                theArrow.setEnd(getRelativeScreenPosition(x, y, layer));
            } else {
                theArrow.setStart(getRelativeScreenPosition(x, y, layer));
            }
            theArrow.redraw();
            onDrag(e, draggable, data, x, y);
        }.bind(this);

        /**
         * enddrag, last step to draw a dragable arrow.
         */
        this.enddrag = function enddrag(e, fAnchor) {
            // Only process left mouse button events
            if (e.button !== 0) {
                return;
            }
            if (fAnchor !== this.initAnchor) {
                if (fAnchor != null) {
                    if (fAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                        if (!this.invert) {
                            currentTarget = fAnchor.initAnchor;
                            theArrow.setEnd(fAnchor.getCoordinates(layer), fAnchor.initAnchor);
                            theArrow.endMulti = fAnchor.id;
                        } else {
                            currentSource = fAnchor.initAnchor;
                            theArrow.setStart(fAnchor.getCoordinates(layer), fAnchor.initAnchor);
                            theArrow.startMulti = fAnchor.id;
                        }
                    } else {
                        if (!this.invert) {
                            currentTarget = fAnchor;
                            theArrow.setEnd(fAnchor.getCoordinates(layer), fAnchor);
                        } else {
                            currentSource = fAnchor;
                            theArrow.setStart(fAnchor.getCoordinates(layer), fAnchor);
                        }
                    }
                    theArrow.deemphasize();
                    if (isVal(currentSource, currentTarget)) {
                        theArrow.calculateHighlight();
                        theArrow.calculateEmphasize();
                        theArrow.redraw();
                        // add the arrow to the arrow list of both anchors
                        this.initAnchor.addArrow(theArrow);
                        if (this.initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                            this.initAnchor.initAnchor.addArrow(theArrow);
                        } else if (fAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                            fAnchor.initAnchor.addArrow(theArrow);
                        }
                        fAnchor.addArrow(theArrow);
                    } else {
                        theArrow.destroy();
                    }
                // mouseup out of an anchor
                } else {
                    theArrow.destroy();
                }
            } else {
                theArrow.destroy();
            }

            if (this.initAnchor instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
                this.initAnchor.context.iObject.wiringEditor.deemphasize(this.initAnchor.initAnchor);
            } else {
                this.initAnchor.context.iObject.wiringEditor.deemphasize(this.initAnchor);
            }

            document.removeEventListener("mouseup", this.enddrag, false);
            document.removeEventListener("mousemove", this.drag, false);
            onFinish(draggable, data);
            document.onmousedown = null; // reenable context menu
            document.onselectstart = null; // reenable text selection in IE
            document.oncontextmenu = null; // reenable text selection
            currentTarget = null;
            currentSource = null;
            this.initAnchor = null;
            this.invert = null;
            return theArrow;
        }.bind(this);
    };

    /*************************************************************************
     * Private methods
     *************************************************************************/

    /**
     * isVal return if the relation between currentTarget and currentSource is
     * a valid connection or not.
     */
    var isVal = function isVal(currentSource, currentTarget) {
        var arrows, i, source, target;

        source = currentSource;
        target = currentTarget;

        if (source instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
            source = currentSource.initAnchor;
        }
        if (target instanceof Wirecloud.ui.WiringEditor.Multiconnector) {
            target = currentTarget.initAnchor;
        }
        if (source === target) {
            return false;
        }

        if (!(source instanceof Wirecloud.ui.WiringEditor.SourceAnchor) || !(target instanceof Wirecloud.ui.WiringEditor.TargetAnchor)) {
            return false;
        }

        if (target.context.iObject === source.context.iObject) {
            return false;
        }

        arrows = source.getArrows();
        for (i = 0; i < arrows.length; i++) {
            if (arrows[i].endAnchor === target) {
                return false;
            }
        }

        return true;
    };

    /**
     * get Relative Screen Position, about from (x,y) to another element
     */
    var getRelativeScreenPosition = function getRelativeScreenPosition(x, y, element) {
        var bounding_box = element.getBoundingClientRect();
        return {
            posX: x - bounding_box.left + element.scrollLeft,
            posY: y - bounding_box.top + element.scrollTop
        };
    };

    /*************************************************************************
     * Make ArrowCreator public
     *************************************************************************/
    Wirecloud.ui.WiringEditor.ArrowCreator = ArrowCreator;
})();
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import {
  Link,
} from 'react-router-dom';

import block from '../../../helpers/bem-cn';

import Icon from '../../Icon/Icon';

const propTypes = {
    className: PropTypes.string,
};

// temporary inline styles untill designer will provide warning icon
const style = {
    color: 'red',
    fontSize: '30px',
};

class Incorrect extends PureComponent {
    state = {
        isOpen: true,
    }

    handleClose = () => {
        console.log('CLOSE');
        this.setState(prevState => ({ isOpen: false }));
    }

    renderInfo = () => {
        const b = block('j-healthcheck__incorrect');

        if (this.state.isOpen) {
            return (

                    {/*<Icon type="correct" className={b('icon')()} />*/}

!
 {/* @TODO: REMOVE after designer will provide icon */}

                        Some services are unvailable. Check it on Health Check list <Link to="/healthcheck">here</Link>.

                    <button className={b('close')} onClick={this.handleClose}>
                        <Icon type="close" />
                    </button>

            );
        }

        return null;
    }

    render() {
        return (
            this.renderInfo()
        );
    }
};

Incorrect.propTypes = propTypes;

export default Incorrect;
<commit_msg>fix in render<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import {
  Link,
} from 'react-router-dom';

import block from '../../../helpers/bem-cn';

import Icon from '../../Icon/Icon';

const propTypes = {
    className: PropTypes.string,
};

// temporary inline styles untill designer will provide warning icon
const style = {
    color: 'red',
    fontSize: '30px',
};

class Incorrect extends PureComponent {
    state = {
        isOpen: true,
    }

    handleClose = () => {
        console.log('CLOSE');
        this.setState(prevState => ({ isOpen: false }));
    }

    render() {
        const b = block('j-healthcheck__incorrect');

        if (this.state.isOpen) {
            return (

                    {/*<Icon type="correct" className={b('icon')()} />*/}

!
 {/* @TODO: REMOVE after designer will provide icon */}

                        Some services are unvailable. Check it on Health Check list <Link to="/healthcheck">here</Link>.

                    <button className={b('close')} onClick={this.handleClose}>
                        <Icon type="close" />
                    </button>

            );
        }

        return null;
    }
};

Incorrect.propTypes = propTypes;

export default Incorrect;
<|endoftext|>


<commit_before>// sum durations
var sum = function () {
    $('.sum').text(function () {
        var sum = 0;
        var table = $(this).parents('table.hours');
        table.find('tbody td:nth-child(4)').each(function (el, cell) {
            sum += parseFloat($(cell).html());
        });
        return sum;
    });
};

var Tracker = Ractive.extend({
    data: {
        error: [],
        list: [],
        projects: [],
        project: null,
        hours: [],
        own_hours: [],
        active: null,
        duration: 0,
        date: moment().format("YYYY-MM-DD"), // needed for default value - a nice trick by accident
        isodateformat: function (date) {
            if (date) {
                return moment(date).format("YYYY-MM-DD");
            }
        },
        datetimeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LLL');
            }
        },
        dateformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LL');
            }
        },
        timeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('HH:mm');
            }
        },
        humanformat: function (datetime) {
            if (datetime) {
                return moment(datetime).fromNow();
            }
        }
    },

    createProject: function(project){
        return $.ajax({
            type: 'POST',
            url: window.location.href,
            data: project
        });
    },

    updateProject: function (project) {
        return $.ajax({
            type: 'PUT',
            url: window.location.href,
            data: project
        });
    },

    deleteProject: function (project_id) {
        return $.ajax({
            type: 'DELETE',
            url: window.location.href + '/' + project_id
        });
    },

    createHours: function (data) {
        return $.ajax({
            type: 'POST',
            url: '/',
            data: _.pick(data, 'project', 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    updateHours: function (data) {
        return $.ajax({
            type: 'PUT',
            url: '/' + data._id,
            data: _.pick(data, 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    create_timepickers: function (start_element, end_element) {
        var tracker = this;
        var startpicker, endpicker;

        startpicker = start_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var endp = endpicker.pickatime('picker');
                var end = endp.get();
                var start = this.get();
                if (start) {
                    var startarr = _.map(start.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    endp.set('min', startarr);
                    if (end) {
                        var endarr = _.map(end.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
        endpicker = end_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var startp = startpicker.pickatime('picker');
                var start = startp.get();
                var end = this.get();
                if (end) {
                    var endarr = _.map(end.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    startp.set('max', endarr);
                    if (start) {
                        var startarr = _.map(start.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
    }

});

module.exports.simple = function (projects, hours) {
    var tracker = new Tracker({
        el: '#simple',
        template: '#template',
        noIntro: true,
        data: {
            projects: projects,
            hours: hours,
            has_project: function (wants) {
                var u = URI(window.location.href);
                if (u.search(true).project) {
                    return wants;
                }
                else {
                    return !wants;
                }
            }
        }
    });

    tracker.on('toggleNew', function (event) {
        event.original.preventDefault();
        tracker.toggle('expanded');
        if (tracker.get('expanded')) {
            if (!Modernizr.inputtypes.date) {
                $('#date').fdatepicker({language: 'nb', weekStart: 1, format: 'yyyy-mm-dd'});
            }
            if (!Modernizr.touch || !Modernizr.inputtypes.time) {
                tracker.create_timepickers($('#start.timepicker'), $('#end.timepicker'));
            }
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('createHours', function (event) {
        event.original.preventDefault();
        event.context.project = $('#project').val();
        event.context.date = $(event.node).find("#date").val();
        event.context.start = $(event.node).find("#start").val();
        event.context.end = $(event.node).find("#end").val();

        tracker.createHours(event.context)
            .then(function(data){
                // everything ok
                tracker.get('hours').unshift(data);

                // should not reset everything: date and project should stay
                //$('form#createHours').trigger('reset');
                $(event.node).find("#start").val('');
                $(event.node).find("#end").val('');
                $(event.node).find("#duration").val('');
                $(event.node).find("#comment").val('');
                $(event.node).find("#date").focus();
                alerts.get('success').push(data.project.name + ' ' + moment(data.date).format('LL') + ' ' + moment(data.created).fromNow());
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateDuration', function (event) {
        var form = $(event.node).parents('form');
        var start = $(form).find(".start").val() ;
        var end = $(form).find(".end").val();
        var startarr, endarr;

        if (start) {
            startarr = _.map(start.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (end) {
            endarr = _.map(end.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (start && end) {
            var duration = moment.duration({
                hours: endarr[0] - startarr[0],
                minutes: endarr[1] - startarr[1]
            });
            if (duration) {
                tracker.set(event.keypath + '.duration', duration.as('hours'));
            }
        }
    });

    return tracker;
};

module.exports.projects = function (projects) {
    var tracker = new Tracker({
        el: '#projects',
        template: '#template',
        data: {
            projects: projects
        }
    });

    tracker.on('createProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };

        tracker.createProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.get('projects').unshift(data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('deleteProject', function (event) {
        tracker.deleteProject(event.context._id)
            .then(function (data) {
                tracker.get('projects').splice(event.keypath.split('.').pop());
            }, function (xhr, status, err) {
                tracker.get('error').push(xhr.responseText);
            });
    });

    return tracker;
};

module.exports.project = function (project, hours) {
    var all, own;
    var u = URI(window.location.href);
    if (u.hash() === "#all") {
        all = true;
    }
    else {
        own = true;
    }
    var own_hours = _.filter(hours, function (h) {
        return (h.user._id.match(/^gartmann/));
    });
    var tracker = new Tracker({
        el: '#project',
        template: '#template',
        data: {
            project: project,
            hours: hours,
            own_hours: own_hours,
            own: own,
            all: all
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('editToggle', function () {
        tracker.toggle('expanded');
    });

    tracker.on('toggleAll', function (event) {
        tracker.toggle('own');
        tracker.toggle('all');
        sum();
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };
        tracker.updateProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.set('project', data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    sum();

    return tracker;
};

<commit_msg>Edit date possible<commit_after>// sum durations
var sum = function () {
    $('.sum').text(function () {
        var sum = 0;
        var table = $(this).parents('table.hours');
        table.find('tbody td:nth-child(4)').each(function (el, cell) {
            sum += parseFloat($(cell).html());
        });
        return sum;
    });
};

var Tracker = Ractive.extend({
    data: {
        error: [],
        list: [],
        projects: [],
        project: null,
        hours: [],
        own_hours: [],
        active: null,
        duration: 0,
        date: moment().format("YYYY-MM-DD"), // needed for default value - a nice trick by accident
        isodateformat: function (date) {
            if (date) {
                return moment(date).format("YYYY-MM-DD");
            }
        },
        datetimeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LLL');
            }
        },
        dateformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LL');
            }
        },
        timeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('HH:mm');
            }
        },
        humanformat: function (datetime) {
            if (datetime) {
                return moment(datetime).fromNow();
            }
        }
    },

    createProject: function(project){
        return $.ajax({
            type: 'POST',
            url: window.location.href,
            data: project
        });
    },

    updateProject: function (project) {
        return $.ajax({
            type: 'PUT',
            url: window.location.href,
            data: project
        });
    },

    deleteProject: function (project_id) {
        return $.ajax({
            type: 'DELETE',
            url: window.location.href + '/' + project_id
        });
    },

    createHours: function (data) {
        return $.ajax({
            type: 'POST',
            url: '/',
            data: _.pick(data, 'project', 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    updateHours: function (data) {
        return $.ajax({
            type: 'PUT',
            url: '/' + data._id,
            data: _.pick(data, 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    create_timepickers: function (start_element, end_element) {
        var tracker = this;
        var startpicker, endpicker;

        startpicker = start_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var endp = endpicker.pickatime('picker');
                var end = endp.get();
                var start = this.get();
                if (start) {
                    var startarr = _.map(start.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    endp.set('min', startarr);
                    if (end) {
                        var endarr = _.map(end.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
        endpicker = end_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var startp = startpicker.pickatime('picker');
                var start = startp.get();
                var end = this.get();
                if (end) {
                    var endarr = _.map(end.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    startp.set('max', endarr);
                    if (start) {
                        var startarr = _.map(start.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
    }

});

module.exports.simple = function (projects, hours) {
    var tracker = new Tracker({
        el: '#simple',
        template: '#template',
        noIntro: true,
        data: {
            projects: projects,
            hours: hours,
            has_project: function (wants) {
                var u = URI(window.location.href);
                if (u.search(true).project) {
                    return wants;
                }
                else {
                    return !wants;
                }
            }
        }
    });

    tracker.on('toggleNew', function (event) {
        event.original.preventDefault();
        tracker.toggle('expanded');
        if (tracker.get('expanded')) {
            if (!Modernizr.inputtypes.date) {
                $('#date').fdatepicker({language: 'nb', weekStart: 1, format: 'yyyy-mm-dd'});
            }
            if (!Modernizr.touch || !Modernizr.inputtypes.time) {
                tracker.create_timepickers($('#start.timepicker'), $('#end.timepicker'));
            }
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('createHours', function (event) {
        event.original.preventDefault();
        event.context.project = $('#project').val();
        event.context.date = $(event.node).find("#date").val();
        event.context.start = $(event.node).find("#start").val();
        event.context.end = $(event.node).find("#end").val();

        tracker.createHours(event.context)
            .then(function(data){
                // everything ok
                tracker.get('hours').unshift(data);

                // should not reset everything: date and project should stay
                //$('form#createHours').trigger('reset');
                $(event.node).find("#start").val('');
                $(event.node).find("#end").val('');
                $(event.node).find("#duration").val('');
                $(event.node).find("#comment").val('');
                $(event.node).find("#date").focus();
                alerts.get('success').push(data.project.name + ' ' + moment(data.date).format('LL') + ' ' + moment(data.created).fromNow());
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.date = $(event.node).find("#date").val();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateDuration', function (event) {
        var form = $(event.node).parents('form');
        var start = $(form).find(".start").val() ;
        var end = $(form).find(".end").val();
        var startarr, endarr;

        if (start) {
            startarr = _.map(start.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (end) {
            endarr = _.map(end.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (start && end) {
            var duration = moment.duration({
                hours: endarr[0] - startarr[0],
                minutes: endarr[1] - startarr[1]
            });
            if (duration) {
                tracker.set(event.keypath + '.duration', duration.as('hours'));
            }
        }
    });

    return tracker;
};

module.exports.projects = function (projects) {
    var tracker = new Tracker({
        el: '#projects',
        template: '#template',
        data: {
            projects: projects
        }
    });

    tracker.on('createProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };

        tracker.createProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.get('projects').unshift(data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('deleteProject', function (event) {
        tracker.deleteProject(event.context._id)
            .then(function (data) {
                tracker.get('projects').splice(event.keypath.split('.').pop());
            }, function (xhr, status, err) {
                tracker.get('error').push(xhr.responseText);
            });
    });

    return tracker;
};

module.exports.project = function (project, hours) {
    var all, own;
    var u = URI(window.location.href);
    if (u.hash() === "#all") {
        all = true;
    }
    else {
        own = true;
    }
    var own_hours = _.filter(hours, function (h) {
        return (h.user._id.match(/^gartmann/));
    });
    var tracker = new Tracker({
        el: '#project',
        template: '#template',
        data: {
            project: project,
            hours: hours,
            own_hours: own_hours,
            own: own,
            all: all
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('editToggle', function () {
        tracker.toggle('expanded');
    });

    tracker.on('toggleAll', function (event) {
        tracker.toggle('own');
        tracker.toggle('all');
        sum();
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };
        tracker.updateProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.set('project', data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    sum();

    return tracker;
};

<|endoftext|>