<commit_before>module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-usemin');
  grunt.loadNpmTasks('grunt-rev');
  grunt.loadNpmTasks('grunt-manifest');
  grunt.loadNpmTasks('grunt-sed');
  grunt.loadNpmTasks('grunt-docco');
  grunt.loadNpmTasks('grunt-growl');

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      less: {
        options: {
          debounceDelay: 250
        },
        files: 'src/less/*.less',
        tasks: ['growl:less', 'less']
      },
      js: {
        options: {
          debounceDelay: 250
        },
        files: 'src/js/*.js',
        tasks: ['growl:js', 'jshint']
      },
      manifest: {
        options: {
          debounceDelay: 250
        },
        files: ['src/index.html', 'src/css/**', 'src/js/**', 'src/img/**', 'src/sounds/**'],
        tasks: ['growl:manifest', 'manifest:src']
      }
    },

    growl: {
      less: {
        title : "Grunt",
        message : "LESS compilation…"
      },
      js: {
        title : "Grunt",
        message : "JS hint…"
      },
      manifest: {
        title : "Grunt",
        message : "Updating manifest.appcache…"
      }
    },

    less: {
      src: {
        files: {
          "src/css/styles.css": "src/less/styles.less"
        }
      }
    },

    clean: {
      dist: {
        src: 'dist/'
      }
    },

    copy: {
      dist: {
        files: [
          { expand: true, cwd: 'src/', src: ['.htaccess', 'esviji-icon.png', 'favicon.ico', 'index.html', 'manifest.webapp'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['css/font/*'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['img/favicon.png', 'img/firefox-os/*', 'img/ios/*', 'img/windows-8/*'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['sounds/sprite.{mp3,ogg}'], dest: 'dist/' }
        ]
      }
    },

    useminPrepare: {
      options: {
        dest: 'dist/'
      },
      html: 'src/index.html'
    },
    usemin: {
      html: 'dist/index.html'
    },

    concat: {
      options: {
        separator: ';'
      }
    },

    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> - Copyright (c) 1992-<%= grunt.template.today("yyyy") %> Nicolas Hoizey <nicolas@hoizey.com> */',
        report:'min',
        compress: {
          global_defs: {
            'DEBUG': false
          }
        }
      }
    },

    cssmin: {
      options: {
        banner: '/*! <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> - Copyright (c) 1992-<%= grunt.template.today("yyyy") %> Nicolas Hoizey <nicolas@hoizey.com> */'
      }
    },

    rev: {
      options: {
        encoding: 'utf8',
        algorithm: 'md5',
        length: 8
      },
      assets: {
        files: [{
          src: [
            'dist/css/styles.css',
            'dist/js/app.js'
          ]
        }]
      }
    },

    manifest: {
      src: {
        options: {
          basePath: 'src/',
          network: ['*'],
          verbose: true,
          timestamp: true
        },
        src: [
          'favicon.ico',
          'img/favicon.png',
          'js/**/*.js',
          'css/styles.css',
          'css/font/*',
          'sounds/*.{ogg,mp3}'
        ],
        dest: 'src/manifest.appcache'
      },
      dist: {
        options: {
          basePath: 'dist/',
          network: ['*'],
          verbose: true,
          timestamp: true
        },
        src: [
          'favicon.ico',
          'img/favicon.png',
          'js/app.js',
          'css/styles.css',
          'css/font/*',
          'sounds/*.{ogg,mp3}'
        ],
        dest: 'dist/manifest.appcache'
      }
    },

    sed: {
      version: {
        path: 'dist/',
        recursive: true,
        pattern: '%VERSION%',
        replacement: '<%= pkg.version %>'
      }
    },

    docco: {
      debug: {
        src: ['src/js/esviji.js'],
        options: {
          output: 'docs/'
        }
      }
    }
  });

  grunt.registerTask('default', ['less', 'manifest:src', 'watch']);
  grunt.registerTask('compile', ['growl:less', 'less', 'growl:manifest', 'manifest:src']);
  grunt.registerTask('package', ['less', 'clean', 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin', 'manifest:dist', 'sed', 'docco']);
};
<commit_msg>Load NPM tasks only when needed<commit_after>module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-manifest');
  grunt.loadNpmTasks('grunt-growl');

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      less: {
        options: {
          debounceDelay: 250
        },
        files: 'src/less/*.less',
        tasks: ['growl:less', 'less']
      },
      js: {
        options: {
          debounceDelay: 250
        },
        files: 'src/js/*.js',
        tasks: ['growl:js', 'jshint']
      },
      manifest: {
        options: {
          debounceDelay: 250
        },
        files: ['src/index.html', 'src/css/**', 'src/js/**', 'src/img/**', 'src/sounds/**'],
        tasks: ['growl:manifest', 'manifest:src']
      }
    },

    growl: {
      less: {
        title : "Grunt",
        message : "LESS compilation…"
      },
      js: {
        title : "Grunt",
        message : "JS hint…"
      },
      manifest: {
        title : "Grunt",
        message : "Updating manifest.appcache…"
      }
    },

    less: {
      src: {
        files: {
          "src/css/styles.css": "src/less/styles.less"
        }
      }
    },

    clean: {
      dist: {
        src: 'dist/'
      }
    },

    copy: {
      dist: {
        files: [
          { expand: true, cwd: 'src/', src: ['.htaccess', 'esviji-icon.png', 'favicon.ico', 'index.html', 'manifest.webapp'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['css/font/*'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['img/favicon.png', 'img/firefox-os/*', 'img/ios/*', 'img/windows-8/*'], dest: 'dist/' },
          { expand: true, cwd: 'src/', src: ['sounds/sprite.{mp3,ogg}'], dest: 'dist/' }
        ]
      }
    },

    useminPrepare: {
      options: {
        dest: 'dist/'
      },
      html: 'src/index.html'
    },
    usemin: {
      html: 'dist/index.html'
    },

    concat: {
      options: {
        separator: ';'
      }
    },

    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> - Copyright (c) 1992-<%= grunt.template.today("yyyy") %> Nicolas Hoizey <nicolas@hoizey.com> */',
        report:'min',
        compress: {
          global_defs: {
            'DEBUG': false
          }
        }
      }
    },

    cssmin: {
      options: {
        banner: '/*! <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> - Copyright (c) 1992-<%= grunt.template.today("yyyy") %> Nicolas Hoizey <nicolas@hoizey.com> */'
      }
    },

    rev: {
      options: {
        encoding: 'utf8',
        algorithm: 'md5',
        length: 8
      },
      assets: {
        files: [{
          src: [
            'dist/css/styles.css',
            'dist/js/app.js'
          ]
        }]
      }
    },

    manifest: {
      src: {
        options: {
          basePath: 'src/',
          network: ['*'],
          verbose: true,
          timestamp: true
        },
        src: [
          'favicon.ico',
          'img/favicon.png',
          'js/**/*.js',
          'css/styles.css',
          'css/font/*',
          'sounds/*.{ogg,mp3}'
        ],
        dest: 'src/manifest.appcache'
      },
      dist: {
        options: {
          basePath: 'dist/',
          network: ['*'],
          verbose: true,
          timestamp: true
        },
        src: [
          'favicon.ico',
          'img/favicon.png',
          'js/app.js',
          'css/styles.css',
          'css/font/*',
          'sounds/*.{ogg,mp3}'
        ],
        dest: 'dist/manifest.appcache'
      }
    },

    sed: {
      version: {
        path: 'dist/',
        recursive: true,
        pattern: '%VERSION%',
        replacement: '<%= pkg.version %>'
      }
    },

    docco: {
      debug: {
        src: ['src/js/esviji.js'],
        options: {
          output: 'docs/'
        }
      }
    }
  });

  grunt.registerTask('default', ['less', 'manifest:src', 'watch']);
  grunt.registerTask('compile', ['growl:less', 'less', 'growl:manifest', 'manifest:src']);
  grunt.registerTask('package', [], function() {
    // cf https://github.com/gruntjs/grunt/issues/975#issuecomment-29058707
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-usemin');
    grunt.loadNpmTasks('grunt-rev');
    grunt.loadNpmTasks('grunt-sed');
    grunt.loadNpmTasks('grunt-docco');
    grunt.task.run('less', 'clean', 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin', 'manifest:dist', 'sed', 'docco');
  });
};
<|endoftext|>


<commit_before>var h = require('mutant/h')
var nest = require('depnest')
var addSuggest = require('suggest-box')

exports.needs = nest({
  'profile.async.suggest': 'first',
  'channel.async.suggest': 'first'
})

exports.gives = nest('app.html.search')

exports.create = function (api) {
  return nest('app.html.search', function (setView) {
    var getProfileSuggestions = api.profile.async.suggest()
    var getChannelSuggestions = api.channel.async.suggest()
    var searchTimer = null
    var searchBox = h('input.search', {
      type: 'search',
      placeholder: 'word, @key, #channel',
      'ev-suggestselect': (ev) => {
        setView(ev.detail.id)
        searchBox.value = ev.detail.id
      },
      'ev-input': (ev) => {
        clearTimeout(searchTimer)
        searchTimer = setTimeout(doSearch, 500)
      },
      'ev-focus': (ev) => {
        if (searchBox.value) {
          doSearch()
        }
      }
    })

    setImmediate(() => {
      addSuggest(searchBox, (inputText, cb) => {
        if (inputText[0] === '@') {
          cb(null, getProfileSuggestions(inputText.slice(1)), {idOnly: true})
        } else if (inputText[0] === '#') {
          cb(null, getChannelSuggestions(inputText.slice(1)))
        }
      }, {cls: 'SuggestBox'})
    })

    return searchBox

    function doSearch () {
      var value = searchBox.value.trim()
      if (value.startsWith('/') || value.startsWith('?') || value.startsWith('@') || value.startsWith('#') || value.startsWith('%')) {
        if (value.startsWith('@') && value.length < 30) {
          return // probably not a key
        } else if (value.length > 2) {
          setView(value)
        }
      } else if (value.trim()) {
        if (value.length > 2) {
          setView(`?${value.trim()}`)
        }
      } else {
        setView('/public')
      }
    }
  })
}
<commit_msg>search: wait until enter pressed<commit_after>var h = require('mutant/h')
var nest = require('depnest')
var addSuggest = require('suggest-box')

exports.needs = nest({
  'profile.async.suggest': 'first',
  'channel.async.suggest': 'first'
})

exports.gives = nest('app.html.search')

exports.create = function (api) {
  return nest('app.html.search', function (setView) {
    var getProfileSuggestions = api.profile.async.suggest()
    var getChannelSuggestions = api.channel.async.suggest()
    var searchBox = h('input.search', {
      type: 'search',
      placeholder: 'word, @key, #channel',
      'ev-suggestselect': (ev) => {
        setView(ev.detail.id)
        searchBox.value = ev.detail.id
      },
      'ev-keydown': (ev) => {
        if (ev.code === 'Enter') {
          doSearch()
          ev.preventDefault()
        }
      }
    })

    setImmediate(() => {
      addSuggest(searchBox, (inputText, cb) => {
        if (inputText[0] === '@') {
          cb(null, getProfileSuggestions(inputText.slice(1)), {idOnly: true})
        } else if (inputText[0] === '#') {
          cb(null, getChannelSuggestions(inputText.slice(1)))
        }
      }, {cls: 'SuggestBox'})
    })

    return searchBox

    function doSearch () {
      var value = searchBox.value.trim()
      if (value.startsWith('/') || value.startsWith('?') || value.startsWith('@') || value.startsWith('#') || value.startsWith('%')) {
        if (value.startsWith('@') && value.length < 30) {
          return // probably not a key
        } else if (value.length > 2) {
          setView(value)
        }
      } else if (value.trim()) {
        if (value.length > 2) {
          setView(`?${value.trim()}`)
        }
      }
    }
  })
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function (grunt) {
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  require('time-grunt')(grunt);

  grunt.initConfig({
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {
      livereload: {
        files: [
          '<%= yeoman.app %>/*.html',
          '{.tmp,<%= yeoman.app %>}/styles/{,**/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,**/}*.js',
          '{.tmp,<%= yeoman.app %>}/scripts/{,**/}*.hbs',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
          'test/spec/{,**/}*.js'
        ],
        tasks: ['exec'],
        options: {
          livereload: true
        }
      }
    },
    connect: {
      testserver: {
        options: {
          port: 1234,
          base: '.'
        }
      }
    },
    exec: {
      mocha: {
        command: 'mocha-phantomjs http://localhost:<%= connect.testserver.options.port %>/test',
        stdout: true
      }
    },
    express: {
      options: {
        port: '9000'
      },
      dev: {
        options: {
          script: 'server/app.js'
        }
      },
      prod: {
        options: {
          script: 'server/app.js'
        }
      },
      test: {
        options: {
          script: 'server/app.js'
        }
      }
    },
    open: {
      server: {
        path: 'http://localhost:<%= express.options.port %>'
      }
    },
    clean: {
      dist: ['.tmp', '<%= yeoman.dist %>/*'],
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js',
        '!<%= yeoman.app %>/scripts/vendor/*',
        'test/spec/{,*/}*.js'
      ]
    },
    requirejs: {
      compile: {
        options: {
          baseUrl: "<%= yeoman.app %>/scripts/",
          mainConfigFile: '<%= yeoman.app %>/scripts/init.js',
          out: "<%= yeoman.dist %>/scripts/"
        }
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,txt}',
            '.htaccess',
            'images/{,*/}*.{webp,gif}',
            'bower_components/requirejs/require.js'
          ]
        }]
      }
    },
    bower: {
      all: {
        rjsConfig: '<%= yeoman.app %>/scripts/main.js'
      }
    },
    handlebars: {
      compile: {
        options: {
          namespace: 'JST',
          amd: true
        },
        files: {
          '.tmp/scripts/templates.js': ['templates/**/*.hbs']
        }
      }
    }
  });

  grunt.registerTask('createDefaultTemplate', function () {
    grunt.file.write('.tmp/scripts/templates.js', 'this.JST = this.JST || {};');
  });

  grunt.registerTask('default', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
    }
    grunt.option('force', true);
    grunt.task.run([
      'clean:server',
      'connect:testserver',
      'express:dev',
      'exec',
      'open',
      'watch'
    ]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'createDefaultTemplate',
    'connect:testserver',
    'exec:mocha'
  ]);

  grunt.registerTask('build', [
    'createDefaultTemplate',
//    'requirejs',
//    'concat',
//    'uglify',
    'copy',
  ]);

};
<commit_msg>Added JSHint to watch task in Gruntfile Signed-off-by: Lidza Louina <Lidza.Louina@gmail.com><commit_after>'use strict';

module.exports = function (grunt) {
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  require('time-grunt')(grunt);

  grunt.initConfig({
    yeoman: {
      app: 'app',
      dist: 'dist'
    },
    watch: {
      livereload: {
        files: [
          '<%= yeoman.app %>/*.html',
          '{.tmp,<%= yeoman.app %>}/styles/{,**/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,**/}*.js',
          '{.tmp,<%= yeoman.app %>}/scripts/{,**/}*.hbs',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
          'test/spec/{,**/}*.js'
        ],
        tasks: ['exec', 'jshint'],
        options: {
          livereload: true
        }
      }
    },
    connect: {
      testserver: {
        options: {
          port: 1234,
          base: '.'
        }
      }
    },
    exec: {
      mocha: {
        command: 'mocha-phantomjs http://localhost:<%= connect.testserver.options.port %>/test',
        stdout: true
      }
    },
    express: {
      options: {
        port: '9000'
      },
      dev: {
        options: {
          script: 'server/app.js'
        }
      },
      prod: {
        options: {
          script: 'server/app.js'
        }
      },
      test: {
        options: {
          script: 'server/app.js'
        }
      }
    },
    open: {
      server: {
        path: 'http://localhost:<%= express.options.port %>'
      }
    },
    clean: {
      dist: ['.tmp', '<%= yeoman.dist %>/*'],
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js',
        '!<%= yeoman.app %>/scripts/vendor/*',
        'test/spec/{,*/}*.js'
      ]
    },
    requirejs: {
      compile: {
        options: {
          baseUrl: "<%= yeoman.app %>/scripts/",
          mainConfigFile: '<%= yeoman.app %>/scripts/init.js',
          out: "<%= yeoman.dist %>/scripts/"
        }
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,txt}',
            '.htaccess',
            'images/{,*/}*.{webp,gif}',
            'bower_components/requirejs/require.js'
          ]
        }]
      }
    },
    bower: {
      all: {
        rjsConfig: '<%= yeoman.app %>/scripts/main.js'
      }
    },
    handlebars: {
      compile: {
        options: {
          namespace: 'JST',
          amd: true
        },
        files: {
          '.tmp/scripts/templates.js': ['templates/**/*.hbs']
        }
      }
    }
  });

  grunt.registerTask('createDefaultTemplate', function () {
    grunt.file.write('.tmp/scripts/templates.js', 'this.JST = this.JST || {};');
  });

  grunt.registerTask('default', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
    }
    grunt.option('force', true);
    grunt.task.run([
      'clean:server',
      'connect:testserver',
      'express:dev',
      'exec',
      'open',
      'watch'
    ]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'createDefaultTemplate',
    'connect:testserver',
    'exec:mocha'
  ]);

  grunt.registerTask('build', [
    'createDefaultTemplate',
//    'requirejs',
//    'concat',
//    'uglify',
    'copy',
  ]);

};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    mochaTest: {
      all: {
        src: ['test/**/*.js']
      }
    },
    watch: {
      all: {
        files:['test/*.js', 'app/index.js'],
        tasks:['mocha']
      }
    }
  });

  grunt.registerTask('default', ['watch']);
  grunt.registerTask('test', ['mochaTest']);

};
<commit_msg>fix task name<commit_after>module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    mochaTest: {
      all: {
        src: ['test/**/*.js']
      }
    },
    watch: {
      all: {
        files:['test/*.js', 'app/index.js'],
        tasks:['mochaTest']
      }
    }
  });

  grunt.registerTask('default', ['watch']);
  grunt.registerTask('test', ['mochaTest']);

};
<|endoftext|>


<commit_before>/*!
    Copyright (C) 2017 Google Inc.
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
*/

(function (can) {
  var _mustachePath;
  var overdueCompute;

  overdueCompute = function (val) {
    var date;
    var today = moment().startOf('day');
    var startOfDate;
    if (this.attr('status') === 'Verified') {
      return '';
    }
    date = moment(this.attr('next_due_date') || this.attr('end_date'));
    startOfDate = moment(date).startOf('day');
    // TODO: [Overdue] Move this logic to helper.
    if (date && today.diff(startOfDate, 'days') <= 0) {
      return '';
    }
    return 'overdue';
  };

  function refreshAttr(instance, attr) {
    if (instance.attr(attr).reify().selfLink) {
      instance.attr(attr).reify().refresh();
    }
  }

  function refreshAttrWrap(attr) {
    return function (ev, instance) {
      if (instance instanceof this) {
        refreshAttr(instance, attr);
      }
    };
  }

  function populateFromWorkflow(form, workflow) {
    if (!workflow || typeof workflow === 'string') {
      // We need to invalidate the form, so we remove workflow if it's not set
      form.removeAttr('workflow');
      return;
    }
    if (workflow.reify) {
      workflow = workflow.reify();
    } else {
      console.log("Can't reify workflow");
      return;
    }
    if (typeof workflow.cycles === undefined || !workflow.cycles) {
      $(document.body).trigger(
        'ajax:flash',
        {warning: 'No cycles in the workflow!'}
      );
      return;
    }

    workflow.refresh_all('cycles').then(function (cycleList) {
      var activeCycleList = _.filter(cycleList, {is_current: true});
      var activeCycle;

      if (!activeCycleList.length) {
        $(document.body).trigger(
          'ajax:flash',
          {warning: 'No active cycles in the workflow!'}
        );
        return;
      }
      activeCycleList = _.sortByOrder(
        activeCycleList, ['start_date'], ['desc']);
      activeCycle = activeCycleList[0];
      form.attr('workflow', {id: workflow.id, type: 'Workflow'});
      form.attr('context', {id: workflow.context.id, type: 'Context'});
      form.attr('cycle', {id: activeCycle.id, type: 'Cycle'});
      form.cycle_task_group = activeCycle.cycle_task_groups[0].id;
    });
  }

  _mustachePath = GGRC.mustache_path + '/cycles';
  can.Model.Cacheable('CMS.Models.Cycle', {
    root_object: 'cycle',
    root_collection: 'cycles',
    category: 'workflow',
    findAll: 'GET /api/cycles',
    findOne: 'GET /api/cycles/{id}',
    create: 'POST /api/cycles',
    update: 'PUT /api/cycles/{id}',
    destroy: 'DELETE /api/cycles/{id}',

    attributes: {
      workflow: 'CMS.Models.Workflow.stub',
      cycle_task_groups: 'CMS.Models.CycleTaskGroup.stubs',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub'
    },

    tree_view_options: {
      draw_children: true,
      attr_list: [{
        attr_title: 'Title',
        attr_name: 'title',
        order: 10
      }, {
        attr_title: 'End Date',
        attr_name: 'end_date',
        order: 20
      }],
      disable_columns_configuration: true
    },
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.bind('created', refreshAttrWrap('workflow').bind(this));
      this.bind('destroyed', function (ev, inst) {
        if (inst instanceof that) {
          can.each(inst.cycle_task_groups, function (cycleTaskGroup) {
            if (!cycleTaskGroup) {
              return;
            }
            cycleTaskGroup = cycleTaskGroup.reify();
            can.trigger(cycleTaskGroup, 'destroyed');
            can.trigger(
              cycleTaskGroup.constructor, 'destroyed', cycleTaskGroup);
          });
        }
      });
    }
  }, {
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.bind('status', function (ev, newVal) {
        if (newVal === 'Verified') {
          new RefreshQueue().enqueue(this.workflow.reify())
            .trigger()
            .then(function (wfs) {
              return wfs[0].get_binding('owners').refresh_instances();
            })
            .then(function (wfOwnerBindings) {
              var currentUser = CMS.Models.get_instance(
                'Person', GGRC.current_user.id);
              if (
                ~can.inArray(
                  currentUser,
                  can.map(wfOwnerBindings, function (wfOwnerBinding) {
                    return wfOwnerBinding.instance;
                  })
                )
              ) {
                that.refresh().then(function () {
                  if (that.attr('is_current')) {
                    that.attr('is_current', false);
                    that.save();
                  }
                });
              }
            });
        }
      });
    },
    overdue: overdueCompute
  });

  _mustachePath = GGRC.mustache_path + '/cycle_task_entries';
  can.Model.Cacheable('CMS.Models.CycleTaskEntry', {
    root_object: 'cycle_task_entry',
    root_collection: 'cycle_task_entries',
    category: 'workflow',
    findAll: 'GET /api/cycle_task_entries',
    findOne: 'GET /api/cycle_task_entries/{id}',
    create: 'POST /api/cycle_task_entries',
    update: 'PUT /api/cycle_task_entries/{id}',
    destroy: 'DELETE /api/cycle_task_entries/{id}',
    info_pane_options: {
      attachments: {
        mapping: 'documents',
        show_view: GGRC.mustache_path + '/base_templates/attachment.mustache'
      }
    },
    attributes: {
      cycle_task_group_object_task: 'CMS.Models.CycleTaskGroupObjectTask.stub',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub',
      object_documents: 'CMS.Models.ObjectDocument.stubs',
      documents: 'CMS.Models.Document.stubs',
      cycle: 'CMS.Models.Cycle.stub'
    },

    tree_view_options: {
      show_view: _mustachePath + '/tree.mustache',
      footer_view: _mustachePath + '/tree_footer.mustache',
      child_options: [{
        // 0: Documents
        model: 'Document',
        mapping: 'documents',
        show_view: _mustachePath + '/documents.mustache',
        footer_view: _mustachePath + '/documents_footer.mustache'
      }]
    },
    init: function () {
      this._super.apply(this, arguments);
      this.bind('created',
        refreshAttrWrap('cycle_task_group_object_task').bind(this));
      this.validateNonBlank('description');
    }
  }, {
    workflowFolder: function () {
      return this.refresh_all('cycle', 'workflow').then(function (workflow) {
        if (workflow.has_binding('folders')) {
          return workflow.refresh_all('folders').then(function (folders) {
            if (folders.length === 0) {
              return null;  // workflow folder has not been assigned
            }
            return folders[0].instance;
          }, function (result) {
            return result;
          });
        }
      });
    }
  });

  _mustachePath = GGRC.mustache_path + '/cycle_task_groups';
  can.Model.Cacheable('CMS.Models.CycleTaskGroup', {
    root_object: 'cycle_task_group',
    root_collection: 'cycle_task_groups',
    category: 'workflow',
    findAll: 'GET /api/cycle_task_groups',
    findOne: 'GET /api/cycle_task_groups/{id}',
    create: 'POST /api/cycle_task_groups',
    update: 'PUT /api/cycle_task_groups/{id}',
    destroy: 'DELETE /api/cycle_task_groups/{id}',

    attributes: {
      cycle: 'CMS.Models.Cycle.stub',
      task_group: 'CMS.Models.TaskGroup.stub',
      cycle_task_group_tasks: 'CMS.Models.CycleTaskGroupObjectTask.stubs',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub'
    },

    tree_view_options: {
      sort_property: 'sort_index',
      draw_children: true
    },

    init: function () {
      var that = this;
      this._super.apply(this, arguments);

      this.validateNonBlank('contact');
      this.validateContact(['_transient.contact', 'contact']);
      this.bind('updated', function (ev, instance) {
        var dfd;
        if (instance instanceof that) {
          dfd = instance.refresh_all_force('cycle', 'workflow');
          dfd.then(function () {
            return $.when(
              instance.refresh_all_force('related_objects'),
              instance.refresh_all_force('cycle_task_group_tasks')
            );
          });
        }
      });
      this.bind('destroyed', function (ev, inst) {
        if (inst instanceof that) {
          can.each(inst.cycle_task_group_tasks, function (ctgt) {
            if (!ctgt) {
              return;
            }
            ctgt = ctgt.reify();
            can.trigger(ctgt, 'destroyed');
            can.trigger(ctgt.constructor, 'destroyed', ctgt);
          });
        }
      });
    }
  }, {
    overdue: overdueCompute
  });

  _mustachePath = GGRC.mustache_path + '/cycle_task_group_object_tasks';
  can.Model.Cacheable('CMS.Models.CycleTaskGroupObjectTask', {
    root_object: 'cycle_task_group_object_task',
    root_collection: 'cycle_task_group_object_tasks',
    mixins: ['timeboxed'],
    category: 'workflow',
    findAll: 'GET /api/cycle_task_group_object_tasks',
    findOne: 'GET /api/cycle_task_group_object_tasks/{id}',
    create: 'POST /api/cycle_task_group_object_tasks',
    update: 'PUT /api/cycle_task_group_object_tasks/{id}',
    destroy: 'DELETE /api/cycle_task_group_object_tasks/{id}',
    title_singular: 'Cycle Task',
    attributes: {
      cycle_task_group: 'CMS.Models.CycleTaskGroup.stub',
      task_group_task: 'CMS.Models.TaskGroupTask.stub',
      cycle_task_entries: 'CMS.Models.CycleTaskEntry.stubs',
      modified_by: 'CMS.Models.Person.stub',
      contact: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub',
      cycle: 'CMS.Models.Cycle.stub'
    },
    permalink_options: {
      url: '<%= base.viewLink %>#current_widget/cycle/<%= instance.cycle.id %>/cycle_task_group/<%= instance.cycle_task_group.id %>/cycle_task_group_object_task/<%= instance.id %>',
      base: 'cycle:workflow'
    },
    info_pane_options: {
      mapped_objects: {
        model: can.Model.Cacheable,
        mapping: 'info_related_objects',
        show_view: GGRC.mustache_path + '/base_templates/subtree.mustache'
      },
      comments: {
        model: can.Model.Cacheable,
        mapping: 'cycle_task_entries',
        show_view: GGRC.mustache_path + '/cycle_task_entries/tree.mustache'
      }
    },
    tree_view_options: {
      sort_property: 'sort_index',
      attr_view: _mustachePath + '/tree-item-attr.mustache',
      attr_list: [
        {
          attr_title: 'Task title',
          attr_name: 'title',
          attr_sort_field: 'task title'
        },
        {
          attr_title: 'Cycle title',
          attr_name: 'workflow',
          attr_sort_field: 'cycle title'
        },
        {
          attr_title: 'Task state',
          attr_name: 'status',
          attr_sort_field: 'task state'
        },
        {
          attr_title: 'Task assignee',
          attr_name: 'assignee',
          attr_sort_field: 'task assignee'
        },
        {
          attr_title: 'Task start date',
          attr_name: 'start_date',
          attr_sort_field: 'task start date'
        },
        {
          attr_title: 'Task due date',
          attr_name: 'end_date',
          attr_sort_field: 'task due date'
        },
        {
          attr_title: 'Task last updated',
          attr_name: 'updated_at',
          attr_sort_field: 'task last updated'
        }
      ],
      display_attr_names: ['title', 'assignee', 'start_date'],
      mandatory_attr_name: ['title'],
      draw_children: true
    },
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.validateNonBlank('title');
      this.validateNonBlank('workflow');
      this.validateNonBlank('cycle');
      this.validateContact(['_transient.contact', 'contact']);
      this.validateNonBlank('start_date');
      this.validateNonBlank('end_date');

      this.bind('updated', function (ev, instance) {
        if (instance instanceof that) {
          instance.refresh_all_force('related_objects').then(function (object) {
            return instance.refresh_all_force(
              'cycle_task_group', 'cycle', 'workflow');
          });
        }
      });
    }
  }, {
    overdue: overdueCompute,
    _workflow: function () {
      return this.refresh_all('cycle', 'workflow').then(function (workflow) {
        return workflow;
      });
    },
    set_properties_from_workflow: function (workflow) {
      // The form sometimes returns plaintext instead of object, return in that case
      if (typeof workflow === 'string') {
        return;
      }
      populateFromWorkflow(this, workflow);
    },
    form_preload: function (newObjectForm) {
      var form = this;
      var workflows;
      var _workflow;
      var cycle;
      var person = {
        id: GGRC.current_user.id,
        type: 'Person'
      };

      if (newObjectForm) {
        // prepopulate dates with default ones
        this.attr('start_date', new Date());
        this.attr('end_date', moment().add({month: 3}).toDate());

        if (!form.contact) {
          form.attr('contact', person);
          form.attr('_transient.contact', person);
        }

        // using setTimeout to execute this after the modal is loaded
        // so we can see when the workflow is already set and use that one
        setTimeout(function () {
          // if we are creating a task from the workflow page, the preset
          // workflow should be that one
          if (form.workflow !== undefined) {
            populateFromWorkflow(form, form.workflow);
            return;
          }

          workflows = CMS.Models.Workflow.findAll({
            kind: 'Backlog', status: 'Active', __sort: '-created_at'});
          workflows.then(function (workflowList) {
            if (!workflowList.length) {
              $(document.body).trigger(
                'ajax:flash',
                {warning: 'No Backlog workflows found! Contact your administrator to enable this functionality.'}
              );
              return;
            }
            _workflow = workflowList[0];
            populateFromWorkflow(form, _workflow);
          });
        }, 0);
      } else {
        cycle = form.cycle.reify();
        if (!_.isUndefined(cycle.workflow)) {
          form.attr('workflow', cycle.workflow.reify());
        }
        if (this.contact) {
          this.attr('_transient.contact', this.contact);
        }
      }
    },
    object: function () {
      return this.refresh_all(
        'task_group_object', 'object'
      ).then(function (object) {
        return object;
      });
    },

    /**
     * Determine whether the Task's response options can be edited, taking
     * the Task and Task's Cycle status into account.
     *
     * @return {Boolean} - true if editing response options is allowed,
     *   false otherwise
     */
    responseOptionsEditable: function () {
      var cycle = this.attr('cycle').reify();
      var status = this.attr('status');

      var isEditable = cycle.attr('is_current') &&
                       !_.contains(['Finished', 'Verified'], status);
      return isEditable;
    }
  });
})(window.can);
<commit_msg>Reuse 'isOverdue' mixin for Cycle Models<commit_after>/*!
    Copyright (C) 2017 Google Inc.
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
*/

(function (can) {
  var _mustachePath;

  function refreshAttr(instance, attr) {
    if (instance.attr(attr).reify().selfLink) {
      instance.attr(attr).reify().refresh();
    }
  }

  function refreshAttrWrap(attr) {
    return function (ev, instance) {
      if (instance instanceof this) {
        refreshAttr(instance, attr);
      }
    };
  }

  function populateFromWorkflow(form, workflow) {
    if (!workflow || typeof workflow === 'string') {
      // We need to invalidate the form, so we remove workflow if it's not set
      form.removeAttr('workflow');
      return;
    }
    if (workflow.reify) {
      workflow = workflow.reify();
    } else {
      console.log("Can't reify workflow");
      return;
    }
    if (typeof workflow.cycles === undefined || !workflow.cycles) {
      $(document.body).trigger(
        'ajax:flash',
        {warning: 'No cycles in the workflow!'}
      );
      return;
    }

    workflow.refresh_all('cycles').then(function (cycleList) {
      var activeCycleList = _.filter(cycleList, {is_current: true});
      var activeCycle;

      if (!activeCycleList.length) {
        $(document.body).trigger(
          'ajax:flash',
          {warning: 'No active cycles in the workflow!'}
        );
        return;
      }
      activeCycleList = _.sortByOrder(
        activeCycleList, ['start_date'], ['desc']);
      activeCycle = activeCycleList[0];
      form.attr('workflow', {id: workflow.id, type: 'Workflow'});
      form.attr('context', {id: workflow.context.id, type: 'Context'});
      form.attr('cycle', {id: activeCycle.id, type: 'Cycle'});
      form.cycle_task_group = activeCycle.cycle_task_groups[0].id;
    });
  }

  _mustachePath = GGRC.mustache_path + '/cycles';
  can.Model.Cacheable('CMS.Models.Cycle', {
    root_object: 'cycle',
    root_collection: 'cycles',
    category: 'workflow',
    findAll: 'GET /api/cycles',
    findOne: 'GET /api/cycles/{id}',
    create: 'POST /api/cycles',
    update: 'PUT /api/cycles/{id}',
    destroy: 'DELETE /api/cycles/{id}',
    mixins: ['isOverdue'],
    attributes: {
      workflow: 'CMS.Models.Workflow.stub',
      cycle_task_groups: 'CMS.Models.CycleTaskGroup.stubs',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub'
    },
    tree_view_options: {
      draw_children: true,
      attr_list: [{
        attr_title: 'Title',
        attr_name: 'title',
        order: 10
      }, {
        attr_title: 'State ',
        attr_name: 'status',
        order: 15
      }, {
        attr_title: 'End Date',
        attr_name: 'end_date',
        order: 20
      }],
      mandatory_attr_name: ['title', 'status', 'end_date'],
      disable_columns_configuration: true
    },
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.bind('created', refreshAttrWrap('workflow').bind(this));
      this.bind('destroyed', function (ev, inst) {
        if (inst instanceof that) {
          can.each(inst.cycle_task_groups, function (cycleTaskGroup) {
            if (!cycleTaskGroup) {
              return;
            }
            cycleTaskGroup = cycleTaskGroup.reify();
            can.trigger(cycleTaskGroup, 'destroyed');
            can.trigger(
              cycleTaskGroup.constructor, 'destroyed', cycleTaskGroup);
          });
        }
      });
    }
  }, {
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.bind('status', function (ev, newVal) {
        if (newVal === 'Verified') {
          new RefreshQueue().enqueue(this.workflow.reify())
            .trigger()
            .then(function (wfs) {
              return wfs[0].get_binding('owners').refresh_instances();
            })
            .then(function (wfOwnerBindings) {
              var currentUser = CMS.Models.get_instance(
                'Person', GGRC.current_user.id);
              if (
                ~can.inArray(
                  currentUser,
                  can.map(wfOwnerBindings, function (wfOwnerBinding) {
                    return wfOwnerBinding.instance;
                  })
                )
              ) {
                that.refresh().then(function () {
                  if (that.attr('is_current')) {
                    that.attr('is_current', false);
                    that.save();
                  }
                });
              }
            });
        }
      });
    }
  });

  _mustachePath = GGRC.mustache_path + '/cycle_task_entries';
  can.Model.Cacheable('CMS.Models.CycleTaskEntry', {
    root_object: 'cycle_task_entry',
    root_collection: 'cycle_task_entries',
    category: 'workflow',
    findAll: 'GET /api/cycle_task_entries',
    findOne: 'GET /api/cycle_task_entries/{id}',
    create: 'POST /api/cycle_task_entries',
    update: 'PUT /api/cycle_task_entries/{id}',
    destroy: 'DELETE /api/cycle_task_entries/{id}',
    info_pane_options: {
      attachments: {
        mapping: 'documents',
        show_view: GGRC.mustache_path + '/base_templates/attachment.mustache'
      }
    },
    attributes: {
      cycle_task_group_object_task: 'CMS.Models.CycleTaskGroupObjectTask.stub',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub',
      object_documents: 'CMS.Models.ObjectDocument.stubs',
      documents: 'CMS.Models.Document.stubs',
      cycle: 'CMS.Models.Cycle.stub'
    },

    tree_view_options: {
      show_view: _mustachePath + '/tree.mustache',
      footer_view: _mustachePath + '/tree_footer.mustache',
      child_options: [{
        // 0: Documents
        model: 'Document',
        mapping: 'documents',
        show_view: _mustachePath + '/documents.mustache',
        footer_view: _mustachePath + '/documents_footer.mustache'
      }]
    },
    init: function () {
      this._super.apply(this, arguments);
      this.bind('created',
        refreshAttrWrap('cycle_task_group_object_task').bind(this));
      this.validateNonBlank('description');
    }
  }, {
    workflowFolder: function () {
      return this.refresh_all('cycle', 'workflow').then(function (workflow) {
        if (workflow.has_binding('folders')) {
          return workflow.refresh_all('folders').then(function (folders) {
            if (folders.length === 0) {
              return null;  // workflow folder has not been assigned
            }
            return folders[0].instance;
          }, function (result) {
            return result;
          });
        }
      });
    }
  });

  _mustachePath = GGRC.mustache_path + '/cycle_task_groups';
  can.Model.Cacheable('CMS.Models.CycleTaskGroup', {
    root_object: 'cycle_task_group',
    root_collection: 'cycle_task_groups',
    category: 'workflow',
    findAll: 'GET /api/cycle_task_groups',
    findOne: 'GET /api/cycle_task_groups/{id}',
    create: 'POST /api/cycle_task_groups',
    update: 'PUT /api/cycle_task_groups/{id}',
    destroy: 'DELETE /api/cycle_task_groups/{id}',
    mixins: ['isOverdue'],
    attributes: {
      cycle: 'CMS.Models.Cycle.stub',
      task_group: 'CMS.Models.TaskGroup.stub',
      cycle_task_group_tasks: 'CMS.Models.CycleTaskGroupObjectTask.stubs',
      modified_by: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub'
    },

    tree_view_options: {
      sort_property: 'sort_index',
      draw_children: true
    },

    init: function () {
      var that = this;
      this._super.apply(this, arguments);

      this.validateNonBlank('contact');
      this.validateContact(['_transient.contact', 'contact']);
      this.bind('updated', function (ev, instance) {
        var dfd;
        if (instance instanceof that) {
          dfd = instance.refresh_all_force('cycle', 'workflow');
          dfd.then(function () {
            return $.when(
              instance.refresh_all_force('related_objects'),
              instance.refresh_all_force('cycle_task_group_tasks')
            );
          });
        }
      });
      this.bind('destroyed', function (ev, inst) {
        if (inst instanceof that) {
          can.each(inst.cycle_task_group_tasks, function (ctgt) {
            if (!ctgt) {
              return;
            }
            ctgt = ctgt.reify();
            can.trigger(ctgt, 'destroyed');
            can.trigger(ctgt.constructor, 'destroyed', ctgt);
          });
        }
      });
    }
  }, {});

  _mustachePath = GGRC.mustache_path + '/cycle_task_group_object_tasks';
  can.Model.Cacheable('CMS.Models.CycleTaskGroupObjectTask', {
    root_object: 'cycle_task_group_object_task',
    root_collection: 'cycle_task_group_object_tasks',
    mixins: ['timeboxed', 'isOverdue'],
    category: 'workflow',
    findAll: 'GET /api/cycle_task_group_object_tasks',
    findOne: 'GET /api/cycle_task_group_object_tasks/{id}',
    create: 'POST /api/cycle_task_group_object_tasks',
    update: 'PUT /api/cycle_task_group_object_tasks/{id}',
    destroy: 'DELETE /api/cycle_task_group_object_tasks/{id}',
    title_singular: 'Cycle Task',
    attributes: {
      cycle_task_group: 'CMS.Models.CycleTaskGroup.stub',
      task_group_task: 'CMS.Models.TaskGroupTask.stub',
      cycle_task_entries: 'CMS.Models.CycleTaskEntry.stubs',
      modified_by: 'CMS.Models.Person.stub',
      contact: 'CMS.Models.Person.stub',
      context: 'CMS.Models.Context.stub',
      cycle: 'CMS.Models.Cycle.stub'
    },
    permalink_options: {
      url: '<%= base.viewLink %>#current_widget' +
      '/cycle/<%= instance.cycle.id %>' +
      '/cycle_task_group/<%= instance.cycle_task_group.id %>' +
      '/cycle_task_group_object_task/<%= instance.id %>',
      base: 'cycle:workflow'
    },
    info_pane_options: {
      mapped_objects: {
        model: can.Model.Cacheable,
        mapping: 'info_related_objects',
        show_view: GGRC.mustache_path + '/base_templates/subtree.mustache'
      },
      comments: {
        model: can.Model.Cacheable,
        mapping: 'cycle_task_entries',
        show_view: GGRC.mustache_path + '/cycle_task_entries/tree.mustache'
      }
    },
    tree_view_options: {
      sort_property: 'sort_index',
      attr_view: _mustachePath + '/tree-item-attr.mustache',
      attr_list: [
        {
          attr_title: 'Task title',
          attr_name: 'title',
          attr_sort_field: 'task title'
        },
        {
          attr_title: 'Cycle title',
          attr_name: 'workflow',
          attr_sort_field: 'cycle title'
        },
        {
          attr_title: 'Task state',
          attr_name: 'status',
          attr_sort_field: 'task state'
        },
        {
          attr_title: 'Task assignee',
          attr_name: 'assignee',
          attr_sort_field: 'task assignee'
        },
        {
          attr_title: 'Task start date',
          attr_name: 'start_date',
          attr_sort_field: 'task start date'
        },
        {
          attr_title: 'Task due date',
          attr_name: 'end_date',
          attr_sort_field: 'task due date'
        },
        {
          attr_title: 'Task last updated',
          attr_name: 'updated_at',
          attr_sort_field: 'task last updated'
        }
      ],
      display_attr_names: ['title', 'assignee', 'start_date'],
      mandatory_attr_name: ['title'],
      draw_children: true
    },
    init: function () {
      var that = this;
      this._super.apply(this, arguments);
      this.validateNonBlank('title');
      this.validateNonBlank('workflow');
      this.validateNonBlank('cycle');
      this.validateContact(['_transient.contact', 'contact']);
      this.validateNonBlank('start_date');
      this.validateNonBlank('end_date');

      this.bind('updated', function (ev, instance) {
        if (instance instanceof that) {
          instance.refresh_all_force('related_objects').then(function (object) {
            return instance.refresh_all_force(
              'cycle_task_group', 'cycle', 'workflow');
          });
        }
      });
    }
  }, {
    _workflow: function () {
      return this.refresh_all('cycle', 'workflow').then(function (workflow) {
        return workflow;
      });
    },
    set_properties_from_workflow: function (workflow) {
      // The form sometimes returns plaintext instead of object, return in that case
      if (typeof workflow === 'string') {
        return;
      }
      populateFromWorkflow(this, workflow);
    },
    form_preload: function (newObjectForm) {
      var form = this;
      var workflows;
      var _workflow;
      var cycle;
      var person = {
        id: GGRC.current_user.id,
        type: 'Person'
      };

      if (newObjectForm) {
        // prepopulate dates with default ones
        this.attr('start_date', new Date());
        this.attr('end_date', moment().add({month: 3}).toDate());

        if (!form.contact) {
          form.attr('contact', person);
          form.attr('_transient.contact', person);
        }

        // using setTimeout to execute this after the modal is loaded
        // so we can see when the workflow is already set and use that one
        setTimeout(function () {
          // if we are creating a task from the workflow page, the preset
          // workflow should be that one
          if (form.workflow !== undefined) {
            populateFromWorkflow(form, form.workflow);
            return;
          }

          workflows = CMS.Models.Workflow.findAll({
            kind: 'Backlog', status: 'Active', __sort: '-created_at'});
          workflows.then(function (workflowList) {
            if (!workflowList.length) {
              $(document.body).trigger(
                'ajax:flash',
                {warning: 'No Backlog' +
                ' workflows found!' +
                ' Contact your administrator to enable this functionality.'
                }
              );
              return;
            }
            _workflow = workflowList[0];
            populateFromWorkflow(form, _workflow);
          });
        }, 0);
      } else {
        cycle = form.cycle.reify();
        if (!_.isUndefined(cycle.workflow)) {
          form.attr('workflow', cycle.workflow.reify());
        }
        if (this.contact) {
          this.attr('_transient.contact', this.contact);
        }
      }
    },
    object: function () {
      return this.refresh_all(
        'task_group_object', 'object'
      ).then(function (object) {
        return object;
      });
    },

    /**
     * Determine whether the Task's response options can be edited, taking
     * the Task and Task's Cycle status into account.
     *
     * @return {Boolean} - true if editing response options is allowed,
     *   false otherwise
     */
    responseOptionsEditable: function () {
      var cycle = this.attr('cycle').reify();
      var status = this.attr('status');

      return cycle.attr('is_current') &&
        !_.contains(['Finished', 'Verified'], status);
    }
  });
})(window.can);
<|endoftext|>


<commit_before>
import { observable } from 'mobx';
import cookie from 'utils/cookie';
import { QUERY_PANEL, SIDEBAR_PANEL } from 'constants/CookieKeys';

const maxAge = 60 * 60 * 24 * 30;

class PanelsStore {
	@observable isShowSidebar = true;
	@observable isShowQuery = false;

	updateSidebar(val) {
		this.isShowSidebar = val;
		cookie.set(SIDEBAR_PANEL, val, { maxAge });
	}

	updateQuery(val) {
		this.isShowQuery = val;
		cookie.set(QUERY_PANEL, val, { maxAge });
	}
}

export default new PanelsStore();
<commit_msg>fix panels bug<commit_after>
import { observable } from 'mobx';
import cookie from 'utils/cookie';
import { QUERY_PANEL, SIDEBAR_PANEL } from 'constants/CookieKeys';

const maxAge = 60 * 60 * 24 * 30;

class PanelsStore {
	@observable isShowSidebar = cookie.get(SIDEBAR_PANEL) !== 'false';
	@observable isShowQuery = cookie.get(QUERY_PANEL) !== 'false';

	updateSidebar(val) {
		this.isShowSidebar = val;
		cookie.set(SIDEBAR_PANEL, val, { maxAge });
	}

	updateQuery(val) {
		this.isShowQuery = val;
		cookie.set(QUERY_PANEL, val, { maxAge });
	}
}

export default new PanelsStore();
<|endoftext|>


<commit_before>/* To prevent jshint from yelling at module.exports. */
/* jshint node:true */

'use strict';

var LIVERELOAD_PORT = 35729;

module.exports = function(grunt) {

	// Loads all grunt tasks
	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
	require('time-grunt')(grunt);

	// App configuration
	var config = grunt.file.readYAML('config/common.yml');

	// Tasks configuration
	grunt.initConfig({

		config: config,

		clean: {
			destination: {
				files: [{
					dot: true,
					src: '<%= config.destination %>/*'
				}]
			},
			icons: {
				files: [{
					dot: true,
					src: '<%= config.source %>/icons/icons*.*'
				}]
			}
		},

		copy: {
			cssToDest: {
				src: '*.css',
				dest: '<%= config.destination %>/css/',
				flatten: true,
				filter: 'isFile',
				expand: true,
				nonull: true,
				cwd: '<%= config.source %>/css/'
			}
		},

		csslint: {
			options: {
				csslintrc: '.csslintrc'
			},
			lax: {
				src: '<%= config.destination %>/css/*.css',
				options: {
					import: false
				}
			},
			strict: {
				src: '<%= config.destination %>/css/*.css',
				options: {
					import: 2
				}
			}
		},

		cssmin: {
			css: {
				src: '<%= config.source %>/css/styles.css',
				dest: '<%= config.source %>/css/styles.min.css',
				options: {
					keepSpecialComments: 0
				}
			}
		},

		gae: {
			options: {
				path: 'appengine',
				auth: 'oauth2'
			},
			deploy: {
				action: 'update'
			},
			local: {
				action: 'run',
				options: {
					async: true,
					args: {
						port: config.port
					}
				}
			},
			stop: {
				action: 'kill'
			}
		},

		htmlmin: {
			all: {
				options: {
					removeCommentsFromCDATA: true,
					// https://github.com/yeoman/grunt-usemin/issues/44
					collapseWhitespace: true,
					collapseBooleanAttributes: true,
					// removeAttributeQuotes: true,
					removeRedundantAttributes: true,
					useShortDoctype: true,
					removeEmptyAttributes: true,
					removeOptionalTags: true
				},
				files: [{
					expand: true,
					cwd: '<%= config.destination %>',
					src: ['**/*.html'],
					dest: '<%= config.destination %>'
				}]
			}
		},

		imagemin: {
			normal: {
				options: {
					optimizationLevel: 7
				},
				files: [{
					expand: true,
					src: ['**/*.png']
				}]
			},
			o2: {
				options: {
					optimizationLevel: 2
				},
				files: [{
					expand: true,
					src: ['**/*.png']
				}]
			}
		},

		jshint: {
			options: {
				jshintrc: '.jshintrc'
			},
			source: [
				'Gruntfile.js',
				'<%= config.source %>/**/*.js',
				'!<%= config.source %>/**/_code/**/*.js'
			]
		},

		open: {
			local: {
				path: 'http://localhost:<%=config.port%>/web/fundamentals'
			},
			staging: {
				path: 'http://web-central.appspot.com/web/fundamentals'
			},
		},

		sass: {
			options: {
				precision: 10,
				includePaths: ['<%= config.source %>/css'],
				imagePath: '<%= config.source %>/imgs',
				outputStyle: 'nested'
			},
			all: {
				files: {
					'<%= config.source %>/css/styles.css': '<%= config.source %>/_sass/styles.scss'
				}
			}
		},

		watch: {
			// When styles change, recompile them
			styles: {
				files: [
					'<%= config.source %>/_sass/**/*.scss',
					'<%= config.source %>/css/**/*.css',
					'!<%= config.source %>/css/**/*.min.css'
				],
				tasks: ['sass', 'cssmin', 'copy:cssToDest']
			},

			// when jekyll source changes, recompile them
			jekyll: {
				files: [
					'<%= config.source %>/**/*.html',
					'<%= config.source %>/**/*.liquid',
					'<%= config.source %>/**/*.markdown',
					'<%= config.source %>/**/*.rb',
					'<%= config.source %>/**/*.md'
				],
				tasks: ['jekyll:appengine']
			},

			// when served files change, reload them in the browser
			served: {
				options: {
					livereload: LIVERELOAD_PORT
				},
				files: [
					'<%= config.destination %>/**/*.html',  // view files (from jekyll)
					'<%= config.destination %>/css/*.css'   // css files (from sass)
				]
			}
		},

		webfont: {
			icons: {
				src: '<%= config.source %>/icons/*.svg',
				dest: '<%= config.source %>/icons/',
				destCss: '<%= config.source %>/_sass/_components/',
				options: {
					hashes: false,
					stylesheet: 'scss',
					relativeFontPath: '../icons',
					htmlDemo: false,
					template: '<%= config.source %>/_templates/icons-template.css'
				}
			}

		}
	});

	grunt.registerTask('wsk-version', 'Uses the Github API to determine the latest web-starter-kit version, and writes it to ./config/wsk-version.yml', function() {
		var latest = require('latest-release');
		var done = this.async();
		var out = './config/wsk-version.yml';

		grunt.log.writeln('Determining latest web-starter-kit version..');

		latest('google', 'web-starter-kit', function(release, err) {
			if (err) {
				grunt.verbose.or.write('Failed to retrieve latest web-starter-kit release information').error().error(err.message);
			} else {
				grunt.log.writeln('Latest version is: ' + release.name);
				grunt.log.writeln('Saved release information under: ' + out);
				/*jshint camelcase: false */
				/*ignore the casing on the variables. These come directly from the Githup API.*/
				grunt.file.write(out,
					'wsk-tag: ' + release.tag_name + '\n' +
					'wsk-name: ' + release.name + '\n' +
					'wsk-zip-url: ' + release.zipball_url + '\n'
					);
				/*jshint camelcase: true */
				done();
			}
		});
	});

	// jekyll:target [--lang <lang_code,lang_code,...|all>]
	// where 'target' is config/target.yml file.
	// defaults to '--lang all'.
	// 'all' builds for all languages specified in config.yml/langs_available + 'en'.
	// builds w/o multilang support if config.yml is missing langs_available.
	grunt.registerTask('jekyll', 'Run jekyll build.\nOptions:\n  [--lang]: list of languages or "all"', function() {
		var langs = grunt.option('lang') || 'all';

		var cfgname = this.args[0] || 'appengine';

		// read langs from config/target.yml
		// returns langs_available + prime_lang
		//         or [] if langs_available is not defined.
		var langsFromConfig = function() {
			/*jshint camelcase: false */
			var cfg = grunt.file.readYAML('config/common.yml');
			if (typeof cfg.langs_available === 'undefined') {
				return [];
			}
			cfg.langs_available.unshift(cfg.prime_lang);
			return cfg.langs_available;
			/*jshint camelcase: true */
		};

		if (langs === 'all' ) {
			langs = langsFromConfig();
		} else {
			langs = langs.split(/,|\s/).filter(function(item) {
				return item.length > 0;
			});
		}

		var cfgfiles = 'config/wsk-version.yml,config/common.yml,config/' + cfgname + '.yml';
		var args = ['build', '--config', cfgfiles, '-t'];
		var spawnJekyll = function(lang, callback) {
			var opts = {env: process.env, stdio: 'inherit'};
			if (lang !== null) {
				opts.env.TRANS_LANG = lang;
			}
			grunt.util.spawn({cmd: 'jekyll', args: args, opts: opts}, callback);
		};

		var done = this.async();
		var count = 0;
		var waitAll = function(err, res, code) {
			if (err) {
				grunt.fatal(String(res), code);
			}
			if (++count >= langs.length) {
				done();
			}
		};

		// multilang build
		for (var i = 0; i < langs.length; i++) {
			spawnJekyll(langs[i], waitAll);
		}
		// simple build (no multilang support)
		if (langs.length === 0) {
			spawnJekyll(null, waitAll);
		}
	});

	// Test task
	grunt.registerTask('test', 'Lints all javascript and CSS sources.', 'jshint:source');

	grunt.registerTask('prepare', ['wsk-version', 'test', 'clean:destination', 'sass', 'cssmin']);

	// Build task
	grunt.registerTask('build', 'Runs the "test" task, then builds the website.', [
		'prepare',
		'jekyll:appengine'   // Build the site with Jekyll
	]);

	// Develop task
	grunt.registerTask('develop', 'The default task for developers.\nRuns the tests, builds the minimum required, serves the content and watches for changes.', [
		'build',   // Build the site with Jekyll
		'gae:local',
		'open:local',
		'watch'
	]);

	// Devsite task
	grunt.registerTask('devsite', 'Runs the build steps with devsite config', [
		'clean:icons',        // Clean up icon font files for regeneration
		'webfont:icons',      // Generate icon font files and SASS
		'prepare',
		'jekyll:devsite',     // Build the site with Jekyll
		'htmlmin:all'         // Minify the final HTML
	]);

	// Default task
	grunt.registerTask('default', 'develop');

};
<commit_msg>Removing the watch from some html files<commit_after>/* To prevent jshint from yelling at module.exports. */
/* jshint node:true */

'use strict';

var LIVERELOAD_PORT = 35729;

module.exports = function(grunt) {

	// Loads all grunt tasks
	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
	require('time-grunt')(grunt);

	// App configuration
	var config = grunt.file.readYAML('config/common.yml');

	// Tasks configuration
	grunt.initConfig({

		config: config,

		clean: {
			destination: {
				files: [{
					dot: true,
					src: '<%= config.destination %>/*'
				}]
			},
			icons: {
				files: [{
					dot: true,
					src: '<%= config.source %>/icons/icons*.*'
				}]
			}
		},

		copy: {
			cssToDest: {
				src: '*.css',
				dest: '<%= config.destination %>/css/',
				flatten: true,
				filter: 'isFile',
				expand: true,
				nonull: true,
				cwd: '<%= config.source %>/css/'
			}
		},

		csslint: {
			options: {
				csslintrc: '.csslintrc'
			},
			lax: {
				src: '<%= config.destination %>/css/*.css',
				options: {
					import: false
				}
			},
			strict: {
				src: '<%= config.destination %>/css/*.css',
				options: {
					import: 2
				}
			}
		},

		cssmin: {
			css: {
				src: '<%= config.source %>/css/styles.css',
				dest: '<%= config.source %>/css/styles.min.css',
				options: {
					keepSpecialComments: 0
				}
			}
		},

		gae: {
			options: {
				path: 'appengine',
				auth: 'oauth2'
			},
			deploy: {
				action: 'update'
			},
			local: {
				action: 'run',
				options: {
					async: true,
					args: {
						port: config.port
					}
				}
			},
			stop: {
				action: 'kill'
			}
		},

		htmlmin: {
			all: {
				options: {
					removeCommentsFromCDATA: true,
					// https://github.com/yeoman/grunt-usemin/issues/44
					collapseWhitespace: true,
					collapseBooleanAttributes: true,
					// removeAttributeQuotes: true,
					removeRedundantAttributes: true,
					useShortDoctype: true,
					removeEmptyAttributes: true,
					removeOptionalTags: true
				},
				files: [{
					expand: true,
					cwd: '<%= config.destination %>',
					src: ['**/*.html'],
					dest: '<%= config.destination %>'
				}]
			}
		},

		imagemin: {
			normal: {
				options: {
					optimizationLevel: 7
				},
				files: [{
					expand: true,
					src: ['**/*.png']
				}]
			},
			o2: {
				options: {
					optimizationLevel: 2
				},
				files: [{
					expand: true,
					src: ['**/*.png']
				}]
			}
		},

		jshint: {
			options: {
				jshintrc: '.jshintrc'
			},
			source: [
				'Gruntfile.js',
				'<%= config.source %>/**/*.js',
				'!<%= config.source %>/**/_code/**/*.js'
			]
		},

		open: {
			local: {
				path: 'http://localhost:<%=config.port%>/web/fundamentals'
			},
			staging: {
				path: 'http://web-central.appspot.com/web/fundamentals'
			},
		},

		sass: {
			options: {
				precision: 10,
				includePaths: ['<%= config.source %>/css'],
				imagePath: '<%= config.source %>/imgs',
				outputStyle: 'nested'
			},
			all: {
				files: {
					'<%= config.source %>/css/styles.css': '<%= config.source %>/_sass/styles.scss'
				}
			}
		},

		watch: {
			// When styles change, recompile them
			styles: {
				files: [
					'<%= config.source %>/_sass/**/*.scss',
					'<%= config.source %>/css/**/*.css',
					'!<%= config.source %>/css/**/*.min.css'
				],
				tasks: ['sass', 'cssmin', 'copy:cssToDest']
			},

			// when jekyll source changes, recompile them
			jekyll: {
				files: [
					'<%= config.source %>/**/*.liquid',
					'<%= config.source %>/**/*.markdown',
					'<%= config.source %>/**/*.rb',
					'<%= config.source %>/**/*.md'
				],
				tasks: ['jekyll:appengine']
			},

			// when served files change, reload them in the browser
			served: {
				options: {
					livereload: LIVERELOAD_PORT
				},
				files: [
					'<%= config.destination %>/**/*.html',  // view files (from jekyll)
					'<%= config.destination %>/css/*.css'   // css files (from sass)
				]
			}
		},

		webfont: {
			icons: {
				src: '<%= config.source %>/icons/*.svg',
				dest: '<%= config.source %>/icons/',
				destCss: '<%= config.source %>/_sass/_components/',
				options: {
					hashes: false,
					stylesheet: 'scss',
					relativeFontPath: '../icons',
					htmlDemo: false,
					template: '<%= config.source %>/_templates/icons-template.css'
				}
			}

		}
	});

	grunt.registerTask('wsk-version', 'Uses the Github API to determine the latest web-starter-kit version, and writes it to ./config/wsk-version.yml', function() {
		var latest = require('latest-release');
		var done = this.async();
		var out = './config/wsk-version.yml';

		grunt.log.writeln('Determining latest web-starter-kit version..');

		latest('google', 'web-starter-kit', function(release, err) {
			if (err) {
				grunt.verbose.or.write('Failed to retrieve latest web-starter-kit release information').error().error(err.message);
			} else {
				grunt.log.writeln('Latest version is: ' + release.name);
				grunt.log.writeln('Saved release information under: ' + out);
				/*jshint camelcase: false */
				/*ignore the casing on the variables. These come directly from the Githup API.*/
				grunt.file.write(out,
					'wsk-tag: ' + release.tag_name + '\n' +
					'wsk-name: ' + release.name + '\n' +
					'wsk-zip-url: ' + release.zipball_url + '\n'
					);
				/*jshint camelcase: true */
				done();
			}
		});
	});

	// jekyll:target [--lang <lang_code,lang_code,...|all>]
	// where 'target' is config/target.yml file.
	// defaults to '--lang all'.
	// 'all' builds for all languages specified in config.yml/langs_available + 'en'.
	// builds w/o multilang support if config.yml is missing langs_available.
	grunt.registerTask('jekyll', 'Run jekyll build.\nOptions:\n  [--lang]: list of languages or "all"', function() {
		var langs = grunt.option('lang') || 'all';

		var cfgname = this.args[0] || 'appengine';

		// read langs from config/target.yml
		// returns langs_available + prime_lang
		//         or [] if langs_available is not defined.
		var langsFromConfig = function() {
			/*jshint camelcase: false */
			var cfg = grunt.file.readYAML('config/common.yml');
			if (typeof cfg.langs_available === 'undefined') {
				return [];
			}
			cfg.langs_available.unshift(cfg.prime_lang);
			return cfg.langs_available;
			/*jshint camelcase: true */
		};

		if (langs === 'all' ) {
			langs = langsFromConfig();
		} else {
			langs = langs.split(/,|\s/).filter(function(item) {
				return item.length > 0;
			});
		}

		var cfgfiles = 'config/wsk-version.yml,config/common.yml,config/' + cfgname + '.yml';
		var args = ['build', '--config', cfgfiles, '-t'];
		var spawnJekyll = function(lang, callback) {
			var opts = {env: process.env, stdio: 'inherit'};
			if (lang !== null) {
				opts.env.TRANS_LANG = lang;
			}
			grunt.util.spawn({cmd: 'jekyll', args: args, opts: opts}, callback);
		};

		var done = this.async();
		var count = 0;
		var waitAll = function(err, res, code) {
			if (err) {
				grunt.fatal(String(res), code);
			}
			if (++count >= langs.length) {
				done();
			}
		};

		// multilang build
		for (var i = 0; i < langs.length; i++) {
			spawnJekyll(langs[i], waitAll);
		}
		// simple build (no multilang support)
		if (langs.length === 0) {
			spawnJekyll(null, waitAll);
		}
	});

	// Test task
	grunt.registerTask('test', 'Lints all javascript and CSS sources.', 'jshint:source');

	grunt.registerTask('prepare', ['wsk-version', 'test', 'clean:destination', 'sass', 'cssmin']);

	// Build task
	grunt.registerTask('build', 'Runs the "test" task, then builds the website.', [
		'prepare',
		'jekyll:appengine'   // Build the site with Jekyll
	]);

	// Develop task
	grunt.registerTask('develop', 'The default task for developers.\nRuns the tests, builds the minimum required, serves the content and watches for changes.', [
		'build',   // Build the site with Jekyll
		'gae:local',
		'open:local',
		'watch'
	]);

	// Devsite task
	grunt.registerTask('devsite', 'Runs the build steps with devsite config', [
		'clean:icons',        // Clean up icon font files for regeneration
		'webfont:icons',      // Generate icon font files and SASS
		'prepare',
		'jekyll:devsite',     // Build the site with Jekyll
		'htmlmin:all'         // Minify the final HTML
	]);

	// Default task
	grunt.registerTask('default', 'develop');

};
<|endoftext|>


<commit_before>const Promise = require('bluebird')
const db = require('../config/db')

exports.add = function (type, data){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('INSERT INTO '+table+' (name) VALUES (?);', [data]).then(function (result){
    return result[0].affectedRows === 1
  }).catch(function (err){
    return false
  })
}

exports.view = function (type){
  var table = getTableName(type)
  if(!table){ return false }

  return Promise.all([
    db.query('SELECT * FROM '+table+' WHERE active = 1;'),
    db.query('SELECT * FROM '+table+' WHERE active = 0;')
  ]).then(function (result){
    return {
      actives: result[0][0],
      inactives: result[1][0]
    }
  })
}

exports.viewAdmins = function (userId){
  return Promise.all([
    db.query('SELECT * FROM Users where userType = 2 and userID != ?;', [userId])
  ]).then(function (result){
    return {
      currentAdmins: result[0][0]
    }
  })
}

exports.viewDoctors = function (userId){
  return Promise.all([
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = -1;'),
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = 0;'),
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = 1;')
  ]).then(function (result){
    return {
      denied: result[0][0],
      unverified: result[1][0],
      verified: result[2][0]
    }
  })
}

exports.verifyDoctor = function (user){
  return db.query('UPDATE DoctorProfile SET verified = 1 WHERE userID =?;', [user.userID]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.denyDoctor = function (user){
  return db.query('UPDATE DoctorProfile SET verified = -1 WHERE userID =?;', [user.userID]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.getAdmin = function (userId){
  return Promise.all([
    db.query('SELECT * FROM Users where userID = ?;', [userId])
  ]).then(function (result){
    return {
      currentAdmin: result[0][0][0]
    }
  })
}

exports.edit = function (type, name, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET name =? WHERE _id =?;', [name, id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.deactivate = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET active = 0 WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.activate = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET active = 1 WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.delete = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('DELETE FROM '+table+' WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

var getTableName = function (type){
  if(type === 'allergy'){
    return 'Allergies'
  }else if(type === 'specialty'){
    return 'Specialties'
  }else if(type === 'medication'){
    return 'Medications'
  }else if(type === 'datatype'){
    return 'DataType'
  }else{
    return false
  }
}
<commit_msg>added comment to describe doctorProfile.verified<commit_after>const Promise = require('bluebird')
const db = require('../config/db')

exports.add = function (type, data){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('INSERT INTO '+table+' (name) VALUES (?);', [data]).then(function (result){
    return result[0].affectedRows === 1
  }).catch(function (err){
    return false
  })
}

exports.view = function (type){
  var table = getTableName(type)
  if(!table){ return false }

  return Promise.all([
    db.query('SELECT * FROM '+table+' WHERE active = 1;'),
    db.query('SELECT * FROM '+table+' WHERE active = 0;')
  ]).then(function (result){
    return {
      actives: result[0][0],
      inactives: result[1][0]
    }
  })
}

exports.viewAdmins = function (userId){
  return Promise.all([
    db.query('SELECT * FROM Users where userType = 2 and userID != ?;', [userId])
  ]).then(function (result){
    return {
      currentAdmins: result[0][0]
    }
  })
}

exports.viewDoctors = function (userId){
  return Promise.all([
    /*
      Unverified doctors: verified = 0
      Denied doctors: verified = -1
      Verified doctors: verified = 1
    */
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = -1;'),
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = 0;'),
    db.query('SELECT * FROM DoctorProfile dp join Users u on u.userID = dp.userID where verified = 1;')
  ]).then(function (result){
    return {
      denied: result[0][0],
      unverified: result[1][0],
      verified: result[2][0]
    }
  })
}

exports.verifyDoctor = function (user){
  return db.query('UPDATE DoctorProfile SET verified = 1 WHERE userID =?;', [user.userID]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.denyDoctor = function (user){
  return db.query('UPDATE DoctorProfile SET verified = -1 WHERE userID =?;', [user.userID]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.getAdmin = function (userId){
  return Promise.all([
    db.query('SELECT * FROM Users where userID = ?;', [userId])
  ]).then(function (result){
    return {
      currentAdmin: result[0][0][0]
    }
  })
}

exports.edit = function (type, name, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET name =? WHERE _id =?;', [name, id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.deactivate = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET active = 0 WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.activate = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('UPDATE '+table+' SET active = 1 WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

exports.delete = function (type, id){
  var table = getTableName(type)
  if(!table){ return false }

  return db.query('DELETE FROM '+table+' WHERE _id =?;', [id]).then(function (result){
    return result[0].affectedRows === 1
  })
}

var getTableName = function (type){
  if(type === 'allergy'){
    return 'Allergies'
  }else if(type === 'specialty'){
    return 'Specialties'
  }else if(type === 'medication'){
    return 'Medications'
  }else if(type === 'datatype'){
    return 'DataType'
  }else{
    return false
  }
}
<|endoftext|>


<commit_before>angular.module('getBaskets', [])

.factory('getUsersBaskets', ['$http', function($http) {

  return function() {
    var url = 'http://localhost:3000/ng_users_folders';

    var promise = $http({
      url: url,
      method: 'GET'
    }).success(function(response) {

      return response;

    }).error(function(response) {

      return {'status': false};

    })

    return promise;
  }

}])

.factory('getLinkstoBasket', ['$http', function($http) {
  var url = 'http://localhost:3000/ng_basket_links'

  return function(basketID) {

    var promise = $http({
      url: url,
      params: {basketID: basketID},
      method: 'GET'
    }).success(function(response) {

      return response;

    }).error(function(response) {

      return {'status':false};

    })

    return promise;

  }

}])<commit_msg>added hard coded api responses<commit_after>angular.module('getBaskets', [])

.factory('getUsersBaskets', ['$http', function($http) {

  return function() {
    var url = 'http://localhost:3000/ng_users_folders';

    var promise = $http({
      url: url,
      method: 'GET'
    }).success(function(response) {

      // console.log(response);
      // array = [
      //  {created_at: "2015-05-16T11:42:44.050-04:00",
      //   id: 2,
      //   name: "Test Basket",
      //   updated_at: "2015-05-16T11:42:44.050-04:00",
      //   user_id: 1}
      // ]

      return response;

    }).error(function(response) {

      return {'status': false};

    })

    return promise;
  }

}])

.factory('getLinkstoBasket', ['$http', function($http) {
  var url = 'http://localhost:3000/ng_basket_links'

  return function(basketID) {

    var promise = $http({
      url: url,
      params: {basketID: basketID},
      method: 'GET'
    }).success(function(response) {

      // console.log(response);
      // array = [
      //   {
      //     created_at: "2015-05-16T11:56:50.556-04:00",
      //     description: "Share your videos with friends, family, and the world",
      //     folder_id: 2,
      //     id: 4,
      //     image: null,
      //     message: "Where did he go?",
      //     title: "Hatbox Ghost Reappears in Haunted Mansion | Disneyland Resort - YouTube",
      //     updated_at: "2015-05-16T11:56:50.556-04:00",
      //     url: "https://www.youtube.com/watch?v=oAg3pP-PYok"
      //   }
      ]
      return response;

    }).error(function(response) {

      return {'status':false};

    })

    return promise;

  }

}])<|endoftext|>


<commit_before>module.exports = function (grunt) {
	'use strict';

	require('source-map-support').install();

	var path = require('path');
	var childProcess = require('child_process');

	grunt.loadNpmTasks('grunt-ts');
	grunt.loadNpmTasks('grunt-ts-clean');
	grunt.loadNpmTasks('grunt-tslint');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-clean');

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		jshint: {
			options: grunt.util._.extend(grunt.file.readJSON('.jshintrc'), {
				reporter: './node_modules/jshint-path-reporter'
			}),
			support: {
				options: {
					node: true
				},
				src: ['Gruntfile.js']
			}
		},
		tslint: {
			options: {
				configuration: grunt.file.readJSON('tslint.json'),
				formatter: 'tslint-path-formatter'
			},
			src: ['src/**/*.ts'],
			test: ['test/src/**/*.ts']
		},
		ts_clean: {
			dist: {
				options: {
					verbose: false
				},
				src: ['dist/**/*'],
				dot: true
			}
		},
		clean: {
			cruft: [
				'tscommand-*.tmp.txt',
				'dist/.baseDir*'
			],
			dist: [
				'dist/**/*'
			],
			tmp: {
				dot: true,
				src: [
				'tmp/**/*'
				]
			},
			test: [
				'test/tmp/**/*'
			]
		},
		ts: {
			options: {
				fast: 'never',
				target: 'es5',
				module: 'commonjs',
				sourceMap: true,
				declaration: true,
				comments: true,
				verbose: false
			},
			build: {
				options: {
					noImplicitAny: true
				},
				src: ['src/**/*.ts'],
				outDir: 'dist/'
			}
		},
		exec: {
			test: {
				options: {
					full: (process.env.TRAVIS === 'true')
				}
			}
		}
	});

	grunt.registerMultiTask('exec', function () {
		var options = this.options({
			full: false
		});
		var done = this.async();

		var run = function (target) {
			var args = [];
			args.push(path.resolve(__dirname, 'dist', 'index.js'));
			if (options.tests) {
				args.push('--tests');
			}
			if (options.lint) {
				args.push('--lint');
			}
			if (options.changes) {
				args.push('--changes');
			}
			if (options.debug) {
				args.push('--debug');
			}
			args.push('--path', target);
			var opts = {
				cwd: target,
				stdio: 'inherit'
			};
			childProcess.spawn('node', args, opts).on('close', function (code) {
				console.log('child process exited with code ' + code);
				done((code === 0));
			});
		};

		if (options.full) {
			var fs = require('fs');
			fs.mkdirSync('tmp');

			var Git = require('git-wrapper');
			var git = new Git({
				'git-dir': 'tmp/.git'
			});
			var opts = {
				depth: 20
			};
			var args = [
				'https://github.com/borisyankov/DefinitelyTyped',
				'tmp'
			];
			console.log('cloning repos..');

			git.exec('clone', opts, args, function (err, msg) {
				console.log(msg);
				if (err) {
					done(err);
				}
				else {
					run(path.resolve(__dirname, 'tmp'));
				}
			});
		}
		else {
			run(path.resolve(__dirname, '..', 'DefinitelyTyped-dojo'));
		}
	});

	grunt.registerTask('dev', [
		'prep',
		'ts:build',
		'exec'
	]);

	grunt.registerTask('run', [
		'clean:tmp',
		'exec'
	]);

	grunt.registerTask('prep', [
		'clean:tmp',
		'clean:dist',
		'clean:cruft',
		'jshint:support'
	]);

	grunt.registerTask('compile', [
		'prep',
		'ts:build',
		'tslint:src'
	]);

	grunt.registerTask('build', [
		'compile',
		'sweep'
	]);

	grunt.registerTask('test', [
		'build',
		'exec'
	]);

	grunt.registerTask('prepublish', [
		'build',
		'ts_clean:dist'
	]);

	grunt.registerTask('sweep', [
		'clean:cruft',
		'clean:tmp',
		'clean:test'
	]);

	grunt.registerTask('debug', ['build']);

	grunt.registerTask('default', ['build']);
};
<commit_msg>tuned gruntfile<commit_after>module.exports = function (grunt) {
	'use strict';

	require('source-map-support').install();

	var path = require('path');
	var childProcess = require('child_process');

	grunt.loadNpmTasks('grunt-ts');
	grunt.loadNpmTasks('grunt-ts-clean');
	grunt.loadNpmTasks('grunt-tslint');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-clean');

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		jshint: {
			options: grunt.util._.extend(grunt.file.readJSON('.jshintrc'), {
				reporter: './node_modules/jshint-path-reporter'
			}),
			support: {
				options: {
					node: true
				},
				src: ['Gruntfile.js']
			}
		},
		tslint: {
			options: {
				configuration: grunt.file.readJSON('tslint.json'),
				formatter: 'tslint-path-formatter'
			},
			src: ['src/**/*.ts'],
			test: ['test/src/**/*.ts']
		},
		ts_clean: {
			dist: {
				options: {
					verbose: false
				},
				src: ['dist/**/*'],
				dot: true
			}
		},
		clean: {
			cruft: [
				'tscommand-*.tmp.txt',
				'dist/.baseDir*'
			],
			dist: [
				'dist/**/*'
			],
			tmp: {
				dot: true,
				src: [
				'tmp/**/*'
				]
			},
			test: [
				'test/tmp/**/*'
			]
		},
		ts: {
			options: {
				fast: 'never',
				target: 'es5',
				module: 'commonjs',
				sourceMap: true,
				declaration: true,
				comments: true,
				verbose: false
			},
			build: {
				options: {
					noImplicitAny: true
				},
				src: ['src/**/*.ts'],
				outDir: 'dist/'
			}
		},
		exec: {
			test: {
				options: {
					full: (process.env.TRAVIS === 'true')
				}
			}
		}
	});

	grunt.registerMultiTask('exec', function () {
		var options = this.options({
			full: true
		});
		var done = this.async();

		var run = function (target) {
			var args = [];
			args.push(path.resolve(__dirname, 'dist', 'index.js'));
			if (options.tests) {
				args.push('--tests');
			}
			if (options.lint) {
				args.push('--lint');
			}
			if (options.changes) {
				args.push('--changes');
			}
			if (options.debug) {
				args.push('--debug');
			}
			args.push('--path', target);
			var opts = {
				cwd: target,
				stdio: 'inherit'
			};
			childProcess.spawn('node', args, opts).on('close', function (code) {
				console.log('child process exited with code ' + code);
				done((code === 0));
			});
		};

		if (options.full) {
			var fs = require('fs');
			var repoDir = path.join(__dirname, 'tmp');
			fs.mkdirSync(repoDir);

			var Git = require('git-wrapper');
			var git = new Git({
				'git-dir': path.join(repoDir, '.git')
			});
			var opts = {
				depth: 20
			};
			var args = [
				'https://github.com/borisyankov/DefinitelyTyped',
				repoDir
			];
			console.log('cloning repos..');

			git.exec('clone', opts, args, function (err, msg) {
				console.log(msg);
				if (err) {
					done(err);
				}
				else {
					run(repoDir);
				}
			});
		}
		else {
			run(path.resolve(__dirname, '..', 'DefinitelyTyped-alt'));
		}
	});

	grunt.registerTask('dev', [
		'prep',
		'ts:build',
		'exec'
	]);

	grunt.registerTask('run', [
		'clean:tmp',
		'exec'
	]);

	grunt.registerTask('prep', [
		'clean:tmp',
		'clean:dist',
		'clean:cruft',
		'jshint:support'
	]);

	grunt.registerTask('compile', [
		'prep',
		'ts:build',
		'tslint:src'
	]);

	grunt.registerTask('build', [
		'compile',
		'sweep'
	]);

	grunt.registerTask('test', [
		'build',
		'exec'
	]);

	grunt.registerTask('prepublish', [
		'build',
		'ts_clean:dist'
	]);

	grunt.registerTask('sweep', [
		'clean:cruft',
		'clean:tmp',
		'clean:test'
	]);

	grunt.registerTask('debug', ['build']);

	grunt.registerTask('default', ['build']);
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
    grunt.initConfig({
        jshint: {
            files: ['client/js/**/*.js', 'server/**/*.js', 'test/*.js'],
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                ignores: ['public/**/*.js'],
                globals: {
                    jQuery: true
                }
            }
        },
        browserify: {
            build: {
                dest: 'public/js/site.js',
                src: ['client/js/index.js'],
                options: {
                    alias: ['client/js/index.js:s7n']
                }
            }
        },
        sass: {
            options: {
                includePaths: [
                    'bower_components/foundation/scss',
                    'bower_components/font-awesome/scss'
                ]
            },
            dest: {
                options: {
                    outputStyle: 'compressed'
                },
                files: {
                    'tmp/css/styles.css': 'client/scss/styles.scss'
                }
            }
        },
        coffee: {
            compile: {
                options: {
                    bare: true
                },
                files: {
                    'tmp/js/chosen.js': [
                        'bower_components/chosen/coffee/lib/abstract-chosen.coffee',
                        'bower_components/chosen/coffee/lib/select-parser.coffee',
                        'bower_components/chosen/coffee/chosen.jquery.coffee'
                    ]
                }
            }
        },
        concat: {
            css: {
                src: [
                    'client/vendor/css/**/*.css',
                    'bower_components/dropzone/downloads/css/dropzone.css',
                    'tmp/css/styles.css'
                ],
                dest: 'public/css/site.css'
            },
            vendor: {
                src: [
                    'bower_components/underscore/underscore.js',
                    'bower_components/jquery/jquery.js',
                    'bower_components/foundation/js/foundation.js',
                    'bower_components/moment/moment.js',
                    'bower_components/dropzone/downloads/dropzone.js',
                    'bower_components/ractive/Ractive.js',
                    'bower_components/ractive-events-tap/Ractive-events-tap.js',
                    'tmp/js/chosen.js',
                    'client/vendor/js/*.js'
                ],
                dest: 'public/js/vendor.js'
            }
        },
        copy: {
            js: {
                expand: true,
                flatten: true,
                filter: 'isFile',
                src: ['bower_components/foundation/js/vendor/modernizr.js'],
                dest: 'public/js/'
            },
            font: {
                expand: true,
                flatten: true,
                filter: 'isFile',
                src: ['bower_components/font-awesome/fonts/*'],
                dest: 'public/fonts/'
            },
            img: {
                expand: true,
                cwd: 'client/img',
                src: ['**'],
                dest: 'public/img/'
            },
            dropzone: {
                expand: true,
                flatten: true,
                cwd: 'bower_components',
                src: ['dropzone/**/*.png'],
                dest: 'public/img/'
            }
        },
        uglify: {
            options: {
                mangle: false,
                compress: true
            },
            vendor: {
                files: {
                    'public/js/vendor.js': ['public/js/vendor.js']
                }
            },
            client: {
                files: {
                    'public/js/site.js': ['public/js/site.js']
                }
            }
        },
        watch: {
            clientjs: {
                files: ['client/js/**/*.js'],
                tasks: ['jshint', 'browserify']
            },
            scss: {
                files: ['client/scss/**/*.scss'],
                tasks: ['sass', 'concat:css']
            }
        },
        nodemon: {
            dev: {
                options: {
                    file: 'cluster.js',
                    watchedExtensions: ['js', 'html']
                }
            }
        },
        concurrent: {
            dev: {
                tasks: ['nodemon', 'watch'],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        abideExtract: {
            js: {
                src: 'server/**/*.js',
                dest: 'locale/templates/LC_MESSAGES/messages.pot'
            },
            jade: {
                src: 'server/views/**/*.jade',
                dest: 'locale/templates/LC_MESSAGES/messages.pot',
                options: {
                    language: 'jade',
                    keyword: '__'
                }
            }
        },
        abideMerge: {
            messages: {
                options: {
                    template: 'locale/templates/LC_MESSAGES/messages.pot',
                    localeDir: 'locale',
                }
            }
        },
        abideCompile: {
            json: {
                dest: 'public/locale/',
                options: {
                    type: 'json'
                }
            }
        }
    });

    //grunt.loadTasks('tasks');

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-nodemon');
    grunt.loadNpmTasks('grunt-concurrent');
    grunt.loadNpmTasks('grunt-i18n-abide');
    grunt.loadNpmTasks('grunt-contrib-coffee');

    grunt.registerTask('default', ['jshint', 'sass', 'coffee', 'concat', 'copy', 'browserify', 'abideCompile']);
    grunt.registerTask('prod', ['default', 'uglify']);
    grunt.registerTask('hint', ['jshint']);
    grunt.registerTask('translate', ['abideExtract', 'abideMerge']);
};
<commit_msg>Copy spritemaps for chosen<commit_after>module.exports = function(grunt) {
    grunt.initConfig({
        jshint: {
            files: ['client/js/**/*.js', 'server/**/*.js', 'test/*.js'],
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                ignores: ['public/**/*.js'],
                globals: {
                    jQuery: true
                }
            }
        },
        browserify: {
            build: {
                dest: 'public/js/site.js',
                src: ['client/js/index.js'],
                options: {
                    alias: ['client/js/index.js:s7n']
                }
            }
        },
        sass: {
            options: {
                includePaths: [
                    'bower_components/foundation/scss',
                    'bower_components/font-awesome/scss'
                ]
            },
            dest: {
                options: {
                    outputStyle: 'compressed'
                },
                files: {
                    'tmp/css/styles.css': 'client/scss/styles.scss'
                }
            }
        },
        coffee: {
            compile: {
                options: {
                    bare: true
                },
                files: {
                    'tmp/js/chosen.js': [
                        'bower_components/chosen/coffee/lib/abstract-chosen.coffee',
                        'bower_components/chosen/coffee/lib/select-parser.coffee',
                        'bower_components/chosen/coffee/chosen.jquery.coffee'
                    ]
                }
            }
        },
        concat: {
            css: {
                src: [
                    'client/vendor/css/**/*.css',
                    'bower_components/dropzone/downloads/css/dropzone.css',
                    'tmp/css/styles.css'
                ],
                dest: 'public/css/site.css'
            },
            vendor: {
                src: [
                    'bower_components/underscore/underscore.js',
                    'bower_components/jquery/jquery.js',
                    'bower_components/foundation/js/foundation.js',
                    'bower_components/moment/moment.js',
                    'bower_components/dropzone/downloads/dropzone.js',
                    'bower_components/ractive/Ractive.js',
                    'bower_components/ractive-events-tap/Ractive-events-tap.js',
                    'tmp/js/chosen.js',
                    'client/vendor/js/*.js'
                ],
                dest: 'public/js/vendor.js'
            }
        },
        copy: {
            js: {
                expand: true,
                flatten: true,
                filter: 'isFile',
                src: ['bower_components/foundation/js/vendor/modernizr.js'],
                dest: 'public/js/'
            },
            font: {
                expand: true,
                flatten: true,
                filter: 'isFile',
                src: ['bower_components/font-awesome/fonts/*'],
                dest: 'public/fonts/'
            },
            img: {
                expand: true,
                cwd: 'client/img',
                src: ['**'],
                dest: 'public/img/'
            },
            dropzone: {
                expand: true,
                flatten: true,
                cwd: 'bower_components',
                src: ['dropzone/**/*.png'],
                dest: 'public/img/'
            },
            chosen: {
                expand: true,
                flatten: true,
                src: ['bower_components/chosen/public/*.png'],
                dest: 'public/img/'
            }
        },
        uglify: {
            options: {
                mangle: false,
                compress: true
            },
            vendor: {
                files: {
                    'public/js/vendor.js': ['public/js/vendor.js']
                }
            },
            client: {
                files: {
                    'public/js/site.js': ['public/js/site.js']
                }
            }
        },
        watch: {
            clientjs: {
                files: ['client/js/**/*.js'],
                tasks: ['jshint', 'browserify']
            },
            scss: {
                files: ['client/scss/**/*.scss'],
                tasks: ['sass', 'concat:css']
            }
        },
        nodemon: {
            dev: {
                options: {
                    file: 'cluster.js',
                    watchedExtensions: ['js', 'html']
                }
            }
        },
        concurrent: {
            dev: {
                tasks: ['nodemon', 'watch'],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        abideExtract: {
            js: {
                src: 'server/**/*.js',
                dest: 'locale/templates/LC_MESSAGES/messages.pot'
            },
            jade: {
                src: 'server/views/**/*.jade',
                dest: 'locale/templates/LC_MESSAGES/messages.pot',
                options: {
                    language: 'jade',
                    keyword: '__'
                }
            }
        },
        abideMerge: {
            messages: {
                options: {
                    template: 'locale/templates/LC_MESSAGES/messages.pot',
                    localeDir: 'locale',
                }
            }
        },
        abideCompile: {
            json: {
                dest: 'public/locale/',
                options: {
                    type: 'json'
                }
            }
        }
    });

    //grunt.loadTasks('tasks');

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-nodemon');
    grunt.loadNpmTasks('grunt-concurrent');
    grunt.loadNpmTasks('grunt-i18n-abide');
    grunt.loadNpmTasks('grunt-contrib-coffee');

    grunt.registerTask('default', ['jshint', 'sass', 'coffee', 'concat', 'copy', 'browserify', 'abideCompile']);
    grunt.registerTask('prod', ['default', 'uglify']);
    grunt.registerTask('hint', ['jshint']);
    grunt.registerTask('translate', ['abideExtract', 'abideMerge']);
};
<|endoftext|>