<commit_before>const fs = require('fs')
const util = require('util')
const parser = require('json-schema-parser')
const immutable = require('immutable')

const buf = fs.readFileSync('./docs/schema/schema.json')
// console.log(JSON.stringify({}, null, 2))
const schemaDef = immutable.fromJS(parser.parse(JSON.parse(buf.toString())))

const printRecursive = (obj, depth, parentKey) => {
  obj.map((v, k) => {
    if (parentKey === 'properties' && !(depth === 1 && k === 'error')) {
      console.log(`[${depth}]${k} ${v.getIn(['type', 0])} ${v.get('description')}`)
    }
    if (k !== 'definitions' && typeof(v) === 'object') {
      printRecursive(v, parentKey === 'properties' ? depth + 1 : depth, k)
    }
  })
}

// console.log(JSON.stringify(schemaDef.toJS(), null, 2))

printRecursive(schemaDef, 1)

// console.log(JSON.stringify(schemaDef.get('properties').toJS(), null, 2))
<commit_msg>生のJSONの形で出力できるようにした<commit_after>const fs = require('fs')
const util = require('util')
const parser = require('json-schema-parser')
const immutable = require('immutable')

const buf = fs.readFileSync('./docs/schema/schema.json')
// console.log(JSON.stringify({}, null, 2))
const schemaDef = immutable.fromJS(parser.parse(JSON.parse(buf.toString())))

const printRecursive = (obj, depth) => {
  return obj.map((v, k) => {
    if (k !== 'definitions' && !(depth === 1 && k === 'error')) {
      console.log(`[${depth}]${k} ${v.getIn(['type', 0])} ${v.get('description')}`)
      if (v.getIn(['type', 0]).toLowerCase() === 'object') {
        return immutable.fromJS({[k]: printRecursive(v.get('properties'), depth + 1)})
      } else if (v.getIn(['type', 0]).toLowerCase() === 'array') {
        const arrayProp = v.getIn(['items', 'properties'])
        if (arrayProp) {
          return immutable.fromJS({[k]: [printRecursive(arrayProp, depth + 1, k)]})
        }
        // TODO: arrayの中身がobjectではない場合を考慮する
      } else if (v.getIn(['type', 0]).toLowerCase() === 'string') {
        return immutable.fromJS({[k]: '文字列'})
      } else if (v.getIn(['type', 0]).toLowerCase() === 'number') {
        return immutable.fromJS({[k]: 0})
      }
    }
  }).reduce((r, v) => r.mergeDeep(v), immutable.fromJS({}))
}

// console.log(JSON.stringify(schemaDef.toJS(), null, 2))

console.log(JSON.stringify(printRecursive(schemaDef.get('properties'), 1).toJS(), null, 2))

// console.log(JSON.stringify(schemaDef.get('properties').toJS(), null, 2))
<|endoftext|>


<commit_before>var fs = require('fs'),
    stripJSONComments = require('strip-json-comments'),
    Collection = require('../lib/index').Collection;

require('fs').readFile(process.argv.slice(2).pop(), 'utf8', function (err, data) {
    if (err) {
        throw err;
    }

    try {
        data = new Collection(JSON.parse(stripJSONComments(data)));
    }
    catch (e) {
        throw e;
    }

    var g = data.toJSON();
    // console.dir(g, {colors: true, depth: 10000});
    //
    fs.writeFileSync('output.json', JSON.stringify(g, null, 4));
});
<commit_msg>reverting change to example code<commit_after>var fs = require('fs'),
    stripJSONComments = require('strip-json-comments'),
    Collection = require('../lib/index').Collection;

require('fs').readFile(process.argv.slice(2).pop(), 'utf8', function (err, data) {
    if (err) {
        throw err;
    }

    try {
        data = new Collection(JSON.parse(stripJSONComments(data)));
    }
    catch (e) {
        throw e;
    }

    console.dir(data, {colors: true, depth: 10000});
});
<|endoftext|>


<commit_before>/* eslint no-console: ["off", { allow: ["warn"] }] */

const path = require('path');
const fs = require('fs');
const chalk = require('chalk');
const Cattleman = require('cattleman');
const shell = require('shelljs');
const sass = require('node-sass');
const importer = require('node-sass-tilde-importer');

const srcPath = 'src';
const distPath = process.env.NODE_ENV === 'production' ? 'dist' : 'app';
const importMap = {};
let builtModules = [];

function shorten(str) {
  let result = str.replace(/\.\.\//g, '');
  result = result.replace(/\//g, path.sep);
  return result;
}

async function build(module) {
  const srcPathDirs = srcPath.split('/');
  const outputStyle = process.env.NODE_ENV === 'production' ? 'compressed' : 'expanded';
  const buildSourceMap = process.env.NODE_ENV !== 'production';

  const file = path.parse(module);
  const moduleDirs = file.dir.split(path.sep);
  const targetDirs = moduleDirs.splice(srcPathDirs.length, moduleDirs.length);
  const targetPath = path.normalize(targetDirs.join(path.sep));
  const targetDir = path.join(distPath, targetPath);

  await sass.render({
    file: module,
    importer,
    outFile: path.join(targetDir, `${file.name}.css`),
    outputStyle,
    sourceMap: buildSourceMap,
  }, (error, result) => {
    if (!error) {
      if (!fs.existsSync(targetDir)) { shell.mkdir('-p', targetDir); }

      fs.writeFileSync(path.join(targetDir, `${file.name}.css`), result.css);

      if (buildSourceMap) {
        fs.writeFileSync(path.join(targetDir, `${file.name}.css.map`), result.map);

        const obj = JSON.parse(result.map.toString());
        const sourceFile = shorten(obj.sources[0]);
        const sourceImports = obj.sources.slice(1);
        if (sourceImports.length && !importMap[sourceFile]) {
          importMap[sourceFile] = sourceImports.map(str => shorten(str));
        }
      }
    }
  });
}

async function rebuild(module) {
  if (builtModules.includes(module)) {
    console.log('CSS: build', chalk.green(module));
    build(module);
  }

  const files = Object.keys(importMap);
  files.forEach((file) => {
    const sources = importMap[file];

    if (sources.includes(module)) {
      console.log('CSS: rebuild', chalk.green(file));
      build(file);
    }
  });
}

(async () => {
  const cattleman = new Cattleman({
    directory: srcPath,
    excludes: ['base', 'styleguide'],
  });
  const modules = cattleman.gatherFiles('.scss');

  const base = path.join('src', 'base', 'base.scss');
  const styleguide = path.join('src', 'styleguide', 'styleguide.scss');
  modules.push(base, styleguide);

  builtModules = modules;

  await Promise.all(modules.map(async (module) => {
    await build(module);
  }));
})();

exports.rebuild = rebuild;
<commit_msg>Add error handling in css task<commit_after>/* eslint no-console: ["off", { allow: ["warn"] }] */

const path = require('path');
const fs = require('fs');
const chalk = require('chalk');
const Cattleman = require('cattleman');
const shell = require('shelljs');
const sass = require('node-sass');
const importer = require('node-sass-tilde-importer');

const srcPath = 'src';
const distPath = process.env.NODE_ENV === 'production' ? 'dist' : 'app';
const importMap = {};
let builtModules = [];

function shorten(str) {
  let result = str.replace(/\.\.\//g, '');
  result = result.replace(/\//g, path.sep);
  return result;
}

async function build(module) {
  const srcPathDirs = srcPath.split('/');
  const outputStyle = process.env.NODE_ENV === 'production' ? 'compressed' : 'expanded';
  const buildSourceMap = process.env.NODE_ENV !== 'production';

  const file = path.parse(module);
  const moduleDirs = file.dir.split(path.sep);
  const targetDirs = moduleDirs.splice(srcPathDirs.length, moduleDirs.length);
  const targetPath = path.normalize(targetDirs.join(path.sep));
  const targetDir = path.join(distPath, targetPath);

  await sass.render({
    file: module,
    importer,
    outFile: path.join(targetDir, `${file.name}.css`),
    outputStyle,
    sourceMap: buildSourceMap,
  }, (error, result) => {
    if (error) {
      console.log(chalk.hex('#F00')(error));
    } else {
      if (!fs.existsSync(targetDir)) { shell.mkdir('-p', targetDir); }

      fs.writeFileSync(path.join(targetDir, `${file.name}.css`), result.css);

      if (buildSourceMap) {
        fs.writeFileSync(path.join(targetDir, `${file.name}.css.map`), result.map);

        const obj = JSON.parse(result.map.toString());
        const sourceFile = shorten(obj.sources[0]);
        const sourceImports = obj.sources.slice(1);
        if (sourceImports.length && !importMap[sourceFile]) {
          importMap[sourceFile] = sourceImports.map(str => shorten(str));
        }
      }
    }
  });
}

async function rebuild(module) {
  if (builtModules.includes(module)) {
    console.log('CSS: build', chalk.green(module));
    build(module);
  }

  const files = Object.keys(importMap);
  files.forEach((file) => {
    const sources = importMap[file];

    if (sources.includes(module)) {
      console.log('CSS: rebuild', chalk.green(file));
      build(file);
    }
  });
}

(async () => {
  const cattleman = new Cattleman({
    directory: srcPath,
    excludes: ['base', 'styleguide'],
  });
  const modules = cattleman.gatherFiles('.scss');

  const base = path.join('src', 'base', 'base.scss');
  const styleguide = path.join('src', 'styleguide', 'styleguide.scss');
  modules.push(base, styleguide);

  builtModules = modules;

  await Promise.all(modules.map(async (module) => {
    await build(module);
  }));
})();

exports.rebuild = rebuild;
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');

var _ = require('underscore');
var optimist = require('optimist');
var modest = require('../lib/modest');

// This file contains various workarounds for optimist because
//
// * .alias() doesn't work as documented (doesn't combine options in argv)
// * .string() doesn't work as documented (doesn't do anything)
// * output is only displayed if showHelp() is executed first
// * showHelp() only displays output if it is executed twice
//
// Remove the workarounds as the above items are fixed

optimist.options({
  "j" : {
    alias : "jquery",
    describe : "Path to (or URL of) jquery.  If omitted, modest will use the npm jquery module."
  },
  "q" : {
    alias : "quiet",
    describe : "Supress output."
  }
})
.alias('?','help')
.alias('h','help')
.describe('h','Show this help message.')
.usage(
  'Usage: modest [options] <directories>\n\
  \n\
  Modest is a utilty for previewing and compiling modular templates in html and making them \n\
  available to javascript.\n\
  \n\
  The "modest" command does the following in each target directory:\n\
  \n\
  1. Places a copy of the preview script (default: "modest-preview.js") for generating previews.\n\
  2. Compiles all files ending with -pre (plus an optional extension). The output files have the\n\
      same names as the input files, but with the "-pre" removed.\n\
  3. Runs (and then removes) javascript in the "-pre" files having the "pre=true" attribute in their script tags.\n\
  4. If one or more modules needs to be available in javascript, creates a "modest.js" containing\n\
      the compiled modules and code needed to support them.  Supported modules are shared by the\n\
      files in the same directory, i.e. there is one "modest.js" file per directory.\n\
  \n\
  If no directories are supplied, the current directory is used.\n\
  \n\
  See "https://github.com/goalzen/modest/wiki/Documentation" for documentation.\n'
);

var argv = optimist.argv;

if(argv.h || argv['?'] || argv.help){
  optimist.showHelp() || optimist.showHelp();
  process.exit();
}

function assertSingleValue(opt){
  if(_.isBoolean(opt)){
    optimist.showHelp(console.log);
    console.error('Error: Option had no value, or no space between option and value');
    process.exit(1);
  }
  if(_.isArray(opt)){
    optimist.showHelp(console.log);
    console.error('Error: Multiple options of the same type');
    process.exit(2);
  }
}

[argv.j,argv.jquery].forEach(assertSingleValue);

var dirs = argv._;

if(_.isEmpty(dirs))
  dirs.push('.');

params = {
  jqueryPath : argv.j || argv.jquery,
  quiet : argv.q || argv.quiet,
  dirs : dirs
};

modest.compile(params);
<commit_msg>fix typo in help<commit_after>#!/usr/bin/env node

var fs = require('fs');

var _ = require('underscore');
var optimist = require('optimist');
var modest = require('../lib/modest');

// This file contains various workarounds for optimist because
//
// * .alias() doesn't work as documented (doesn't combine options in argv)
// * .string() doesn't work as documented (doesn't do anything)
// * output is only displayed if showHelp() is executed first
// * showHelp() only displays output if it is executed twice
//
// Remove the workarounds as the above items are fixed

optimist.options({
  "j" : {
    alias : "jquery",
    describe : "Path to (or URL of) jquery.  If omitted, modest will use the npm jquery module."
  },
  "q" : {
    alias : "quiet",
    describe : "Suppress output."
  }
})
.alias('?','help')
.alias('h','help')
.describe('h','Show this help message.')
.usage(
  'Usage: modest [options] <directories>\n\
  \n\
  Modest is a utilty for previewing and compiling modular templates in html and making them \n\
  available to javascript.\n\
  \n\
  The "modest" command does the following in each target directory:\n\
  \n\
  1. Places a copy of the preview script (default: "modest-preview.js") for generating previews.\n\
  2. Compiles all files ending with -pre (plus an optional extension). The output files have the\n\
      same names as the input files, but with the "-pre" removed.\n\
  3. Runs (and then removes) javascript in the "-pre" files having the "pre=true" attribute in their script tags.\n\
  4. If one or more modules needs to be available in javascript, creates a "modest.js" containing\n\
      the compiled modules and code needed to support them.  Supported modules are shared by the\n\
      files in the same directory, i.e. there is one "modest.js" file per directory.\n\
  \n\
  If no directories are supplied, the current directory is used.\n\
  \n\
  See "https://github.com/goalzen/modest/wiki/Documentation" for documentation.\n'
);

var argv = optimist.argv;

if(argv.h || argv['?'] || argv.help){
  optimist.showHelp() || optimist.showHelp();
  process.exit();
}

function assertSingleValue(opt){
  if(_.isBoolean(opt)){
    optimist.showHelp(console.log);
    console.error('Error: Option had no value, or no space between option and value');
    process.exit(1);
  }
  if(_.isArray(opt)){
    optimist.showHelp(console.log);
    console.error('Error: Multiple options of the same type');
    process.exit(2);
  }
}

[argv.j,argv.jquery].forEach(assertSingleValue);

var dirs = argv._;

if(_.isEmpty(dirs))
  dirs.push('.');

params = {
  jqueryPath : argv.j || argv.jquery,
  quiet : argv.q || argv.quiet,
  dirs : dirs
};

modest.compile(params);
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular.module('ps.sync').service('SyncService', function ($rootScope) {
        this.updateScope = function () {
            var event = localStorage.getItem('event');
            if (event) {
                $rootScope.event = JSON.parse(event);
                $rootScope.$apply();
                console.log('updated scope');
            }
        };

        this.persistScope = function() {
            localStorage.setItem('event', JSON.stringify($rootScope.event));
            console.log('persisted scope');
        };

        return this;
    });
})();<commit_msg>use angular to/fromJson<commit_after>(function () {
    'use strict';

    angular.module('ps.sync').service('SyncService', function ($rootScope) {
        this.updateScope = function () {
            var event = localStorage.getItem('event');
            if (event) {
                $rootScope.event = angular.fromJson(event);
                $rootScope.$apply();
                console.log('updated scope');
            }
        };

        this.persistScope = function () {
            if (!$rootScope.event) {
                $rootScope.event = {};
            }
            localStorage.setItem('event', angular.toJson($rootScope.event));
            console.log('persisted scope');
        };

        return this;
    });
})();<|endoftext|>


<commit_before>function showState(data){
	var tomorrow = moment().add(1,'days');
	var now = moment();

	var birthday_org = moment(data.baby.birthday);
	var birthday = moment(data.baby.birthday2);

	var diff_day = tomorrow.diff(birthday,'days');
	var diff_day_org = now.diff(birthday_org,'days',true);
	var hour = 24*(diff_day_org - parseInt(diff_day_org));
	var minute = 60*(hour - parseInt(hour));
	var sec = 60*(minute - parseInt(minute));
	var duration = moment.duration(tomorrow.diff(birthday));

	var months = parseInt(duration.years()*12 + duration.months());
	var days = parseInt(duration.days());

	$('#current-state').text('');

	var str = $("
 태어난지 "+months+"개월 "+days+"일 이 지났습니다. ("+parseInt(diff_day)+"일)
정확히는 "+parseInt(diff_day_org)+"일 "+parseInt(hour)+"시간 "+parseInt(minute)+"분 "+parseInt(sec)+"초 지났습니다.
");

	$('#current-state').append(str);

	setTimeout(function(){
		showState(data);
	}, 1000);
}

function showEvents(data){
	for(var i in data.events){
		var t_event = data.events[i];

		var event_value = t_event.value;
		var now = moment();

		if(t_event.type == 'days'){
			event_value += 1;
			//now = moment().add(1,'days');
		}

		var event_day = moment(data.baby.birthday2).add(t_event.value,t_event.type);

		var diff_day = event_day.diff(now,'days',true);
		if(diff_day < 0) continue;

		var row = $("
");
		var title = $(""+t_event.name+"	");
		var date = $(""+event_day.format('YYYY-MM-DD')+"	");
		var diff = $(""+parseInt(diff_day+1)+"	");

		$("#event-state-body").append( row.append(title,date,diff) );
	}
}
<commit_msg>bug fix<commit_after>function showState(data){
	var tomorrow = moment().add(1,'days');
	var now = moment();

	var birthday_org = moment(data.baby.birthday);
	var birthday = moment(data.baby.birthday2);

	var diff_day = tomorrow.diff(birthday,'days');
	var diff_day_org = now.diff(birthday_org,'days',true);
	var hour = 24*(diff_day_org - parseInt(diff_day_org));
	var minute = 60*(hour - parseInt(hour));
	var sec = 60*(minute - parseInt(minute));
	var duration = moment.duration(tomorrow.diff(birthday));

	var months = parseInt(duration.years()*12 + duration.months());
	var days = parseInt(duration.days());

	$('#current-state').text('');

	var str = $("
 태어난지 "+months+"개월 "+days+"일 이 지났습니다. ("+parseInt(diff_day)+"일)
정확히는 "+parseInt(diff_day_org)+"일 "+parseInt(hour)+"시간 "+parseInt(minute)+"분 "+parseInt(sec)+"초 지났습니다.
");

	$('#current-state').append(str);

	setTimeout(function(){
		showState(data);
	}, 1000);
}

function showEvents(data){
	for(var i in data.events){
		var t_event = data.events[i];

		var event_value = t_event.value;
		var now = moment();

		if(t_event.type == 'd'){
			event_value += 1;
			//now = moment().add(1,'days');
		}

		var event_day = moment(data.baby.birthday2).add(t_event.value,t_event.type);

		var diff_day = event_day.diff(now,'days',true);
		if(diff_day < 0) continue;

		var row = $("
");
		var title = $(""+t_event.name+"	");
		var date = $(""+event_day.format('YYYY-MM-DD')+"	");
		var diff = $(""+parseInt(diff_day+1)+"	");

		$("#event-state-body").append( row.append(title,date,diff) );
	}
}
<|endoftext|>


<commit_before>var models = require('../models');

var schemaController = {};

schemaController.getSchemas = function(req, res){
    var developer = 1; //TODO: Load from middleware
    models.Schema.findAll({
        where: {
            DeveloperId: developer
        }
    }).then(function(schemas){
        res.json(schemas);
    });
};

schemaController.postSchemas = function(req, res){
    //TODO: Implement
};

schemaController.getSchema = function(req, res){
    //TODO: Implement
};

schemaController.putSchema = function(req, res){
    //TODO: Implement
};

schemaController.deleteSchema = function(req, res){
    //TODO: Implement
};

module.exports = schemaController;<commit_msg>Implemented resource Schema<commit_after>var models = require('../models');

var schemaController = {};

schemaController.getSchemas = function(req, res){
    var developer = req.authenticated.type === 'developer' ? req.authenticated.entity : req.authenticated.entity.Developer;
    models.Schema.findAll({
        where: {
            DeveloperId: developer.id
        }
    }).then(function(schemas){
        res.json(schemas);
    });
};

schemaController.postSchemas = function(req, res){
    var developer = req.authenticated.type === 'developer' ? req.authenticated.entity : req.authenticated.entity.Developer;
    models.Schema.create({
        name: req.body.name,
        DeveloperId: developer.id,
        dataRules: req.body.dataRules,
        maxBlobs: req.body.maxBlobs,
        maxBlobSize: req.body.maxBlobSize
    }).then(function(schema){
        res.json(schema);
    });
};

schemaController.getSchema = function(req, res){
    var developer = req.authenticated.type === 'developer' ? req.authenticated.entity : req.authenticated.entity.Developer;
    models.Schema.findOne({
        where:{
            id: req.params.schema,
            DeveloperId: developer.id
        }
    }).then(function(schema){
        if(schema){
            res.json(schema);
        }else{
            res.json({
                error: "Not Found"
            });
        }
    });
};

schemaController.putSchema = function(req, res){
    var developer = req.authenticated.type === 'developer' ? req.authenticated.entity : req.authenticated.entity.Developer;
    models.Group.findOne({
        where: {
            id:req.params.group,
            DeveloperId: developer.id
        }

    }).then(function(group){
        if(group){
            group.name = req.body.name;
            group.save().then(function(savedGroup){
                res.json(savedGroup);
            });
        }else{
            res.json({
                error: "Not Found"
            });
        }

    });
};

schemaController.deleteSchema = function(req, res){
    var developer = req.authenticated.type === 'developer' ? req.authenticated.entity : req.authenticated.entity.Developer;
    models.Schema.destroy({
        where:{
            id: req.params.schema,
            DeveloperId: developer.id
        }
    }).then(function(numDestroyed){
        if(0 < numDestroyed){
            res.json({
                status: "Success"
            });
        }else{
            res.json({
                error: "Not Found"
            });
        }
    });
};

module.exports = schemaController;<|endoftext|>


<commit_before>// http://eslint.org/
module.exports = {
    "extends": "eslint:recommended",

    // http://eslint.org/docs/user-guide/configuring#specifying-environments
    "env": {
        "browser": true,
    },

    // http://eslint.org/docs/user-guide/configuring#specifying-globals
    "globals": {
        // false means it shouldn't be overwritten
        "define": false,
        "hqDefine": false,
        "hqImport": false,
        "requirejs": false,
        "gettext": false,
        "ngettext": false,
        "assert": false,
        "sinon": false,
        "$": false,
        "ko": false,
        "_": false,
        "L": true,
        "it": false,
        "describe": false,
        "beforeEach": false,
    },

    // http://eslint.org/docs/rules/
    // http://eslint.org/docs/user-guide/configuring#configuring-rules
    "rules": {
        // First option can be off, warn, or error
        "comma-dangle": ["warn", "always-multiline"],
        "eqeqeq": ["error"],
        "indent": ["warn", 4, {"SwitchCase":1}],
        "linebreak-style": ["error", "unix"],
        "semi": ["error", "always"],
        "no-new-object": ["error"],
        "no-unneeded-ternary": ["error"],
        "no-throw-literal": ["error"],
        "no-use-before-define": ["error"],
    }
};
<commit_msg>Remove no-use-before-define which doesn't do what I thought<commit_after>// http://eslint.org/
module.exports = {
    "extends": "eslint:recommended",

    // http://eslint.org/docs/user-guide/configuring#specifying-environments
    "env": {
        "browser": true,
    },

    // http://eslint.org/docs/user-guide/configuring#specifying-globals
    "globals": {
        // false means it shouldn't be overwritten
        "define": false,
        "hqDefine": false,
        "hqImport": false,
        "requirejs": false,
        "gettext": false,
        "ngettext": false,
        "assert": false,
        "sinon": false,
        "$": false,
        "ko": false,
        "_": false,
        "L": true,
        "it": false,
        "describe": false,
        "beforeEach": false,
    },

    // http://eslint.org/docs/rules/
    // http://eslint.org/docs/user-guide/configuring#configuring-rules
    "rules": {
        // First option can be off, warn, or error
        "comma-dangle": ["warn", "always-multiline"],
        "eqeqeq": ["error"],
        "indent": ["warn", 4, {"SwitchCase":1}],
        "linebreak-style": ["error", "unix"],
        "semi": ["error", "always"],
        "no-new-object": ["error"],
        "no-unneeded-ternary": ["error"],
        "no-throw-literal": ["error"],
    }
};
<|endoftext|>


<commit_before>angular.module('n52.core.flot', [])
    .directive('flot', ['$translate',
        function($translate) {
            return {
                restrict: 'EA',
                template: '

',
                scope: {
                    seriesSelectionChanged: '&onSeriesSelectionChange',
                    timeChanged: '&onTimeChange',
                    dataset: '=',
                    options: '=',
                    identifier: '='
                },
                link: function(scope, element, attributes) {
                    var height, plot, plotArea, width, _ref, _ref1;
                    plot = null;
                    width = attributes.width || '100%';
                    height = attributes.height || '100%';
                    if (((_ref = scope.options) !== null ? (_ref1 = _ref.legend) !== null ? _ref1.container : void 0 : void 0) instanceof jQuery) {
                        throw 'Please use a jQuery expression string with the legend.container option.';
                    }

                    if (!scope.options) {
                        scope.options = {
                            legend: {
                                show: false
                            }
                        };
                    }

                    plotArea = $(element.children()[0]);
                    plotArea.css({
                        width: width,
                        height: height
                    });

                    var plotChart = function(plotArea, dataset, options) {
                        if (dataset && dataset.length !== 0) {
                            var plotObj = $.plot(plotArea, dataset, options);
                            createPlotAnnotation(plotArea, options);
                            createYAxis(plotObj);
                            setSelection(plotObj, options);
                        } else {
                            plotArea.empty();
                            $('.axisLabel').remove();
                        }
                    };

                    var setSelection = function(plot, options) {
                        if (plot && options.selection.range) {
                            plot.setSelection({
                                xaxis: {
                                    from: options.selection.range.from,
                                    to: options.selection.range.to
                                }
                            }, true);
                        }
                    };

                    var createPlotAnnotation = function(plotArea, options) {
                        if (!options.annotation || !options.annotation.hide) {
                            plotArea.append('
' + $translate.instant('chart.annotation') + '
');
                        }
                    };

                    var createYAxis = function(plot) {
                        if (plot.getOptions().yaxis.show) {
                            // remove old labels
                            $(plot.getPlaceholder()).find('.yaxisLabel').remove();

                            // createYAxis
                            $.each(plot.getAxes(), $.proxy(function(i, axis) {
                                if (!axis.show)
                                    return;
                                var box = axis.box;
                                if (axis.direction === 'y') {
                                    $('

')
                                        .data('axis.n', axis.n)
                                        .appendTo(plot.getPlaceholder());
                                    $('

')
                                        .data('axis.n', axis.n)
                                        .appendTo(plot.getPlaceholder())
                                        .click($.proxy(function(event) {
                                            var selection = {};
                                            var target = $(event.currentTarget);
                                            var selected = false;
                                            $.each($('.axisTarget'), function(index, elem) {
                                                elem = $(elem);
                                                if (target.data('axis.n') === elem.data('axis.n')) {
                                                    selected = elem.hasClass('selected');
                                                    return false; // break loop
                                                }
                                            });
                                            $.each(plot.getData(), function(index, elem) {
                                                if (target.data('axis.n') === elem.yaxis.n) {
                                                    selection[elem.id] = !selected;
                                                } else {
                                                    selection[elem.id] = false;
                                                }
                                            });
                                            if (!selected) {
                                                target.addClass('selected');
                                            }
                                            scope.$apply();
                                            scope.seriesSelectionChanged({
                                                selection: selection
                                            });
                                            scope.$emit('redrawChart');
                                        }, this));
                                    var yaxisLabel = $('

').text(axis.options.uom)
                                        .appendTo(plot.getPlaceholder())
                                        .data('axis.n', axis.n);
                                    if (axis.options.tsColors) {
                                        $.each(axis.options.tsColors, function(idx, color) {
                                            $('').html(' ●').css('color', color).addClass('labelColorMarker').appendTo(yaxisLabel);
                                        });
                                    }
                                    yaxisLabel.css('margin-left', -8 - (yaxisLabel.height() - yaxisLabel.width()) / 2);
                                }
                            }, this));

                            // set selection to axis
                            $.each(plot.getData(), function(index, elem) {
                                if (elem.selected) {
                                    $('.flot-y' + elem.yaxis.n + '-axis').addClass('selected');
                                    $.each($('.axisTarget'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                    $.each($('.axisTargetStyle'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                    $.each($('.axisLabel.yaxisLabel'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                }
                            });
                        }
                    };

                    scope.$watch('options', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    }, true);

                    scope.$watch('dataset', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    }, true);

                    addResizeListener(element[0], function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    });

                    var redrawChartListener = scope.$on('redrawChart', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    });

                    $(plotArea).bind('plotzoom', function(evt, plot) {
                        var xaxis = plot.getXAxes()[0];
                        var from = moment(xaxis.min);
                        var till = moment(xaxis.max);
                        changeTime(from, till);
                    });

                    // plot pan ended event
                    $(plotArea).bind('plotpanEnd', function(evt, plot) {
                        var xaxis = plot.getXAxes()[0];
                        changeTime(moment(xaxis.min), moment(xaxis.max));
                    });

                    $(plotArea).bind('touchended', function(evt, plot) {
                        var xaxis = plot.xaxis;
                        var from = moment(xaxis.from);
                        var till = moment(xaxis.to);
                        changeTime(from, till);
                    });

                    // plot selected event
                    $(plotArea).bind('plotselected', function(evt, ranges) {
                        changeTime(moment(ranges.xaxis.from), moment(ranges.xaxis.to));
                    });

                    var changeTime = function(from, till) {
                        scope.timeChanged({
                            time: {
                                from: from,
                                till: till
                            }
                        });
                    };

                    scope.$on('$destroy', function() {
                        redrawChartListener();
                    });
                }
            };
        }
    ]);

// borrowed from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ to have a cross browser solution for element resize detection
(function() {
    var attachEvent = document.attachEvent;
    var isIE = navigator.userAgent.match(/Trident/);
    console.log(isIE);
    var requestFrame = (function() {
        var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||

            function(fn) {
                return window.setTimeout(fn, 20);
            };
        return function(fn) {
            return raf(fn);
        };
    })();

    var cancelFrame = (function() {
        var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
            window.clearTimeout;
        return function(id) {
            return cancel(id);
        };
    })();

    function resizeListener(e) {
        var win = e.target || e.srcElement;
        if (win.__resizeRAF__) cancelFrame(win.__resizeRAF__);
        win.__resizeRAF__ = requestFrame(function() {
            var trigger = win.__resizeTrigger__;
            trigger.__resizeListeners__.forEach(function(fn) {
                fn.call(trigger, e);
            });
        });
    }

    function objectLoad(e) {
        this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__;
        this.contentDocument.defaultView.addEventListener('resize', resizeListener);
    }

    window.addResizeListener = function(element, fn) {
        if (!element.__resizeListeners__) {
            element.__resizeListeners__ = [];
            if (attachEvent) {
                element.__resizeTrigger__ = element;
                element.attachEvent('onresize', resizeListener);
            } else {
                if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
                var obj = element.__resizeTrigger__ = document.createElement('object');
                obj.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');
                obj.__resizeElement__ = element;
                obj.onload = objectLoad;
                obj.type = 'text/html';
                if (isIE) element.appendChild(obj);
                obj.data = 'about:blank';
                if (!isIE) element.appendChild(obj);
            }
        }
        element.__resizeListeners__.push(fn);
    };

    window.removeResizeListener = function(element, fn) {
        element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
        if (!element.__resizeListeners__.length) {
            if (attachEvent) element.detachEvent('onresize', resizeListener);
            else {
                element.__resizeTrigger__.contentDocument.defaultView.removeEventListener('resize', resizeListener);
                element.__resizeTrigger__ = !element.removeChild(element.__resizeTrigger__);
            }
        }
    };
})();
<commit_msg>closes #20 - moved the resizing in an angular service<commit_after>angular.module('n52.core.flot', [])
    .directive('flot', ['$translate', 'resizeSrvc',
        function($translate, resizeSrvc) {
            return {
                restrict: 'EA',
                template: '

',
                scope: {
                    seriesSelectionChanged: '&onSeriesSelectionChange',
                    timeChanged: '&onTimeChange',
                    dataset: '=',
                    options: '=',
                    identifier: '='
                },
                link: function(scope, element, attributes) {
                    var height, plot, plotArea, width, _ref, _ref1;
                    plot = null;
                    width = attributes.width || '100%';
                    height = attributes.height || '100%';
                    if (((_ref = scope.options) !== null ? (_ref1 = _ref.legend) !== null ? _ref1.container : void 0 : void 0) instanceof jQuery) {
                        throw 'Please use a jQuery expression string with the legend.container option.';
                    }

                    if (!scope.options) {
                        scope.options = {
                            legend: {
                                show: false
                            }
                        };
                    }

                    plotArea = $(element.children()[0]);
                    plotArea.css({
                        width: width,
                        height: height
                    });

                    var plotChart = function(plotArea, dataset, options) {
                        if (dataset && dataset.length !== 0) {
                            var plotObj = $.plot(plotArea, dataset, options);
                            createPlotAnnotation(plotArea, options);
                            createYAxis(plotObj);
                            setSelection(plotObj, options);
                        } else {
                            plotArea.empty();
                            $('.axisLabel').remove();
                        }
                    };

                    var setSelection = function(plot, options) {
                        if (plot && options.selection.range) {
                            plot.setSelection({
                                xaxis: {
                                    from: options.selection.range.from,
                                    to: options.selection.range.to
                                }
                            }, true);
                        }
                    };

                    var createPlotAnnotation = function(plotArea, options) {
                        if (!options.annotation || !options.annotation.hide) {
                            plotArea.append('
' + $translate.instant('chart.annotation') + '
');
                        }
                    };

                    var createYAxis = function(plot) {
                        if (plot.getOptions().yaxis.show) {
                            // remove old labels
                            $(plot.getPlaceholder()).find('.yaxisLabel').remove();

                            // createYAxis
                            $.each(plot.getAxes(), $.proxy(function(i, axis) {
                                if (!axis.show)
                                    return;
                                var box = axis.box;
                                if (axis.direction === 'y') {
                                    $('

')
                                        .data('axis.n', axis.n)
                                        .appendTo(plot.getPlaceholder());
                                    $('

')
                                        .data('axis.n', axis.n)
                                        .appendTo(plot.getPlaceholder())
                                        .click($.proxy(function(event) {
                                            var selection = {};
                                            var target = $(event.currentTarget);
                                            var selected = false;
                                            $.each($('.axisTarget'), function(index, elem) {
                                                elem = $(elem);
                                                if (target.data('axis.n') === elem.data('axis.n')) {
                                                    selected = elem.hasClass('selected');
                                                    return false; // break loop
                                                }
                                            });
                                            $.each(plot.getData(), function(index, elem) {
                                                if (target.data('axis.n') === elem.yaxis.n) {
                                                    selection[elem.id] = !selected;
                                                } else {
                                                    selection[elem.id] = false;
                                                }
                                            });
                                            if (!selected) {
                                                target.addClass('selected');
                                            }
                                            scope.$apply();
                                            scope.seriesSelectionChanged({
                                                selection: selection
                                            });
                                            scope.$emit('redrawChart');
                                        }, this));
                                    var yaxisLabel = $('

').text(axis.options.uom)
                                        .appendTo(plot.getPlaceholder())
                                        .data('axis.n', axis.n);
                                    if (axis.options.tsColors) {
                                        $.each(axis.options.tsColors, function(idx, color) {
                                            $('').html(' ●').css('color', color).addClass('labelColorMarker').appendTo(yaxisLabel);
                                        });
                                    }
                                    yaxisLabel.css('margin-left', -8 - (yaxisLabel.height() - yaxisLabel.width()) / 2);
                                }
                            }, this));

                            // set selection to axis
                            $.each(plot.getData(), function(index, elem) {
                                if (elem.selected) {
                                    $('.flot-y' + elem.yaxis.n + '-axis').addClass('selected');
                                    $.each($('.axisTarget'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                    $.each($('.axisTargetStyle'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                    $.each($('.axisLabel.yaxisLabel'), function() {
                                        if ($(this).data('axis.n') === elem.yaxis.n) {
                                            if (!$(this).hasClass('selected')) {
                                                $(this).addClass('selected');
                                                return false;
                                            }
                                        }
                                    });
                                }
                            });
                        }
                    };

                    scope.$watch('options', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    }, true);

                    scope.$watch('dataset', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    }, true);

                    resizeSrvc.addResizeListener(element[0], function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    });

                    var redrawChartListener = scope.$on('redrawChart', function() {
                        plotChart(plotArea, scope.dataset, scope.options);
                    });

                    $(plotArea).bind('plotzoom', function(evt, plot) {
                        var xaxis = plot.getXAxes()[0];
                        var from = moment(xaxis.min);
                        var till = moment(xaxis.max);
                        changeTime(from, till);
                    });

                    // plot pan ended event
                    $(plotArea).bind('plotpanEnd', function(evt, plot) {
                        var xaxis = plot.getXAxes()[0];
                        changeTime(moment(xaxis.min), moment(xaxis.max));
                    });

                    $(plotArea).bind('touchended', function(evt, plot) {
                        var xaxis = plot.xaxis;
                        var from = moment(xaxis.from);
                        var till = moment(xaxis.to);
                        changeTime(from, till);
                    });

                    // plot selected event
                    $(plotArea).bind('plotselected', function(evt, ranges) {
                        changeTime(moment(ranges.xaxis.from), moment(ranges.xaxis.to));
                    });

                    var changeTime = function(from, till) {
                        scope.timeChanged({
                            time: {
                                from: from,
                                till: till
                            }
                        });
                    };

                    scope.$on('$destroy', function() {
                        redrawChartListener();
                    });
                }
            };
        }
    ])
    .service('resizeSrvc', [
        function() {
            // borrowed from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ to have a cross browser solution for element resize detection
            var attachEvent = document.attachEvent;
            var isIE = navigator.userAgent.match(/Trident/);
            console.log(isIE);
            var requestFrame = (function() {
                var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
                    function(fn) {
                        return window.setTimeout(fn, 20);
                    };
                return function(fn) {
                    return raf(fn);
                };
            })();

            var cancelFrame = (function() {
                var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
                    window.clearTimeout;
                return function(id) {
                    return cancel(id);
                };
            })();

            function resizeListener(e) {
                var win = e.target || e.srcElement;
                if (win.__resizeRAF__) cancelFrame(win.__resizeRAF__);
                win.__resizeRAF__ = requestFrame(function() {
                    var trigger = win.__resizeTrigger__;
                    trigger.__resizeListeners__.forEach(function(fn) {
                        fn.call(trigger, e);
                    });
                });
            }

            function objectLoad(e) {
                this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__;
                this.contentDocument.defaultView.addEventListener('resize', resizeListener);
            }

            this.addResizeListener = function(element, fn) {
                if (!element.__resizeListeners__) {
                    element.__resizeListeners__ = [];
                    if (attachEvent) {
                        element.__resizeTrigger__ = element;
                        element.attachEvent('onresize', resizeListener);
                    } else {
                        if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
                        var obj = element.__resizeTrigger__ = document.createElement('object');
                        obj.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');
                        obj.__resizeElement__ = element;
                        obj.onload = objectLoad;
                        obj.type = 'text/html';
                        if (isIE) element.appendChild(obj);
                        obj.data = 'about:blank';
                        if (!isIE) element.appendChild(obj);
                    }
                }
                element.__resizeListeners__.push(fn);
            };

            this.removeResizeListener = function(element, fn) {
                element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
                if (!element.__resizeListeners__.length) {
                    if (attachEvent) element.detachEvent('onresize', resizeListener);
                    else {
                        element.__resizeTrigger__.contentDocument.defaultView.removeEventListener('resize', resizeListener);
                        element.__resizeTrigger__ = !element.removeChild(element.__resizeTrigger__);
                    }
                }
            };
        }
    ]);
<|endoftext|>


<commit_before>'use strict';

describe('client', function () {

  var $scope, element, $routeParams, clientFactory, q, location, $location,
  deferred, $httpBackend, networkFactory, zoneFactory, reportFactory, groupPolicyFactory;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    clientFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      create: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    groupPolicyFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    reportFactory = {
      clientstats: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    networkFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Report", reportFactory);
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
    $provide.value("Client", clientFactory);
    $provide.value("GroupPolicy", groupPolicyFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the clients', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.period = 'my-period';
      $routeParams.per = 100;
      $routeParams.page = 10;
      $routeParams.fn = 'my-fn';
      $routeParams.type = 'my-type';
      $routeParams.ap_mac = 'ap-mac';
      $routeParams.client_mac = 'client-mac';
      $routeParams.period = '1d';
      $routeParams.policy_id = '1';
      $scope.loading = true;
      $scope.location = { slug: 123 }
      var elem = angular.element('<clients-index><clients location="location" loading="loading"></clients></clients-index>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      expect(clientScope.selected.length).toEqual(0);
      expect(clientScope.options.autoSelect).toEqual(true);
      expect(clientScope.options.boundaryLinks).toEqual(false);
      expect(clientScope.options.largeEditDialog).toEqual(false);
      expect(clientScope.options.pageSelector).toEqual(false);
      expect(clientScope.options.rowSelection).toEqual(true);
      // expect(clientScope.query.order).toEqual('-lastseen');
      expect(clientScope.query.order).toEqual('updated_at');
      expect(clientScope.query.limit).toEqual(100);
      expect(clientScope.query.page).toEqual(10);
      expect(clientScope.toggleSearch).toEqual(false);
      expect(clientScope.type).toEqual('my-type');
      expect(clientScope.ap_mac).toEqual('ap-mac');
      expect(clientScope.client_mac).toEqual('client-mac');
      expect(clientScope.policy_id).toEqual('1');
      expect(clientScope.period).toEqual('1d');

      var d = new Date();
      d.setHours(d.getHours()-2);
      var t = parseInt(d) / 1000;
      expect(clientScope.start).toEqual(t);

      expect(clientScope.menu.length).toEqual(1);
      expect(clientScope.menu[0].type).toEqual('view');
    });

    it("should trigger the menu action", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      var client = { id: 123 };
      clientScope.menuAction('view', client)
      expect($location.path()).toEqual('/locations/123/clients/123')
    });

    it("should update the search params", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      clientScope.updatePage();
      var s = $location.search();
      expect(s.ap_mac).toEqual('ap-mac');
      expect(s.client_mac).toEqual('client-mac')
    });

    it("should have the default search columns", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      expect(clientScope.columns.device_name).toEqual(true);
      expect(clientScope.columns.client_mac).toEqual(true);
      expect(clientScope.columns.ssid).toEqual(true);
      expect(clientScope.columns.txbps).toEqual(true);
      expect(clientScope.columns.rxbps).toEqual(false);
      expect(clientScope.columns.expected_throughput).toEqual(false);
      expect(clientScope.columns.tx).toEqual(true);
      expect(clientScope.columns.txbitrate).toEqual(false);
      expect(clientScope.columns.rxbitrate).toEqual(false);
      expect(clientScope.columns.snr).toEqual(true);
      expect(clientScope.columns.signal).toEqual(false);
      expect(clientScope.columns.ip).toEqual(true);
      expect(clientScope.columns.lastseen).toEqual(true);
      expect(clientScope.columns.capabilities).toEqual(false);
      expect(clientScope.columns.manufacturer).toEqual(false);
      expect(clientScope.columns.splash_username).toEqual(false);
      expect(clientScope.columns.type).toEqual(true);
    });

    it("should fetch the clients", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);
      expect(clientScope._links).toEqual({});
    });

    // Keeps failing since we added the group policies fn
    it("should load the timelines", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      spyOn(groupPolicyFactory, 'get').and.callThrough();
      spyOn(reportFactory, 'clientstats').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);
      expect(clientScope.loadingChart).toEqual(true);

      var data = { timeline: 'my-timeline' };
      deferred.resolve(data);
      $scope.$apply();

      // expect(clientScope.loadingChart).toEqual(undefined);
    });

    // Keeps failing since we added the group policies fn
    xit("should load the group policies and filter", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      spyOn(groupPolicyFactory, 'get').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);

      var data = { timeline: [] };
      deferred.resolve(data);
      $scope.$apply();

      var gp = { group_policies: [{id: 1111}] };
      deferred.resolve(data);
      $scope.$apply();

      expect(clientScope.group_policies[0].id).toEqual(111111111111);
    });

    it("should create a client", function() {
      var clientScope = element.find('client-detail').isolateScope()
      spyOn(clientFactory, 'create').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

  });

  describe('displays the client', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.period = 'my-period';
      $routeParams.fn = 'mean';
      $routeParams.ap_mac = 'ap-mac';
      $scope.loading = true;
      var elem = angular.element('<client-chart><client-detail loading="loading"></client-detail></client-chart>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    // it("should set the default scopes vals", function() {
    //   var clientScope = element.find('client-detail').isolateScope()
    //   spyOn(clientFactory, 'get').and.callThrough();
    //   expect(clientScope.location.slug).toEqual('xxx');
    //   expect(clientScope.ap_mac).toEqual('ap-mac');
    //   expect(clientScope.fn).toEqual({key: 'mean', value: 'mean'});
    //   expect(clientScope.period).toEqual('my-period');

    //   var client = { id: 123 };
    //   deferred.resolve(client);
    //   $scope.$apply();

    //   expect(clientScope.client.id).toEqual(123);
    // });

    it("should fetch the group policies", function() {
      // var clientScope = element.find('client-detail').isolateScope()
      // spyOn(clientFactory, 'update').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

    it("should update a client", function() {
      // var clientScope = element.find('client-detail').isolateScope()
      // spyOn(clientFactory, 'update').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

  });

});<commit_msg>split self-destructing network form into two<commit_after>'use strict';

describe('client', function () {

  var $scope, element, $routeParams, clientFactory, q, location, $location,
  deferred, $httpBackend, networkFactory, zoneFactory, reportFactory, groupPolicyFactory;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    clientFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      create: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    groupPolicyFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    reportFactory = {
      clientstats: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    networkFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Report", reportFactory);
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
    $provide.value("Client", clientFactory);
    $provide.value("GroupPolicy", groupPolicyFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the clients', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.period = 'my-period';
      $routeParams.per = 100;
      $routeParams.page = 10;
      $routeParams.fn = 'my-fn';
      $routeParams.type = 'my-type';
      $routeParams.ap_mac = 'ap-mac';
      $routeParams.client_mac = 'client-mac';
      $routeParams.period = '1d';
      $routeParams.policy_id = '1';
      $scope.loading = true;
      $scope.location = { slug: 123 }
      var elem = angular.element('<clients-index><clients location="location" loading="loading"></clients></clients-index>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      expect(clientScope.selected.length).toEqual(0);
      expect(clientScope.options.autoSelect).toEqual(true);
      expect(clientScope.options.boundaryLinks).toEqual(false);
      expect(clientScope.options.largeEditDialog).toEqual(false);
      expect(clientScope.options.pageSelector).toEqual(false);
      expect(clientScope.options.rowSelection).toEqual(true);
      // expect(clientScope.query.order).toEqual('-lastseen');
      expect(clientScope.query.order).toEqual('updated_at');
      expect(clientScope.query.limit).toEqual(100);
      expect(clientScope.query.page).toEqual(10);
      expect(clientScope.toggleSearch).toEqual(false);
      expect(clientScope.type).toEqual('my-type');
      expect(clientScope.ap_mac).toEqual('ap-mac');
      expect(clientScope.client_mac).toEqual('client-mac');
      expect(clientScope.policy_id).toEqual('1');
      expect(clientScope.period).toEqual('1d');

      var d = new Date();
      d.setHours(d.getHours()-2);
      var t = parseInt(d) / 1000;
      expect(clientScope.start).toEqual(t);

      expect(clientScope.menu.length).toEqual(1);
      expect(clientScope.menu[0].type).toEqual('view');
    });

    it("should trigger the menu action", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      var client = { id: 123 };
      clientScope.menuAction('view', client)
      expect($location.path()).toEqual('/locations/123/clients/123')
    });

    it("should update the search params", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      clientScope.updatePage();
      var s = $location.search();
      expect(s.ap_mac).toEqual('ap-mac');
      expect(s.client_mac).toEqual('client-mac')
    });

    it("should have the default search columns", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      expect(clientScope.columns.device_name).toEqual(true);
      expect(clientScope.columns.client_mac).toEqual(true);
      expect(clientScope.columns.ssid).toEqual(true);
      expect(clientScope.columns.txbps).toEqual(true);
      expect(clientScope.columns.rxbps).toEqual(false);
      expect(clientScope.columns.expected_throughput).toEqual(false);
      expect(clientScope.columns.tx).toEqual(true);
      expect(clientScope.columns.txbitrate).toEqual(false);
      expect(clientScope.columns.rxbitrate).toEqual(false);
      expect(clientScope.columns.snr).toEqual(true);
      expect(clientScope.columns.signal).toEqual(false);
      expect(clientScope.columns.ip).toEqual(true);
      expect(clientScope.columns.lastseen).toEqual(true);
      expect(clientScope.columns.capabilities).toEqual(false);
      expect(clientScope.columns.manufacturer).toEqual(false);
      expect(clientScope.columns.splash_username).toEqual(false);
      expect(clientScope.columns.type).toEqual(true);
    });

    it("should fetch the clients", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);
      expect(clientScope._links).toEqual({});
    });

    // Keeps failing since we added the group policies fn
    it("should load the timelines", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      spyOn(groupPolicyFactory, 'get').and.callThrough();
      spyOn(reportFactory, 'clientstats').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);
      expect(clientScope.loadingChart).toEqual(true);

      var data = { timeline: 'my-timeline' };
      deferred.resolve(data);
      $scope.$apply();

      // expect(clientScope.loadingChart).toEqual(undefined);
    });

    // Keeps failing since we added the group policies fn
    xit("should load the group policies and filter", function() {
      var clientScope = element.find('clients').isolateScope()
      spyOn(clientFactory, 'query').and.callThrough();
      spyOn(groupPolicyFactory, 'get').and.callThrough();

      var res = { clients: [{ id: 123 } ], _links: {} };
      deferred.resolve(res);
      $scope.$apply();

      expect(clientScope.clients[0].id).toEqual(123);

      var data = { timeline: [] };
      deferred.resolve(data);
      $scope.$apply();

      var gp = { group_policies: [{id: 1111}] };
      deferred.resolve(data);
      $scope.$apply();

      expect(clientScope.group_policies[0].id).toEqual(111111111111);
    });

    it("should create a client", function() {
      var clientScope = element.find('client-detail').isolateScope()
      spyOn(clientFactory, 'create').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

  });

  describe('displays the client', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.period = 'my-period';
      $routeParams.fn = 'mean';
      $routeParams.ap_mac = 'ap-mac';
      $scope.loading = true;
      var elem = angular.element('<client-chart><client-detail loading="loading"></client-detail></client-chart>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    // it("should set the default scopes vals", function() {
    //   var clientScope = element.find('client-detail').isolateScope()
    //   spyOn(clientFactory, 'get').and.callThrough();
    //   expect(clientScope.location.slug).toEqual('xxx');
    //   expect(clientScope.ap_mac).toEqual('ap-mac');
    //   expect(clientScope.fn).toEqual({key: 'mean', value: 'mean'});
    //   expect(clientScope.period).toEqual('my-period');

    //   var client = { id: 123 };
    //   deferred.resolve(client);
    //   $scope.$apply();

    //   expect(clientScope.client.id).toEqual(123);
    // });

    it("should fetch the group policies", function() {
      // var clientScope = element.find('client-detail').isolateScope()
      // spyOn(clientFactory, 'update').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

    it("should update a client", function() {
      // var clientScope = element.find('client-detail').isolateScope()
      // spyOn(clientFactory, 'update').and.callThrough();

      // clientScope.update();
      // expect(clientScope.client.updating).toEqual(true);
      // var client = { id: 123 };
      // deferred.resolve(client);
      // $scope.$apply();

      // expect(clientScope.client.updating).toEqual(undefined);
    });

  });

});
<|endoftext|>


<commit_before>/* global define */

define([
    'underscore',
    'backbone',
    '../core'
], function(_, Backbone, c) {

    var PaginatorMixin = {
        comparator: 'page_num',

        refresh: function() {
            if (!this.pending) {
                this.pending = true;

                var _this = this;
                this.fetch({
                    reset: true
                }).done(function() {
                    delete _this.pending;
                    _this.setCurrentPage(_this.models[0].id);
                });
            }
        },

        // Parses the initial fetch which is a single page, resets if necessary
        parse: function(resp, options) {
            if (!options.reset) {
                // TODO Smartly shuffle pages when only the size changes.
                // The data is not invalid, just broken up differently.
                this.reset(null, {
                    silent: true
                });
            }

            this.perPage = resp.per_page;   // jshint ignore:line
            this.trigger('change:pagesize', this, this.perPage);
            this.numPages = resp.num_pages; // jshint ignore:line
            this.trigger('change:pagecount', this, this.numPages);
            this.objectCount = resp.object_count;   // jshint ignore:line
            this.trigger('change:objectcount', this, this.objectCount);
            this.currentPageNum = null;
            this.setCurrentPage(resp.page_num); // jshint ignore:line

            return [resp];
        },

        // Ensures `num` is within the bounds
        hasPage: function(num) {
            return (1 <= num && num <= this.numPages);
        },

        // Checks the a _next_ page exists for num (or the current page)
        hasNextPage: function(num) {
            if (!num) num = this.currentPageNum;

            return num < this.numPages;
        },

        // Checks the a _previous_ page exists for num (or the current page)
        hasPreviousPage: function(num) {
            if (!num) num = this.currentPageNum;

            return num > 1;
        },

        // Set the current page which triggers the 'change:page' event
        setCurrentPage: function(num) {
            if (num === this.currentPageNum) return;

            if (!this.hasPage(num)) {
                throw new Error('Cannot set the current page out of bounds');
            }

            this.previousPageNum = this.currentPageNum;
            this.currentPageNum = num;

            return this.trigger.apply(this, ['change:currentpage', this].concat(
                [].slice.call(this.getCurrentPageStats())));
        },

        // Gets or fetches the page for num, if options.active is true
        // the page is set as the current one.
        // If the page does not already exist, the model is created, added
        // to the collected and fetched. Once fetched, the page is resolved.
        getPage: function(num, options) {
            if (!options) options = {};

            if (!this.hasPage(num)) return;

            var model = this.get(num);
            if (!model && options.load !== false) {
                model = new this.model({
                    page_num: num       // jshint ignore:line
                });

                model.pending = true;
                this.add(model);

                model.fetch().done(function() {
                    delete model.pending;
                });
            }

            if (model && options.active !== false) {
                this.setCurrentPage(num);
            }

            return model;
        },

        getCurrentPage: function(options) {
            return this.getPage(this.currentPageNum, options);
        },

        getFirstPage: function(options) {
            return this.getPage(1, options);
        },

        getLastPage: function(options) {
            return this.getPage(this.numPages, options);
        },

        // Gets the next page relative to the current page
        getNextPage: function(num, options) {
            if (!num) num = this.currentPageNum;

            return this.getPage(num + 1, options);
        },

        // Gets the previous page relative to the current page
        getPreviousPage: function(num, options) {
            if (!num) num = this.currentPageNum;

            return this.getPage(num - 1, options);
        },

        // Checks if the current page is pending. Use of this check prevents
        // stampeding the server with requests if the current one has not
        // responded yet.
        pageIsLoading: function(num) {
            if (!num) num = this.currentPageNum;

            var page = this.getPage(num, {
                active: false,
                load: false
            });

            if (page) {
                return !!page.pending;
            }
        },

        getPageCount: function() {
            return this.numPages;
        },

        getCurrentPageStats: function() {
            return [
                this.currentPageNum, {
                    previous: this.previousPageNum,
                    first: this.currentPageNum === 1,
                    last: this.currentPageNum === this.numPages
                }
            ];
        }

    };

    // Provides the facility for fetching it's own clice of content based on
    // the collection it's contained in.
    var Page = Backbone.Model.extend({
        idAttribute: 'page_num',

        url: function() {
            var url = _.result(this.collection, 'url');
            return c.utils.alterUrlParams(url, {
                page: this.id,
                per_page: this.collection.perPage   // jshint ignore:line
            });
        }
    });

    // Paginator collection for managing its pages
    var Paginator = Backbone.Collection.extend({
        model: Page
    });

    _.extend(Paginator.prototype, PaginatorMixin);

    return {
        PaginatorMixin: PaginatorMixin,
        Page: Page,
        Paginator: Paginator
    };

});
<commit_msg>Abort pending requests on paginator refresh<commit_after>/* global define */

define([
    'underscore',
    'backbone',
    '../core'
], function(_, Backbone, c) {

    var PaginatorMixin = {
        comparator: 'page_num',

        refresh: function() {
            var url = _.result(this, 'url');

            if (this.pending) {
                // Request already being made, otherwise abort
                if (url === this.pending.url) return;

                this.pending.abort();
            }

            var _this = this;

            this.pending = this.fetch({
                reset: true
            }).done(function() {
                delete _this.pending;
                _this.setCurrentPage(_this.models[0].id);
            });

            // This is a deferred and does not contain any of the
            // ajax settings, so we set the url for later reference.
            this.pending.url = url;
        },

        // Parses the initial fetch which is a single page, resets if necessary
        parse: function(resp, options) {
            if (!options.reset) {
                // TODO Smartly shuffle pages when only the size changes.
                // The data is not invalid, just broken up differently.
                this.reset(null, {
                    silent: true
                });
            }

            this.perPage = resp.per_page;   // jshint ignore:line
            this.trigger('change:pagesize', this, this.perPage);
            this.numPages = resp.num_pages; // jshint ignore:line
            this.trigger('change:pagecount', this, this.numPages);
            this.objectCount = resp.object_count;   // jshint ignore:line
            this.trigger('change:objectcount', this, this.objectCount);
            this.currentPageNum = null;
            this.setCurrentPage(resp.page_num); // jshint ignore:line

            return [resp];
        },

        // Ensures `num` is within the bounds
        hasPage: function(num) {
            return (1 <= num && num <= this.numPages);
        },

        // Checks the a _next_ page exists for num (or the current page)
        hasNextPage: function(num) {
            if (!num) num = this.currentPageNum;

            return num < this.numPages;
        },

        // Checks the a _previous_ page exists for num (or the current page)
        hasPreviousPage: function(num) {
            if (!num) num = this.currentPageNum;

            return num > 1;
        },

        // Set the current page which triggers the 'change:page' event
        setCurrentPage: function(num) {
            if (num === this.currentPageNum) return;

            if (!this.hasPage(num)) {
                throw new Error('Cannot set the current page out of bounds');
            }

            this.previousPageNum = this.currentPageNum;
            this.currentPageNum = num;

            return this.trigger.apply(this, ['change:currentpage', this].concat(
                [].slice.call(this.getCurrentPageStats())));
        },

        // Gets or fetches the page for num, if options.active is true
        // the page is set as the current one.
        // If the page does not already exist, the model is created, added
        // to the collected and fetched. Once fetched, the page is resolved.
        getPage: function(num, options) {
            if (!options) options = {};

            if (!this.hasPage(num)) return;

            var model = this.get(num);
            if (!model && options.load !== false) {
                model = new this.model({
                    page_num: num       // jshint ignore:line
                });

                model.pending = true;
                this.add(model);

                model.fetch().done(function() {
                    delete model.pending;
                });
            }

            if (model && options.active !== false) {
                this.setCurrentPage(num);
            }

            return model;
        },

        getCurrentPage: function(options) {
            return this.getPage(this.currentPageNum, options);
        },

        getFirstPage: function(options) {
            return this.getPage(1, options);
        },

        getLastPage: function(options) {
            return this.getPage(this.numPages, options);
        },

        // Gets the next page relative to the current page
        getNextPage: function(num, options) {
            if (!num) num = this.currentPageNum;

            return this.getPage(num + 1, options);
        },

        // Gets the previous page relative to the current page
        getPreviousPage: function(num, options) {
            if (!num) num = this.currentPageNum;

            return this.getPage(num - 1, options);
        },

        // Checks if the current page is pending. Use of this check prevents
        // stampeding the server with requests if the current one has not
        // responded yet.
        pageIsLoading: function(num) {
            if (!num) num = this.currentPageNum;

            var page = this.getPage(num, {
                active: false,
                load: false
            });

            if (page) {
                return !!page.pending;
            }
        },

        getPageCount: function() {
            return this.numPages;
        },

        getCurrentPageStats: function() {
            return [
                this.currentPageNum, {
                    previous: this.previousPageNum,
                    first: this.currentPageNum === 1,
                    last: this.currentPageNum === this.numPages
                }
            ];
        }

    };

    // Provides the facility for fetching it's own clice of content based on
    // the collection it's contained in.
    var Page = Backbone.Model.extend({
        idAttribute: 'page_num',

        url: function() {
            var url = _.result(this.collection, 'url');
            return c.utils.alterUrlParams(url, {
                page: this.id,
                per_page: this.collection.perPage   // jshint ignore:line
            });
        }
    });

    // Paginator collection for managing its pages
    var Paginator = Backbone.Collection.extend({
        model: Page
    });

    _.extend(Paginator.prototype, PaginatorMixin);

    return {
        PaginatorMixin: PaginatorMixin,
        Page: Page,
        Paginator: Paginator
    };

});
<|endoftext|>